diff options
594 files changed, 12665 insertions, 4747 deletions
diff --git a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java index ea733696e1f7..2b2918c0a6f0 100644 --- a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java +++ b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java @@ -28,6 +28,8 @@ import static android.app.AlarmManager.INTERVAL_HOUR; import static android.app.AlarmManager.RTC; import static android.app.AlarmManager.RTC_WAKEUP; import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY; +import static android.os.PowerWhitelistManager.REASON_ALARM_MANAGER_WHILE_IDLE; +import static android.os.PowerWhitelistManager.TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED; import static android.os.PowerWhitelistManager.TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED; import static android.os.UserHandle.USER_SYSTEM; @@ -524,10 +526,12 @@ public class AlarmManagerService extends SystemService { if (mLastAllowWhileIdleWhitelistDuration != ALLOW_WHILE_IDLE_WHITELIST_DURATION) { mLastAllowWhileIdleWhitelistDuration = ALLOW_WHILE_IDLE_WHITELIST_DURATION; - mOptsWithFgs.setTemporaryAppWhitelistDuration(ALLOW_WHILE_IDLE_WHITELIST_DURATION); - mOptsWithoutFgs.setTemporaryAppWhitelistDuration( + mOptsWithFgs.setTemporaryAppAllowlist(ALLOW_WHILE_IDLE_WHITELIST_DURATION, + TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED, + REASON_ALARM_MANAGER_WHILE_IDLE, ""); + mOptsWithoutFgs.setTemporaryAppAllowlist(ALLOW_WHILE_IDLE_WHITELIST_DURATION, TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED, - ALLOW_WHILE_IDLE_WHITELIST_DURATION); + REASON_ALARM_MANAGER_WHILE_IDLE, ""); } } diff --git a/apex/media/aidl/private/android/media/IMediaCommunicationService.aidl b/apex/media/aidl/private/android/media/IMediaCommunicationService.aidl index 3d50d14e1b83..fb3172b8c764 100644 --- a/apex/media/aidl/private/android/media/IMediaCommunicationService.aidl +++ b/apex/media/aidl/private/android/media/IMediaCommunicationService.aidl @@ -15,7 +15,17 @@ */ package android.media; +import android.media.Session2Token; +import android.media.IMediaCommunicationServiceCallback; +import android.media.MediaParceledListSlice; + /** {@hide} */ interface IMediaCommunicationService { + void notifySession2Created(in Session2Token sessionToken); + boolean isTrusted(String controllerPackageName, int controllerPid, int controllerUid); + MediaParceledListSlice getSession2Tokens(int userId); + + void registerCallback(IMediaCommunicationServiceCallback callback, String packageName); + void unregisterCallback(IMediaCommunicationServiceCallback callback); } diff --git a/apex/media/aidl/private/android/media/IMediaCommunicationServiceCallback.aidl b/apex/media/aidl/private/android/media/IMediaCommunicationServiceCallback.aidl new file mode 100644 index 000000000000..3d5321c9d7d8 --- /dev/null +++ b/apex/media/aidl/private/android/media/IMediaCommunicationServiceCallback.aidl @@ -0,0 +1,26 @@ +/** + * Copyright 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.media; + +import android.media.Session2Token; +import android.media.MediaParceledListSlice; + +/** {@hide} */ +interface IMediaCommunicationServiceCallback { + void onSession2Created(in Session2Token token); + void onSession2Changed(in MediaParceledListSlice tokens); +} + diff --git a/apex/media/framework/api/current.txt b/apex/media/framework/api/current.txt index a2366df0660a..1beef40b9e4f 100644 --- a/apex/media/framework/api/current.txt +++ b/apex/media/framework/api/current.txt @@ -26,6 +26,7 @@ package android.media { } public class MediaCommunicationManager { + method @NonNull public java.util.List<android.media.Session2Token> getSession2Tokens(); method @IntRange(from=1) public int getVersion(); } diff --git a/apex/media/framework/api/module-lib-current.txt b/apex/media/framework/api/module-lib-current.txt index ad9114fa23cf..eb6397a1826b 100644 --- a/apex/media/framework/api/module-lib-current.txt +++ b/apex/media/framework/api/module-lib-current.txt @@ -1,6 +1,16 @@ // Signature format: 2.0 package android.media { + public class MediaCommunicationManager { + method @RequiresPermission(android.Manifest.permission.MEDIA_CONTENT_CONTROL) public void registerSessionCallback(@NonNull java.util.concurrent.Executor, @NonNull android.media.MediaCommunicationManager.SessionCallback); + method public void unregisterSessionCallback(@NonNull android.media.MediaCommunicationManager.SessionCallback); + } + + public static interface MediaCommunicationManager.SessionCallback { + method public default void onSession2TokenCreated(@NonNull android.media.Session2Token); + method public default void onSession2TokensChanged(@NonNull java.util.List<android.media.Session2Token>); + } + public class MediaFrameworkInitializer { method public static void registerServiceWrappers(); method public static void setMediaServiceManager(@NonNull android.media.MediaServiceManager); diff --git a/apex/media/framework/java/android/media/Controller2Link.java b/apex/media/framework/java/android/media/Controller2Link.java index 04185e79b0ad..8eefec73194c 100644 --- a/apex/media/framework/java/android/media/Controller2Link.java +++ b/apex/media/framework/java/android/media/Controller2Link.java @@ -26,7 +26,7 @@ import android.os.ResultReceiver; import java.util.Objects; /** - * Handles incoming commands from {@link MediaSession2} to both {@link MediaController2}. + * Handles incoming commands from {@link MediaSession2} to {@link MediaController2}. * @hide */ // @SystemApi diff --git a/apex/media/framework/java/android/media/MediaCommunicationManager.java b/apex/media/framework/java/android/media/MediaCommunicationManager.java index e686076c871c..9ec25fe48a2e 100644 --- a/apex/media/framework/java/android/media/MediaCommunicationManager.java +++ b/apex/media/framework/java/android/media/MediaCommunicationManager.java @@ -15,18 +15,36 @@ */ package android.media; +import static android.Manifest.permission.MEDIA_CONTENT_CONTROL; +import static android.annotation.SystemApi.Client.MODULE_LIBRARIES; + +import android.annotation.CallbackExecutor; import android.annotation.IntRange; import android.annotation.NonNull; +import android.annotation.RequiresPermission; +import android.annotation.SystemApi; import android.annotation.SystemService; import android.content.Context; +import android.media.session.MediaSession; +import android.media.session.MediaSessionManager; +import android.os.RemoteException; +import android.os.UserHandle; +import android.service.media.MediaBrowserService; +import android.util.Log; +import com.android.internal.annotations.GuardedBy; import com.android.modules.utils.build.SdkLevel; +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.Executor; + /** * Provides support for interacting with {@link android.media.MediaSession2 MediaSession2s} * that applications have published to express their ongoing media playback state. */ -// TODO: Add notifySession2Created() and sendMessage(). @SystemService(Context.MEDIA_COMMUNICATION_SERVICE) public class MediaCommunicationManager { private static final String TAG = "MediaCommunicationManager"; @@ -44,6 +62,13 @@ public class MediaCommunicationManager { private final Context mContext; private final IMediaCommunicationService mService; + private final Object mLock = new Object(); + private final CopyOnWriteArrayList<SessionCallbackRecord> mTokenCallbackRecords = + new CopyOnWriteArrayList<>(); + + @GuardedBy("mLock") + private MediaCommunicationServiceCallbackStub mCallbackStub; + /** * @hide */ @@ -64,4 +89,197 @@ public class MediaCommunicationManager { public @IntRange(from = 1) int getVersion() { return CURRENT_VERSION; } + + /** + * Notifies that a new {@link MediaSession2} with type {@link Session2Token#TYPE_SESSION} is + * created. + * @param token newly created session2 token + * @hide + */ + public void notifySession2Created(@NonNull Session2Token token) { + Objects.requireNonNull(token, "token shouldn't be null"); + if (token.getType() != Session2Token.TYPE_SESSION) { + throw new IllegalArgumentException("token's type should be TYPE_SESSION"); + } + try { + mService.notifySession2Created(token); + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + } + } + + /** + * Checks whether the remote user is a trusted app. + * <p> + * An app is trusted if the app holds the + * {@link android.Manifest.permission#MEDIA_CONTENT_CONTROL} permission or has an enabled + * notification listener. + * + * @param userInfo The remote user info from either + * {@link MediaSession#getCurrentControllerInfo()} or + * {@link MediaBrowserService#getCurrentBrowserInfo()}. + * @return {@code true} if the remote user is trusted or {@code false} otherwise. + * @hide + */ + public boolean isTrustedForMediaControl(@NonNull MediaSessionManager.RemoteUserInfo userInfo) { + Objects.requireNonNull(userInfo, "userInfo shouldn't be null"); + if (userInfo.getPackageName() == null) { + return false; + } + try { + return mService.isTrusted( + userInfo.getPackageName(), userInfo.getPid(), userInfo.getUid()); + } catch (RemoteException e) { + Log.w(TAG, "Cannot communicate with the service.", e); + } + return false; + } + + /** + * This API is not generally intended for third party application developers. + * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a> + * <a href="{@docRoot}reference/androidx/media2/session/package-summary.html">Media2 session + * Library</a> for consistent behavior across all devices. + * <p> + * Gets a list of {@link Session2Token} with type {@link Session2Token#TYPE_SESSION} for the + * current user. + * <p> + * Although this API can be used without any restriction, each session owners can accept or + * reject your uses of {@link MediaSession2}. + * + * @return A list of {@link Session2Token}. + */ + @NonNull + public List<Session2Token> getSession2Tokens() { + return getSession2Tokens(UserHandle.myUserId()); + } + + /** + * Adds a callback to be notified when the list of active sessions changes. + * <p> + * This requires the {@link android.Manifest.permission#MEDIA_CONTENT_CONTROL} permission be + * held by the calling app. + * </p> + * @hide + */ + @SystemApi(client = MODULE_LIBRARIES) + @RequiresPermission(MEDIA_CONTENT_CONTROL) + public void registerSessionCallback(@CallbackExecutor @NonNull Executor executor, + @NonNull SessionCallback callback) { + Objects.requireNonNull(executor, "executor must not be null"); + Objects.requireNonNull(callback, "callback must not be null"); + + if (!mTokenCallbackRecords.addIfAbsent( + new SessionCallbackRecord(executor, callback))) { + Log.w(TAG, "registerSession2TokenCallback: Ignoring the same callback"); + return; + } + synchronized (mLock) { + if (mCallbackStub == null) { + MediaCommunicationServiceCallbackStub callbackStub = + new MediaCommunicationServiceCallbackStub(); + try { + mService.registerCallback(callbackStub, mContext.getPackageName()); + mCallbackStub = callbackStub; + } catch (RemoteException ex) { + Log.e(TAG, "Failed to register callback.", ex); + } + } + } + } + + /** + * Stops receiving active sessions updates on the specified callback. + * @hide + */ + @SystemApi(client = MODULE_LIBRARIES) + public void unregisterSessionCallback(@NonNull SessionCallback callback) { + if (!mTokenCallbackRecords.remove( + new SessionCallbackRecord(null, callback))) { + Log.w(TAG, "unregisterSession2TokenCallback: Ignoring an unknown callback."); + return; + } + synchronized (mLock) { + if (mCallbackStub != null && mTokenCallbackRecords.isEmpty()) { + try { + mService.unregisterCallback(mCallbackStub); + } catch (RemoteException ex) { + Log.e(TAG, "Failed to unregister callback.", ex); + } + mCallbackStub = null; + } + } + } + + private List<Session2Token> getSession2Tokens(int userId) { + try { + MediaParceledListSlice slice = mService.getSession2Tokens(userId); + return slice == null ? Collections.emptyList() : slice.getList(); + } catch (RemoteException e) { + Log.e(TAG, "Failed to get session tokens", e); + } + return Collections.emptyList(); + } + + /** + * Callback for listening to changes to the sessions. + * @see #registerSessionCallback(Executor, SessionCallback) + * @hide + */ + @SystemApi(client = MODULE_LIBRARIES) + public interface SessionCallback { + /** + * Called when a new {@link MediaSession2 media session2} is created. + * @param token the newly created token + */ + default void onSession2TokenCreated(@NonNull Session2Token token) {} + + /** + * Called when {@link #getSession2Tokens() session tokens} are changed. + */ + default void onSession2TokensChanged(@NonNull List<Session2Token> tokens) {} + } + + private static final class SessionCallbackRecord { + public final Executor executor; + public final SessionCallback callback; + + SessionCallbackRecord(Executor executor, SessionCallback callback) { + this.executor = executor; + this.callback = callback; + } + + @Override + public int hashCode() { + return Objects.hash(callback); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof SessionCallbackRecord)) { + return false; + } + return Objects.equals(this.callback, ((SessionCallbackRecord) obj).callback); + } + } + + class MediaCommunicationServiceCallbackStub extends IMediaCommunicationServiceCallback.Stub { + @Override + public void onSession2Created(Session2Token token) throws RemoteException { + for (SessionCallbackRecord record : mTokenCallbackRecords) { + record.executor.execute(() -> record.callback.onSession2TokenCreated(token)); + } + } + + @Override + public void onSession2Changed(MediaParceledListSlice tokens) throws RemoteException { + List<Session2Token> tokenList = tokens.getList(); + for (SessionCallbackRecord record : mTokenCallbackRecords) { + record.executor.execute(() -> record.callback.onSession2TokensChanged(tokenList)); + } + } + } } diff --git a/apex/media/framework/java/android/media/MediaSession2.java b/apex/media/framework/java/android/media/MediaSession2.java index 6560afedab0f..6397ba3996f3 100644 --- a/apex/media/framework/java/android/media/MediaSession2.java +++ b/apex/media/framework/java/android/media/MediaSession2.java @@ -32,7 +32,6 @@ import android.annotation.Nullable; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; -import android.media.session.MediaSessionManager; import android.media.session.MediaSessionManager.RemoteUserInfo; import android.os.BadParcelableException; import android.os.Bundle; @@ -87,7 +86,7 @@ public class MediaSession2 implements AutoCloseable { private final String mSessionId; private final PendingIntent mSessionActivity; private final Session2Token mSessionToken; - private final MediaSessionManager mSessionManager; + private final MediaCommunicationManager mCommunicationManager; private final Handler mResultHandler; //@GuardedBy("mLock") @@ -115,8 +114,7 @@ public class MediaSession2 implements AutoCloseable { mSessionStub = new Session2Link(this); mSessionToken = new Session2Token(Process.myUid(), TYPE_SESSION, context.getPackageName(), mSessionStub, tokenExtras); - mSessionManager = (MediaSessionManager) mContext.getSystemService( - Context.MEDIA_SESSION_SERVICE); + mCommunicationManager = mContext.getSystemService(MediaCommunicationManager.class); // NOTE: mResultHandler uses main looper, so this MUST NOT be blocked. mResultHandler = new Handler(context.getMainLooper()); mClosed = false; @@ -352,7 +350,7 @@ public class MediaSession2 implements AutoCloseable { final ControllerInfo controllerInfo = new ControllerInfo( remoteUserInfo, - mSessionManager.isTrustedForMediaControl(remoteUserInfo), + mCommunicationManager.isTrustedForMediaControl(remoteUserInfo), controller, connectionHints); mCallbackExecutor.execute(() -> { @@ -608,8 +606,8 @@ public class MediaSession2 implements AutoCloseable { // Notify framework about the newly create session after the constructor is finished. // Otherwise, framework may access the session before the initialization is finished. try { - MediaSessionManager manager = (MediaSessionManager) mContext.getSystemService( - Context.MEDIA_SESSION_SERVICE); + MediaCommunicationManager manager = + mContext.getSystemService(MediaCommunicationManager.class); manager.notifySession2Created(session2.getToken()); } catch (Exception e) { session2.close(); diff --git a/apex/media/service/java/com/android/server/media/MediaCommunicationService.java b/apex/media/service/java/com/android/server/media/MediaCommunicationService.java index 0468fdf30ba8..06de3f8d27d0 100644 --- a/apex/media/service/java/com/android/server/media/MediaCommunicationService.java +++ b/apex/media/service/java/com/android/server/media/MediaCommunicationService.java @@ -15,27 +15,538 @@ */ package com.android.server.media; +import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; +import static android.os.UserHandle.ALL; +import static android.os.UserHandle.getUserHandleForUid; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.app.ActivityManager; +import android.app.NotificationManager; import android.content.Context; +import android.content.pm.PackageManager; import android.media.IMediaCommunicationService; +import android.media.IMediaCommunicationServiceCallback; +import android.media.MediaController2; +import android.media.MediaParceledListSlice; +import android.media.Session2CommandGroup; +import android.media.Session2Token; +import android.os.Binder; +import android.os.Handler; +import android.os.IBinder; +import android.os.Looper; +import android.os.Process; +import android.os.RemoteException; +import android.os.UserHandle; +import android.os.UserManager; +import android.util.Log; +import android.util.SparseArray; +import android.util.SparseIntArray; +import com.android.internal.annotations.GuardedBy; import com.android.server.SystemService; +import java.lang.ref.WeakReference; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.concurrent.Executor; +import java.util.concurrent.Executors; +import java.util.stream.Collectors; + /** - * A system service that managers {@link android.media.MediaSession2} creations + * A system service that manages {@link android.media.MediaSession2} creations * and their ongoing media playback state. * @hide */ public class MediaCommunicationService extends SystemService { + private static final String TAG = "MediaCommunicationService"; + private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); + + final Context mContext; + + private final Object mLock = new Object(); + private final Handler mHandler = new Handler(Looper.getMainLooper()); + + @GuardedBy("mLock") + private final SparseIntArray mFullUserIds = new SparseIntArray(); + @GuardedBy("mLock") + private final SparseArray<FullUserRecord> mUserRecords = new SparseArray<>(); + + private final Executor mRecordExecutor = Executors.newSingleThreadExecutor(); + @GuardedBy("mLock") + private final List<CallbackRecord> mCallbackRecords = new ArrayList<>(); + final NotificationManager mNotificationManager; public MediaCommunicationService(Context context) { super(context); + mContext = context; + mNotificationManager = context.getSystemService(NotificationManager.class); } @Override public void onStart() { publishBinderService(Context.MEDIA_COMMUNICATION_SERVICE, new Stub()); + updateUser(); + } + + @Override + public void onUserStarting(@NonNull TargetUser user) { + if (DEBUG) Log.d(TAG, "onUserStarting: " + user); + updateUser(); + } + + @Override + public void onUserSwitching(@Nullable TargetUser from, @NonNull TargetUser to) { + if (DEBUG) Log.d(TAG, "onUserSwitching: " + to); + updateUser(); + } + + @Override + public void onUserStopped(@NonNull TargetUser targetUser) { + int userId = targetUser.getUserHandle().getIdentifier(); + + if (DEBUG) Log.d(TAG, "onUserStopped: " + userId); + synchronized (mLock) { + FullUserRecord user = getFullUserRecordLocked(userId); + if (user != null) { + if (user.getFullUserId() == userId) { + user.destroySessionsForUserLocked(UserHandle.ALL.getIdentifier()); + mUserRecords.remove(userId); + } else { + user.destroySessionsForUserLocked(userId); + } + } + updateUser(); + } + } + + @Nullable + CallbackRecord findCallbackRecordLocked(@Nullable IMediaCommunicationServiceCallback callback) { + if (callback == null) { + return null; + } + for (CallbackRecord record : mCallbackRecords) { + if (Objects.equals(callback.asBinder(), record.mCallback.asBinder())) { + return record; + } + } + return null; + } + + private FullUserRecord getFullUserRecordLocked(int userId) { + int fullUserId = mFullUserIds.get(userId, -1); + if (fullUserId < 0) { + return null; + } + return mUserRecords.get(fullUserId); + } + + private boolean hasMediaControlPermission(int pid, int uid) { + // Check if it's system server or has MEDIA_CONTENT_CONTROL. + // Note that system server doesn't have MEDIA_CONTENT_CONTROL, so we need extra + // check here. + if (uid == Process.SYSTEM_UID || mContext.checkPermission( + android.Manifest.permission.MEDIA_CONTENT_CONTROL, pid, uid) + == PackageManager.PERMISSION_GRANTED) { + return true; + } else if (DEBUG) { + Log.d(TAG, "uid(" + uid + ") hasn't granted MEDIA_CONTENT_CONTROL"); + } + return false; + } + + private void updateUser() { + UserManager manager = mContext.getSystemService(UserManager.class); + List<UserHandle> allUsers = manager.getUserHandles(/*excludeDying=*/false); + + synchronized (mLock) { + mFullUserIds.clear(); + if (allUsers != null) { + for (UserHandle user : allUsers) { + UserHandle parent = manager.getProfileParent(user); + if (parent != null) { + mFullUserIds.put(user.getIdentifier(), parent.getIdentifier()); + } else { + mFullUserIds.put(user.getIdentifier(), user.getIdentifier()); + if (mUserRecords.get(user.getIdentifier()) == null) { + mUserRecords.put(user.getIdentifier(), + new FullUserRecord(user.getIdentifier())); + } + } + } + } + // Ensure that the current full user exists. + int currentFullUserId = ActivityManager.getCurrentUser(); + FullUserRecord currentFullUserRecord = mUserRecords.get(currentFullUserId); + if (currentFullUserRecord == null) { + Log.w(TAG, "Cannot find FullUserInfo for the current user " + currentFullUserId); + currentFullUserRecord = new FullUserRecord(currentFullUserId); + mUserRecords.put(currentFullUserId, currentFullUserRecord); + } + mFullUserIds.put(currentFullUserId, currentFullUserId); + } + } + + void dispatchSessionCreated(Session2Token token) { + for (CallbackRecord record : mCallbackRecords) { + if (record.mUserId != ALL.getIdentifier() + && record.mUserId != getUserHandleForUid(token.getUid()).getIdentifier()) { + continue; + } + try { + record.mCallback.onSession2Created(token); + } catch (RemoteException e) { + e.printStackTrace(); + } + } + } + + void onSessionDied(Session2Record record) { + synchronized (mLock) { + destroySessionLocked(record); + } + } + + private void destroySessionLocked(Session2Record session) { + if (DEBUG) { + Log.d(TAG, "Destroying " + session); + } + if (session.isClosed()) { + Log.w(TAG, "Destroying already destroyed session. Ignoring."); + return; + } + + FullUserRecord user = getFullUserRecordLocked(session.getUserId()); + + if (user != null) { + user.removeSession(session); + } + + session.close(); } private class Stub extends IMediaCommunicationService.Stub { + @Override + public void notifySession2Created(Session2Token sessionToken) { + final int pid = Binder.getCallingPid(); + final int uid = Binder.getCallingUid(); + final long token = Binder.clearCallingIdentity(); + + try { + if (DEBUG) { + Log.d(TAG, "Session2 is created " + sessionToken); + } + if (uid != sessionToken.getUid()) { + throw new SecurityException("Unexpected Session2Token's UID, expected=" + uid + + " but actually=" + sessionToken.getUid()); + } + synchronized (mLock) { + int userId = getUserHandleForUid(sessionToken.getUid()).getIdentifier(); + FullUserRecord user = getFullUserRecordLocked(userId); + if (user == null) { + Log.w(TAG, "notifySession2Created: Ignore session of an unknown user"); + return; + } + user.addSession(new Session2Record(MediaCommunicationService.this, + sessionToken, mRecordExecutor)); + mHandler.post(() -> dispatchSessionCreated(sessionToken)); + } + } finally { + Binder.restoreCallingIdentity(token); + } + } + + /** + * Returns if the controller's package is trusted (i.e. has either MEDIA_CONTENT_CONTROL + * permission or an enabled notification listener) + * + * @param controllerPackageName package name of the controller app + * @param controllerPid pid of the controller app + * @param controllerUid uid of the controller app + */ + @Override + public boolean isTrusted(String controllerPackageName, int controllerPid, + int controllerUid) { + final int uid = Binder.getCallingUid(); + final int userId = UserHandle.getUserHandleForUid(uid).getIdentifier(); + final long token = Binder.clearCallingIdentity(); + try { + // Don't perform check between controllerPackageName and controllerUid. + // When an (activity|service) runs on the another apps process by specifying + // android:process in the AndroidManifest.xml, then PID and UID would have the + // running process' information instead of the (activity|service) that has created + // MediaController. + // Note that we can use Context#getOpPackageName() instead of + // Context#getPackageName() for getting package name that matches with the PID/UID, + // but it doesn't tell which package has created the MediaController, so useless. + return hasMediaControlPermission(controllerPid, controllerUid) + || hasEnabledNotificationListener( + userId, controllerPackageName, controllerUid); + } finally { + Binder.restoreCallingIdentity(token); + } + } + + @Override + public MediaParceledListSlice getSession2Tokens(int userId) { + final int pid = Binder.getCallingPid(); + final int uid = Binder.getCallingUid(); + final long token = Binder.clearCallingIdentity(); + + try { + // Check that they can make calls on behalf of the user and get the final user id + int resolvedUserId = handleIncomingUser(pid, uid, userId, null); + List<Session2Token> result; + synchronized (mLock) { + FullUserRecord user = getFullUserRecordLocked(userId); + result = user.getSession2Tokens(resolvedUserId); + } + return new MediaParceledListSlice(result); + } finally { + Binder.restoreCallingIdentity(token); + } + } + + @Override + public void registerCallback(IMediaCommunicationServiceCallback callback, + String packageName) throws RemoteException { + Objects.requireNonNull(callback, "callback should not be null"); + Objects.requireNonNull(packageName, "packageName should not be null"); + + synchronized (mLock) { + if (findCallbackRecordLocked(callback) == null) { + + CallbackRecord record = new CallbackRecord(callback, packageName, + Binder.getCallingUid(), Binder.getCallingPid()); + mCallbackRecords.add(record); + try { + callback.asBinder().linkToDeath(record, 0); + } catch (RemoteException e) { + Log.w(TAG, "Failed to register callback", e); + mCallbackRecords.remove(record); + } + } else { + Log.e(TAG, "registerCallback is called with already registered callback. " + + "packageName=" + packageName); + } + } + } + + @Override + public void unregisterCallback(IMediaCommunicationServiceCallback callback) + throws RemoteException { + synchronized (mLock) { + CallbackRecord existingRecord = findCallbackRecordLocked(callback); + if (existingRecord != null) { + mCallbackRecords.remove(existingRecord); + callback.asBinder().unlinkToDeath(existingRecord, 0); + } else { + Log.e(TAG, "unregisterCallback is called with unregistered callback."); + } + } + } + + private boolean hasEnabledNotificationListener(int callingUserId, + String controllerPackageName, int controllerUid) { + int controllerUserId = UserHandle.getUserHandleForUid(controllerUid).getIdentifier(); + if (callingUserId != controllerUserId) { + // Enabled notification listener only works within the same user. + return false; + } + + if (mNotificationManager.hasEnabledNotificationListener(controllerPackageName, + UserHandle.getUserHandleForUid(controllerUid))) { + return true; + } + if (DEBUG) { + Log.d(TAG, controllerPackageName + " (uid=" + controllerUid + + ") doesn't have an enabled notification listener"); + } + return false; + } + + // Handles incoming user by checking whether the caller has permission to access the + // given user id's information or not. Permission is not necessary if the given user id is + // equal to the caller's user id, but if not, the caller needs to have the + // INTERACT_ACROSS_USERS_FULL permission. Otherwise, a security exception will be thrown. + // The return value will be the given user id, unless the given user id is + // UserHandle.CURRENT, which will return the ActivityManager.getCurrentUser() value instead. + private int handleIncomingUser(int pid, int uid, int userId, String packageName) { + int callingUserId = UserHandle.getUserHandleForUid(uid).getIdentifier(); + if (userId == callingUserId) { + return userId; + } + + boolean canInteractAcrossUsersFull = mContext.checkPermission( + INTERACT_ACROSS_USERS_FULL, pid, uid) == PackageManager.PERMISSION_GRANTED; + if (canInteractAcrossUsersFull) { + if (userId == UserHandle.CURRENT.getIdentifier()) { + return ActivityManager.getCurrentUser(); + } + return userId; + } + + throw new SecurityException("Permission denied while calling from " + packageName + + " with user id: " + userId + "; Need to run as either the calling user id (" + + callingUserId + "), or with " + INTERACT_ACROSS_USERS_FULL + " permission"); + } + } + + final class CallbackRecord implements IBinder.DeathRecipient { + private final IMediaCommunicationServiceCallback mCallback; + private final String mPackageName; + private final int mUid; + private int mPid; + private final int mUserId; + + CallbackRecord(IMediaCommunicationServiceCallback callback, + String packageName, int uid, int pid) { + mCallback = callback; + mPackageName = packageName; + mUid = uid; + mPid = pid; + mUserId = (mContext.checkPermission( + INTERACT_ACROSS_USERS_FULL, pid, uid) == PackageManager.PERMISSION_GRANTED) + ? ALL.getIdentifier() : UserHandle.getUserHandleForUid(mUid).getIdentifier(); + } + + @Override + public String toString() { + return "CallbackRecord[callback=" + mCallback + ", pkg=" + mPackageName + + ", uid=" + mUid + ", pid=" + mPid + "]"; + } + + @Override + public void binderDied() { + synchronized (mLock) { + mCallbackRecords.remove(this); + } + } + } + + final class FullUserRecord { + private final int mFullUserId; + /** Sorted list of media sessions */ + private final List<Session2Record> mSessionRecords = new ArrayList<>(); + + FullUserRecord(int fullUserId) { + mFullUserId = fullUserId; + } + + public void addSession(Session2Record record) { + mSessionRecords.add(record); + } + + public void removeSession(Session2Record record) { + mSessionRecords.remove(record); + //TODO: Handle if the removed session was the media button session. + } + + public int getFullUserId() { + return mFullUserId; + } + + public List<Session2Token> getSession2Tokens(int userId) { + return mSessionRecords.stream() + .filter(record -> record.isActive() + && (userId == UserHandle.ALL.getIdentifier() + || record.getUserId() == userId)) + .map(Session2Record::getSessionToken) + .collect(Collectors.toList()); + } + + public void destroySessionsForUserLocked(int userId) { + synchronized (mLock) { + for (Session2Record record : mSessionRecords) { + if (userId == UserHandle.ALL.getIdentifier() + || record.getUserId() == userId) { + destroySessionLocked(record); + } + } + } + } + } + + static final class Session2Record { + private final Session2Token mSessionToken; + private final Object mLock = new Object(); + private final WeakReference<MediaCommunicationService> mServiceRef; + @GuardedBy("mLock") + private final MediaController2 mController; + + @GuardedBy("mLock") + private boolean mIsConnected; + @GuardedBy("mLock") + private boolean mIsClosed; + + Session2Record(MediaCommunicationService service, Session2Token token, + Executor controllerExecutor) { + mServiceRef = new WeakReference<>(service); + mSessionToken = token; + mController = new MediaController2.Builder(service.getContext(), token) + .setControllerCallback(controllerExecutor, new Controller2Callback()) + .build(); + } + + public int getUserId() { + return UserHandle.getUserHandleForUid(mSessionToken.getUid()).getIdentifier(); + } + + public boolean isActive() { + synchronized (mLock) { + return mIsConnected; + } + } + + public boolean isClosed() { + synchronized (mLock) { + return mIsClosed; + } + } + + public void close() { + synchronized (mLock) { + mIsClosed = true; + // Call close regardless of the mIsConnected. This may be called when it's not yet + // connected. + mController.close(); + } + } + + public Session2Token getSessionToken() { + return mSessionToken; + } + + private class Controller2Callback extends MediaController2.ControllerCallback { + @Override + public void onConnected(MediaController2 controller, + Session2CommandGroup allowedCommands) { + if (DEBUG) { + Log.d(TAG, "connected to " + mSessionToken + ", allowed=" + allowedCommands); + } + synchronized (mLock) { + mIsConnected = true; + } + MediaCommunicationService service = mServiceRef.get(); + if (service != null) { + //TODO: notify session state changed + } + } + + @Override + public void onDisconnected(MediaController2 controller) { + if (DEBUG) { + Log.d(TAG, "disconnected from " + mSessionToken); + } + synchronized (mLock) { + mIsConnected = false; + } + MediaCommunicationService service = mServiceRef.get(); + if (service != null) { + service.onSessionDied(Session2Record.this); + } + } + } } } diff --git a/api/Android.bp b/api/Android.bp index 1fdf1771bb13..1d4698e7c512 100644 --- a/api/Android.bp +++ b/api/Android.bp @@ -347,49 +347,3 @@ genrule { out: ["combined-removed-dex.txt"], cmd: "$(location gen_combined_removed_dex.sh) $(location metalava) $(genDir) $(in) > $(out)", } - -genrule { - name: "services-system-server-current.txt", - srcs: [ - ":service-permission{.system-server.api.txt}", - ":non-updatable-system-server-current.txt", - ], - out: ["system-server-current.txt"], - tools: ["metalava"], - cmd: "$(location metalava) --no-banner --format=v2 $(in) --api $(out)", - dists: [ - { - targets: ["droidcore"], - dir: "api", - dest: "system-server-current.txt", - }, - { - targets: ["sdk", "win_sdk"], - dir: "apistubs/android/system-server/api", - dest: "merge-android.txt", - }, - ], -} - -genrule { - name: "services-system-server-removed.txt", - srcs: [ - ":service-permission{.system-server.removed-api.txt}", - ":non-updatable-system-server-removed.txt", - ], - out: ["system-server-removed.txt"], - tools: ["metalava"], - cmd: "$(location metalava) --no-banner --format=v2 $(in) --api $(out)", - dists: [ - { - targets: ["droidcore"], - dir: "api", - dest: "system-server-removed.txt", - }, - { - targets: ["sdk", "win_sdk"], - dir: "apistubs/android/system-server/api", - dest: "merge-removed.txt", - }, - ], -} diff --git a/config/dirty-image-objects b/config/dirty-image-objects index 2dfe0197d898..dfd091cc1aff 100644 --- a/config/dirty-image-objects +++ b/config/dirty-image-objects @@ -28,359 +28,359 @@ # Then, grep for lines containing "Private dirty object" from the output. # This particular file was generated by dumping systemserver and systemui. # -android.accounts.Account -android.accounts.OnAccountsUpdateListener -android.animation.LayoutTransition -android.app.ActivityManager -android.app.ActivityManager$OnUidImportanceListener -android.app.ActivityTaskManager -android.app.ActivityThread -android.app.admin.DevicePolicyManager -android.app.AlarmManager -android.app.Application -android.app.AppOpsManager -android.app.backup.BackupManager -android.app.ContextImpl -android.app.INotificationManager -android.app.Notification$BigPictureStyle -android.app.Notification$BigTextStyle -android.app.Notification$InboxStyle -android.app.NotificationChannel -android.app.NotificationChannelGroup -android.app.NotificationManager -android.app.PendingIntent -android.app.PendingIntent$OnFinished -android.app.QueuedWork -android.app.ResourcesManager -android.app.WallpaperManager -android.app.WindowConfiguration -android.bluetooth.BluetoothAdapter -android.bluetooth.BluetoothDevice -android.bluetooth.BluetoothProfile -android.bluetooth.IBluetoothA2dp -android.bluetooth.IBluetoothHeadsetPhone -android.bluetooth.IBluetoothHidDevice -android.bluetooth.IBluetoothHidHost -android.bluetooth.IBluetoothMap -android.bluetooth.IBluetoothPan -android.bluetooth.IBluetoothPbap -android.bluetooth.IBluetoothSap -android.content.ClipboardManager$OnPrimaryClipChangedListener -android.content.ComponentName -android.content.ContentProvider$PipeDataWriter -android.content.ContentResolver -android.content.Context -android.content.Intent -android.content.pm.PackageManager$OnPermissionsChangedListener -android.content.pm.VersionedPackage -android.content.res.Configuration -android.content.SharedPreferences$OnSharedPreferenceChangeListener -android.database.CursorWindow -android.database.sqlite.SQLiteCompatibilityWalFlags -android.database.sqlite.SQLiteDatabase$CursorFactory -android.database.sqlite.SQLiteGlobal -android.database.sqlite.SQLiteTransactionListener -android.ddm.DdmHandleAppName -android.graphics.Bitmap -android.graphics.Canvas -android.graphics.drawable.AdaptiveIconDrawable -android.graphics.drawable.ColorDrawable -android.graphics.drawable.GradientDrawable -android.graphics.drawable.Icon -android.graphics.drawable.InsetDrawable -android.graphics.drawable.RippleDrawable -android.graphics.drawable.VectorDrawable$VGroup -android.graphics.ImageDecoder -android.graphics.Rect -android.graphics.TemporaryBuffer -android.hardware.biometrics.BiometricSourceType -android.hardware.display.ColorDisplayManager$ColorDisplayManagerInternal -android.hardware.display.DisplayManagerGlobal -android.hardware.display.NightDisplayListener$Callback -android.hardware.input.InputManager -android.hardware.input.InputManager$InputDeviceListener -android.hardware.SensorPrivacyManager -android.hardware.SystemSensorManager -android.icu.impl.OlsonTimeZone -android.icu.text.BreakIterator -android.icu.text.Collator -android.icu.text.DateFormat$BooleanAttribute -android.icu.text.DateTimePatternGenerator$DTPGflags -android.icu.text.PluralRules$Operand -android.icu.util.TimeZone -android.location.GpsStatus$Listener -android.location.LocationListener -android.media.AudioManager -android.media.MediaRouter -android.media.PlayerBase -android.media.session.MediaSessionManager -android.net.apf.ApfCapabilities -android.net.ConnectivityManager -android.net.ConnectivityManager$OnNetworkActiveListener -android.net.ConnectivityThread$Singleton -android.net.IpConfiguration$IpAssignment -android.net.IpConfiguration$ProxySettings -android.net.IpPrefix -android.net.LinkAddress -android.net.LinkProperties -android.net.Network -android.net.NetworkCapabilities -android.net.NetworkInfo -android.net.NetworkInfo$State -android.net.NetworkRequest -android.net.NetworkRequest$Type -android.net.RouteInfo -android.net.StringNetworkSpecifier -android.net.TrafficStats -android.net.UidRange -android.net.Uri$HierarchicalUri -android.net.Uri$StringUri -android.net.wifi.WifiManager -android.net.wifi.WifiManager$SoftApCallback -android.os.AsyncResult -android.os.AsyncTask -android.os.BinderProxy -android.os.Bundle -android.os.DeadObjectException -android.os.Environment -android.os.FileObserver -android.os.Handler -android.os.IDeviceIdleController -android.os.LocaleList -android.os.Looper -android.os.Message -android.os.ParcelUuid -android.os.Process -android.os.RecoverySystem -android.os.ServiceManager -android.os.storage.StorageManager -android.os.StrictMode -android.os.Trace -android.os.WorkSource -android.os.WorkSource$WorkChain -android.permission.PermissionManager -android.provider.FontsContract -android.provider.Settings$SettingNotFoundException -android.renderscript.RenderScriptCacheDir -android.security.IKeyChainService -android.security.keystore.AndroidKeyStoreProvider -android.security.net.config.ApplicationConfig -android.security.net.config.SystemCertificateSource$NoPreloadHolder -android.telecom.PhoneAccountHandle -android.telephony.AnomalyReporter -android.telephony.CellSignalStrengthCdma -android.telephony.CellSignalStrengthGsm -android.telephony.CellSignalStrengthLte -android.telephony.CellSignalStrengthNr -android.telephony.CellSignalStrengthTdscdma -android.telephony.CellSignalStrengthWcdma -android.telephony.DataSpecificRegistrationInfo -android.telephony.emergency.EmergencyNumber -android.telephony.ims.ImsMmTelManager$CapabilityCallback$CapabilityBinder -android.telephony.ims.ImsMmTelManager$RegistrationCallback$RegistrationBinder -android.telephony.ims.ImsReasonInfo -android.telephony.ims.ProvisioningManager$Callback$CallbackBinder -android.telephony.ModemActivityInfo -android.telephony.ModemInfo -android.telephony.NetworkRegistrationInfo -android.telephony.NetworkService -android.telephony.TelephonyManager -android.telephony.VoiceSpecificRegistrationInfo -android.text.format.DateFormat -android.text.method.SingleLineTransformationMethod -android.text.Selection$MemoryTextWatcher -android.text.SpanWatcher -android.text.style.AlignmentSpan -android.text.style.CharacterStyle -android.text.style.LeadingMarginSpan -android.text.style.LineBackgroundSpan -android.text.style.LineHeightSpan -android.text.style.MetricAffectingSpan -android.text.style.ReplacementSpan -android.text.style.SuggestionSpan -android.text.style.TabStopSpan -android.text.TextUtils -android.text.TextWatcher -android.transition.ChangeClipBounds -android.transition.ChangeImageTransform -android.transition.ChangeTransform -android.util.ArrayMap -android.util.ArraySet -android.util.DisplayMetrics -android.util.EventLog -android.util.Log -android.util.Patterns -android.view.AbsSavedState$1 -android.view.accessibility.AccessibilityManager -android.view.accessibility.AccessibilityManager$AccessibilityServicesStateChangeListener -android.view.accessibility.AccessibilityManager$TouchExplorationStateChangeListener -android.view.accessibility.AccessibilityNodeIdManager -android.view.autofill.AutofillManager -android.view.autofill.Helper -android.view.Choreographer -android.view.inputmethod.InputMethodManager -android.view.IWindowManager -android.view.PointerIcon -android.view.RemoteAnimationAdapter -android.view.ThreadedRenderer -android.view.View -android.view.View$OnHoverListener -android.view.ViewRootImpl -android.view.ViewStub -android.view.ViewStub$OnInflateListener -android.view.ViewTreeObserver -android.view.WindowManager$LayoutParams -android.view.WindowManagerGlobal -android.widget.ActionMenuPresenter$OverflowMenuButton -android.widget.ActionMenuView -android.widget.Button -android.widget.CheckBox -android.widget.FrameLayout -android.widget.ImageButton -android.widget.ImageView -android.widget.LinearLayout -android.widget.RelativeLayout -android.widget.SeekBar -android.widget.Space -android.widget.TextView -android.widget.Toolbar -byte[] -com.android.ims.ImsManager -com.android.internal.logging.MetricsLogger -com.android.internal.os.BackgroundThread -com.android.internal.os.BinderInternal -com.android.internal.os.BinderInternal$BinderProxyLimitListener -com.android.internal.os.RuntimeInit -com.android.internal.os.SomeArgs -com.android.internal.policy.DecorView -com.android.internal.statusbar.IStatusBarService -com.android.internal.telephony.AppSmsManager -android.telephony.CallerInfoAsyncQuery$OnQueryCompleteListener -com.android.internal.telephony.CarrierActionAgent -com.android.internal.telephony.cat.CatService -com.android.internal.telephony.cat.IconLoader -com.android.internal.telephony.cat.RilMessageDecoder -com.android.internal.telephony.cdma.CdmaSubscriptionSourceManager -com.android.internal.telephony.cdma.EriManager -com.android.internal.telephony.CellularNetworkValidator -com.android.internal.telephony.CommandException -com.android.internal.telephony.dataconnection.DataConnection$DcActivatingState -com.android.internal.telephony.dataconnection.DataConnection$DcActiveState -com.android.internal.telephony.dataconnection.DataConnection$DcInactiveState -com.android.internal.telephony.dataconnection.DataEnabledSettings -com.android.internal.telephony.dataconnection.DcTracker -com.android.internal.telephony.euicc.EuiccCardController -com.android.internal.telephony.euicc.EuiccController -com.android.internal.telephony.GsmAlphabet -com.android.internal.telephony.GsmCdmaCallTracker -com.android.internal.telephony.GsmCdmaPhone -com.android.internal.telephony.IccPhoneBookInterfaceManager -com.android.internal.telephony.IccSmsInterfaceManager -com.android.internal.telephony.ims.ImsResolver -com.android.internal.telephony.imsphone.ImsExternalCallTracker -com.android.internal.telephony.imsphone.ImsPhone -com.android.internal.telephony.imsphone.ImsPhoneCallTracker -com.android.internal.telephony.ims.RcsMessageStoreController -com.android.internal.telephony.IntentBroadcaster -com.android.internal.telephony.ITelephonyRegistry$Stub$Proxy -com.android.internal.telephony.metrics.TelephonyMetrics -com.android.internal.telephony.MultiSimSettingController -com.android.internal.telephony.nano.CarrierIdProto$CarrierAttribute -com.android.internal.telephony.nano.CarrierIdProto$CarrierId -com.android.internal.telephony.nano.TelephonyProto$RilDataCall -com.android.internal.telephony.nano.TelephonyProto$SmsSession$Event -com.android.internal.telephony.nano.TelephonyProto$TelephonyCallSession$Event$RilCall -com.android.internal.telephony.NitzStateMachine -com.android.internal.telephony.PhoneConfigurationManager -com.android.internal.telephony.PhoneFactory -com.android.internal.telephony.PhoneSwitcher -com.android.internal.telephony.ProxyController -com.android.internal.telephony.RadioConfig -com.android.internal.telephony.RIL -com.android.internal.telephony.RILRequest -com.android.internal.telephony.RilWakelockInfo -com.android.internal.telephony.ServiceStateTracker -com.android.internal.telephony.SimActivationTracker -com.android.internal.telephony.SmsApplication -com.android.internal.telephony.SmsBroadcastUndelivered -com.android.internal.telephony.SmsStorageMonitor -com.android.internal.telephony.SmsUsageMonitor -com.android.internal.telephony.SubscriptionController -com.android.internal.telephony.SubscriptionInfoUpdater -com.android.internal.telephony.TelephonyComponentFactory -com.android.internal.telephony.TelephonyDevController -com.android.internal.telephony.TelephonyTester -com.android.internal.telephony.uicc.AdnRecordCache -com.android.internal.telephony.uicc.UiccCardApplication -com.android.internal.telephony.uicc.UiccController -com.android.internal.telephony.uicc.UiccProfile -com.android.internal.telephony.uicc.UiccStateChangedLauncher -com.android.internal.telephony.uicc.UsimFileHandler -com.android.internal.telephony.uicc.VoiceMailConstants -com.android.internal.util.LatencyTracker -com.android.internal.util.StateMachine$SmHandler -com.android.okhttp.OkHttpClient -com.android.okhttp.okio.AsyncTimeout -com.android.okhttp.okio.SegmentPool -com.android.phone.ecc.nano.ProtobufEccData$CountryInfo -com.android.phone.ecc.nano.ProtobufEccData$EccInfo -com.android.server.sip.SipWakeupTimer -com.android.server.SystemConfig -dalvik.system.BaseDexClassLoader -dalvik.system.BlockGuard -dalvik.system.CloseGuard -dalvik.system.RuntimeHooks -dalvik.system.SocketTagger -java.io.BufferedReader -java.lang.AssertionError -java.lang.Boolean -java.lang.Byte -java.lang.Character -java.lang.CharSequence -java.lang.Class -java.lang.IllegalAccessException -java.lang.IllegalStateException -java.lang.NoSuchMethodException -java.lang.NullPointerException -java.lang.Object -java.lang.Object[] -java.lang.ref.FinalizerReference -java.lang.Runnable -java.lang.SecurityException -java.lang.Short -java.lang.String[] -java.lang.System -java.lang.Thread -java.lang.Throwable -java.lang.UnsatisfiedLinkError -java.net.Inet6Address -java.net.Socket -java.net.SocketException -java.nio.Bits -java.nio.charset.Charset -java.security.interfaces.RSAPrivateKey -java.security.Provider -java.util.Collections -java.util.concurrent.Executor -java.util.GregorianCalendar -java.util.Locale -java.util.Locale$NoImagePreloadHolder -java.util.Scanner -java.util.Set -java.util.TimeZone -javax.net.SocketFactory -javax.net.ssl.HttpsURLConnection -javax.net.ssl.HttpsURLConnection$NoPreloadHolder -javax.net.ssl.SSLContext -javax.net.ssl.SSLSessionContext -javax.net.ssl.SSLSocketFactory -libcore.io.Libcore -libcore.io.Memory -libcore.net.NetworkSecurityPolicy -libcore.timezone.TimeZoneFinder -org.apache.http.params.HttpParams -sun.misc.Cleaner -sun.nio.ch.FileChannelImpl -sun.nio.ch.FileChannelImpl$Unmapper -sun.nio.fs.UnixChannelFactory -sun.security.jca.Providers +Landroid/accounts/Account; +Landroid/accounts/OnAccountsUpdateListener; +Landroid/animation/LayoutTransition; +Landroid/app/ActivityManager; +Landroid/app/ActivityManager$OnUidImportanceListener; +Landroid/app/ActivityTaskManager; +Landroid/app/ActivityThread; +Landroid/app/admin/DevicePolicyManager; +Landroid/app/AlarmManager; +Landroid/app/Application; +Landroid/app/AppOpsManager; +Landroid/app/backup/BackupManager; +Landroid/app/ContextImpl; +Landroid/app/INotificationManager; +Landroid/app/Notification$BigPictureStyle; +Landroid/app/Notification$BigTextStyle; +Landroid/app/Notification$InboxStyle; +Landroid/app/NotificationChannel; +Landroid/app/NotificationChannelGroup; +Landroid/app/NotificationManager; +Landroid/app/PendingIntent; +Landroid/app/PendingIntent$OnFinished; +Landroid/app/QueuedWork; +Landroid/app/ResourcesManager; +Landroid/app/WallpaperManager; +Landroid/app/WindowConfiguration; +Landroid/bluetooth/BluetoothAdapter; +Landroid/bluetooth/BluetoothDevice; +Landroid/bluetooth/BluetoothProfile; +Landroid/bluetooth/IBluetoothA2dp; +Landroid/bluetooth/IBluetoothHeadsetPhone; +Landroid/bluetooth/IBluetoothHidDevice; +Landroid/bluetooth/IBluetoothHidHost; +Landroid/bluetooth/IBluetoothMap; +Landroid/bluetooth/IBluetoothPan; +Landroid/bluetooth/IBluetoothPbap; +Landroid/bluetooth/IBluetoothSap; +Landroid/content/ClipboardManager$OnPrimaryClipChangedListener; +Landroid/content/ComponentName; +Landroid/content/ContentProvider$PipeDataWriter; +Landroid/content/ContentResolver; +Landroid/content/Context; +Landroid/content/Intent; +Landroid/content/pm/PackageManager$OnPermissionsChangedListener; +Landroid/content/pm/VersionedPackage; +Landroid/content/res/Configuration; +Landroid/content/SharedPreferences$OnSharedPreferenceChangeListener; +Landroid/database/CursorWindow; +Landroid/database/sqlite/SQLiteCompatibilityWalFlags; +Landroid/database/sqlite/SQLiteDatabase$CursorFactory; +Landroid/database/sqlite/SQLiteGlobal; +Landroid/database/sqlite/SQLiteTransactionListener; +Landroid/ddm/DdmHandleAppName; +Landroid/graphics/Bitmap; +Landroid/graphics/Canvas; +Landroid/graphics/drawable/AdaptiveIconDrawable; +Landroid/graphics/drawable/ColorDrawable; +Landroid/graphics/drawable/GradientDrawable; +Landroid/graphics/drawable/Icon; +Landroid/graphics/drawable/InsetDrawable; +Landroid/graphics/drawable/RippleDrawable; +Landroid/graphics/drawable/VectorDrawable$VGroup; +Landroid/graphics/ImageDecoder; +Landroid/graphics/Rect; +Landroid/graphics/TemporaryBuffer; +Landroid/hardware/biometrics/BiometricSourceType; +Landroid/hardware/display/ColorDisplayManager$ColorDisplayManagerInternal; +Landroid/hardware/display/DisplayManagerGlobal; +Landroid/hardware/display/NightDisplayListener$Callback; +Landroid/hardware/input/InputManager; +Landroid/hardware/input/InputManager$InputDeviceListener; +Landroid/hardware/SensorPrivacyManager; +Landroid/hardware/SystemSensorManager; +Landroid/icu/impl/OlsonTimeZone; +Landroid/icu/text/BreakIterator; +Landroid/icu/text/Collator; +Landroid/icu/text/DateFormat$BooleanAttribute; +Landroid/icu/text/DateTimePatternGenerator$DTPGflags; +Landroid/icu/text/PluralRules$Operand; +Landroid/icu/util/TimeZone; +Landroid/location/GpsStatus$Listener; +Landroid/location/LocationListener; +Landroid/media/AudioManager; +Landroid/media/MediaRouter; +Landroid/media/PlayerBase; +Landroid/media/session/MediaSessionManager; +Landroid/net/apf/ApfCapabilities; +Landroid/net/ConnectivityManager; +Landroid/net/ConnectivityManager$OnNetworkActiveListener; +Landroid/net/ConnectivityThread$Singleton; +Landroid/net/IpConfiguration$IpAssignment; +Landroid/net/IpConfiguration$ProxySettings; +Landroid/net/IpPrefix; +Landroid/net/LinkAddress; +Landroid/net/LinkProperties; +Landroid/net/Network; +Landroid/net/NetworkCapabilities; +Landroid/net/NetworkInfo; +Landroid/net/NetworkInfo$State; +Landroid/net/NetworkRequest; +Landroid/net/NetworkRequest$Type; +Landroid/net/RouteInfo; +Landroid/net/StringNetworkSpecifier; +Landroid/net/TrafficStats; +Landroid/net/UidRange; +Landroid/net/Uri$HierarchicalUri; +Landroid/net/Uri$StringUri; +Landroid/net/wifi/WifiManager; +Landroid/net/wifi/WifiManager$SoftApCallback; +Landroid/os/AsyncResult; +Landroid/os/AsyncTask; +Landroid/os/BinderProxy; +Landroid/os/Bundle; +Landroid/os/DeadObjectException; +Landroid/os/Environment; +Landroid/os/FileObserver; +Landroid/os/Handler; +Landroid/os/IDeviceIdleController; +Landroid/os/LocaleList; +Landroid/os/Looper; +Landroid/os/Message; +Landroid/os/ParcelUuid; +Landroid/os/Process; +Landroid/os/RecoverySystem; +Landroid/os/ServiceManager; +Landroid/os/storage/StorageManager; +Landroid/os/StrictMode; +Landroid/os/Trace; +Landroid/os/WorkSource; +Landroid/os/WorkSource$WorkChain; +Landroid/permission/PermissionManager; +Landroid/provider/FontsContract; +Landroid/provider/Settings$SettingNotFoundException; +Landroid/renderscript/RenderScriptCacheDir; +Landroid/security/IKeyChainService; +Landroid/security/keystore/AndroidKeyStoreProvider; +Landroid/security/net/config/ApplicationConfig; +Landroid/security/net/config/SystemCertificateSource$NoPreloadHolder; +Landroid/telecom/PhoneAccountHandle; +Landroid/telephony/AnomalyReporter; +Landroid/telephony/CellSignalStrengthCdma; +Landroid/telephony/CellSignalStrengthGsm; +Landroid/telephony/CellSignalStrengthLte; +Landroid/telephony/CellSignalStrengthNr; +Landroid/telephony/CellSignalStrengthTdscdma; +Landroid/telephony/CellSignalStrengthWcdma; +Landroid/telephony/DataSpecificRegistrationInfo; +Landroid/telephony/emergency/EmergencyNumber; +Landroid/telephony/ims/ImsMmTelManager$CapabilityCallback$CapabilityBinder; +Landroid/telephony/ims/ImsMmTelManager$RegistrationCallback$RegistrationBinder; +Landroid/telephony/ims/ImsReasonInfo; +Landroid/telephony/ims/ProvisioningManager$Callback$CallbackBinder; +Landroid/telephony/ModemActivityInfo; +Landroid/telephony/ModemInfo; +Landroid/telephony/NetworkRegistrationInfo; +Landroid/telephony/NetworkService; +Landroid/telephony/TelephonyManager; +Landroid/telephony/VoiceSpecificRegistrationInfo; +Landroid/text/format/DateFormat; +Landroid/text/method/SingleLineTransformationMethod; +Landroid/text/Selection$MemoryTextWatcher; +Landroid/text/SpanWatcher; +Landroid/text/style/AlignmentSpan; +Landroid/text/style/CharacterStyle; +Landroid/text/style/LeadingMarginSpan; +Landroid/text/style/LineBackgroundSpan; +Landroid/text/style/LineHeightSpan; +Landroid/text/style/MetricAffectingSpan; +Landroid/text/style/ReplacementSpan; +Landroid/text/style/SuggestionSpan; +Landroid/text/style/TabStopSpan; +Landroid/text/TextUtils; +Landroid/text/TextWatcher; +Landroid/transition/ChangeClipBounds; +Landroid/transition/ChangeImageTransform; +Landroid/transition/ChangeTransform; +Landroid/util/ArrayMap; +Landroid/util/ArraySet; +Landroid/util/DisplayMetrics; +Landroid/util/EventLog; +Landroid/util/Log; +Landroid/util/Patterns; +Landroid/view/AbsSavedState$1; +Landroid/view/accessibility/AccessibilityManager; +Landroid/view/accessibility/AccessibilityManager$AccessibilityServicesStateChangeListener; +Landroid/view/accessibility/AccessibilityManager$TouchExplorationStateChangeListener; +Landroid/view/accessibility/AccessibilityNodeIdManager; +Landroid/view/autofill/AutofillManager; +Landroid/view/autofill/Helper; +Landroid/view/Choreographer; +Landroid/view/inputmethod/InputMethodManager; +Landroid/view/IWindowManager; +Landroid/view/PointerIcon; +Landroid/view/RemoteAnimationAdapter; +Landroid/view/ThreadedRenderer; +Landroid/view/View; +Landroid/view/View$OnHoverListener; +Landroid/view/ViewRootImpl; +Landroid/view/ViewStub; +Landroid/view/ViewStub$OnInflateListener; +Landroid/view/ViewTreeObserver; +Landroid/view/WindowManager$LayoutParams; +Landroid/view/WindowManagerGlobal; +Landroid/widget/ActionMenuPresenter$OverflowMenuButton; +Landroid/widget/ActionMenuView; +Landroid/widget/Button; +Landroid/widget/CheckBox; +Landroid/widget/FrameLayout; +Landroid/widget/ImageButton; +Landroid/widget/ImageView; +Landroid/widget/LinearLayout; +Landroid/widget/RelativeLayout; +Landroid/widget/SeekBar; +Landroid/widget/Space; +Landroid/widget/TextView; +Landroid/widget/Toolbar; +[B +Lcom/android/ims/ImsManager; +Lcom/android/internal/logging/MetricsLogger; +Lcom/android/internal/os/BackgroundThread; +Lcom/android/internal/os/BinderInternal; +Lcom/android/internal/os/BinderInternal$BinderProxyLimitListener; +Lcom/android/internal/os/RuntimeInit; +Lcom/android/internal/os/SomeArgs; +Lcom/android/internal/policy/DecorView; +Lcom/android/internal/statusbar/IStatusBarService; +Lcom/android/internal/telephony/AppSmsManager; +Landroid/telephony/CallerInfoAsyncQuery$OnQueryCompleteListener; +Lcom/android/internal/telephony/CarrierActionAgent; +Lcom/android/internal/telephony/cat/CatService; +Lcom/android/internal/telephony/cat/IconLoader; +Lcom/android/internal/telephony/cat/RilMessageDecoder; +Lcom/android/internal/telephony/cdma/CdmaSubscriptionSourceManager; +Lcom/android/internal/telephony/cdma/EriManager; +Lcom/android/internal/telephony/CellularNetworkValidator; +Lcom/android/internal/telephony/CommandException; +Lcom/android/internal/telephony/dataconnection/DataConnection$DcActivatingState; +Lcom/android/internal/telephony/dataconnection/DataConnection$DcActiveState; +Lcom/android/internal/telephony/dataconnection/DataConnection$DcInactiveState; +Lcom/android/internal/telephony/dataconnection/DataEnabledSettings; +Lcom/android/internal/telephony/dataconnection/DcTracker; +Lcom/android/internal/telephony/euicc/EuiccCardController; +Lcom/android/internal/telephony/euicc/EuiccController; +Lcom/android/internal/telephony/GsmAlphabet; +Lcom/android/internal/telephony/GsmCdmaCallTracker; +Lcom/android/internal/telephony/GsmCdmaPhone; +Lcom/android/internal/telephony/IccPhoneBookInterfaceManager; +Lcom/android/internal/telephony/IccSmsInterfaceManager; +Lcom/android/internal/telephony/ims/ImsResolver; +Lcom/android/internal/telephony/imsphone/ImsExternalCallTracker; +Lcom/android/internal/telephony/imsphone/ImsPhone; +Lcom/android/internal/telephony/imsphone/ImsPhoneCallTracker; +Lcom/android/internal/telephony/ims/RcsMessageStoreController; +Lcom/android/internal/telephony/IntentBroadcaster; +Lcom/android/internal/telephony/ITelephonyRegistry$Stub$Proxy; +Lcom/android/internal/telephony/metrics/TelephonyMetrics; +Lcom/android/internal/telephony/MultiSimSettingController; +Lcom/android/internal/telephony/nano/CarrierIdProto$CarrierAttribute; +Lcom/android/internal/telephony/nano/CarrierIdProto$CarrierId; +Lcom/android/internal/telephony/nano/TelephonyProto$RilDataCall; +Lcom/android/internal/telephony/nano/TelephonyProto$SmsSession$Event; +Lcom/android/internal/telephony/nano/TelephonyProto$TelephonyCallSession$Event$RilCall; +Lcom/android/internal/telephony/NitzStateMachine; +Lcom/android/internal/telephony/PhoneConfigurationManager; +Lcom/android/internal/telephony/PhoneFactory; +Lcom/android/internal/telephony/PhoneSwitcher; +Lcom/android/internal/telephony/ProxyController; +Lcom/android/internal/telephony/RadioConfig; +Lcom/android/internal/telephony/RIL; +Lcom/android/internal/telephony/RILRequest; +Lcom/android/internal/telephony/RilWakelockInfo; +Lcom/android/internal/telephony/ServiceStateTracker; +Lcom/android/internal/telephony/SimActivationTracker; +Lcom/android/internal/telephony/SmsApplication; +Lcom/android/internal/telephony/SmsBroadcastUndelivered; +Lcom/android/internal/telephony/SmsStorageMonitor; +Lcom/android/internal/telephony/SmsUsageMonitor; +Lcom/android/internal/telephony/SubscriptionController; +Lcom/android/internal/telephony/SubscriptionInfoUpdater; +Lcom/android/internal/telephony/TelephonyComponentFactory; +Lcom/android/internal/telephony/TelephonyDevController; +Lcom/android/internal/telephony/TelephonyTester; +Lcom/android/internal/telephony/uicc/AdnRecordCache; +Lcom/android/internal/telephony/uicc/UiccCardApplication; +Lcom/android/internal/telephony/uicc/UiccController; +Lcom/android/internal/telephony/uicc/UiccProfile; +Lcom/android/internal/telephony/uicc/UiccStateChangedLauncher; +Lcom/android/internal/telephony/uicc/UsimFileHandler; +Lcom/android/internal/telephony/uicc/VoiceMailConstants; +Lcom/android/internal/util/LatencyTracker; +Lcom/android/internal/util/StateMachine$SmHandler; +Lcom/android/okhttp/OkHttpClient; +Lcom/android/okhttp/okio/AsyncTimeout; +Lcom/android/okhttp/okio/SegmentPool; +Lcom/android/phone/ecc/nano/ProtobufEccData$CountryInfo; +Lcom/android/phone/ecc/nano/ProtobufEccData$EccInfo; +Lcom/android/server/sip/SipWakeupTimer; +Lcom/android/server/SystemConfig; +Ldalvik/system/BaseDexClassLoader; +Ldalvik/system/BlockGuard; +Ldalvik/system/CloseGuard; +Ldalvik/system/RuntimeHooks; +Ldalvik/system/SocketTagger; +Ljava/io/BufferedReader; +Ljava/lang/AssertionError; +Ljava/lang/Boolean; +Ljava/lang/Byte; +Ljava/lang/Character; +Ljava/lang/CharSequence; +Ljava/lang/Class; +Ljava/lang/IllegalAccessException; +Ljava/lang/IllegalStateException; +Ljava/lang/NoSuchMethodException; +Ljava/lang/NullPointerException; +Ljava/lang/Object; +[Ljava/lang/Object; +Ljava/lang/ref/FinalizerReference; +Ljava/lang/Runnable; +Ljava/lang/SecurityException; +Ljava/lang/Short; +[Ljava/lang/String; +Ljava/lang/System; +Ljava/lang/Thread; +Ljava/lang/Throwable; +Ljava/lang/UnsatisfiedLinkError; +Ljava/net/Inet6Address; +Ljava/net/Socket; +Ljava/net/SocketException; +Ljava/nio/Bits; +Ljava/nio/charset/Charset; +Ljava/security/interfaces/RSAPrivateKey; +Ljava/security/Provider; +Ljava/util/Collections; +Ljava/util/concurrent/Executor; +Ljava/util/GregorianCalendar; +Ljava/util/Locale; +Ljava/util/Locale$NoImagePreloadHolder; +Ljava/util/Scanner; +Ljava/util/Set; +Ljava/util/TimeZone; +Ljavax/net/SocketFactory; +Ljavax/net/ssl/HttpsURLConnection; +Ljavax/net/ssl/HttpsURLConnection$NoPreloadHolder; +Ljavax/net/ssl/SSLContext; +Ljavax/net/ssl/SSLSessionContext; +Ljavax/net/ssl/SSLSocketFactory; +Llibcore/io/Libcore; +Llibcore/io/Memory; +Llibcore/net/NetworkSecurityPolicy; +Llibcore/timezone/TimeZoneFinder; +Lorg/apache/http/params/HttpParams; +Lsun/misc/Cleaner; +Lsun/nio/ch/FileChannelImpl; +Lsun/nio/ch/FileChannelImpl$Unmapper; +Lsun/nio/fs/UnixChannelFactory; +Lsun/security/jca/Providers; diff --git a/core/api/current.txt b/core/api/current.txt index 5f6c9b684409..8733632a701c 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -21,7 +21,6 @@ package android { field public static final String ACTIVITY_RECOGNITION = "android.permission.ACTIVITY_RECOGNITION"; field public static final String ADD_VOICEMAIL = "com.android.voicemail.permission.ADD_VOICEMAIL"; field public static final String ANSWER_PHONE_CALLS = "android.permission.ANSWER_PHONE_CALLS"; - field public static final String BACKGROUND_CAMERA = "android.permission.BACKGROUND_CAMERA"; field public static final String BATTERY_STATS = "android.permission.BATTERY_STATS"; field public static final String BIND_ACCESSIBILITY_SERVICE = "android.permission.BIND_ACCESSIBILITY_SERVICE"; field public static final String BIND_APPWIDGET = "android.permission.BIND_APPWIDGET"; @@ -134,7 +133,6 @@ package android { field public static final String RECEIVE_SMS = "android.permission.RECEIVE_SMS"; field public static final String RECEIVE_WAP_PUSH = "android.permission.RECEIVE_WAP_PUSH"; field public static final String RECORD_AUDIO = "android.permission.RECORD_AUDIO"; - field public static final String RECORD_BACKGROUND_AUDIO = "android.permission.RECORD_BACKGROUND_AUDIO"; field public static final String REORDER_TASKS = "android.permission.REORDER_TASKS"; field public static final String REQUEST_COMPANION_PROFILE_WATCH = "android.permission.REQUEST_COMPANION_PROFILE_WATCH"; field public static final String REQUEST_COMPANION_RUN_IN_BACKGROUND = "android.permission.REQUEST_COMPANION_RUN_IN_BACKGROUND"; @@ -12563,7 +12561,6 @@ package android.content.pm { field public static final String FEATURE_WIFI_DIRECT = "android.hardware.wifi.direct"; field public static final String FEATURE_WIFI_PASSPOINT = "android.hardware.wifi.passpoint"; field public static final String FEATURE_WIFI_RTT = "android.hardware.wifi.rtt"; - field public static final int FLAG_PERMISSION_ALLOWLIST_ROLE = 8; // 0x8 field public static final int FLAG_PERMISSION_WHITELIST_INSTALLER = 2; // 0x2 field public static final int FLAG_PERMISSION_WHITELIST_SYSTEM = 1; // 0x1 field public static final int FLAG_PERMISSION_WHITELIST_UPGRADE = 4; // 0x4 @@ -12702,7 +12699,6 @@ package android.content.pm { field public static final int FLAG_HARD_RESTRICTED = 4; // 0x4 field public static final int FLAG_IMMUTABLY_RESTRICTED = 16; // 0x10 field public static final int FLAG_INSTALLED = 1073741824; // 0x40000000 - field public static final int FLAG_INSTALLER_EXEMPT_IGNORED = 32; // 0x20 field public static final int FLAG_SOFT_RESTRICTED = 8; // 0x8 field public static final int PROTECTION_DANGEROUS = 1; // 0x1 field public static final int PROTECTION_FLAG_APPOP = 64; // 0x40 @@ -12902,6 +12898,7 @@ package android.content.pm { method public void reportShortcutUsed(String); method public boolean requestPinShortcut(@NonNull android.content.pm.ShortcutInfo, @Nullable android.content.IntentSender); method public boolean setDynamicShortcuts(@NonNull java.util.List<android.content.pm.ShortcutInfo>); + method public void updateShortcutVisibility(@NonNull String, @Nullable byte[], boolean); method public boolean updateShortcuts(@NonNull java.util.List<android.content.pm.ShortcutInfo>); field public static final int FLAG_MATCH_CACHED = 8; // 0x8 field public static final int FLAG_MATCH_DYNAMIC = 2; // 0x2 @@ -19293,8 +19290,8 @@ package android.location { method @NonNull public android.location.GnssAntennaInfo.Builder setSignalGainCorrections(@Nullable android.location.GnssAntennaInfo.SphericalCorrections); } - @Deprecated public static interface GnssAntennaInfo.Listener { - method @Deprecated public void onGnssAntennaInfoReceived(@NonNull java.util.List<android.location.GnssAntennaInfo>); + public static interface GnssAntennaInfo.Listener { + method public void onGnssAntennaInfoReceived(@NonNull java.util.List<android.location.GnssAntennaInfo>); } public static final class GnssAntennaInfo.PhaseCenterOffset implements android.os.Parcelable { @@ -19683,7 +19680,7 @@ package android.location { method public boolean hasProvider(@NonNull String); method public boolean isLocationEnabled(); method public boolean isProviderEnabled(@NonNull String); - method @Deprecated public boolean registerAntennaInfoListener(@NonNull java.util.concurrent.Executor, @NonNull android.location.GnssAntennaInfo.Listener); + method public boolean registerAntennaInfoListener(@NonNull java.util.concurrent.Executor, @NonNull android.location.GnssAntennaInfo.Listener); method @Deprecated @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public boolean registerGnssMeasurementsCallback(@NonNull android.location.GnssMeasurementsEvent.Callback); method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public boolean registerGnssMeasurementsCallback(@NonNull android.location.GnssMeasurementsEvent.Callback, @Nullable android.os.Handler); method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public boolean registerGnssMeasurementsCallback(@NonNull java.util.concurrent.Executor, @NonNull android.location.GnssMeasurementsEvent.Callback); @@ -19720,13 +19717,11 @@ package android.location { method public void setTestProviderEnabled(@NonNull String, boolean); method public void setTestProviderLocation(@NonNull String, @NonNull android.location.Location); method @Deprecated public void setTestProviderStatus(@NonNull String, int, @Nullable android.os.Bundle, long); - method @Deprecated public void unregisterAntennaInfoListener(@NonNull android.location.GnssAntennaInfo.Listener); + method public void unregisterAntennaInfoListener(@NonNull android.location.GnssAntennaInfo.Listener); method public void unregisterGnssMeasurementsCallback(@NonNull android.location.GnssMeasurementsEvent.Callback); method public void unregisterGnssNavigationMessageCallback(@NonNull android.location.GnssNavigationMessage.Callback); method public void unregisterGnssStatusCallback(@NonNull android.location.GnssStatus.Callback); - field public static final String ACTION_GNSS_ANTENNA_INFOS_CHANGED = "android.location.action.GNSS_ANTENNA_INFOS_CHANGED"; field public static final String ACTION_GNSS_CAPABILITIES_CHANGED = "android.location.action.GNSS_CAPABILITIES_CHANGED"; - field public static final String EXTRA_GNSS_ANTENNA_INFOS = "android.location.extra.GNSS_ANTENNA_INFOS"; field public static final String EXTRA_GNSS_CAPABILITIES = "android.location.extra.GNSS_CAPABILITIES"; field public static final String EXTRA_LOCATION_ENABLED = "android.location.extra.LOCATION_ENABLED"; field public static final String EXTRA_PROVIDER_ENABLED = "android.location.extra.PROVIDER_ENABLED"; @@ -19869,7 +19864,6 @@ package android.media { method public int getFlags(); method public int getUsage(); method public int getVolumeControlStream(); - method @NonNull public static String usageToString(int); method public void writeToParcel(android.os.Parcel, int); field public static final int ALLOW_CAPTURE_BY_ALL = 1; // 0x1 field public static final int ALLOW_CAPTURE_BY_NONE = 3; // 0x3 @@ -21302,8 +21296,8 @@ package android.media { public static final class MediaCodecInfo.AudioCapabilities { method public android.util.Range<java.lang.Integer> getBitrateRange(); method @NonNull public android.util.Range<java.lang.Integer>[] getInputChannelCountRanges(); - method public int getMaxInputChannelCount(); - method public int getMinInputChannelCount(); + method @IntRange(from=1, to=255) public int getMaxInputChannelCount(); + method @IntRange(from=1, to=255) public int getMinInputChannelCount(); method public android.util.Range<java.lang.Integer>[] getSupportedSampleRateRanges(); method public int[] getSupportedSampleRates(); method public boolean isSampleRateSupported(int); @@ -24760,7 +24754,7 @@ package android.media.session { method @NonNull public java.util.List<android.media.session.MediaController> getActiveSessions(@Nullable android.content.ComponentName); method @NonNull public java.util.List<android.media.Session2Token> getSession2Tokens(); method public boolean isTrustedForMediaControl(@NonNull android.media.session.MediaSessionManager.RemoteUserInfo); - method public void notifySession2Created(@NonNull android.media.Session2Token); + method @Deprecated public void notifySession2Created(@NonNull android.media.Session2Token); method public void removeOnActiveSessionsChangedListener(@NonNull android.media.session.MediaSessionManager.OnActiveSessionsChangedListener); method public void removeOnSession2TokensChangedListener(@NonNull android.media.session.MediaSessionManager.OnSession2TokensChangedListener); } @@ -38082,6 +38076,7 @@ package android.service.notification { field public static final int INTERRUPTION_FILTER_PRIORITY = 2; // 0x2 field public static final int INTERRUPTION_FILTER_UNKNOWN = 0; // 0x0 field public static final String META_DATA_DEFAULT_FILTER_TYPES = "android.service.notification.default_filter_types"; + field public static final String META_DATA_DISABLED_FILTER_TYPES = "android.service.notification.disabled_filter_types"; field public static final int NOTIFICATION_CHANNEL_OR_GROUP_ADDED = 1; // 0x1 field public static final int NOTIFICATION_CHANNEL_OR_GROUP_DELETED = 3; // 0x3 field public static final int NOTIFICATION_CHANNEL_OR_GROUP_UPDATED = 2; // 0x2 @@ -39792,7 +39787,7 @@ package android.telecom { method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public String getVoiceMailNumber(android.telecom.PhoneAccountHandle); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean handleMmi(String); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean handleMmi(String, android.telecom.PhoneAccountHandle); - method public boolean hasCompanionInCallServiceAccess(); + method public boolean hasManageOngoingCallsPermission(); method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public boolean isInCall(); method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public boolean isInManagedCall(); method public boolean isIncomingCallPermitted(android.telecom.PhoneAccountHandle); @@ -40444,7 +40439,7 @@ package android.telephony { } public static final class CarrierConfigManager.ImsServiceEntitlement { - field public static final String KEY_AES_URL_STRING = "imsserviceentitlement.aes_url_string"; + field public static final String KEY_ENTITLEMENT_SERVER_URL_STRING = "imsserviceentitlement.entitlement_server_url_string"; field public static final String KEY_PREFIX = "imsserviceentitlement."; } @@ -41672,7 +41667,6 @@ package android.telephony { public final class SignalStrengthUpdateRequest implements android.os.Parcelable { method public int describeContents(); - method @NonNull public android.os.IBinder getLiveToken(); method @NonNull public java.util.Collection<android.telephony.SignalThresholdInfo> getSignalThresholdInfos(); method public boolean isReportingRequestedWhileIdle(); method public void writeToParcel(@NonNull android.os.Parcel, int); diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt index e6f0e4804655..7ea7d61ac3c5 100644 --- a/core/api/module-lib-current.txt +++ b/core/api/module-lib-current.txt @@ -214,6 +214,16 @@ package android.os { } +package android.os.storage { + + public class StorageManager { + method public void notifyAppIoBlocked(@NonNull String, int, int, int); + method public void notifyAppIoResumed(@NonNull String, int, int, int); + field public static final int APP_IO_BLOCKED_REASON_TRANSCODING = 0; // 0x0 + } + +} + package android.provider { public final class DeviceConfig { diff --git a/core/api/system-current.txt b/core/api/system-current.txt index b55eb99db44a..89b564b051ad 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -27,6 +27,7 @@ package android { field public static final String ALLOW_ANY_CODEC_FOR_PLAYBACK = "android.permission.ALLOW_ANY_CODEC_FOR_PLAYBACK"; field public static final String AMBIENT_WALLPAPER = "android.permission.AMBIENT_WALLPAPER"; field public static final String APPROVE_INCIDENT_REPORTS = "android.permission.APPROVE_INCIDENT_REPORTS"; + field public static final String BACKGROUND_CAMERA = "android.permission.BACKGROUND_CAMERA"; field public static final String BACKUP = "android.permission.BACKUP"; field public static final String BATTERY_PREDICTION = "android.permission.BATTERY_PREDICTION"; field public static final String BIND_ATTENTION_SERVICE = "android.permission.BIND_ATTENTION_SERVICE"; @@ -215,6 +216,7 @@ package android { field public static final String RECEIVE_DEVICE_CUSTOMIZATION_READY = "android.permission.RECEIVE_DEVICE_CUSTOMIZATION_READY"; field public static final String RECEIVE_EMERGENCY_BROADCAST = "android.permission.RECEIVE_EMERGENCY_BROADCAST"; field public static final String RECEIVE_WIFI_CREDENTIAL_CHANGE = "android.permission.RECEIVE_WIFI_CREDENTIAL_CHANGE"; + field public static final String RECORD_BACKGROUND_AUDIO = "android.permission.RECORD_BACKGROUND_AUDIO"; field public static final String RECOVERY = "android.permission.RECOVERY"; field public static final String RECOVER_KEYSTORE = "android.permission.RECOVER_KEYSTORE"; field public static final String REGISTER_CALL_PROVIDER = "android.permission.REGISTER_CALL_PROVIDER"; @@ -645,7 +647,6 @@ package android.app { method public void setDontSendToRestrictedApps(boolean); method @RequiresPermission(anyOf={android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST, android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND, android.Manifest.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND}) public void setTemporaryAppAllowlist(long, int, int, @Nullable String); method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST, android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND, android.Manifest.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND}) public void setTemporaryAppWhitelistDuration(long); - method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST, android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND, android.Manifest.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND}) public void setTemporaryAppWhitelistDuration(int, long); method public android.os.Bundle toBundle(); } @@ -2570,7 +2571,6 @@ package android.content.pm { field public static final int FLAG_PERMISSION_ONE_TIME = 65536; // 0x10000 field public static final int FLAG_PERMISSION_POLICY_FIXED = 4; // 0x4 field public static final int FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT = 2048; // 0x800 - field public static final int FLAG_PERMISSION_RESTRICTION_ROLE_EXEMPT = 262144; // 0x40000 field public static final int FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT = 4096; // 0x1000 field public static final int FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT = 8192; // 0x2000 field public static final int FLAG_PERMISSION_REVIEW_REQUIRED = 64; // 0x40 @@ -2756,6 +2756,15 @@ package android.content.pm.permission { package android.content.pm.verify.domain { + public final class DomainOwner implements android.os.Parcelable { + ctor public DomainOwner(@NonNull String, boolean); + method public int describeContents(); + method @NonNull public String getPackageName(); + method public boolean isOverrideable(); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.content.pm.verify.domain.DomainOwner> CREATOR; + } + public final class DomainVerificationInfo implements android.os.Parcelable { method public int describeContents(); method @NonNull public java.util.Map<java.lang.String,java.lang.Integer> getHostToStateMap(); @@ -2768,6 +2777,7 @@ package android.content.pm.verify.domain { public interface DomainVerificationManager { method @Nullable @RequiresPermission(anyOf={android.Manifest.permission.DOMAIN_VERIFICATION_AGENT, android.Manifest.permission.UPDATE_DOMAIN_VERIFICATION_USER_SELECTION}) public android.content.pm.verify.domain.DomainVerificationInfo getDomainVerificationInfo(@NonNull String) throws android.content.pm.PackageManager.NameNotFoundException; method @Nullable @RequiresPermission(android.Manifest.permission.UPDATE_DOMAIN_VERIFICATION_USER_SELECTION) public android.content.pm.verify.domain.DomainVerificationUserSelection getDomainVerificationUserSelection(@NonNull String) throws android.content.pm.PackageManager.NameNotFoundException; + method @NonNull @RequiresPermission(android.Manifest.permission.UPDATE_DOMAIN_VERIFICATION_USER_SELECTION) public java.util.List<android.content.pm.verify.domain.DomainOwner> getOwnersForDomain(@NonNull String); method @NonNull @RequiresPermission(android.Manifest.permission.DOMAIN_VERIFICATION_AGENT) public java.util.List<java.lang.String> getValidVerificationPackageNames(); method public static boolean isStateModifiable(int); method public static boolean isStateVerified(int); @@ -2789,13 +2799,16 @@ package android.content.pm.verify.domain { public final class DomainVerificationUserSelection implements android.os.Parcelable { method public int describeContents(); - method @NonNull public java.util.Map<java.lang.String,java.lang.Boolean> getHostToUserSelectionMap(); + method @NonNull public java.util.Map<java.lang.String,java.lang.Integer> getHostToStateMap(); method @NonNull public java.util.UUID getIdentifier(); method @NonNull public String getPackageName(); method @NonNull public android.os.UserHandle getUser(); method @NonNull public boolean isLinkHandlingAllowed(); method public void writeToParcel(@NonNull android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.content.pm.verify.domain.DomainVerificationUserSelection> CREATOR; + field public static final int DOMAIN_STATE_NONE = 0; // 0x0 + field public static final int DOMAIN_STATE_SELECTED = 1; // 0x1 + field public static final int DOMAIN_STATE_VERIFIED = 2; // 0x2 } } @@ -10758,6 +10771,10 @@ package android.telephony { field public static final String KEY_SUPPORT_CDMA_1X_VOICE_CALLS_BOOL = "support_cdma_1x_voice_calls_bool"; } + public static final class CarrierConfigManager.Ims { + field public static final String KEY_PUBLISH_SERVICE_DESC_FEATURE_TAG_MAP_OVERRIDE_STRING_ARRAY = "ims.publish_service_desc_feature_tag_map_override_string_array"; + } + public static final class CarrierConfigManager.Wifi { field public static final String KEY_AVOID_5GHZ_SOFTAP_FOR_LAA_BOOL = "wifi.avoid_5ghz_softap_for_laa_bool"; field public static final String KEY_AVOID_5GHZ_WIFI_DIRECT_FOR_LAA_BOOL = "wifi.avoid_5ghz_wifi_direct_for_laa_bool"; @@ -13389,7 +13406,7 @@ package android.telephony.ims.stub { } public static interface CapabilityExchangeEventListener.OptionsRequestCallback { - method public default void onRespondToCapabilityRequest(@NonNull android.telephony.ims.RcsContactUceCapability, boolean); + method public void onRespondToCapabilityRequest(@NonNull android.telephony.ims.RcsContactUceCapability, boolean); method public void onRespondToCapabilityRequestWithError(@IntRange(from=100, to=699) int, @NonNull String); } diff --git a/core/api/test-current.txt b/core/api/test-current.txt index 28724f271a7f..1c54e84c6914 100644 --- a/core/api/test-current.txt +++ b/core/api/test-current.txt @@ -5,6 +5,7 @@ package android { field public static final String ACCESS_NOTIFICATIONS = "android.permission.ACCESS_NOTIFICATIONS"; field public static final String ACTIVITY_EMBEDDING = "android.permission.ACTIVITY_EMBEDDING"; field public static final String APPROVE_INCIDENT_REPORTS = "android.permission.APPROVE_INCIDENT_REPORTS"; + field public static final String BACKGROUND_CAMERA = "android.permission.BACKGROUND_CAMERA"; field public static final String BIND_CELL_BROADCAST_SERVICE = "android.permission.BIND_CELL_BROADCAST_SERVICE"; field public static final String BRIGHTNESS_SLIDER_USAGE = "android.permission.BRIGHTNESS_SLIDER_USAGE"; field public static final String BROADCAST_CLOSE_SYSTEM_DIALOGS = "android.permission.BROADCAST_CLOSE_SYSTEM_DIALOGS"; @@ -30,6 +31,7 @@ package android { field public static final String QUERY_USERS = "android.permission.QUERY_USERS"; field public static final String READ_CELL_BROADCASTS = "android.permission.READ_CELL_BROADCASTS"; field public static final String READ_PRIVILEGED_PHONE_STATE = "android.permission.READ_PRIVILEGED_PHONE_STATE"; + field public static final String RECORD_BACKGROUND_AUDIO = "android.permission.RECORD_BACKGROUND_AUDIO"; field public static final String REMOVE_TASKS = "android.permission.REMOVE_TASKS"; field public static final String RESET_APP_ERRORS = "android.permission.RESET_APP_ERRORS"; field public static final String START_TASKS_FROM_RECENTS = "android.permission.START_TASKS_FROM_RECENTS"; @@ -562,6 +564,16 @@ package android.app.blob { } +package android.app.contentsuggestions { + + public final class ContentSuggestionsManager { + method @RequiresPermission(android.Manifest.permission.MANAGE_CONTENT_SUGGESTIONS) public void resetTemporaryService(int); + method @RequiresPermission(android.Manifest.permission.MANAGE_CONTENT_SUGGESTIONS) public void setDefaultServiceEnabled(int, boolean); + method @RequiresPermission(android.Manifest.permission.MANAGE_CONTENT_SUGGESTIONS) public void setTemporaryService(int, @NonNull String, int); + } + +} + package android.app.prediction { public final class AppPredictor { diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java index 71f164f49262..c812e8e1782a 100644 --- a/core/java/android/app/ActivityManagerInternal.java +++ b/core/java/android/app/ActivityManagerInternal.java @@ -113,10 +113,6 @@ public abstract class ActivityManagerInternal { IBinder allowlistToken, long duration, @TempAllowListType int type, @ReasonCode int reasonCode, @Nullable String reason); - @Deprecated - public abstract void setPendingIntentWhitelistDuration(IIntentSender target, - IBinder allowlistToken, long duration, @TempAllowListType int type); - /** * Returns the flags set for a {@link PendingIntent}. */ diff --git a/core/java/android/app/BroadcastOptions.java b/core/java/android/app/BroadcastOptions.java index 2e06e9b80595..477e96b16daf 100644 --- a/core/java/android/app/BroadcastOptions.java +++ b/core/java/android/app/BroadcastOptions.java @@ -144,23 +144,6 @@ public class BroadcastOptions { * Set a duration for which the system should temporary place an application on the * power allowlist when this broadcast is being delivered to it, specify the temp allowlist * type. - * @param type one of {@link TempAllowListType} - * @param duration the duration in milliseconds; 0 means to not place on allowlist. - * @deprecated use {@link #setTemporaryAppAllowlist(long, int, int, String)} instead. - */ - @Deprecated - @RequiresPermission(anyOf = {android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST, - android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND, - android.Manifest.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND}) - public void setTemporaryAppWhitelistDuration(@TempAllowListType int type, long duration) { - setTemporaryAppAllowlist(duration, type, - PowerWhitelistManager.REASON_UNKNOWN, null); - } - - /** - * Set a duration for which the system should temporary place an application on the - * power allowlist when this broadcast is being delivered to it, specify the temp allowlist - * type. * @param duration the duration in milliseconds; 0 means to not place on allowlist. * @param type one of {@link TempAllowListType} * @param reasonCode one of {@link ReasonCode}, use diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index f7304fbee6d6..8167622ff13c 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -5013,6 +5013,7 @@ public class Notification implements Parcelable bindNotificationHeader(contentView, p); bindLargeIconAndApplyMargin(contentView, p, result); boolean showProgress = handleProgressBar(contentView, ex, p); + boolean hasSecondLine = showProgress; if (p.hasTitle()) { contentView.setViewVisibility(R.id.title, View.VISIBLE); contentView.setTextViewText(R.id.title, processTextSpans(p.title)); @@ -5028,11 +5029,27 @@ public class Notification implements Parcelable contentView.setTextViewText(textId, processTextSpans(p.text)); setTextViewColorSecondary(contentView, textId, p); contentView.setViewVisibility(textId, View.VISIBLE); + hasSecondLine = true; } + setHeaderlessVerticalMargins(contentView, p, hasSecondLine); return contentView; } + private static void setHeaderlessVerticalMargins(RemoteViews contentView, + StandardTemplateParams p, boolean hasSecondLine) { + if (!p.mHeaderless) { + return; + } + int marginDimen = hasSecondLine + ? R.dimen.notification_headerless_margin_twoline + : R.dimen.notification_headerless_margin_oneline; + contentView.setViewLayoutMarginDimen(R.id.notification_headerless_view_column, + RemoteViews.MARGIN_TOP, marginDimen); + contentView.setViewLayoutMarginDimen(R.id.notification_headerless_view_column, + RemoteViews.MARGIN_BOTTOM, marginDimen); + } + private CharSequence processTextSpans(CharSequence text) { if (hasForegroundColor() || mInNightMode) { return ContrastColorUtil.clearColorSpans(text); @@ -5494,12 +5511,28 @@ public class Notification implements Parcelable big.setViewVisibility(R.id.notification_material_reply_text_3, View.GONE); big.setTextViewText(R.id.notification_material_reply_text_3, null); - final boolean snoozeEnabled = mContext.getContentResolver() != null - && (Settings.Secure.getInt(mContext.getContentResolver(), - Settings.Secure.SHOW_NOTIFICATION_SNOOZE, 0) == 1); - int bottomMarginDimen = snoozeEnabled ? 0 : R.dimen.notification_content_margin; + // This may get erased by bindSnoozeAction big.setViewLayoutMarginDimen(R.id.notification_action_list_margin_target, - RemoteViews.MARGIN_BOTTOM, bottomMarginDimen); + RemoteViews.MARGIN_BOTTOM, R.dimen.notification_content_margin); + } + + private void bindSnoozeAction(RemoteViews big, StandardTemplateParams p) { + boolean hideSnoozeButton = mN.isForegroundService() || mN.fullScreenIntent != null + || isColorized(p) || p.mViewType == StandardTemplateParams.VIEW_TYPE_HEADS_UP; + big.setBoolean(R.id.snooze_button, "setEnabled", !hideSnoozeButton); + if (hideSnoozeButton) { + // Only hide; NotificationContentView will show it when it adds the click listener + big.setViewVisibility(R.id.snooze_button, View.GONE); + } + + final boolean snoozeEnabled = !hideSnoozeButton + && mContext.getContentResolver() != null + && (Settings.Secure.getInt(mContext.getContentResolver(), + Settings.Secure.SHOW_NOTIFICATION_SNOOZE, 0) == 1); + if (snoozeEnabled) { + big.setViewLayoutMarginDimen(R.id.notification_action_list_margin_target, + RemoteViews.MARGIN_BOTTOM, 0); + } } /** @@ -5521,6 +5554,7 @@ public class Notification implements Parcelable RemoteViews big = applyStandardTemplate(layoutId, p, result); resetStandardTemplateWithActions(big); + bindSnoozeAction(big, p); boolean validRemoteInput = false; @@ -6834,26 +6868,13 @@ public class Notification implements Parcelable if (decorationType <= DevFlags.DECORATION_PARTIAL) { template.removeFromParent(R.id.notification_top_line); } - if (decorationType != DevFlags.DECORATION_FULL_COMPATIBLE) { - // Change the max content size from 60dp (the compatible size) to 48dp - // (the constrained size). This is done by increasing the minimum margin - // (implemented as top/bottom margins) and decreasing the extra margin - // (implemented as the height of shrinkable top/bottom views in the column). - template.setViewLayoutMarginDimen( - R.id.notification_headerless_view_column, - RemoteViews.MARGIN_TOP, - R.dimen.notification_headerless_margin_constrained_minimum); - template.setViewLayoutMarginDimen( - R.id.notification_headerless_view_column, - RemoteViews.MARGIN_BOTTOM, - R.dimen.notification_headerless_margin_constrained_minimum); - template.setViewLayoutHeightDimen( - R.id.notification_headerless_margin_extra_top, - R.dimen.notification_headerless_margin_constrained_extra); - template.setViewLayoutHeightDimen( - R.id.notification_headerless_margin_extra_bottom, - R.dimen.notification_headerless_margin_constrained_extra); - } + // The vertical margins are bigger in the "two-line" scenario than the "one-line" + // scenario, but the 'compatible' decoration state is intended to have 3 lines, + // (1 for the top line views and 2 for the custom views), so in that one case we + // use the smaller 1-line margins. This gives the compatible case 88-16*2=56 dp of + // height, 24dp of which goes to the top line, leaving 32dp for the custom view. + boolean hasSecondLine = decorationType != DevFlags.DECORATION_FULL_COMPATIBLE; + Builder.setHeaderlessVerticalMargins(template, p, hasSecondLine); } else { // also update the end margin to account for the large icon or expander Resources resources = context.getResources(); @@ -9358,6 +9379,7 @@ public class Notification implements Parcelable // Bind actions. mBuilder.resetStandardTemplateWithActions(contentView); + mBuilder.bindSnoozeAction(contentView, p); bindCallActions(contentView, p); // Bind some extra conversation-specific header fields. @@ -9417,11 +9439,16 @@ public class Notification implements Parcelable } private void bindCallerVerification(RemoteViews contentView, StandardTemplateParams p) { + String iconContentDescription = null; + boolean showDivider = true; if (mVerificationIcon != null) { contentView.setImageViewIcon(R.id.verification_icon, mVerificationIcon); contentView.setDrawableTint(R.id.verification_icon, false /* targetBackground */, mBuilder.getSecondaryTextColor(p), PorterDuff.Mode.SRC_ATOP); contentView.setViewVisibility(R.id.verification_icon, View.VISIBLE); + iconContentDescription = mBuilder.mContext.getString( + R.string.notification_verified_content_description); + showDivider = false; // the icon replaces the divider } else { contentView.setViewVisibility(R.id.verification_icon, View.GONE); } @@ -9429,8 +9456,17 @@ public class Notification implements Parcelable contentView.setTextViewText(R.id.verification_text, mVerificationText); mBuilder.setTextViewColorSecondary(contentView, R.id.verification_text, p); contentView.setViewVisibility(R.id.verification_text, View.VISIBLE); + iconContentDescription = null; // let the app's text take precedence } else { contentView.setViewVisibility(R.id.verification_text, View.GONE); + showDivider = false; // no divider if no text + } + contentView.setContentDescription(R.id.verification_icon, iconContentDescription); + if (showDivider) { + contentView.setViewVisibility(R.id.verification_divider, View.VISIBLE); + mBuilder.setTextViewColorSecondary(contentView, R.id.verification_divider, p); + } else { + contentView.setViewVisibility(R.id.verification_divider, View.GONE); } } @@ -11998,6 +12034,7 @@ public class Notification implements Parcelable boolean mHideTitle; boolean mHideActions; boolean mHideProgress; + boolean mHideSnoozeButton; boolean mPromotePicture; boolean mAllowActionIcons; CharSequence title; @@ -12015,6 +12052,7 @@ public class Notification implements Parcelable mHideTitle = false; mHideActions = false; mHideProgress = false; + mHideSnoozeButton = false; mPromotePicture = false; mAllowActionIcons = false; title = null; @@ -12061,6 +12099,11 @@ public class Notification implements Parcelable return this; } + final StandardTemplateParams hideSnoozeButton(boolean hideSnoozeButton) { + this.mHideSnoozeButton = hideSnoozeButton; + return this; + } + final StandardTemplateParams promotePicture(boolean promotePicture) { this.mPromotePicture = promotePicture; return this; diff --git a/core/java/android/app/admin/DeviceAdminReceiver.java b/core/java/android/app/admin/DeviceAdminReceiver.java index 721a444f0f15..cccc9294c2d5 100644 --- a/core/java/android/app/admin/DeviceAdminReceiver.java +++ b/core/java/android/app/admin/DeviceAdminReceiver.java @@ -585,6 +585,9 @@ public class DeviceAdminReceiver extends BroadcastReceiver { * @param intent The received intent as per {@link #onReceive}. */ public void onEnabled(@NonNull Context context, @NonNull Intent intent) { + if (LOCAL_LOGV) { + Log.v(TAG, getClass().getName() + ".onEnabled() on user " + context.getUserId()); + } } /** @@ -600,6 +603,10 @@ public class DeviceAdminReceiver extends BroadcastReceiver { */ public @Nullable CharSequence onDisableRequested(@NonNull Context context, @NonNull Intent intent) { + if (LOCAL_LOGV) { + Log.v(TAG, getClass().getName() + ".onDisableRequested() on user " + + context.getUserId()); + } return null; } @@ -612,6 +619,9 @@ public class DeviceAdminReceiver extends BroadcastReceiver { * @param intent The received intent as per {@link #onReceive}. */ public void onDisabled(@NonNull Context context, @NonNull Intent intent) { + if (LOCAL_LOGV) { + Log.v(TAG, getClass().getName() + ".onDisabled() on user " + context.getUserId()); + } } /** @@ -786,6 +796,10 @@ public class DeviceAdminReceiver extends BroadcastReceiver { * @param intent The received intent as per {@link #onReceive}. */ public void onProfileProvisioningComplete(@NonNull Context context, @NonNull Intent intent) { + if (LOCAL_LOGV) { + Log.v(TAG, getClass().getName() + ".onProfileProvisioningComplete() on user " + + context.getUserId()); + } } /** @@ -961,6 +975,9 @@ public class DeviceAdminReceiver extends BroadcastReceiver { */ public void onUserAdded(@NonNull Context context, @NonNull Intent intent, @NonNull UserHandle addedUser) { + if (LOCAL_LOGV) { + Log.v(TAG, getClass().getName() + ".onUserAdded() on user " + context.getUserId()); + } } /** @@ -974,6 +991,9 @@ public class DeviceAdminReceiver extends BroadcastReceiver { */ public void onUserRemoved(@NonNull Context context, @NonNull Intent intent, @NonNull UserHandle removedUser) { + if (LOCAL_LOGV) { + Log.v(TAG, getClass().getName() + ".onUserRemoved() on user " + context.getUserId()); + } } /** @@ -987,6 +1007,9 @@ public class DeviceAdminReceiver extends BroadcastReceiver { */ public void onUserStarted(@NonNull Context context, @NonNull Intent intent, @NonNull UserHandle startedUser) { + if (LOCAL_LOGV) { + Log.v(TAG, getClass().getName() + ".onUserStarted() on user " + context.getUserId()); + } } /** @@ -1000,6 +1023,9 @@ public class DeviceAdminReceiver extends BroadcastReceiver { */ public void onUserStopped(@NonNull Context context, @NonNull Intent intent, @NonNull UserHandle stoppedUser) { + if (LOCAL_LOGV) { + Log.v(TAG, getClass().getName() + ".onUserStopped() on user " + context.getUserId()); + } } /** @@ -1013,6 +1039,9 @@ public class DeviceAdminReceiver extends BroadcastReceiver { */ public void onUserSwitched(@NonNull Context context, @NonNull Intent intent, @NonNull UserHandle switchedUser) { + if (LOCAL_LOGV) { + Log.v(TAG, getClass().getName() + ".onUserSwitched() on user " + context.getUserId()); + } } /** @@ -1104,7 +1133,8 @@ public class DeviceAdminReceiver extends BroadcastReceiver { public void onReceive(@NonNull Context context, @NonNull Intent intent) { String action = intent.getAction(); if (LOCAL_LOGV) { - Log.v(TAG, "onReceive(): received " + action + " on user " + context.getUserId()); + Log.v(TAG, getClass().getName() + ".onReceive(): received " + action + " on user " + + context.getUserId()); } if (ACTION_PASSWORD_CHANGED.equals(action)) { diff --git a/core/java/android/app/backup/BackupAgent.java b/core/java/android/app/backup/BackupAgent.java index 85cfe835c28d..22492ccd0373 100644 --- a/core/java/android/app/backup/BackupAgent.java +++ b/core/java/android/app/backup/BackupAgent.java @@ -564,10 +564,6 @@ public abstract class BackupAgent extends ContextWrapper { @VisibleForTesting public IncludeExcludeRules getIncludeExcludeRules(FullBackup.BackupScheme backupScheme) throws IOException, XmlPullParserException { - if (isDeviceToDeviceMigration()) { - return IncludeExcludeRules.emptyRules(); - } - Map<String, Set<PathWithRequiredFlags>> manifestIncludeMap; ArraySet<PathWithRequiredFlags> manifestExcludeSet; diff --git a/core/java/android/app/backup/FullBackup.java b/core/java/android/app/backup/FullBackup.java index 3701ea825933..829b6cd43934 100644 --- a/core/java/android/app/backup/FullBackup.java +++ b/core/java/android/app/backup/FullBackup.java @@ -20,11 +20,15 @@ import static android.app.backup.BackupManager.OperationType; import android.annotation.Nullable; import android.annotation.StringDef; +import android.app.compat.CompatChanges; +import android.compat.annotation.ChangeId; +import android.compat.annotation.EnabledSince; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.res.XmlResourceParser; +import android.os.Build; import android.os.ParcelFileDescriptor; import android.os.Process; import android.os.storage.StorageManager; @@ -96,6 +100,14 @@ public class FullBackup { public static final String FLAG_REQUIRED_FAKE_CLIENT_SIDE_ENCRYPTION = "fakeClientSideEncryption"; + /** + * When this change is enabled, include / exclude rules specified via + * {@code android:fullBackupContent} are ignored during D2D transfers. + */ + @ChangeId + @EnabledSince(targetSdkVersion = Build.VERSION_CODES.S) + private static final long IGNORE_FULL_BACKUP_CONTENT_IN_D2D = 180523564L; + @StringDef({ ConfigSection.CLOUD_BACKUP, ConfigSection.DEVICE_TRANSFER @@ -527,7 +539,10 @@ public class FullBackup { } } - // TODO(b/180523564): Ignore the old config for apps targeting Android S+ during D2D. + if (operationType == OperationType.MIGRATION + && CompatChanges.isChangeEnabled(IGNORE_FULL_BACKUP_CONTENT_IN_D2D)) { + return; + } if (mFullBackupContent != 0) { // Fall back to the old config. diff --git a/core/java/android/app/contentsuggestions/ContentSuggestionsManager.java b/core/java/android/app/contentsuggestions/ContentSuggestionsManager.java index b3f9e31abaa4..33f83026ba0f 100644 --- a/core/java/android/app/contentsuggestions/ContentSuggestionsManager.java +++ b/core/java/android/app/contentsuggestions/ContentSuggestionsManager.java @@ -19,7 +19,9 @@ package android.app.contentsuggestions; import android.annotation.CallbackExecutor; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.RequiresPermission; import android.annotation.SystemApi; +import android.annotation.TestApi; import android.annotation.UserIdInt; import android.graphics.Bitmap; import android.os.Binder; @@ -220,6 +222,72 @@ public final class ContentSuggestionsManager { } /** + * Resets the temporary service implementation to the default component. + * + * @hide + */ + @TestApi + @RequiresPermission(android.Manifest.permission.MANAGE_CONTENT_SUGGESTIONS) + public void resetTemporaryService(@UserIdInt int userId) { + if (mService == null) { + Log.e(TAG, "resetTemporaryService called, but no ContentSuggestionsManager " + + "configured"); + return; + } + try { + mService.resetTemporaryService(userId); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * Temporarily sets the service implementation. + * + * @param userId user Id to set the temporary service on. + * @param serviceName name of the new component + * @param duration how long the change will be valid (the service will be automatically reset + * to the default component after this timeout expires). + * + * @hide + */ + @TestApi + @RequiresPermission(android.Manifest.permission.MANAGE_CONTENT_SUGGESTIONS) + public void setTemporaryService( + @UserIdInt int userId, @NonNull String serviceName, int duration) { + if (mService == null) { + Log.e(TAG, "setTemporaryService called, but no ContentSuggestionsManager " + + "configured"); + return; + } + try { + mService.setTemporaryService(userId, serviceName, duration); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * Sets whether the default service should be used. + * + * @hide + */ + @TestApi + @RequiresPermission(android.Manifest.permission.MANAGE_CONTENT_SUGGESTIONS) + public void setDefaultServiceEnabled(@UserIdInt int userId, boolean enabled) { + if (mService == null) { + Log.e(TAG, "setDefaultServiceEnabled called, but no ContentSuggestionsManager " + + "configured"); + return; + } + try { + mService.setDefaultServiceEnabled(userId, enabled); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** * Callback to receive content selections from * {@link #suggestContentSelections(SelectionsRequest, Executor, SelectionsCallback)}. */ diff --git a/core/java/android/app/contentsuggestions/IContentSuggestionsManager.aidl b/core/java/android/app/contentsuggestions/IContentSuggestionsManager.aidl index 8e6338babf22..9350eeb0ee66 100644 --- a/core/java/android/app/contentsuggestions/IContentSuggestionsManager.aidl +++ b/core/java/android/app/contentsuggestions/IContentSuggestionsManager.aidl @@ -45,4 +45,7 @@ oneway interface IContentSuggestionsManager { in IClassificationsCallback callback); void notifyInteraction(int userId, in String requestId, in Bundle interaction); void isEnabled(int userId, in IResultReceiver receiver); + void resetTemporaryService(int userId); + void setTemporaryService(int userId, in String serviceName, int duration); + void setDefaultServiceEnabled(int userId, boolean enabled); } diff --git a/core/java/android/content/pm/IShortcutService.aidl b/core/java/android/content/pm/IShortcutService.aidl index 29a55b7a74da..b34574811bca 100644 --- a/core/java/android/content/pm/IShortcutService.aidl +++ b/core/java/android/content/pm/IShortcutService.aidl @@ -78,4 +78,7 @@ interface IShortcutService { ParceledListSlice getShortcuts(String packageName, int matchFlags, int userId); void pushDynamicShortcut(String packageName, in ShortcutInfo shortcut, int userId); + + void updateShortcutVisibility(String callingPkg, String packageName, in byte[] certificate, + in boolean visible, int userId); }
\ No newline at end of file diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index ca882417394e..29dea6bb09db 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -4075,16 +4075,6 @@ public abstract class PackageManager { public static final int FLAG_PERMISSION_AUTO_REVOKED = 1 << 17; /** - * Permission flag: The permission is restricted but the app is exempt - * from the restriction and is allowed to hold this permission in its - * full form and the exemption is provided by the held roles. - * - * @hide - */ - @SystemApi - public static final int FLAG_PERMISSION_RESTRICTION_ROLE_EXEMPT = 1 << 18; - - /** * Permission flag: This location permission is selected as the level of granularity of * location accuracy. * Example: If this flag is set for ACCESS_FINE_LOCATION, FINE location is the selected location @@ -4113,8 +4103,7 @@ public abstract class PackageManager { public static final int FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT = FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT | FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT - | FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT - | FLAG_PERMISSION_RESTRICTION_ROLE_EXEMPT; + | FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT; /** * Mask for all permission flags. @@ -4199,20 +4188,11 @@ public abstract class PackageManager { */ public static final int FLAG_PERMISSION_WHITELIST_UPGRADE = 1 << 2; - /** - * Permission allowlist flag: permissions exempted by the system - * when being granted a role. - * Permissions can also be exempted by the installer, the system, or on - * upgrade. - */ - public static final int FLAG_PERMISSION_ALLOWLIST_ROLE = 1 << 3; - /** @hide */ @IntDef(flag = true, prefix = {"FLAG_PERMISSION_WHITELIST_"}, value = { FLAG_PERMISSION_WHITELIST_SYSTEM, FLAG_PERMISSION_WHITELIST_INSTALLER, - FLAG_PERMISSION_WHITELIST_UPGRADE, - FLAG_PERMISSION_ALLOWLIST_ROLE + FLAG_PERMISSION_WHITELIST_UPGRADE }) @Retention(RetentionPolicy.SOURCE) public @interface PermissionWhitelistFlags {} @@ -5244,10 +5224,6 @@ public abstract class PackageManager { * This list corresponds to the {@link #FLAG_PERMISSION_WHITELIST_INSTALLER} flag. * Can be accessed by pre-installed holders of a dedicated permission or the * installer on record. - * - * <li>one for cases where the system exempts the permission when granting a role. - * This list corresponds to the {@link #FLAG_PERMISSION_ALLOWLIST_ROLE} flag. Can - * be accessed by pre-installed holders of a dedicated permission. * </ol> * * <p> @@ -5266,7 +5242,6 @@ public abstract class PackageManager { * @see #FLAG_PERMISSION_WHITELIST_SYSTEM * @see #FLAG_PERMISSION_WHITELIST_UPGRADE * @see #FLAG_PERMISSION_WHITELIST_INSTALLER - * @see #FLAG_PERMISSION_ALLOWLIST_ROLE * * @throws SecurityException if you try to access a whitelist that you have no access to. */ @@ -5306,10 +5281,6 @@ public abstract class PackageManager { * This list corresponds to the {@link #FLAG_PERMISSION_WHITELIST_INSTALLER} flag. * Can be modified by pre-installed holders of a dedicated permission or the installer * on record. - * - * <li>one for cases where the system exempts the permission when permission when - * granting a role. This list corresponds to the {@link #FLAG_PERMISSION_ALLOWLIST_ROLE} - * flag. Can be modified by pre-installed holders of a dedicated permission. * </ol> * * <p>You need to specify the whitelists for which to set the whitelisted permissions @@ -5333,7 +5304,6 @@ public abstract class PackageManager { * @see #FLAG_PERMISSION_WHITELIST_SYSTEM * @see #FLAG_PERMISSION_WHITELIST_UPGRADE * @see #FLAG_PERMISSION_WHITELIST_INSTALLER - * @see #FLAG_PERMISSION_ALLOWLIST_ROLE * * @throws SecurityException if you try to modify a whitelist that you have no access to. */ @@ -5403,7 +5373,6 @@ public abstract class PackageManager { * @see #FLAG_PERMISSION_WHITELIST_SYSTEM * @see #FLAG_PERMISSION_WHITELIST_UPGRADE * @see #FLAG_PERMISSION_WHITELIST_INSTALLER - * @see #FLAG_PERMISSION_ALLOWLIST_ROLE * * @throws SecurityException if you try to modify a whitelist that you have no access to. */ diff --git a/core/java/android/content/pm/PermissionInfo.java b/core/java/android/content/pm/PermissionInfo.java index 0e70a3e4e600..83baca668d55 100644 --- a/core/java/android/content/pm/PermissionInfo.java +++ b/core/java/android/content/pm/PermissionInfo.java @@ -411,14 +411,6 @@ public class PermissionInfo extends PackageItemInfo implements Parcelable { public static final int FLAG_IMMUTABLY_RESTRICTED = 1<<4; /** - * Flag for {@link #flags}, corresponding to <code>installerExemptIgnored</code> - * value of {@link android.R.attr#permissionFlags}. - * - * <p> Modifier for permission restriction. This permission cannot be exempted by the installer. - */ - public static final int FLAG_INSTALLER_EXEMPT_IGNORED = 1 << 5; - - /** * Flag for {@link #flags}, indicating that this permission has been * installed into the system's globally defined permissions. */ @@ -724,11 +716,6 @@ public class PermissionInfo extends PackageItemInfo implements Parcelable { } /** @hide */ - public boolean isInstallerExemptIgnored() { - return (flags & PermissionInfo.FLAG_INSTALLER_EXEMPT_IGNORED) != 0; - } - - /** @hide */ public boolean isAppOp() { return (protectionLevel & PermissionInfo.PROTECTION_FLAG_APPOP) != 0; } diff --git a/core/java/android/content/pm/ShortcutManager.java b/core/java/android/content/pm/ShortcutManager.java index 35c99a13a152..d3bac79aa2b9 100644 --- a/core/java/android/content/pm/ShortcutManager.java +++ b/core/java/android/content/pm/ShortcutManager.java @@ -39,6 +39,7 @@ import android.os.Parcel; import android.os.Parcelable; import android.os.RemoteException; import android.os.ServiceManager; +import android.os.UserHandle; import com.android.internal.annotations.VisibleForTesting; @@ -771,4 +772,20 @@ public class ShortcutManager { } } + /** + * Granting another app the access to the shortcuts you own. You must provide the package name + * and their SHA256 certificate digest in order to granting the access. + * + * Once granted, the other app can retain a copy of all the shortcuts you own when calling + * {@link LauncherApps#getShortcuts(LauncherApps.ShortcutQuery, UserHandle)}. + */ + public void updateShortcutVisibility(@NonNull final String packageName, + @Nullable final byte[] certificate, final boolean visible) { + try { + mService.updateShortcutVisibility(mContext.getPackageName(), packageName, certificate, + visible, injectMyUserId()); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } } diff --git a/core/java/android/content/pm/verify/domain/DomainOwner.aidl b/core/java/android/content/pm/verify/domain/DomainOwner.aidl new file mode 100644 index 000000000000..41366d1a29b2 --- /dev/null +++ b/core/java/android/content/pm/verify/domain/DomainOwner.aidl @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.content.pm.verify.domain; + +parcelable DomainOwner; diff --git a/core/java/android/content/pm/verify/domain/DomainOwner.java b/core/java/android/content/pm/verify/domain/DomainOwner.java new file mode 100644 index 000000000000..b050f5da7928 --- /dev/null +++ b/core/java/android/content/pm/verify/domain/DomainOwner.java @@ -0,0 +1,219 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.content.pm.verify.domain; + +import android.annotation.NonNull; +import android.annotation.SystemApi; +import android.os.Parcelable; + +import com.android.internal.util.DataClass; + +import java.util.Set; +import java.util.UUID; + +/** + * @hide + */ +@SystemApi +@DataClass(genParcelable = true, genEqualsHashCode = true, genAidl = true, genToString = true) +public final class DomainOwner implements Parcelable { + + /** + * Package name of that owns the domain. + */ + @NonNull + private final String mPackageName; + + /** + * Whether or not this owner can be automatically overridden. + * + * @see DomainVerificationManager#setDomainVerificationUserSelection(UUID, Set, boolean) + */ + private final boolean mOverrideable; + + + + // Code below generated by codegen v1.0.22. + // + // DO NOT MODIFY! + // CHECKSTYLE:OFF Generated code + // + // To regenerate run: + // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/content/pm/verify/domain/DomainOwner.java + // + // To exclude the generated code from IntelliJ auto-formatting enable (one-time): + // Settings > Editor > Code Style > Formatter Control + //@formatter:off + + + /** + * Creates a new DomainOwner. + * + * @param packageName + * Package name of that owns the domain. + * @param overrideable + * Whether or not this owner can be automatically overridden. If all owners for a domain are + * overrideable, then calling + * {@link DomainVerificationManager#setDomainVerificationUserSelection(UUID, + * Set, boolean)} to enable the domain will disable all other owners. On the other hand, if any + * of the owners are non-overrideable, then + * {@link DomainVerificationManager#setDomainVerificationLinkHandlingAllowed(String, + * boolean)} must be called with false to disable all of the other owners before this domain can + * be taken by a new owner through + * {@link DomainVerificationManager#setDomainVerificationUserSelection(UUID, + * Set, boolean)}. + */ + @DataClass.Generated.Member + public DomainOwner( + @NonNull String packageName, + boolean overrideable) { + this.mPackageName = packageName; + com.android.internal.util.AnnotationValidations.validate( + NonNull.class, null, mPackageName); + this.mOverrideable = overrideable; + + // onConstructed(); // You can define this method to get a callback + } + + /** + * Package name of that owns the domain. + */ + @DataClass.Generated.Member + public @NonNull String getPackageName() { + return mPackageName; + } + + /** + * Whether or not this owner can be automatically overridden. If all owners for a domain are + * overrideable, then calling + * {@link DomainVerificationManager#setDomainVerificationUserSelection(UUID, + * Set, boolean)} to enable the domain will disable all other owners. On the other hand, if any + * of the owners are non-overrideable, then + * {@link DomainVerificationManager#setDomainVerificationLinkHandlingAllowed(String, + * boolean)} must be called with false to disable all of the other owners before this domain can + * be taken by a new owner through + * {@link DomainVerificationManager#setDomainVerificationUserSelection(UUID, + * Set, boolean)}. + */ + @DataClass.Generated.Member + public boolean isOverrideable() { + return mOverrideable; + } + + @Override + @DataClass.Generated.Member + public String toString() { + // You can override field toString logic by defining methods like: + // String fieldNameToString() { ... } + + return "DomainOwner { " + + "packageName = " + mPackageName + ", " + + "overrideable = " + mOverrideable + + " }"; + } + + @Override + @DataClass.Generated.Member + public boolean equals(@android.annotation.Nullable Object o) { + // You can override field equality logic by defining either of the methods like: + // boolean fieldNameEquals(DomainOwner other) { ... } + // boolean fieldNameEquals(FieldType otherValue) { ... } + + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + @SuppressWarnings("unchecked") + DomainOwner that = (DomainOwner) o; + //noinspection PointlessBooleanExpression + return true + && java.util.Objects.equals(mPackageName, that.mPackageName) + && mOverrideable == that.mOverrideable; + } + + @Override + @DataClass.Generated.Member + public int hashCode() { + // You can override field hashCode logic by defining methods like: + // int fieldNameHashCode() { ... } + + int _hash = 1; + _hash = 31 * _hash + java.util.Objects.hashCode(mPackageName); + _hash = 31 * _hash + Boolean.hashCode(mOverrideable); + return _hash; + } + + @Override + @DataClass.Generated.Member + public void writeToParcel(@NonNull android.os.Parcel dest, int flags) { + // You can override field parcelling by defining methods like: + // void parcelFieldName(Parcel dest, int flags) { ... } + + byte flg = 0; + if (mOverrideable) flg |= 0x2; + dest.writeByte(flg); + dest.writeString(mPackageName); + } + + @Override + @DataClass.Generated.Member + public int describeContents() { return 0; } + + /** @hide */ + @SuppressWarnings({"unchecked", "RedundantCast"}) + @DataClass.Generated.Member + /* package-private */ DomainOwner(@NonNull android.os.Parcel in) { + // You can override field unparcelling by defining methods like: + // static FieldType unparcelFieldName(Parcel in) { ... } + + byte flg = in.readByte(); + boolean overrideable = (flg & 0x2) != 0; + String packageName = in.readString(); + + this.mPackageName = packageName; + com.android.internal.util.AnnotationValidations.validate( + NonNull.class, null, mPackageName); + this.mOverrideable = overrideable; + + // onConstructed(); // You can define this method to get a callback + } + + @DataClass.Generated.Member + public static final @NonNull Parcelable.Creator<DomainOwner> CREATOR + = new Parcelable.Creator<DomainOwner>() { + @Override + public DomainOwner[] newArray(int size) { + return new DomainOwner[size]; + } + + @Override + public DomainOwner createFromParcel(@NonNull android.os.Parcel in) { + return new DomainOwner(in); + } + }; + + @DataClass.Generated( + time = 1614119379978L, + codegenVersion = "1.0.22", + sourceFile = "frameworks/base/core/java/android/content/pm/verify/domain/DomainOwner.java", + inputSignatures = "private final @android.annotation.NonNull java.lang.String mPackageName\nprivate final boolean mOverrideable\nclass DomainOwner extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genParcelable=true, genEqualsHashCode=true, genAidl=true, genToString=true)") + @Deprecated + private void __metadata() {} + + + //@formatter:on + // End of generated code + +} diff --git a/core/java/android/content/pm/verify/domain/DomainSet.aidl b/core/java/android/content/pm/verify/domain/DomainSet.aidl new file mode 100644 index 000000000000..fab131dfa317 --- /dev/null +++ b/core/java/android/content/pm/verify/domain/DomainSet.aidl @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.content.pm.verify.domain; + +parcelable DomainSet; diff --git a/core/java/android/content/pm/verify/domain/DomainSet.java b/core/java/android/content/pm/verify/domain/DomainSet.java new file mode 100644 index 000000000000..243ff0820e24 --- /dev/null +++ b/core/java/android/content/pm/verify/domain/DomainSet.java @@ -0,0 +1,160 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.content.pm.verify.domain; + +import android.annotation.NonNull; +import android.os.Parcel; +import android.os.Parcelable; + +import com.android.internal.util.DataClass; + +import java.util.Set; + +/** + * Wraps an input set of domains from the client process, to be sent to the server. Handles cases + * where the data size is too large by writing data using {@link Parcel#writeBlob(byte[])}. + * + * @hide + */ +@DataClass(genParcelable = true, genAidl = true, genEqualsHashCode = true) +public class DomainSet implements Parcelable { + + @NonNull + private final Set<String> mDomains; + + private void parcelDomains(@NonNull Parcel dest, @SuppressWarnings("unused") int flags) { + DomainVerificationUtils.writeHostSet(dest, mDomains); + } + + private Set<String> unparcelDomains(@NonNull Parcel in) { + return DomainVerificationUtils.readHostSet(in); + } + + + + // Code below generated by codegen v1.0.22. + // + // DO NOT MODIFY! + // CHECKSTYLE:OFF Generated code + // + // To regenerate run: + // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/content/pm/verify/domain + // /DomainSet.java + // + // To exclude the generated code from IntelliJ auto-formatting enable (one-time): + // Settings > Editor > Code Style > Formatter Control + //@formatter:off + + + @DataClass.Generated.Member + public DomainSet( + @NonNull Set<String> domains) { + this.mDomains = domains; + com.android.internal.util.AnnotationValidations.validate( + NonNull.class, null, mDomains); + + // onConstructed(); // You can define this method to get a callback + } + + @DataClass.Generated.Member + public @NonNull Set<String> getDomains() { + return mDomains; + } + + @Override + @DataClass.Generated.Member + public boolean equals(@android.annotation.Nullable Object o) { + // You can override field equality logic by defining either of the methods like: + // boolean fieldNameEquals(DomainSet other) { ... } + // boolean fieldNameEquals(FieldType otherValue) { ... } + + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + @SuppressWarnings("unchecked") + DomainSet that = (DomainSet) o; + //noinspection PointlessBooleanExpression + return true + && java.util.Objects.equals(mDomains, that.mDomains); + } + + @Override + @DataClass.Generated.Member + public int hashCode() { + // You can override field hashCode logic by defining methods like: + // int fieldNameHashCode() { ... } + + int _hash = 1; + _hash = 31 * _hash + java.util.Objects.hashCode(mDomains); + return _hash; + } + + @Override + @DataClass.Generated.Member + public void writeToParcel(@NonNull Parcel dest, int flags) { + // You can override field parcelling by defining methods like: + // void parcelFieldName(Parcel dest, int flags) { ... } + + parcelDomains(dest, flags); + } + + @Override + @DataClass.Generated.Member + public int describeContents() { return 0; } + + /** @hide */ + @SuppressWarnings({"unchecked", "RedundantCast"}) + @DataClass.Generated.Member + protected DomainSet(@NonNull Parcel in) { + // You can override field unparcelling by defining methods like: + // static FieldType unparcelFieldName(Parcel in) { ... } + + Set<String> domains = unparcelDomains(in); + + this.mDomains = domains; + com.android.internal.util.AnnotationValidations.validate( + NonNull.class, null, mDomains); + + // onConstructed(); // You can define this method to get a callback + } + + @DataClass.Generated.Member + public static final @NonNull Parcelable.Creator<DomainSet> CREATOR + = new Parcelable.Creator<DomainSet>() { + @Override + public DomainSet[] newArray(int size) { + return new DomainSet[size]; + } + + @Override + public DomainSet createFromParcel(@NonNull Parcel in) { + return new DomainSet(in); + } + }; + + @DataClass.Generated( + time = 1613169242020L, + codegenVersion = "1.0.22", + sourceFile = "frameworks/base/core/java/android/content/pm/verify/domain/DomainSet.java", + inputSignatures = "private final @android.annotation.NonNull java.util.Set<java.lang.String> mDomains\nprivate void parcelDomains(android.os.Parcel,int)\nprivate java.util.Set<java.lang.String> unparcelDomains(android.os.Parcel)\nclass DomainSet extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genParcelable=true, genAidl=true, genEqualsHashCode=true)") + @Deprecated + private void __metadata() {} + + + //@formatter:on + // End of generated code + +} diff --git a/core/java/android/content/pm/verify/domain/DomainVerificationInfo.java b/core/java/android/content/pm/verify/domain/DomainVerificationInfo.java index 7afbe1fcb69f..809587524f58 100644 --- a/core/java/android/content/pm/verify/domain/DomainVerificationInfo.java +++ b/core/java/android/content/pm/verify/domain/DomainVerificationInfo.java @@ -19,7 +19,9 @@ package android.content.pm.verify.domain; import android.annotation.NonNull; import android.annotation.SystemApi; import android.content.pm.PackageManager; +import android.os.Parcel; import android.os.Parcelable; +import android.util.ArrayMap; import com.android.internal.util.DataClass; import com.android.internal.util.Parcelling; @@ -34,12 +36,12 @@ import java.util.UUID; * against the digital asset links response from the server hosting that domain. * <p> * These values for each domain can be modified through - * {@link DomainVerificationManager#setDomainVerificationStatus(UUID, Set, int)}. + * {@link DomainVerificationManager#setDomainVerificationStatus(UUID, + * Set, int)}. * * @hide */ @SystemApi -@SuppressWarnings("DefaultAnnotationParam") @DataClass(genAidl = true, genHiddenConstructor = true, genParcelable = true, genToString = true, genEqualsHashCode = true) public final class DomainVerificationInfo implements Parcelable { @@ -71,22 +73,30 @@ public final class DomainVerificationInfo implements Parcelable { private final String mPackageName; /** - * Map of host names to their current state. State is an integer, which defaults to - * {@link DomainVerificationManager#STATE_NO_RESPONSE}. State can be modified by the - * domain verification agent (the intended consumer of this API), which can be equal - * to {@link DomainVerificationManager#STATE_SUCCESS} when verified, or equal to or - * greater than {@link DomainVerificationManager#STATE_FIRST_VERIFIER_DEFINED} for - * any unsuccessful response. + * Map of host names to their current state. State is an integer, which defaults to {@link + * DomainVerificationManager#STATE_NO_RESPONSE}. State can be modified by the domain + * verification agent (the intended consumer of this API), which can be equal to {@link + * DomainVerificationManager#STATE_SUCCESS} when verified, or equal to or greater than {@link + * DomainVerificationManager#STATE_FIRST_VERIFIER_DEFINED} for any unsuccessful response. * <p> - * Any value non-inclusive between those 2 values are reserved for use by the system. - * The domain verification agent may be able to act on these reserved values, and this - * ability can be queried using {@link DomainVerificationManager#isStateModifiable(int)}. - * It is expected that the agent attempt to verify all domains that it can modify the - * state of, even if it does not understand the meaning of those values. + * Any value non-inclusive between those 2 values are reserved for use by the system. The domain + * verification agent may be able to act on these reserved values, and this ability can be + * queried using {@link DomainVerificationManager#isStateModifiable(int)}. It is expected that + * the agent attempt to verify all domains that it can modify the state of, even if it does not + * understand the meaning of those values. */ @NonNull private final Map<String, Integer> mHostToStateMap; + private void parcelHostToStateMap(Parcel dest, @SuppressWarnings("unused") int flags) { + DomainVerificationUtils.writeHostMap(dest, mHostToStateMap); + } + + private Map<String, Integer> unparcelHostToStateMap(Parcel in) { + return DomainVerificationUtils.readHostMap(in, new ArrayMap<>(), + DomainVerificationUserSelection.class.getClassLoader()); + } + // Code below generated by codegen v1.0.22. @@ -95,7 +105,8 @@ public final class DomainVerificationInfo implements Parcelable { // CHECKSTYLE:OFF Generated code // // To regenerate run: - // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/content/pm/verify/domain/DomainVerificationInfo.java + // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/content/pm/verify/domain + // /DomainVerificationInfo.java // // To exclude the generated code from IntelliJ auto-formatting enable (one-time): // Settings > Editor > Code Style > Formatter Control @@ -123,18 +134,17 @@ public final class DomainVerificationInfo implements Parcelable { * @param packageName * The package name that this data corresponds to. * @param hostToStateMap - * Map of host names to their current state. State is an integer, which defaults to - * {@link DomainVerificationManager#STATE_NO_RESPONSE}. State can be modified by the - * domain verification agent (the intended consumer of this API), which can be equal - * to {@link DomainVerificationManager#STATE_SUCCESS} when verified, or equal to or - * greater than {@link DomainVerificationManager#STATE_FIRST_VERIFIER_DEFINED} for - * any unsuccessful response. + * Map of host names to their current state. State is an integer, which defaults to {@link + * DomainVerificationManager#STATE_NO_RESPONSE}. State can be modified by the domain + * verification agent (the intended consumer of this API), which can be equal to {@link + * DomainVerificationManager#STATE_SUCCESS} when verified, or equal to or greater than {@link + * DomainVerificationManager#STATE_FIRST_VERIFIER_DEFINED} for any unsuccessful response. * <p> - * Any value non-inclusive between those 2 values are reserved for use by the system. - * The domain verification agent may be able to act on these reserved values, and this - * ability can be queried using {@link DomainVerificationManager#isStateModifiable(int)}. - * It is expected that the agent attempt to verify all domains that it can modify the - * state of, even if it does not understand the meaning of those values. + * Any value non-inclusive between those 2 values are reserved for use by the system. The domain + * verification agent may be able to act on these reserved values, and this ability can be + * queried using {@link DomainVerificationManager#isStateModifiable(int)}. It is expected that + * the agent attempt to verify all domains that it can modify the state of, even if it does not + * understand the meaning of those values. * @hide */ @DataClass.Generated.Member @@ -185,18 +195,17 @@ public final class DomainVerificationInfo implements Parcelable { } /** - * Map of host names to their current state. State is an integer, which defaults to - * {@link DomainVerificationManager#STATE_NO_RESPONSE}. State can be modified by the - * domain verification agent (the intended consumer of this API), which can be equal - * to {@link DomainVerificationManager#STATE_SUCCESS} when verified, or equal to or - * greater than {@link DomainVerificationManager#STATE_FIRST_VERIFIER_DEFINED} for - * any unsuccessful response. + * Map of host names to their current state. State is an integer, which defaults to {@link + * DomainVerificationManager#STATE_NO_RESPONSE}. State can be modified by the domain + * verification agent (the intended consumer of this API), which can be equal to {@link + * DomainVerificationManager#STATE_SUCCESS} when verified, or equal to or greater than {@link + * DomainVerificationManager#STATE_FIRST_VERIFIER_DEFINED} for any unsuccessful response. * <p> - * Any value non-inclusive between those 2 values are reserved for use by the system. - * The domain verification agent may be able to act on these reserved values, and this - * ability can be queried using {@link DomainVerificationManager#isStateModifiable(int)}. - * It is expected that the agent attempt to verify all domains that it can modify the - * state of, even if it does not understand the meaning of those values. + * Any value non-inclusive between those 2 values are reserved for use by the system. The domain + * verification agent may be able to act on these reserved values, and this ability can be + * queried using {@link DomainVerificationManager#isStateModifiable(int)}. It is expected that + * the agent attempt to verify all domains that it can modify the state of, even if it does not + * understand the meaning of those values. */ @DataClass.Generated.Member public @NonNull Map<String,Integer> getHostToStateMap() { @@ -260,13 +269,13 @@ public final class DomainVerificationInfo implements Parcelable { @Override @DataClass.Generated.Member - public void writeToParcel(@NonNull android.os.Parcel dest, int flags) { + public void writeToParcel(@NonNull Parcel dest, int flags) { // You can override field parcelling by defining methods like: // void parcelFieldName(Parcel dest, int flags) { ... } sParcellingForIdentifier.parcel(mIdentifier, dest, flags); dest.writeString(mPackageName); - dest.writeMap(mHostToStateMap); + parcelHostToStateMap(dest, flags); } @Override @@ -276,14 +285,13 @@ public final class DomainVerificationInfo implements Parcelable { /** @hide */ @SuppressWarnings({"unchecked", "RedundantCast"}) @DataClass.Generated.Member - /* package-private */ DomainVerificationInfo(@NonNull android.os.Parcel in) { + /* package-private */ DomainVerificationInfo(@NonNull Parcel in) { // You can override field unparcelling by defining methods like: // static FieldType unparcelFieldName(Parcel in) { ... } UUID identifier = sParcellingForIdentifier.unparcel(in); String packageName = in.readString(); - Map<String,Integer> hostToStateMap = new java.util.LinkedHashMap<>(); - in.readMap(hostToStateMap, Integer.class.getClassLoader()); + Map<String,Integer> hostToStateMap = unparcelHostToStateMap(in); this.mIdentifier = identifier; com.android.internal.util.AnnotationValidations.validate( @@ -307,16 +315,16 @@ public final class DomainVerificationInfo implements Parcelable { } @Override - public DomainVerificationInfo createFromParcel(@NonNull android.os.Parcel in) { + public DomainVerificationInfo createFromParcel(@NonNull Parcel in) { return new DomainVerificationInfo(in); } }; @DataClass.Generated( - time = 1611862790369L, + time = 1613002530369L, codegenVersion = "1.0.22", sourceFile = "frameworks/base/core/java/android/content/pm/verify/domain/DomainVerificationInfo.java", - inputSignatures = "private final @android.annotation.NonNull @com.android.internal.util.DataClass.ParcelWith(com.android.internal.util.Parcelling.BuiltIn.ForUUID.class) java.util.UUID mIdentifier\nprivate final @android.annotation.NonNull java.lang.String mPackageName\nprivate final @android.annotation.NonNull java.util.Map<java.lang.String,java.lang.Integer> mHostToStateMap\nclass DomainVerificationInfo extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genAidl=true, genHiddenConstructor=true, genParcelable=true, genToString=true, genEqualsHashCode=true)") + inputSignatures = "private final @android.annotation.NonNull @com.android.internal.util.DataClass.ParcelWith(com.android.internal.util.Parcelling.BuiltIn.ForUUID.class) java.util.UUID mIdentifier\nprivate final @android.annotation.NonNull java.lang.String mPackageName\nprivate final @android.annotation.NonNull java.util.Map<java.lang.String,java.lang.Integer> mHostToStateMap\nprivate void parcelHostToStateMap(android.os.Parcel,int)\nprivate java.util.Map<java.lang.String,java.lang.Integer> unparcelHostToStateMap(android.os.Parcel)\nclass DomainVerificationInfo extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genAidl=true, genHiddenConstructor=true, genParcelable=true, genToString=true, genEqualsHashCode=true)") @Deprecated private void __metadata() {} diff --git a/core/java/android/content/pm/verify/domain/DomainVerificationManager.java b/core/java/android/content/pm/verify/domain/DomainVerificationManager.java index cbb3baaa6700..11402afac8b6 100644 --- a/core/java/android/content/pm/verify/domain/DomainVerificationManager.java +++ b/core/java/android/content/pm/verify/domain/DomainVerificationManager.java @@ -239,7 +239,15 @@ public interface DomainVerificationManager { * {@link Context#createPackageContextAsUser(String, int, UserHandle)} should be used. * * Enabling an unverified domain will allow an application to open it, but this can only occur - * if no other app on the device is approved for the domain. + * if no other app on the device is approved for a higher approval level. This can queried + * using {@link #getOwnersForDomain(String)}. + * + * If all owners for a domain are {@link DomainOwner#isOverrideable()}, then calling this to + * enable that domain will disable all other owners. + * + * On the other hand, if any of the owners are non-overrideable, then this must be called with + * false for all of the other owners to disable them before the domain can be taken by a new + * owner. * * @param domainSetId See {@link DomainVerificationInfo#getIdentifier()}. * @param domains The domains to toggle the state of. @@ -276,6 +284,19 @@ public interface DomainVerificationManager { throws NameNotFoundException; /** + * For the given domain, return all apps which are approved to open it in a + * greater than 0 priority. This does not mean that all apps can actually open + * an Intent with that domain. That will be decided by the set of apps which + * are the highest priority level, ignoring all lower priority levels. + * + * By default the list will be returned ordered from lowest to highest + * priority. + */ + @NonNull + @RequiresPermission(android.Manifest.permission.UPDATE_DOMAIN_VERIFICATION_USER_SELECTION) + List<DomainOwner> getOwnersForDomain(@NonNull String domain); + + /** * Thrown if a {@link DomainVerificationInfo#getIdentifier()}} or an associated set of domains * provided by the caller is no longer valid. This may be recoverable, and the caller should * re-query the package name associated with the ID using diff --git a/core/java/android/content/pm/verify/domain/DomainVerificationManagerImpl.java b/core/java/android/content/pm/verify/domain/DomainVerificationManagerImpl.java index 5938def5c83c..8b9865c2b436 100644 --- a/core/java/android/content/pm/verify/domain/DomainVerificationManagerImpl.java +++ b/core/java/android/content/pm/verify/domain/DomainVerificationManagerImpl.java @@ -21,11 +21,9 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; import android.content.pm.PackageManager.NameNotFoundException; -import android.content.pm.verify.domain.IDomainVerificationManager; import android.os.RemoteException; import android.os.ServiceSpecificException; -import java.util.ArrayList; import java.util.List; import java.util.Set; import java.util.UUID; @@ -89,7 +87,7 @@ public class DomainVerificationManagerImpl implements DomainVerificationManager int state) throws IllegalArgumentException, NameNotFoundException { try { mDomainVerificationManager.setDomainVerificationStatus(domainSetId.toString(), - new ArrayList<>(domains), state); + new DomainSet(domains), state); } catch (Exception e) { Exception converted = rethrow(e, domainSetId); if (converted instanceof NameNotFoundException) { @@ -126,7 +124,7 @@ public class DomainVerificationManagerImpl implements DomainVerificationManager throws IllegalArgumentException, NameNotFoundException { try { mDomainVerificationManager.setDomainVerificationUserSelection(domainSetId.toString(), - new ArrayList<>(domains), enabled, mContext.getUserId()); + new DomainSet(domains), enabled, mContext.getUserId()); } catch (Exception e) { Exception converted = rethrow(e, domainSetId); if (converted instanceof NameNotFoundException) { @@ -158,6 +156,16 @@ public class DomainVerificationManagerImpl implements DomainVerificationManager } } + @NonNull + @Override + public List<DomainOwner> getOwnersForDomain(@NonNull String domain) { + try { + return mDomainVerificationManager.getOwnersForDomain(domain, mContext.getUserId()); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + private Exception rethrow(Exception exception, @Nullable UUID domainSetId) { return rethrow(exception, domainSetId, null); } diff --git a/core/java/android/content/pm/verify/domain/DomainVerificationRequest.java b/core/java/android/content/pm/verify/domain/DomainVerificationRequest.java index 473abce26d81..65f6d7c18135 100644 --- a/core/java/android/content/pm/verify/domain/DomainVerificationRequest.java +++ b/core/java/android/content/pm/verify/domain/DomainVerificationRequest.java @@ -19,6 +19,7 @@ package android.content.pm.verify.domain; import android.annotation.NonNull; import android.annotation.SystemApi; import android.content.Intent; +import android.os.Parcel; import android.os.Parcelable; import com.android.internal.util.DataClass; @@ -27,11 +28,11 @@ import com.android.internal.util.Parcelling; import java.util.Set; /** - * Request object sent in the {@link Intent} that's broadcast to the domain verification - * agent, retrieved through {@link DomainVerificationManager#EXTRA_VERIFICATION_REQUEST}. + * Request object sent in the {@link Intent} that's broadcast to the domain verification agent, + * retrieved through {@link DomainVerificationManager#EXTRA_VERIFICATION_REQUEST}. * <p> - * This contains the set of packages which have been invalidated and will require - * re-verification. The exact domains can be retrieved with + * This contains the set of packages which have been invalidated and will require re-verification. + * The exact domains can be retrieved with * {@link DomainVerificationManager#getDomainVerificationInfo(String)} * * @hide @@ -42,14 +43,22 @@ import java.util.Set; public final class DomainVerificationRequest implements Parcelable { /** - * The package names of the apps that need to be verified. The receiver should call - * {@link DomainVerificationManager#getDomainVerificationInfo(String)} with each of - * these values to get the actual set of domains that need to be acted on. + * The package names of the apps that need to be verified. The receiver should call {@link + * DomainVerificationManager#getDomainVerificationInfo(String)} with each of these values to get + * the actual set of domains that need to be acted on. */ @NonNull @DataClass.ParcelWith(Parcelling.BuiltIn.ForStringSet.class) private final Set<String> mPackageNames; + private void parcelPackageNames(@NonNull Parcel dest, @SuppressWarnings("unused") int flags) { + DomainVerificationUtils.writeHostSet(dest, mPackageNames); + } + + private Set<String> unparcelPackageNames(@NonNull Parcel in) { + return DomainVerificationUtils.readHostSet(in); + } + // Code below generated by codegen v1.0.22. @@ -58,7 +67,8 @@ public final class DomainVerificationRequest implements Parcelable { // CHECKSTYLE:OFF Generated code // // To regenerate run: - // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/content/pm/verify/domain/DomainVerificationRequest.java + // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/content/pm/verify/domain + // /DomainVerificationRequest.java // // To exclude the generated code from IntelliJ auto-formatting enable (one-time): // Settings > Editor > Code Style > Formatter Control @@ -69,9 +79,9 @@ public final class DomainVerificationRequest implements Parcelable { * Creates a new DomainVerificationRequest. * * @param packageNames - * The package names of the apps that need to be verified. The receiver should call - * {@link DomainVerificationManager#getDomainVerificationInfo(String)} with each of - * these values to get the actual set of domains that need to be acted on. + * The package names of the apps that need to be verified. The receiver should call {@link + * DomainVerificationManager#getDomainVerificationInfo(String)} with each of these values to get + * the actual set of domains that need to be acted on. * @hide */ @DataClass.Generated.Member @@ -85,9 +95,9 @@ public final class DomainVerificationRequest implements Parcelable { } /** - * The package names of the apps that need to be verified. The receiver should call - * {@link DomainVerificationManager#getDomainVerificationInfo(String)} with each of - * these values to get the actual set of domains that need to be acted on. + * The package names of the apps that need to be verified. The receiver should call {@link + * DomainVerificationManager#getDomainVerificationInfo(String)} with each of these values to get + * the actual set of domains that need to be acted on. */ @DataClass.Generated.Member public @NonNull Set<String> getPackageNames() { @@ -134,11 +144,11 @@ public final class DomainVerificationRequest implements Parcelable { @Override @DataClass.Generated.Member - public void writeToParcel(@NonNull android.os.Parcel dest, int flags) { + public void writeToParcel(@NonNull Parcel dest, int flags) { // You can override field parcelling by defining methods like: // void parcelFieldName(Parcel dest, int flags) { ... } - sParcellingForPackageNames.parcel(mPackageNames, dest, flags); + parcelPackageNames(dest, flags); } @Override @@ -148,11 +158,11 @@ public final class DomainVerificationRequest implements Parcelable { /** @hide */ @SuppressWarnings({"unchecked", "RedundantCast"}) @DataClass.Generated.Member - /* package-private */ DomainVerificationRequest(@NonNull android.os.Parcel in) { + /* package-private */ DomainVerificationRequest(@NonNull Parcel in) { // You can override field unparcelling by defining methods like: // static FieldType unparcelFieldName(Parcel in) { ... } - Set<String> packageNames = sParcellingForPackageNames.unparcel(in); + Set<String> packageNames = unparcelPackageNames(in); this.mPackageNames = packageNames; com.android.internal.util.AnnotationValidations.validate( @@ -170,16 +180,16 @@ public final class DomainVerificationRequest implements Parcelable { } @Override - public DomainVerificationRequest createFromParcel(@NonNull android.os.Parcel in) { + public DomainVerificationRequest createFromParcel(@NonNull Parcel in) { return new DomainVerificationRequest(in); } }; @DataClass.Generated( - time = 1611862814990L, + time = 1613169505495L, codegenVersion = "1.0.22", sourceFile = "frameworks/base/core/java/android/content/pm/verify/domain/DomainVerificationRequest.java", - inputSignatures = "private final @android.annotation.NonNull @com.android.internal.util.DataClass.ParcelWith(com.android.internal.util.Parcelling.BuiltIn.ForStringSet.class) java.util.Set<java.lang.String> mPackageNames\nclass DomainVerificationRequest extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genHiddenConstructor=true, genAidl=false, genEqualsHashCode=true)") + inputSignatures = "private final @android.annotation.NonNull @com.android.internal.util.DataClass.ParcelWith(com.android.internal.util.Parcelling.BuiltIn.ForStringSet.class) java.util.Set<java.lang.String> mPackageNames\nprivate void parcelPackageNames(android.os.Parcel,int)\nprivate java.util.Set<java.lang.String> unparcelPackageNames(android.os.Parcel)\nclass DomainVerificationRequest extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genHiddenConstructor=true, genAidl=false, genEqualsHashCode=true)") @Deprecated private void __metadata() {} diff --git a/core/java/android/content/pm/verify/domain/DomainVerificationUserSelection.java b/core/java/android/content/pm/verify/domain/DomainVerificationUserSelection.java index 73346ef0273b..d23f5f133841 100644 --- a/core/java/android/content/pm/verify/domain/DomainVerificationUserSelection.java +++ b/core/java/android/content/pm/verify/domain/DomainVerificationUserSelection.java @@ -20,8 +20,10 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; import android.content.Context; +import android.os.Parcel; import android.os.Parcelable; import android.os.UserHandle; +import android.util.ArrayMap; import com.android.internal.util.DataClass; import com.android.internal.util.Parcelling; @@ -40,29 +42,46 @@ import java.util.UUID; * toggle affects <b>all</b> links and is not based on the verification state of the domains. * <p> * Assuming the toggle is enabled, the user can also select additional unverified domains to grant - * to the application to open, which is reflected in {@link #getHostToUserSelectionMap()}. But only - * a single application can be approved for a domain unless the applications are both approved. If - * another application is approved, the user will not be allowed to enable the domain. + * to the application to open, which is reflected in {@link #getHostToStateMap()}. But only a single + * application can be approved for a domain unless the applications are both approved. If another + * application is approved, the user will not be allowed to enable the domain. * <p> * These values can be changed through the * {@link DomainVerificationManager#setDomainVerificationLinkHandlingAllowed(String, - * boolean)} and - * {@link DomainVerificationManager#setDomainVerificationUserSelection(UUID, Set, + * boolean)} and {@link DomainVerificationManager#setDomainVerificationUserSelection(UUID, Set, * boolean)} APIs. * <p> - * Note that because state is per user, if a different user needs to be changed, one will - * need to use {@link Context#createContextAsUser(UserHandle, int)} and hold the - * {@link android.Manifest.permission#INTERACT_ACROSS_USERS} permission. + * Note that because state is per user, if a different user needs to be changed, one will need to + * use {@link Context#createContextAsUser(UserHandle, int)} and hold the {@link + * android.Manifest.permission#INTERACT_ACROSS_USERS} permission. * * @hide */ @SystemApi @SuppressWarnings("DefaultAnnotationParam") @DataClass(genAidl = true, genHiddenConstructor = true, genParcelable = true, genToString = true, - genEqualsHashCode = true) + genEqualsHashCode = true, genHiddenConstDefs = true) public final class DomainVerificationUserSelection implements Parcelable { /** + * The domain is unverified and unselected, and the application is unable to open web links + * that resolve to the domain. + */ + public static final int DOMAIN_STATE_NONE = 0; + + /** + * The domain has been selected through the + * {@link DomainVerificationManager#setDomainVerificationUserSelection(UUID, Set, boolean)} + * API, under the assumption it has not been reset by the system. + */ + public static final int DOMAIN_STATE_SELECTED = 1; + + /** + * The domain has been previously verified by the domain verification agent. + */ + public static final int DOMAIN_STATE_VERIFIED = 2; + + /** * @see DomainVerificationInfo#getIdentifier */ @NonNull @@ -88,15 +107,20 @@ public final class DomainVerificationUserSelection implements Parcelable { private final boolean mLinkHandlingAllowed; /** - * Retrieve the existing user selection state for the matching - * {@link #getPackageName()}, as was previously set by - * {@link DomainVerificationManager#setDomainVerificationUserSelection(UUID, Set, - * boolean)}. - * - * @return Map of hosts to enabled state for the given package and user. + * Mapping of domain host to state, as defined by {@link DomainState}. */ @NonNull - private final Map<String, Boolean> mHostToUserSelectionMap; + private final Map<String, Integer> mHostToStateMap; + + private void parcelHostToStateMap(Parcel dest, @SuppressWarnings("unused") int flags) { + DomainVerificationUtils.writeHostMap(dest, mHostToStateMap); + } + + @NonNull + private Map<String, Integer> unparcelHostToStateMap(Parcel in) { + return DomainVerificationUtils.readHostMap(in, new ArrayMap<>(), + DomainVerificationUserSelection.class.getClassLoader()); + } @@ -106,14 +130,37 @@ public final class DomainVerificationUserSelection implements Parcelable { // CHECKSTYLE:OFF Generated code // // To regenerate run: - // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/content/pm/verify/domain - // /DomainVerificationUserSelection.java + // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/content/pm/verify/domain/DomainVerificationUserSelection.java // // To exclude the generated code from IntelliJ auto-formatting enable (one-time): // Settings > Editor > Code Style > Formatter Control //@formatter:off + /** @hide */ + @android.annotation.IntDef(prefix = "DOMAIN_STATE_", value = { + DOMAIN_STATE_NONE, + DOMAIN_STATE_SELECTED, + DOMAIN_STATE_VERIFIED + }) + @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) + @DataClass.Generated.Member + public @interface DomainState {} + + /** @hide */ + @DataClass.Generated.Member + public static String domainStateToString(@DomainState int value) { + switch (value) { + case DOMAIN_STATE_NONE: + return "DOMAIN_STATE_NONE"; + case DOMAIN_STATE_SELECTED: + return "DOMAIN_STATE_SELECTED"; + case DOMAIN_STATE_VERIFIED: + return "DOMAIN_STATE_VERIFIED"; + default: return Integer.toHexString(value); + } + } + /** * Creates a new DomainVerificationUserSelection. * @@ -123,11 +170,8 @@ public final class DomainVerificationUserSelection implements Parcelable { * The user that this data corresponds to. * @param linkHandlingAllowed * Whether or not this package is allowed to open links. - * @param hostToUserSelectionMap - * Retrieve the existing user selection state for the matching - * {@link #getPackageName()}, as was previously set by - * {@link DomainVerificationManager#setDomainVerificationUserSelection(UUID, Set, - * boolean)}. + * @param hostToStateMap + * Mapping of domain host to state, as defined by {@link DomainState}. * @hide */ @DataClass.Generated.Member @@ -136,7 +180,7 @@ public final class DomainVerificationUserSelection implements Parcelable { @NonNull String packageName, @NonNull UserHandle user, @NonNull boolean linkHandlingAllowed, - @NonNull Map<String,Boolean> hostToUserSelectionMap) { + @NonNull Map<String,Integer> hostToStateMap) { this.mIdentifier = identifier; com.android.internal.util.AnnotationValidations.validate( NonNull.class, null, mIdentifier); @@ -149,9 +193,9 @@ public final class DomainVerificationUserSelection implements Parcelable { this.mLinkHandlingAllowed = linkHandlingAllowed; com.android.internal.util.AnnotationValidations.validate( NonNull.class, null, mLinkHandlingAllowed); - this.mHostToUserSelectionMap = hostToUserSelectionMap; + this.mHostToStateMap = hostToStateMap; com.android.internal.util.AnnotationValidations.validate( - NonNull.class, null, mHostToUserSelectionMap); + NonNull.class, null, mHostToStateMap); // onConstructed(); // You can define this method to get a callback } @@ -189,16 +233,11 @@ public final class DomainVerificationUserSelection implements Parcelable { } /** - * Retrieve the existing user selection state for the matching - * {@link #getPackageName()}, as was previously set by - * {@link DomainVerificationManager#setDomainVerificationUserSelection(UUID, Set, - * boolean)}. - * - * @return Map of hosts to enabled state for the given package and user. + * Mapping of domain host to state, as defined by {@link DomainState}. */ @DataClass.Generated.Member - public @NonNull Map<String,Boolean> getHostToUserSelectionMap() { - return mHostToUserSelectionMap; + public @NonNull Map<String,Integer> getHostToStateMap() { + return mHostToStateMap; } @Override @@ -212,7 +251,7 @@ public final class DomainVerificationUserSelection implements Parcelable { "packageName = " + mPackageName + ", " + "user = " + mUser + ", " + "linkHandlingAllowed = " + mLinkHandlingAllowed + ", " + - "hostToUserSelectionMap = " + mHostToUserSelectionMap + + "hostToStateMap = " + mHostToStateMap + " }"; } @@ -233,7 +272,7 @@ public final class DomainVerificationUserSelection implements Parcelable { && java.util.Objects.equals(mPackageName, that.mPackageName) && java.util.Objects.equals(mUser, that.mUser) && mLinkHandlingAllowed == that.mLinkHandlingAllowed - && java.util.Objects.equals(mHostToUserSelectionMap, that.mHostToUserSelectionMap); + && java.util.Objects.equals(mHostToStateMap, that.mHostToStateMap); } @Override @@ -247,7 +286,7 @@ public final class DomainVerificationUserSelection implements Parcelable { _hash = 31 * _hash + java.util.Objects.hashCode(mPackageName); _hash = 31 * _hash + java.util.Objects.hashCode(mUser); _hash = 31 * _hash + Boolean.hashCode(mLinkHandlingAllowed); - _hash = 31 * _hash + java.util.Objects.hashCode(mHostToUserSelectionMap); + _hash = 31 * _hash + java.util.Objects.hashCode(mHostToStateMap); return _hash; } @@ -264,7 +303,7 @@ public final class DomainVerificationUserSelection implements Parcelable { @Override @DataClass.Generated.Member - public void writeToParcel(@NonNull android.os.Parcel dest, int flags) { + public void writeToParcel(@NonNull Parcel dest, int flags) { // You can override field parcelling by defining methods like: // void parcelFieldName(Parcel dest, int flags) { ... } @@ -274,7 +313,7 @@ public final class DomainVerificationUserSelection implements Parcelable { sParcellingForIdentifier.parcel(mIdentifier, dest, flags); dest.writeString(mPackageName); dest.writeTypedObject(mUser, flags); - dest.writeMap(mHostToUserSelectionMap); + parcelHostToStateMap(dest, flags); } @Override @@ -284,7 +323,7 @@ public final class DomainVerificationUserSelection implements Parcelable { /** @hide */ @SuppressWarnings({"unchecked", "RedundantCast"}) @DataClass.Generated.Member - /* package-private */ DomainVerificationUserSelection(@NonNull android.os.Parcel in) { + /* package-private */ DomainVerificationUserSelection(@NonNull Parcel in) { // You can override field unparcelling by defining methods like: // static FieldType unparcelFieldName(Parcel in) { ... } @@ -293,8 +332,7 @@ public final class DomainVerificationUserSelection implements Parcelable { UUID identifier = sParcellingForIdentifier.unparcel(in); String packageName = in.readString(); UserHandle user = (UserHandle) in.readTypedObject(UserHandle.CREATOR); - Map<String,Boolean> hostToUserSelectionMap = new java.util.LinkedHashMap<>(); - in.readMap(hostToUserSelectionMap, Boolean.class.getClassLoader()); + Map<String,Integer> hostToStateMap = unparcelHostToStateMap(in); this.mIdentifier = identifier; com.android.internal.util.AnnotationValidations.validate( @@ -308,9 +346,9 @@ public final class DomainVerificationUserSelection implements Parcelable { this.mLinkHandlingAllowed = linkHandlingAllowed; com.android.internal.util.AnnotationValidations.validate( NonNull.class, null, mLinkHandlingAllowed); - this.mHostToUserSelectionMap = hostToUserSelectionMap; + this.mHostToStateMap = hostToStateMap; com.android.internal.util.AnnotationValidations.validate( - NonNull.class, null, mHostToUserSelectionMap); + NonNull.class, null, mHostToStateMap); // onConstructed(); // You can define this method to get a callback } @@ -324,16 +362,16 @@ public final class DomainVerificationUserSelection implements Parcelable { } @Override - public DomainVerificationUserSelection createFromParcel(@NonNull android.os.Parcel in) { + public DomainVerificationUserSelection createFromParcel(@NonNull Parcel in) { return new DomainVerificationUserSelection(in); } }; @DataClass.Generated( - time = 1612829797220L, + time = 1613683603297L, codegenVersion = "1.0.22", sourceFile = "frameworks/base/core/java/android/content/pm/verify/domain/DomainVerificationUserSelection.java", - inputSignatures = "private final @android.annotation.NonNull @com.android.internal.util.DataClass.ParcelWith(com.android.internal.util.Parcelling.BuiltIn.ForUUID.class) java.util.UUID mIdentifier\nprivate final @android.annotation.NonNull java.lang.String mPackageName\nprivate final @android.annotation.NonNull android.os.UserHandle mUser\nprivate final @android.annotation.NonNull boolean mLinkHandlingAllowed\nprivate final @android.annotation.NonNull java.util.Map<java.lang.String,java.lang.Boolean> mHostToUserSelectionMap\nclass DomainVerificationUserSelection extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genAidl=true, genHiddenConstructor=true, genParcelable=true, genToString=true, genEqualsHashCode=true)") + inputSignatures = "public static final int DOMAIN_STATE_NONE\npublic static final int DOMAIN_STATE_SELECTED\npublic static final int DOMAIN_STATE_VERIFIED\nprivate final @android.annotation.NonNull @com.android.internal.util.DataClass.ParcelWith(com.android.internal.util.Parcelling.BuiltIn.ForUUID.class) java.util.UUID mIdentifier\nprivate final @android.annotation.NonNull java.lang.String mPackageName\nprivate final @android.annotation.NonNull android.os.UserHandle mUser\nprivate final @android.annotation.NonNull boolean mLinkHandlingAllowed\nprivate final @android.annotation.NonNull java.util.Map<java.lang.String,java.lang.Integer> mHostToStateMap\nprivate void parcelHostToStateMap(android.os.Parcel,int)\nprivate @android.annotation.NonNull java.util.Map<java.lang.String,java.lang.Integer> unparcelHostToStateMap(android.os.Parcel)\nclass DomainVerificationUserSelection extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genAidl=true, genHiddenConstructor=true, genParcelable=true, genToString=true, genEqualsHashCode=true, genHiddenConstDefs=true)") @Deprecated private void __metadata() {} diff --git a/core/java/android/content/pm/verify/domain/DomainVerificationUtils.java b/core/java/android/content/pm/verify/domain/DomainVerificationUtils.java new file mode 100644 index 000000000000..93005fae1772 --- /dev/null +++ b/core/java/android/content/pm/verify/domain/DomainVerificationUtils.java @@ -0,0 +1,181 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.content.pm.verify.domain; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.os.IBinder; +import android.os.Parcel; +import android.util.ArraySet; + +import java.util.Collections; +import java.util.Map; +import java.util.Set; + +/** + * @hide + */ +public class DomainVerificationUtils { + + private static final int STRINGS_TARGET_BYTE_SIZE = IBinder.getSuggestedMaxIpcSizeBytes() / 2; + + /** + * Write a map containing web hosts to the given parcel, using {@link Parcel#writeBlob(byte[])} + * if the limit exceeds {@link IBinder#getSuggestedMaxIpcSizeBytes()} / 2. This assumes that the + * written map is the only data structure in the caller that varies based on the host data set. + * Other data that will be written to the parcel after this method will not be considered in the + * calculation. + */ + public static void writeHostMap(@NonNull Parcel dest, @NonNull Map<String, ?> map) { + boolean targetSizeExceeded = false; + int totalSize = dest.dataSize(); + for (String host : map.keySet()) { + totalSize += estimatedByteSizeOf(host); + if (totalSize > STRINGS_TARGET_BYTE_SIZE) { + targetSizeExceeded = true; + break; + } + } + + dest.writeBoolean(targetSizeExceeded); + + if (!targetSizeExceeded) { + dest.writeMap(map); + return; + } + + Parcel data = Parcel.obtain(); + try { + data.writeMap(map); + dest.writeBlob(data.marshall()); + } finally { + data.recycle(); + } + } + + /** + * Retrieve a map previously written by {@link #writeHostMap(Parcel, Map)}. + */ + @NonNull + @SuppressWarnings("rawtypes") + public static <T extends Map> T readHostMap(@NonNull Parcel in, @NonNull T map, + @NonNull ClassLoader classLoader) { + boolean targetSizeExceeded = in.readBoolean(); + + if (!targetSizeExceeded) { + in.readMap(map, classLoader); + return map; + } + + Parcel data = Parcel.obtain(); + try { + byte[] blob = in.readBlob(); + data.unmarshall(blob, 0, blob.length); + data.setDataPosition(0); + data.readMap(map, classLoader); + } finally { + data.recycle(); + } + + return map; + } + + /** + * {@link ArraySet} variant of {@link #writeHostMap(Parcel, Map)}. + */ + public static void writeHostSet(@NonNull Parcel dest, @NonNull Set<String> set) { + boolean targetSizeExceeded = false; + int totalSize = dest.dataSize(); + for (String host : set) { + totalSize += estimatedByteSizeOf(host); + if (totalSize > STRINGS_TARGET_BYTE_SIZE) { + targetSizeExceeded = true; + break; + } + } + + dest.writeBoolean(targetSizeExceeded); + + if (!targetSizeExceeded) { + writeSet(dest, set); + return; + } + + Parcel data = Parcel.obtain(); + try { + writeSet(data, set); + dest.writeBlob(data.marshall()); + } finally { + data.recycle(); + } + } + + /** + * {@link ArraySet} variant of {@link #readHostMap(Parcel, Map, ClassLoader)}. + */ + @NonNull + public static Set<String> readHostSet(@NonNull Parcel in) { + boolean targetSizeExceeded = in.readBoolean(); + + if (!targetSizeExceeded) { + return readSet(in); + } + + Parcel data = Parcel.obtain(); + try { + byte[] blob = in.readBlob(); + data.unmarshall(blob, 0, blob.length); + data.setDataPosition(0); + return readSet(data); + } finally { + data.recycle(); + } + } + + private static void writeSet(@NonNull Parcel dest, @Nullable Set<String> set) { + if (set == null) { + dest.writeInt(-1); + return; + } + dest.writeInt(set.size()); + for (String string : set) { + dest.writeString(string); + } + } + + @NonNull + private static Set<String> readSet(@NonNull Parcel in) { + int size = in.readInt(); + if (size == -1) { + return Collections.emptySet(); + } + + ArraySet<String> set = new ArraySet<>(size); + for (int count = 0; count < size; count++) { + set.add(in.readString()); + } + return set; + } + + /** + * Ballpark the size of domains to avoid unnecessary allocation of ashmem when sending domains + * across the client-server API. + */ + public static int estimatedByteSizeOf(String string) { + return string.length() * 2 + 12; + } +} diff --git a/core/java/android/content/pm/verify/domain/IDomainVerificationManager.aidl b/core/java/android/content/pm/verify/domain/IDomainVerificationManager.aidl index 21dd623b46bc..701af320fb01 100644 --- a/core/java/android/content/pm/verify/domain/IDomainVerificationManager.aidl +++ b/core/java/android/content/pm/verify/domain/IDomainVerificationManager.aidl @@ -16,6 +16,8 @@ package android.content.pm.verify.domain; +import android.content.pm.verify.domain.DomainOwner; +import android.content.pm.verify.domain.DomainSet; import android.content.pm.verify.domain.DomainVerificationInfo; import android.content.pm.verify.domain.DomainVerificationUserSelection; import java.util.List; @@ -35,10 +37,13 @@ interface IDomainVerificationManager { DomainVerificationUserSelection getDomainVerificationUserSelection(String packageName, int userId); - void setDomainVerificationStatus(String domainSetId, in List<String> domains, int state); + @nullable + List<DomainOwner> getOwnersForDomain(String domain, int userId); + + void setDomainVerificationStatus(String domainSetId, in DomainSet domains, int state); void setDomainVerificationLinkHandlingAllowed(String packageName, boolean allowed, int userId); - void setDomainVerificationUserSelection(String domainSetId, in List<String> domains, + void setDomainVerificationUserSelection(String domainSetId, in DomainSet domains, boolean enabled, int userId); } diff --git a/core/java/android/content/pm/verify/domain/OWNERS b/core/java/android/content/pm/verify/domain/OWNERS new file mode 100644 index 000000000000..c669112e0512 --- /dev/null +++ b/core/java/android/content/pm/verify/domain/OWNERS @@ -0,0 +1,5 @@ +# Bug component: 36137 + +chiuwinson@google.com +patb@google.com +toddke@google.com
\ No newline at end of file diff --git a/core/java/android/hardware/fingerprint/FingerprintSensorPropertiesInternal.java b/core/java/android/hardware/fingerprint/FingerprintSensorPropertiesInternal.java index 663a70452b24..51addc95ac79 100644 --- a/core/java/android/hardware/fingerprint/FingerprintSensorPropertiesInternal.java +++ b/core/java/android/hardware/fingerprint/FingerprintSensorPropertiesInternal.java @@ -85,8 +85,8 @@ public class FingerprintSensorPropertiesInternal extends SensorPropertiesInterna boolean resetLockoutRequiresHardwareAuthToken) { // TODO(b/179175438): Value should be provided from the HAL this(sensorId, strength, maxEnrollmentsPerUser, sensorType, - resetLockoutRequiresHardwareAuthToken, 0 /* sensorLocationX */, - 0 /* sensorLocationY */, 0 /* sensorRadius */); + resetLockoutRequiresHardwareAuthToken, 540 /* sensorLocationX */, + 1636 /* sensorLocationY */, 130 /* sensorRadius */); } /** diff --git a/core/java/android/hardware/soundtrigger/OWNERS b/core/java/android/hardware/soundtrigger/OWNERS index 816bc6bba639..e5d037003ac4 100644 --- a/core/java/android/hardware/soundtrigger/OWNERS +++ b/core/java/android/hardware/soundtrigger/OWNERS @@ -1 +1,2 @@ -include /core/java/android/media/soundtrigger/OWNERS +ytai@google.com +elaurent@google.com diff --git a/core/java/android/net/NetworkIdentity.java b/core/java/android/net/NetworkIdentity.java index 32b19a462218..303a40755d4e 100644 --- a/core/java/android/net/NetworkIdentity.java +++ b/core/java/android/net/NetworkIdentity.java @@ -18,6 +18,7 @@ package android.net; import static android.net.ConnectivityManager.TYPE_WIFI; +import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; import android.net.wifi.WifiInfo; @@ -41,6 +42,22 @@ public class NetworkIdentity implements Comparable<NetworkIdentity> { public static final int SUBTYPE_COMBINED = -1; + /** + * Network has no {@code NetworkCapabilities#NET_CAPABILITY_OEM_*}. + * @hide + */ + public static final int OEM_NONE = 0x0; + /** + * Network has {@link NetworkCapabilities#NET_CAPABILITY_OEM_PAID}. + * @hide + */ + public static final int OEM_PAID = 0x1; + /** + * Network has {@link NetworkCapabilities#NET_CAPABILITY_OEM_PRIVATE}. + * @hide + */ + public static final int OEM_PRIVATE = 0x2; + final int mType; final int mSubType; final String mSubscriberId; @@ -48,10 +65,11 @@ public class NetworkIdentity implements Comparable<NetworkIdentity> { final boolean mRoaming; final boolean mMetered; final boolean mDefaultNetwork; + final int mOemManaged; public NetworkIdentity( int type, int subType, String subscriberId, String networkId, boolean roaming, - boolean metered, boolean defaultNetwork) { + boolean metered, boolean defaultNetwork, int oemManaged) { mType = type; mSubType = subType; mSubscriberId = subscriberId; @@ -59,12 +77,13 @@ public class NetworkIdentity implements Comparable<NetworkIdentity> { mRoaming = roaming; mMetered = metered; mDefaultNetwork = defaultNetwork; + mOemManaged = oemManaged; } @Override public int hashCode() { return Objects.hash(mType, mSubType, mSubscriberId, mNetworkId, mRoaming, mMetered, - mDefaultNetwork); + mDefaultNetwork, mOemManaged); } @Override @@ -75,7 +94,8 @@ public class NetworkIdentity implements Comparable<NetworkIdentity> { && Objects.equals(mSubscriberId, ident.mSubscriberId) && Objects.equals(mNetworkId, ident.mNetworkId) && mMetered == ident.mMetered - && mDefaultNetwork == ident.mDefaultNetwork; + && mDefaultNetwork == ident.mDefaultNetwork + && mOemManaged == ident.mOemManaged; } return false; } @@ -102,6 +122,8 @@ public class NetworkIdentity implements Comparable<NetworkIdentity> { } builder.append(", metered=").append(mMetered); builder.append(", defaultNetwork=").append(mDefaultNetwork); + // TODO(180557699): Print a human readable string for OEM managed state. + builder.append(", oemManaged=").append(mOemManaged); return builder.append("}").toString(); } @@ -120,6 +142,7 @@ public class NetworkIdentity implements Comparable<NetworkIdentity> { proto.write(NetworkIdentityProto.ROAMING, mRoaming); proto.write(NetworkIdentityProto.METERED, mMetered); proto.write(NetworkIdentityProto.DEFAULT_NETWORK, mDefaultNetwork); + proto.write(NetworkIdentityProto.OEM_MANAGED_NETWORK, mOemManaged); proto.end(start); } @@ -152,6 +175,10 @@ public class NetworkIdentity implements Comparable<NetworkIdentity> { return mDefaultNetwork; } + public int getOemManaged() { + return mOemManaged; + } + /** * Build a {@link NetworkIdentity} from the given {@link NetworkState} and {@code subType}, * assuming that any mobile networks are using the current IMSI. The subType if applicable, @@ -171,6 +198,8 @@ public class NetworkIdentity implements Comparable<NetworkIdentity> { subscriberId = state.subscriberId; + final int oemManaged = getOemBitfield(state.networkCapabilities); + if (legacyType == TYPE_WIFI) { if (state.networkCapabilities.getSsid() != null) { networkId = state.networkCapabilities.getSsid(); @@ -185,7 +214,24 @@ public class NetworkIdentity implements Comparable<NetworkIdentity> { } return new NetworkIdentity(legacyType, subType, subscriberId, networkId, roaming, metered, - defaultNetwork); + defaultNetwork, oemManaged); + } + + /** + * Builds a bitfield of {@code NetworkIdentity.OEM_*} based on {@link NetworkCapabilities}. + * @hide + */ + public static int getOemBitfield(NetworkCapabilities nc) { + int oemManaged = OEM_NONE; + + if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PAID)) { + oemManaged |= OEM_PAID; + } + if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE)) { + oemManaged |= OEM_PRIVATE; + } + + return oemManaged; } @Override @@ -209,6 +255,9 @@ public class NetworkIdentity implements Comparable<NetworkIdentity> { if (res == 0) { res = Boolean.compare(mDefaultNetwork, another.mDefaultNetwork); } + if (res == 0) { + res = Integer.compare(mOemManaged, another.mOemManaged); + } return res; } } diff --git a/core/java/android/net/NetworkStateSnapshot.aidl b/core/java/android/net/NetworkStateSnapshot.aidl new file mode 100644 index 000000000000..cb602d7927ce --- /dev/null +++ b/core/java/android/net/NetworkStateSnapshot.aidl @@ -0,0 +1,19 @@ +/** + * Copyright (c) 2021, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net; + +parcelable NetworkStateSnapshot; diff --git a/core/java/android/net/NetworkStateSnapshot.java b/core/java/android/net/NetworkStateSnapshot.java new file mode 100644 index 000000000000..881b373fa241 --- /dev/null +++ b/core/java/android/net/NetworkStateSnapshot.java @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.os.Parcel; +import android.os.Parcelable; + +import java.util.Objects; + +/** + * Snapshot of network state. + * + * @hide + */ +public final class NetworkStateSnapshot implements Parcelable { + @NonNull + public final LinkProperties linkProperties; + @NonNull + public final NetworkCapabilities networkCapabilities; + @NonNull + public final Network network; + @Nullable + public final String subscriberId; + public final int legacyType; + + public NetworkStateSnapshot(@NonNull LinkProperties linkProperties, + @NonNull NetworkCapabilities networkCapabilities, @NonNull Network network, + @Nullable String subscriberId, int legacyType) { + this.linkProperties = Objects.requireNonNull(linkProperties); + this.networkCapabilities = Objects.requireNonNull(networkCapabilities); + this.network = Objects.requireNonNull(network); + this.subscriberId = subscriberId; + this.legacyType = legacyType; + } + + public NetworkStateSnapshot(@NonNull Parcel in) { + linkProperties = in.readParcelable(null); + networkCapabilities = in.readParcelable(null); + network = in.readParcelable(null); + subscriberId = in.readString(); + legacyType = in.readInt(); + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(@NonNull Parcel out, int flags) { + out.writeParcelable(linkProperties, flags); + out.writeParcelable(networkCapabilities, flags); + out.writeParcelable(network, flags); + out.writeString(subscriberId); + out.writeInt(legacyType); + } + + @NonNull + public static final Creator<NetworkStateSnapshot> CREATOR = + new Creator<NetworkStateSnapshot>() { + @NonNull + @Override + public NetworkStateSnapshot createFromParcel(@NonNull Parcel in) { + return new NetworkStateSnapshot(in); + } + + @NonNull + @Override + public NetworkStateSnapshot[] newArray(int size) { + return new NetworkStateSnapshot[size]; + } + }; + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof NetworkStateSnapshot)) return false; + NetworkStateSnapshot that = (NetworkStateSnapshot) o; + return legacyType == that.legacyType + && Objects.equals(linkProperties, that.linkProperties) + && Objects.equals(networkCapabilities, that.networkCapabilities) + && Objects.equals(network, that.network) + && Objects.equals(subscriberId, that.subscriberId); + } + + @Override + public int hashCode() { + return Objects.hash(linkProperties, networkCapabilities, network, subscriberId, legacyType); + } +} diff --git a/core/java/android/net/NetworkTemplate.java b/core/java/android/net/NetworkTemplate.java index aa61e03b285c..c83dd99c2a3b 100644 --- a/core/java/android/net/NetworkTemplate.java +++ b/core/java/android/net/NetworkTemplate.java @@ -23,6 +23,7 @@ import static android.net.ConnectivityManager.TYPE_PROXY; import static android.net.ConnectivityManager.TYPE_WIFI; import static android.net.ConnectivityManager.TYPE_WIFI_P2P; import static android.net.ConnectivityManager.TYPE_WIMAX; +import static android.net.NetworkIdentity.OEM_NONE; import static android.net.NetworkStats.DEFAULT_NETWORK_ALL; import static android.net.NetworkStats.DEFAULT_NETWORK_NO; import static android.net.NetworkStats.DEFAULT_NETWORK_YES; @@ -99,6 +100,22 @@ public class NetworkTemplate implements Parcelable { */ public static final int NETWORK_TYPE_5G_NSA = -2; + /** + * Value to match both OEM managed and unmanaged networks (all networks). + * @hide + */ + public static final int OEM_MANAGED_ALL = -1; + /** + * Value to match networks which are not OEM managed. + * @hide + */ + public static final int OEM_MANAGED_NO = OEM_NONE; + /** + * Value to match any OEM managed network. + * @hide + */ + public static final int OEM_MANAGED_YES = -2; + private static boolean isKnownMatchRule(final int rule) { switch (rule) { case MATCH_MOBILE: @@ -151,10 +168,10 @@ public class NetworkTemplate implements Parcelable { @NetworkType int ratType) { if (TextUtils.isEmpty(subscriberId)) { return new NetworkTemplate(MATCH_MOBILE_WILDCARD, null, null, null, - METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, ratType); + METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, ratType, OEM_MANAGED_ALL); } return new NetworkTemplate(MATCH_MOBILE, subscriberId, new String[]{subscriberId}, null, - METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, ratType); + METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, ratType, OEM_MANAGED_ALL); } /** @@ -235,6 +252,9 @@ public class NetworkTemplate implements Parcelable { private final int mDefaultNetwork; private final int mSubType; + // Bitfield containing OEM network properties{@code NetworkIdentity#OEM_*}. + private final int mOemManaged; + @UnsupportedAppUsage public NetworkTemplate(int matchRule, String subscriberId, String networkId) { this(matchRule, subscriberId, new String[] { subscriberId }, networkId); @@ -243,11 +263,12 @@ public class NetworkTemplate implements Parcelable { public NetworkTemplate(int matchRule, String subscriberId, String[] matchSubscriberIds, String networkId) { this(matchRule, subscriberId, matchSubscriberIds, networkId, METERED_ALL, ROAMING_ALL, - DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL); + DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, OEM_MANAGED_ALL); } public NetworkTemplate(int matchRule, String subscriberId, String[] matchSubscriberIds, - String networkId, int metered, int roaming, int defaultNetwork, int subType) { + String networkId, int metered, int roaming, int defaultNetwork, int subType, + int oemManaged) { mMatchRule = matchRule; mSubscriberId = subscriberId; mMatchSubscriberIds = matchSubscriberIds; @@ -256,6 +277,7 @@ public class NetworkTemplate implements Parcelable { mRoaming = roaming; mDefaultNetwork = defaultNetwork; mSubType = subType; + mOemManaged = oemManaged; if (!isKnownMatchRule(matchRule)) { Log.e(TAG, "Unknown network template rule " + matchRule @@ -272,6 +294,7 @@ public class NetworkTemplate implements Parcelable { mRoaming = in.readInt(); mDefaultNetwork = in.readInt(); mSubType = in.readInt(); + mOemManaged = in.readInt(); } @Override @@ -284,6 +307,7 @@ public class NetworkTemplate implements Parcelable { dest.writeInt(mRoaming); dest.writeInt(mDefaultNetwork); dest.writeInt(mSubType); + dest.writeInt(mOemManaged); } @Override @@ -319,13 +343,16 @@ public class NetworkTemplate implements Parcelable { if (mSubType != NETWORK_TYPE_ALL) { builder.append(", subType=").append(mSubType); } + if (mOemManaged != OEM_MANAGED_ALL) { + builder.append(", oemManaged=").append(mOemManaged); + } return builder.toString(); } @Override public int hashCode() { return Objects.hash(mMatchRule, mSubscriberId, mNetworkId, mMetered, mRoaming, - mDefaultNetwork, mSubType); + mDefaultNetwork, mSubType, mOemManaged); } @Override @@ -338,7 +365,8 @@ public class NetworkTemplate implements Parcelable { && mMetered == other.mMetered && mRoaming == other.mRoaming && mDefaultNetwork == other.mDefaultNetwork - && mSubType == other.mSubType; + && mSubType == other.mSubType + && mOemManaged == other.mOemManaged; } return false; } @@ -384,6 +412,7 @@ public class NetworkTemplate implements Parcelable { if (!matchesMetered(ident)) return false; if (!matchesRoaming(ident)) return false; if (!matchesDefaultNetwork(ident)) return false; + if (!matchesOemNetwork(ident)) return false; switch (mMatchRule) { case MATCH_MOBILE: @@ -425,6 +454,13 @@ public class NetworkTemplate implements Parcelable { || (mDefaultNetwork == DEFAULT_NETWORK_NO && !ident.mDefaultNetwork); } + private boolean matchesOemNetwork(NetworkIdentity ident) { + return (mOemManaged == OEM_MANAGED_ALL) + || (mOemManaged == OEM_MANAGED_YES + && ident.mOemManaged != OEM_NONE) + || (mOemManaged == ident.mOemManaged); + } + private boolean matchesCollapsedRatType(NetworkIdentity ident) { return mSubType == NETWORK_TYPE_ALL || getCollapsedRatType(mSubType) == getCollapsedRatType(ident.mSubType); diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java index cf9b534fc29f..6901df7508ab 100644 --- a/core/java/android/os/BatteryStats.java +++ b/core/java/android/os/BatteryStats.java @@ -2179,12 +2179,6 @@ public abstract class BatteryStats implements Parcelable { public abstract void finishIteratingHistoryLocked(); - public abstract boolean startIteratingOldHistoryLocked(); - - public abstract boolean getNextOldHistoryLocked(HistoryItem out); - - public abstract void finishIteratingOldHistoryLocked(); - /** * Return the base time offset for the battery history. */ @@ -7061,24 +7055,6 @@ public abstract class BatteryStats implements Parcelable { finishIteratingHistoryLocked(); } } - - if (startIteratingOldHistoryLocked()) { - try { - final HistoryItem rec = new HistoryItem(); - pw.println("Old battery History:"); - HistoryPrinter hprinter = new HistoryPrinter(); - long baseTime = -1; - while (getNextOldHistoryLocked(rec)) { - if (baseTime < 0) { - baseTime = rec.time; - } - hprinter.printNextItem(pw, rec, baseTime, false, (flags&DUMP_VERBOSE) != 0); - } - pw.println(); - } finally { - finishIteratingOldHistoryLocked(); - } - } } if (filtering && (flags&(DUMP_CHARGED_ONLY|DUMP_DAILY_ONLY)) == 0) { diff --git a/core/java/android/os/BatteryUsageStats.java b/core/java/android/os/BatteryUsageStats.java index 35a5a7c7c1d0..de7b88575e98 100644 --- a/core/java/android/os/BatteryUsageStats.java +++ b/core/java/android/os/BatteryUsageStats.java @@ -20,6 +20,9 @@ import android.annotation.NonNull; import android.util.Range; import android.util.SparseArray; +import com.android.internal.os.BatteryStatsHistory; +import com.android.internal.os.BatteryStatsHistoryIterator; + import java.util.ArrayList; import java.util.List; @@ -37,12 +40,16 @@ public final class BatteryUsageStats implements Parcelable { private final ArrayList<UidBatteryConsumer> mUidBatteryConsumers; private final ArrayList<SystemBatteryConsumer> mSystemBatteryConsumers; private final ArrayList<UserBatteryConsumer> mUserBatteryConsumers; + private final Parcel mHistoryBuffer; + private final List<BatteryStats.HistoryTag> mHistoryTagPool; private BatteryUsageStats(@NonNull Builder builder) { mStatsStartRealtimeMs = builder.mStatsStartRealtimeMs; mDischargePercentage = builder.mDischargePercentage; mDischargedPowerLowerBound = builder.mDischargedPowerLowerBoundMah; mDischargedPowerUpperBound = builder.mDischargedPowerUpperBoundMah; + mHistoryBuffer = builder.mHistoryBuffer; + mHistoryTagPool = builder.mHistoryTagPool; double totalPower = 0; @@ -125,6 +132,19 @@ public final class BatteryUsageStats implements Parcelable { return mUserBatteryConsumers; } + /** + * Returns an iterator for {@link android.os.BatteryStats.HistoryItem}'s. + */ + @NonNull + public BatteryStatsHistoryIterator iterateBatteryStatsHistory() { + if (mHistoryBuffer == null) { + throw new IllegalStateException( + "Battery history was not requested in the BatteryUsageStatsQuery"); + } + return new BatteryStatsHistoryIterator(new BatteryStatsHistory(mHistoryBuffer), + mHistoryTagPool); + } + @Override public int describeContents() { return 0; @@ -142,6 +162,29 @@ public final class BatteryUsageStats implements Parcelable { source.readParcelableList(mSystemBatteryConsumers, getClass().getClassLoader()); mUserBatteryConsumers = new ArrayList<>(); source.readParcelableList(mUserBatteryConsumers, getClass().getClassLoader()); + if (source.readBoolean()) { + mHistoryBuffer = Parcel.obtain(); + mHistoryBuffer.setDataSize(0); + mHistoryBuffer.setDataPosition(0); + + int historyBufferSize = source.readInt(); + int curPos = source.dataPosition(); + mHistoryBuffer.appendFrom(source, curPos, historyBufferSize); + source.setDataPosition(curPos + historyBufferSize); + + int historyTagCount = source.readInt(); + mHistoryTagPool = new ArrayList<>(historyTagCount); + for (int i = 0; i < historyTagCount; i++) { + BatteryStats.HistoryTag tag = new BatteryStats.HistoryTag(); + tag.string = source.readString(); + tag.uid = source.readInt(); + tag.poolIdx = source.readInt(); + mHistoryTagPool.add(tag); + } + } else { + mHistoryBuffer = null; + mHistoryTagPool = null; + } } @Override @@ -154,6 +197,23 @@ public final class BatteryUsageStats implements Parcelable { dest.writeParcelableList(mUidBatteryConsumers, flags); dest.writeParcelableList(mSystemBatteryConsumers, flags); dest.writeParcelableList(mUserBatteryConsumers, flags); + if (mHistoryBuffer != null) { + dest.writeBoolean(true); + + final int historyBufferSize = mHistoryBuffer.dataSize(); + dest.writeInt(historyBufferSize); + dest.appendFrom(mHistoryBuffer, 0, historyBufferSize); + + dest.writeInt(mHistoryTagPool.size()); + for (int i = mHistoryTagPool.size() - 1; i >= 0; i--) { + final BatteryStats.HistoryTag tag = mHistoryTagPool.get(i); + dest.writeString(tag.string); + dest.writeInt(tag.uid); + dest.writeInt(tag.poolIdx); + } + } else { + dest.writeBoolean(false); + } } @NonNull @@ -183,6 +243,8 @@ public final class BatteryUsageStats implements Parcelable { new SparseArray<>(); private final SparseArray<UserBatteryConsumer.Builder> mUserBatteryConsumerBuilders = new SparseArray<>(); + private Parcel mHistoryBuffer; + private List<BatteryStats.HistoryTag> mHistoryTagPool; public Builder(int customPowerComponentCount, int customTimeComponentCount) { mCustomPowerComponentCount = customPowerComponentCount; @@ -227,6 +289,17 @@ public final class BatteryUsageStats implements Parcelable { } /** + * Sets the parceled recent history. + */ + @NonNull + public Builder setBatteryHistory(Parcel historyBuffer, + List<BatteryStats.HistoryTag> historyTagPool) { + mHistoryBuffer = historyBuffer; + mHistoryTagPool = historyTagPool; + return this; + } + + /** * Creates or returns a exiting UidBatteryConsumer, which represents battery attribution * data for an individual UID. */ diff --git a/core/java/android/os/BatteryUsageStatsQuery.java b/core/java/android/os/BatteryUsageStatsQuery.java index 17cb735eea49..9518bf197fa0 100644 --- a/core/java/android/os/BatteryUsageStatsQuery.java +++ b/core/java/android/os/BatteryUsageStatsQuery.java @@ -40,6 +40,7 @@ public final class BatteryUsageStatsQuery implements Parcelable { */ @IntDef(flag = true, prefix = { "FLAG_BATTERY_USAGE_STATS_" }, value = { FLAG_BATTERY_USAGE_STATS_POWER_PROFILE_MODEL, + FLAG_BATTERY_USAGE_STATS_INCLUDE_HISTORY, }) @Retention(RetentionPolicy.SOURCE) public @interface BatteryUsageStatsFlags {} @@ -53,6 +54,12 @@ public final class BatteryUsageStatsQuery implements Parcelable { */ public static final int FLAG_BATTERY_USAGE_STATS_POWER_PROFILE_MODEL = 1; + /** + * Indicates that battery history should be included in the BatteryUsageStats. + * @hide + */ + public static final int FLAG_BATTERY_USAGE_STATS_INCLUDE_HISTORY = 2; + private final int mFlags; @NonNull private final int[] mUserIds; @@ -146,10 +153,10 @@ public final class BatteryUsageStatsQuery implements Parcelable { } /** - * Sets flags to modify the behavior of {@link BatteryStatsManager#getBatteryUsageStats}. + * Requests that battery history be included in the BatteryUsageStats. */ - public Builder setFlags(@BatteryUsageStatsFlags int flags) { - mFlags = flags; + public Builder includeBatteryHistory() { + mFlags |= BatteryUsageStatsQuery.FLAG_BATTERY_USAGE_STATS_INCLUDE_HISTORY; return this; } diff --git a/core/java/android/os/BugreportManager.java b/core/java/android/os/BugreportManager.java index a435ac12d33c..73bb8d566500 100644 --- a/core/java/android/os/BugreportManager.java +++ b/core/java/android/os/BugreportManager.java @@ -68,8 +68,11 @@ public final class BugreportManager { /** * An interface describing the callback for bugreport progress and status. * - * <p>In general, callers can expect to receive {@link #onProgress} calls as the bugreport - * progresses, followed by a terminal call to either {@link #onFinished} or {@link #onError}. + * <p>Callers will receive {@link #onProgress} calls as the bugreport progresses, followed by a + * terminal call to either {@link #onFinished} or {@link #onError}. + * + * <p>If an issue is encountered while starting the bugreport asynchronously, callers will + * receive an {@link #onError} call without any {@link #onProgress} callbacks. */ public abstract static class BugreportCallback { /** diff --git a/core/java/android/os/IUserManager.aidl b/core/java/android/os/IUserManager.aidl index 7437e037fa3e..087568defb27 100644 --- a/core/java/android/os/IUserManager.aidl +++ b/core/java/android/os/IUserManager.aidl @@ -113,7 +113,7 @@ interface IUserManager { boolean hasBadge(int userId); boolean isUserUnlocked(int userId); boolean isUserRunning(int userId); - boolean isUserForeground(); + boolean isUserForeground(int userId); boolean isUserNameSet(int userId); boolean hasRestrictedProfiles(); boolean requestQuietModeEnabled(String callingPackage, boolean enableQuietMode, int userId, in IntentSender target, int flags); diff --git a/core/java/android/os/SystemClock.java b/core/java/android/os/SystemClock.java index e29d75611856..d8f63444dd1c 100644 --- a/core/java/android/os/SystemClock.java +++ b/core/java/android/os/SystemClock.java @@ -338,8 +338,7 @@ public final class SystemClock { try { time = mMgr.getGnssTimeMillis(); } catch (RemoteException e) { - e.rethrowFromSystemServer(); - return 0; + throw e.rethrowFromSystemServer(); } if (time == null) { throw new DateTimeException("Gnss based time is not available."); diff --git a/core/java/android/os/TEST_MAPPING b/core/java/android/os/TEST_MAPPING index 1bdc82a82c6c..97e03e9d0d94 100644 --- a/core/java/android/os/TEST_MAPPING +++ b/core/java/android/os/TEST_MAPPING @@ -38,6 +38,23 @@ "include-filter": "com.android.server.pm.parsing.PackageInfoUserFieldsTest" } ] + }, + { + "file_patterns": ["BatteryStats.java"], + "name": "FrameworksCoreTests", + "options": [ + { "include-filter": "com.android.internal.os.BatteryStatsTests" }, + { "exclude-annotation": "com.android.internal.os.SkipPresubmit" } + ] + }, + { + "file_patterns": ["BatteryStats.java"], + "name": "FrameworksServicesTests", + "options": [ + { "include-filter": "com.android.server.am.BatteryStatsServiceTest" }, + { "include-filter": "com.android.server.am.MeasuredEnergySnapshotTest" }, + { "include-filter": "com.android.server.am.BatteryExternalStatsWorkerTest" } + ] } ], "postsubmit": [ diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java index 682754e66904..5069e0319119 100644 --- a/core/java/android/os/UserManager.java +++ b/core/java/android/os/UserManager.java @@ -2316,13 +2316,14 @@ public class UserManager { } /** - * Checks if the calling user is running on foreground. + * Checks if the context user is running in the foreground. * - * @return whether the calling user is running on foreground. + * @return whether the context user is running in the foreground. */ + @UserHandleAware public boolean isUserForeground() { try { - return mService.isUserForeground(); + return mService.isUserForeground(mUserId); } catch (RemoteException re) { throw re.rethrowFromSystemServer(); } diff --git a/core/java/android/os/ZygoteProcess.java b/core/java/android/os/ZygoteProcess.java index 06203ff15094..9ffc5aa0022c 100644 --- a/core/java/android/os/ZygoteProcess.java +++ b/core/java/android/os/ZygoteProcess.java @@ -426,7 +426,7 @@ public class ZygoteProcess { // avoid writing a partial response to the zygote. for (String arg : args) { // Making two indexOf calls here is faster than running a manually fused loop due - // to the fact that indexOf is a optimized intrinsic. + // to the fact that indexOf is an optimized intrinsic. if (arg.indexOf('\n') >= 0) { throw new ZygoteStartFailedEx("Embedded newlines not allowed"); } else if (arg.indexOf('\r') >= 0) { diff --git a/core/java/android/os/storage/IStorageManager.aidl b/core/java/android/os/storage/IStorageManager.aidl index 4669b208b163..0041699df9ef 100644 --- a/core/java/android/os/storage/IStorageManager.aidl +++ b/core/java/android/os/storage/IStorageManager.aidl @@ -196,4 +196,6 @@ interface IStorageManager { void clearUserKeyAuth(int userId, int serialNumber, in byte[] token, in byte[] secret) = 88; void fixupAppDir(in String path) = 89; void disableAppDataIsolation(in String pkgName, int pid, int userId) = 90; -} + void notifyAppIoBlocked(in String volumeUuid, int uid, int tid, int reason) = 91; + void notifyAppIoResumed(in String volumeUuid, int uid, int tid, int reason) = 92; + } diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java index 3a5426c60b24..7c8874cc1ea7 100644 --- a/core/java/android/os/storage/StorageManager.java +++ b/core/java/android/os/storage/StorageManager.java @@ -2699,6 +2699,80 @@ public class StorageManager { } } + /** + * Reason to provide if app IO is blocked/resumed because of transcoding + * + * @hide + */ + @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) + public static final int APP_IO_BLOCKED_REASON_TRANSCODING = 0; + + /** + * Constants for use with + * {@link #notifyAppIoBlocked} and {@link notifyAppIoResumed}, to specify the reason an app's + * IO is blocked/resumed. + * + * @hide + */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = { "APP_IO_BLOCKED_REASON_" }, value = { + APP_IO_BLOCKED_REASON_TRANSCODING + }) + public @interface AppIoBlockedReason {} + + /** + * Notify the system that an app with {@code uid} and {@code tid} is blocked on an IO request on + * {@code volumeUuid} for {@code reason}. + * + * This blocked state can be used to modify the ANR behavior for the app while it's blocked. + * For example during transcoding. + * + * This can only be called by the {@link ExternalStorageService} holding the + * {@link android.Manifest.permission#WRITE_MEDIA_STORAGE} permission. + * + * @param volumeUuid the UUID of the storage volume that the app IO is blocked on + * @param uid the UID of the app blocked on IO + * @param tid the tid of the app blocked on IO + * @param reason the reason the app is blocked on IO + * + * @hide + */ + @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) + public void notifyAppIoBlocked(@NonNull String volumeUuid, int uid, int tid, + @AppIoBlockedReason int reason) { + try { + mStorageManager.notifyAppIoBlocked(volumeUuid, uid, tid, reason); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * Notify the system that an app with {@code uid} and {@code tid} has resmued a previously + * blocked IO request on {@code volumeUuid} for {@code reason}. + * + * All app IO will be automatically marked as unblocked if {@code volumeUuid} is unmounted. + * + * This can only be called by the {@link ExternalStorageService} holding the + * {@link android.Manifest.permission#WRITE_MEDIA_STORAGE} permission. + * + * @param volumeUuid the UUID of the storage volume that the app IO is resumed on + * @param uid the UID of the app resuming IO + * @param tid the tid of the app resuming IO + * @param reason the reason the app is resuming IO + * + * @hide + */ + @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) + public void notifyAppIoResumed(@NonNull String volumeUuid, int uid, int tid, + @AppIoBlockedReason int reason) { + try { + mStorageManager.notifyAppIoResumed(volumeUuid, uid, tid, reason); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + private final Object mFuseAppLoopLock = new Object(); @GuardedBy("mFuseAppLoopLock") diff --git a/core/java/android/permission/PermissionManager.java b/core/java/android/permission/PermissionManager.java index ff01011bd19b..bae36b299247 100644 --- a/core/java/android/permission/PermissionManager.java +++ b/core/java/android/permission/PermissionManager.java @@ -485,10 +485,6 @@ public final class PermissionManager { * One for cases where the installer of the package allowlists a permission. This list * corresponds to the {@link PackageManager#FLAG_PERMISSION_WHITELIST_INSTALLER} flag. Can be * accessed by pre-installed holders of a dedicated permission or the installer on record. - * <li> - * One for cases where the system exempts the permission when granting a role. This list - * corresponds to the {@link PackageManager#FLAG_PERMISSION_ALLOWLIST_ROLE} flag. Can be - * accessed by pre-installed holders of a dedicated permission. * </ol> * * @param packageName the app for which to get allowlisted permissions @@ -502,7 +498,6 @@ public final class PermissionManager { * @see PackageManager#FLAG_PERMISSION_WHITELIST_SYSTEM * @see PackageManager#FLAG_PERMISSION_WHITELIST_UPGRADE * @see PackageManager#FLAG_PERMISSION_WHITELIST_INSTALLER - * @see PackageManager#FLAG_PERMISSION_ALLOWLIST_ROLE * * @hide Pending API */ @@ -549,10 +544,6 @@ public final class PermissionManager { * One for cases where the installer of the package allowlists a permission. This list * corresponds to the {@link PackageManager#FLAG_PERMISSION_WHITELIST_INSTALLER} flag. Can be * accessed by pre-installed holders of a dedicated permission or the installer on record. - * <li> - * One for cases where the system exempts the permission when granting a role. This list - * corresponds to the {@link PackageManager#FLAG_PERMISSION_ALLOWLIST_ROLE} flag. Can be - * accessed by pre-installed holders of a dedicated permission. * </ol> * <p> * You need to specify the allowlists for which to set the allowlisted permissions which will @@ -570,7 +561,6 @@ public final class PermissionManager { * @see PackageManager#FLAG_PERMISSION_WHITELIST_SYSTEM * @see PackageManager#FLAG_PERMISSION_WHITELIST_UPGRADE * @see PackageManager#FLAG_PERMISSION_WHITELIST_INSTALLER - * @see PackageManager#FLAG_PERMISSION_ALLOWLIST_ROLE * * @hide Pending API */ @@ -613,10 +603,6 @@ public final class PermissionManager { * One for cases where the installer of the package allowlists a permission. This list * corresponds to the {@link PackageManager#FLAG_PERMISSION_WHITELIST_INSTALLER} flag. Can be * accessed by pre-installed holders of a dedicated permission or the installer on record. - * <li> - * One for cases where the system exempts the permission when granting a role. This list - * corresponds to the {@link PackageManager#FLAG_PERMISSION_ALLOWLIST_ROLE} flag. Can be - * accessed by pre-installed holders of a dedicated permission. * </ol> * <p> * You need to specify the allowlists for which to set the allowlisted permissions which will @@ -634,7 +620,6 @@ public final class PermissionManager { * @see PackageManager#FLAG_PERMISSION_WHITELIST_SYSTEM * @see PackageManager#FLAG_PERMISSION_WHITELIST_UPGRADE * @see PackageManager#FLAG_PERMISSION_WHITELIST_INSTALLER - * @see PackageManager#FLAG_PERMISSION_ALLOWLIST_ROLE * * @hide Pending API */ diff --git a/core/java/android/permission/PermissionUsageHelper.java b/core/java/android/permission/PermissionUsageHelper.java index 0e35ef98f1b7..4c9e77c35135 100644 --- a/core/java/android/permission/PermissionUsageHelper.java +++ b/core/java/android/permission/PermissionUsageHelper.java @@ -57,6 +57,8 @@ import android.util.ArraySet; import android.view.inputmethod.InputMethodInfo; import android.view.inputmethod.InputMethodManager; +import com.android.internal.R; + import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -186,6 +188,15 @@ public class PermissionUsageHelper { == PackageManager.PERMISSION_GRANTED; } + private boolean isSpeechRecognizerUsage(String op, String packageName) { + if (!OPSTR_RECORD_AUDIO.equals(op)) { + return false; + } + + return packageName.equals( + mContext.getString(R.string.config_systemSpeechRecognizer)); + } + /** * @see PermissionManager.getIndicatorAppOpUsageData */ @@ -317,7 +328,8 @@ public class PermissionUsageHelper { if (packageName.equals(SYSTEM_PKG) || (!isUserSensitive(packageName, user, op) && !isLocationProvider(packageName, user) - && !isAppPredictor(packageName, user))) { + && !isAppPredictor(packageName, user)) + && !isSpeechRecognizerUsage(op, packageName)) { continue; } diff --git a/core/java/android/security/keystore/recovery/RecoveryController.java b/core/java/android/security/keystore/recovery/RecoveryController.java index d859b1c33c94..6788353ba2fb 100644 --- a/core/java/android/security/keystore/recovery/RecoveryController.java +++ b/core/java/android/security/keystore/recovery/RecoveryController.java @@ -27,8 +27,11 @@ import android.os.RemoteException; import android.os.ServiceManager; import android.os.ServiceSpecificException; import android.security.KeyStore; -import android.security.keystore.AndroidKeyStoreProvider; +import android.security.KeyStore2; import android.security.keystore.KeyPermanentlyInvalidatedException; +import android.security.keystore2.AndroidKeyStoreProvider; +import android.system.keystore2.Domain; +import android.system.keystore2.KeyDescriptor; import com.android.internal.widget.ILockSettings; @@ -709,10 +712,34 @@ public class RecoveryController { */ @NonNull Key getKeyFromGrant(@NonNull String grantAlias) throws UnrecoverableKeyException, KeyPermanentlyInvalidatedException { - return AndroidKeyStoreProvider.loadAndroidKeyStoreKeyFromKeystore( - mKeyStore, - grantAlias, - KeyStore.UID_SELF); + if (grantAlias.startsWith(APPLICATION_KEY_GRANT_PREFIX)) { + return AndroidKeyStoreProvider + .loadAndroidKeyStoreSecretKeyFromKeystore( + KeyStore2.getInstance(), + getGrantDescriptor(grantAlias)); + } + // TODO(b/171305545): remove KeyStore1 logic. + return android.security.keystore.AndroidKeyStoreProvider.loadAndroidKeyStoreKeyFromKeystore( + mKeyStore, + grantAlias, + KeyStore.UID_SELF); + + } + + private static final String APPLICATION_KEY_GRANT_PREFIX = "recoverable_key:"; + + private static @Nullable KeyDescriptor getGrantDescriptor(String grantAlias) { + KeyDescriptor result = new KeyDescriptor(); + result.domain = Domain.GRANT; + result.blob = null; + result.alias = null; + try { + result.nspace = Long.parseUnsignedLong( + grantAlias.substring(APPLICATION_KEY_GRANT_PREFIX.length()), 16); + } catch (NumberFormatException e) { + return null; + } + return result; } /** diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java index 73e66d0212fa..7aa5bbc930fb 100644 --- a/core/java/android/service/notification/NotificationListenerService.java +++ b/core/java/android/service/notification/NotificationListenerService.java @@ -85,6 +85,10 @@ import java.util.Objects; * android:name="android.service.notification.default_filter_types" * android:value="1,2"> * </meta-data> + * <meta-data + * android:name="android.service.notification.disabled_filter_types" + * android:value="2"> + * </meta-data> * </service></pre> * * <p>The service should wait for the {@link #onListenerConnected()} event @@ -123,6 +127,19 @@ public abstract class NotificationListenerService extends Service { = "android.service.notification.default_filter_types"; /** + * The name of the {@code meta-data} tag containing a comma separated list of default + * integer notification types that this listener never wants to receive. See + * {@link #FLAG_FILTER_TYPE_ONGOING}, + * {@link #FLAG_FILTER_TYPE_CONVERSATIONS}, {@link #FLAG_FILTER_TYPE_ALERTING), + * and {@link #FLAG_FILTER_TYPE_SILENT}. + * <p>Types provided in this list will appear as 'off' and 'disabled' in the user interface, + * so users don't enable a type that the listener will never bridge to their paired devices.</p> + * + */ + public static final String META_DATA_DISABLED_FILTER_TYPES + = "android.service.notification.disabled_filter_types"; + + /** * {@link #getCurrentInterruptionFilter() Interruption filter} constant - * Normal interruption filter. */ diff --git a/core/java/android/view/OWNERS b/core/java/android/view/OWNERS index c43c410ab995..e66b17aa4426 100644 --- a/core/java/android/view/OWNERS +++ b/core/java/android/view/OWNERS @@ -77,7 +77,3 @@ per-file SyncRtSurfaceTransactionApplier.java = file:/services/core/java/com/and per-file ViewRootInsetsControllerHost.java = file:/services/core/java/com/android/server/wm/OWNERS per-file Window*.java = file:/services/core/java/com/android/server/wm/OWNERS per-file Window*.aidl = file:/services/core/java/com/android/server/wm/OWNERS - -# Scroll Capture -per-file *ScrollCapture*.java = file:/packages/SystemUI/src/com/android/systemui/screenshot/OWNERS -per-file *CaptureHelper*.java = file:/packages/SystemUI/src/com/android/systemui/screenshot/OWNERS diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java index 0832578d80c5..03dd10050724 100644 --- a/core/java/android/view/SurfaceControl.java +++ b/core/java/android/view/SurfaceControl.java @@ -3504,64 +3504,4 @@ public final class SurfaceControl implements Parcelable { public static Transaction getGlobalTransaction() { return sGlobalTransaction; } - - /** - * Wrapper for sending blur data to SurfaceFlinger. - * @hide - */ - public static final class BlurRegion { - public int blurRadius; - public float cornerRadiusTL; - public float cornerRadiusTR; - public float cornerRadiusBL; - public float cornerRadiusBR; - public float alpha = 1; - public boolean visible = true; - public final Rect rect = new Rect(); - - private final float[] mFloatArray = new float[10]; - - public BlurRegion() { - } - - public BlurRegion(BlurRegion other) { - rect.set(other.rect); - blurRadius = other.blurRadius; - alpha = other.alpha; - cornerRadiusTL = other.cornerRadiusTL; - cornerRadiusTR = other.cornerRadiusTR; - cornerRadiusBL = other.cornerRadiusBL; - cornerRadiusBR = other.cornerRadiusBR; - } - - /** - * Serializes this class into a float array that's more JNI friendly. - */ - public float[] toFloatArray() { - mFloatArray[0] = blurRadius; - mFloatArray[1] = alpha; - mFloatArray[2] = rect.left; - mFloatArray[3] = rect.top; - mFloatArray[4] = rect.right; - mFloatArray[5] = rect.bottom; - mFloatArray[6] = cornerRadiusTL; - mFloatArray[7] = cornerRadiusTR; - mFloatArray[8] = cornerRadiusBL; - mFloatArray[9] = cornerRadiusBR; - return mFloatArray; - } - - @Override - public String toString() { - return "BlurRegion{" - + "blurRadius=" + blurRadius - + ", corners={" + cornerRadiusTL - + "," + cornerRadiusTR - + "," + cornerRadiusBL - + "," + cornerRadiusBR - + "}, alpha=" + alpha - + ", rect=" + rect - + "}"; - } - } } diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 4f6679b2bc97..f8e65bd0d056 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -3969,11 +3969,12 @@ public final class ViewRootImpl implements ViewParent, } private void addFrameCallbackIfNeeded() { - boolean nextDrawUseBlastSync = mNextDrawUseBlastSync; - boolean hasBlur = mBlurRegionAggregator.hasRegions(); - boolean reportNextDraw = mReportNextDraw; + final boolean nextDrawUseBlastSync = mNextDrawUseBlastSync; + final boolean reportNextDraw = mReportNextDraw; + final boolean hasBlurUpdates = mBlurRegionAggregator.hasUpdates(); + final boolean needsCallbackForBlur = hasBlurUpdates || mBlurRegionAggregator.hasRegions(); - if (!nextDrawUseBlastSync && !reportNextDraw && !hasBlur) { + if (!nextDrawUseBlastSync && !reportNextDraw && !needsCallbackForBlur) { return; } @@ -3981,18 +3982,22 @@ public final class ViewRootImpl implements ViewParent, Log.d(mTag, "Creating frameDrawingCallback" + " nextDrawUseBlastSync=" + nextDrawUseBlastSync + " reportNextDraw=" + reportNextDraw - + " hasBlur=" + hasBlur); + + " hasBlurUpdates=" + hasBlurUpdates); } - // The callback will run on a worker thread pool from the render thread. + final BackgroundBlurDrawable.BlurRegion[] blurRegionsForFrame = + needsCallbackForBlur ? mBlurRegionAggregator.getBlurRegionsCopyForRT() : null; + + // The callback will run on the render thread. HardwareRenderer.FrameDrawingCallback frameDrawingCallback = frame -> { if (DEBUG_BLAST) { Log.d(mTag, "Received frameDrawingCallback frameNum=" + frame + "." + " Creating transactionCompleteCallback=" + nextDrawUseBlastSync); } - if (hasBlur) { - mBlurRegionAggregator.dispatchBlurTransactionIfNeeded(frame); + if (needsCallbackForBlur) { + mBlurRegionAggregator + .dispatchBlurTransactionIfNeeded(frame, blurRegionsForFrame, hasBlurUpdates); } if (mBlastBufferQueue == null) { diff --git a/core/java/com/android/internal/graphics/drawable/BackgroundBlurDrawable.java b/core/java/com/android/internal/graphics/drawable/BackgroundBlurDrawable.java index 96dac565eb3d..402d7fed90c5 100644 --- a/core/java/com/android/internal/graphics/drawable/BackgroundBlurDrawable.java +++ b/core/java/com/android/internal/graphics/drawable/BackgroundBlurDrawable.java @@ -19,6 +19,7 @@ package com.android.internal.graphics.drawable; import android.annotation.ColorInt; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.UiThread; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; @@ -31,12 +32,14 @@ import android.graphics.PorterDuffXfermode; import android.graphics.Rect; import android.graphics.RenderNode; import android.graphics.drawable.Drawable; -import android.util.ArrayMap; +import android.util.ArraySet; import android.util.Log; -import android.view.SurfaceControl; +import android.util.LongSparseArray; import android.view.ViewRootImpl; import com.android.internal.R; +import com.android.internal.annotations.GuardedBy; +import com.android.internal.annotations.VisibleForTesting; /** * A drawable that keeps track of a blur region, pokes a hole under it, and propagates its state @@ -52,26 +55,40 @@ public final class BackgroundBlurDrawable extends Drawable { private final Paint mPaint = new Paint(); private final Path mRectPath = new Path(); private final float[] mTmpRadii = new float[8]; - private final SurfaceControl.BlurRegion mBlurRegion = new SurfaceControl.BlurRegion(); - // This will be called from a thread pool. - private final RenderNode.PositionUpdateListener mPositionUpdateListener = + private boolean mVisible = true; + + // Confined to UiThread. The values are copied into a BlurRegion, which lives on + // RenderThread to avoid interference with UiThread updates. + private int mBlurRadius; + private float mCornerRadiusTL; + private float mCornerRadiusTR; + private float mCornerRadiusBL; + private float mCornerRadiusBR; + private float mAlpha = 1; + + // Do not update from UiThread. This holds the latest position for this drawable. It is used + // by the Aggregator from RenderThread to get the final position of the blur region sent to SF + private final Rect mRect = new Rect(); + // This is called from a thread pool. The callbacks might come out of order w.r.t. the frame + // number, so we send a Runnable holding the actual update to the Aggregator. The Aggregator + // can apply the update on RenderThread when processing that same frame. + @VisibleForTesting + public final RenderNode.PositionUpdateListener mPositionUpdateListener = new RenderNode.PositionUpdateListener() { @Override public void positionChanged(long frameNumber, int left, int top, int right, int bottom) { - synchronized (mAggregator) { - mBlurRegion.rect.set(left, top, right, bottom); - mAggregator.onBlurRegionUpdated(BackgroundBlurDrawable.this, mBlurRegion); - } + mAggregator.onRenderNodePositionChanged(frameNumber, () -> { + mRect.set(left, top, right, bottom); + }); } @Override public void positionLost(long frameNumber) { - synchronized (mAggregator) { - mBlurRegion.rect.setEmpty(); - mAggregator.onBlurRegionUpdated(BackgroundBlurDrawable.this, mBlurRegion); - } + mAggregator.onRenderNodePositionChanged(frameNumber, () -> { + mRect.setEmpty(); + }); } }; @@ -79,6 +96,7 @@ public final class BackgroundBlurDrawable extends Drawable { mAggregator = aggregator; mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC)); mPaint.setColor(Color.TRANSPARENT); + mPaint.setAntiAlias(true); mRenderNode = new RenderNode("BackgroundBlurDrawable"); mRenderNode.addPositionUpdateListener(mPositionUpdateListener); } @@ -104,23 +122,30 @@ public final class BackgroundBlurDrawable extends Drawable { public boolean setVisible(boolean visible, boolean restart) { boolean changed = super.setVisible(visible, restart); if (changed) { - mBlurRegion.visible = visible; + mVisible = visible; + mAggregator.onBlurDrawableUpdated(this); } return changed; } @Override public void setAlpha(int alpha) { - mBlurRegion.alpha = alpha / 255f; - invalidateSelf(); + if (mAlpha != alpha / 255f) { + mAlpha = alpha / 255f; + invalidateSelf(); + mAggregator.onBlurDrawableUpdated(this); + } } /** * Blur radius in pixels. */ public void setBlurRadius(int blurRadius) { - mBlurRegion.blurRadius = blurRadius; - invalidateSelf(); + if (mBlurRadius != blurRadius) { + mBlurRadius = blurRadius; + invalidateSelf(); + mAggregator.onBlurDrawableUpdated(this); + } } /** @@ -139,14 +164,18 @@ public final class BackgroundBlurDrawable extends Drawable { */ public void setCornerRadius(float cornerRadiusTL, float cornerRadiusTR, float cornerRadiusBL, float cornerRadiusBR) { - synchronized (mAggregator) { - mBlurRegion.cornerRadiusTL = cornerRadiusTL; - mBlurRegion.cornerRadiusTR = cornerRadiusTR; - mBlurRegion.cornerRadiusBL = cornerRadiusBL; - mBlurRegion.cornerRadiusBR = cornerRadiusBR; + if (mCornerRadiusTL != cornerRadiusTL + || mCornerRadiusTR != cornerRadiusTR + || mCornerRadiusBL != cornerRadiusBL + || mCornerRadiusBR != cornerRadiusBR) { + mCornerRadiusTL = cornerRadiusTL; + mCornerRadiusTR = cornerRadiusTR; + mCornerRadiusBL = cornerRadiusBL; + mCornerRadiusBR = cornerRadiusBR; + updatePath(); + invalidateSelf(); + mAggregator.onBlurDrawableUpdated(this); } - updatePath(); - invalidateSelf(); } @Override @@ -157,12 +186,10 @@ public final class BackgroundBlurDrawable extends Drawable { } private void updatePath() { - synchronized (mAggregator) { - mTmpRadii[0] = mTmpRadii[1] = mBlurRegion.cornerRadiusTL; - mTmpRadii[2] = mTmpRadii[3] = mBlurRegion.cornerRadiusTR; - mTmpRadii[4] = mTmpRadii[5] = mBlurRegion.cornerRadiusBL; - mTmpRadii[6] = mTmpRadii[7] = mBlurRegion.cornerRadiusBR; - } + mTmpRadii[0] = mTmpRadii[1] = mCornerRadiusTL; + mTmpRadii[2] = mTmpRadii[3] = mCornerRadiusTR; + mTmpRadii[4] = mTmpRadii[5] = mCornerRadiusBL; + mTmpRadii[6] = mTmpRadii[7] = mCornerRadiusBR; mRectPath.reset(); if (getAlpha() == 0 || !isVisible()) { return; @@ -182,17 +209,32 @@ public final class BackgroundBlurDrawable extends Drawable { return PixelFormat.TRANSLUCENT; } + @Override + public String toString() { + return "BackgroundBlurDrawable{" + + "blurRadius=" + mBlurRadius + + ", corners={" + mCornerRadiusTL + + "," + mCornerRadiusTR + + "," + mCornerRadiusBL + + "," + mCornerRadiusBR + + "}, alpha=" + mAlpha + + ", visible=" + mVisible + + "}"; + } + /** * Responsible for keeping track of all blur regions of a {@link ViewRootImpl} and posting a * message when it's time to propagate them. */ public static final class Aggregator { - - private final ArrayMap<BackgroundBlurDrawable, SurfaceControl.BlurRegion> mBlurRegions = - new ArrayMap<>(); + private final Object mRtLock = new Object(); + // Maintains a list of all *visible* blur drawables. Confined to UI thread + private final ArraySet<BackgroundBlurDrawable> mDrawables = new ArraySet(); + @GuardedBy("mRtLock") + private final LongSparseArray<ArraySet<Runnable>> mFrameRtUpdates = new LongSparseArray(); private final ViewRootImpl mViewRoot; - private float[][] mTmpBlurRegionsArray; - private boolean mNeedsUpdate; + private BlurRegion[] mTmpBlurRegionsForFrame = new BlurRegion[0]; + private boolean mHasUiUpdates; public Aggregator(ViewRootImpl viewRoot) { mViewRoot = viewRoot; @@ -209,60 +251,191 @@ public final class BackgroundBlurDrawable extends Drawable { } /** - * Called from RenderThread only, already locked. - * @param drawable - * @param blurRegion + * Called when a BackgroundBlurDrawable has been updated */ - void onBlurRegionUpdated(BackgroundBlurDrawable drawable, - SurfaceControl.BlurRegion blurRegion) { - if (blurRegion.rect.isEmpty() || blurRegion.alpha == 0 || blurRegion.blurRadius == 0 - || !blurRegion.visible) { - mBlurRegions.remove(drawable); - mNeedsUpdate = true; - if (DEBUG) { - Log.d(TAG, "Remove " + blurRegion); + @UiThread + void onBlurDrawableUpdated(BackgroundBlurDrawable drawable) { + final boolean shouldBeDrawn = + drawable.mAlpha != 0 && drawable.mBlurRadius > 0 && drawable.mVisible; + final boolean isDrawn = mDrawables.contains(drawable); + if (shouldBeDrawn) { + mHasUiUpdates = true; + if (!isDrawn) { + mDrawables.add(drawable); + if (DEBUG) { + Log.d(TAG, "Add " + drawable); + } + } else { + if (DEBUG) { + Log.d(TAG, "Update " + drawable); + } } - } else { - mBlurRegions.put(drawable, blurRegion); - mNeedsUpdate = true; + } else if (!shouldBeDrawn && isDrawn) { + mHasUiUpdates = true; + mDrawables.remove(drawable); if (DEBUG) { - Log.d(TAG, "Update " + blurRegion); + Log.d(TAG, "Remove " + drawable); } } } + // Called from a thread pool + void onRenderNodePositionChanged(long frameNumber, Runnable update) { + // One of the blur region's position has changed, so we have to send an updated list + // of blur regions to SurfaceFlinger for this frame. + synchronized (mRtLock) { + ArraySet<Runnable> frameRtUpdates = mFrameRtUpdates.get(frameNumber); + if (frameRtUpdates == null) { + frameRtUpdates = new ArraySet<>(); + mFrameRtUpdates.put(frameNumber, frameRtUpdates); + } + frameRtUpdates.add(update); + } + } + + /** + * @return true if there are any updates that need to be sent to SF + */ + @UiThread + public boolean hasUpdates() { + return mHasUiUpdates; + } + /** - * If there are any blur regions visible on the screen at the moment. + * @return true if there are any visible blur regions */ + @UiThread public boolean hasRegions() { - return mBlurRegions.size() > 0; + return mDrawables.size() > 0; + } + + /** + * @return an array of BlurRegions, which are holding a copy of the information in + * all the currently visible BackgroundBlurDrawables + */ + @UiThread + public BlurRegion[] getBlurRegionsCopyForRT() { + if (mHasUiUpdates) { + mTmpBlurRegionsForFrame = new BlurRegion[mDrawables.size()]; + for (int i = 0; i < mDrawables.size(); i++) { + mTmpBlurRegionsForFrame[i] = new BlurRegion(mDrawables.valueAt(i)); + } + mHasUiUpdates = false; + } + + return mTmpBlurRegionsForFrame; } /** - * Dispatch blur updates, if there were any. - * @param frameNumber Frame where the update should happen. + * Called on RenderThread. + * + * @return all blur regions if there are any ui or position updates for this frame, + * null otherwise */ - public void dispatchBlurTransactionIfNeeded(long frameNumber) { - synchronized (this) { - if (!mNeedsUpdate) { - return; + @VisibleForTesting + public float[][] getBlurRegionsToDispatchToSf(long frameNumber, + BlurRegion[] blurRegionsForFrame, boolean hasUiUpdatesForFrame) { + synchronized (mRtLock) { + if (!hasUiUpdatesForFrame && (mFrameRtUpdates.size() == 0 + || mFrameRtUpdates.keyAt(0) > frameNumber)) { + return null; } - mNeedsUpdate = false; - if (mTmpBlurRegionsArray == null - || mTmpBlurRegionsArray.length != mBlurRegions.size()) { - mTmpBlurRegionsArray = new float[mBlurRegions.size()][]; + // mFrameRtUpdates holds position updates coming from a thread pool span from + // RenderThread. At this point, all position updates for frame frameNumber should + // have been added to mFrameRtUpdates. + // Here, we apply all updates for frames <= frameNumber in case some previous update + // has been missed. This also protects mFrameRtUpdates from memory leaks. + while (mFrameRtUpdates.size() != 0 && mFrameRtUpdates.keyAt(0) <= frameNumber) { + final ArraySet<Runnable> frameUpdates = mFrameRtUpdates.valueAt(0); + mFrameRtUpdates.removeAt(0); + for (int i = 0; i < frameUpdates.size(); i++) { + frameUpdates.valueAt(i).run(); + } } + } + + if (DEBUG) { + Log.d(TAG, "Dispatching " + blurRegionsForFrame.length + " blur regions:"); + } + + final float[][] blurRegionsArray = new float[blurRegionsForFrame.length][]; + for (int i = 0; i < blurRegionsArray.length; i++) { + blurRegionsArray[i] = blurRegionsForFrame[i].toFloatArray(); if (DEBUG) { - Log.d(TAG, "onBlurRegionUpdated will dispatch " + mTmpBlurRegionsArray.length - + " regions for frame " + frameNumber); - } - for (int i = 0; i < mTmpBlurRegionsArray.length; i++) { - mTmpBlurRegionsArray[i] = mBlurRegions.valueAt(i).toFloatArray(); + Log.d(TAG, blurRegionsForFrame[i].toString()); } + } + return blurRegionsArray; + } - mViewRoot.dispatchBlurRegions(mTmpBlurRegionsArray, frameNumber); + /** + * Called on RenderThread in FrameDrawingCallback. + * Dispatch all blur regions if there are any ui or position updates. + */ + public void dispatchBlurTransactionIfNeeded(long frameNumber, + BlurRegion[] blurRegionsForFrame, boolean hasUiUpdatesForFrame) { + final float[][] blurRegionsArray = getBlurRegionsToDispatchToSf(frameNumber, + blurRegionsForFrame, hasUiUpdatesForFrame); + if (blurRegionsArray != null) { + mViewRoot.dispatchBlurRegions(blurRegionsArray, frameNumber); } } + + } + + /** + * Wrapper for sending blur data to SurfaceFlinger + * Confined to RenderThread. + */ + public static final class BlurRegion { + public final int blurRadius; + public final float cornerRadiusTL; + public final float cornerRadiusTR; + public final float cornerRadiusBL; + public final float cornerRadiusBR; + public final float alpha; + public final Rect rect; + + BlurRegion(BackgroundBlurDrawable drawable) { + alpha = drawable.mAlpha; + blurRadius = drawable.mBlurRadius; + cornerRadiusTL = drawable.mCornerRadiusTL; + cornerRadiusTR = drawable.mCornerRadiusTR; + cornerRadiusBL = drawable.mCornerRadiusBL; + cornerRadiusBR = drawable.mCornerRadiusBR; + rect = drawable.mRect; + } + + /** + * Serializes this class into a float array that's more JNI friendly. + */ + float[] toFloatArray() { + final float[] floatArray = new float[10]; + floatArray[0] = blurRadius; + floatArray[1] = alpha; + floatArray[2] = rect.left; + floatArray[3] = rect.top; + floatArray[4] = rect.right; + floatArray[5] = rect.bottom; + floatArray[6] = cornerRadiusTL; + floatArray[7] = cornerRadiusTR; + floatArray[8] = cornerRadiusBL; + floatArray[9] = cornerRadiusBR; + return floatArray; + } + + @Override + public String toString() { + return "BlurRegion{" + + "blurRadius=" + blurRadius + + ", corners={" + cornerRadiusTL + + "," + cornerRadiusTR + + "," + cornerRadiusBL + + "," + cornerRadiusBR + + "}, alpha=" + alpha + + ", rect=" + rect + + "}"; + } } } diff --git a/core/java/com/android/internal/os/BatteryStatsHistory.java b/core/java/com/android/internal/os/BatteryStatsHistory.java index bdb65f33ad1a..879e0a8cfe10 100644 --- a/core/java/com/android/internal/os/BatteryStatsHistory.java +++ b/core/java/com/android/internal/os/BatteryStatsHistory.java @@ -16,6 +16,8 @@ package com.android.internal.os; +import android.annotation.NonNull; +import android.annotation.Nullable; import android.os.BatteryStats; import android.os.Parcel; import android.os.StatFs; @@ -61,6 +63,7 @@ public class BatteryStatsHistory { public static final String FILE_SUFFIX = ".bin"; private static final int MIN_FREE_SPACE = 100 * 1024 * 1024; + @Nullable private final BatteryStatsImpl mStats; private final Parcel mHistoryBuffer; private final File mHistoryDir; @@ -107,7 +110,8 @@ public class BatteryStatsHistory { * @param systemDir typically /data/system * @param historyBuffer The in-memory history buffer. */ - public BatteryStatsHistory(BatteryStatsImpl stats, File systemDir, Parcel historyBuffer) { + public BatteryStatsHistory(@NonNull BatteryStatsImpl stats, File systemDir, + Parcel historyBuffer) { mStats = stats; mHistoryBuffer = historyBuffer; mHistoryDir = new File(systemDir, HISTORY_DIR); @@ -149,11 +153,10 @@ public class BatteryStatsHistory { /** * Used when BatteryStatsImpl object is created from deserialization of a parcel, * such as Settings app or checkin file. - * @param stats BatteryStatsImpl object. - * @param historyBuffer the history buffer inside BatteryStatsImpl + * @param historyBuffer the history buffer */ - public BatteryStatsHistory(BatteryStatsImpl stats, Parcel historyBuffer) { - mStats = stats; + public BatteryStatsHistory(Parcel historyBuffer) { + mStats = null; mHistoryDir = null; mHistoryBuffer = historyBuffer; } @@ -184,10 +187,16 @@ public class BatteryStatsHistory { * create next history file. */ public void startNextFile() { + if (mStats == null) { + Slog.wtf(TAG, "mStats should not be null when writing history"); + return; + } + if (mFileNumbers.isEmpty()) { Slog.wtf(TAG, "mFileNumbers should never be empty"); return; } + // The last number in mFileNumbers is the highest number. The next file number is highest // number plus one. final int next = mFileNumbers.get(mFileNumbers.size() - 1) + 1; @@ -357,7 +366,7 @@ public class BatteryStatsHistory { private boolean skipHead(Parcel p) { p.setDataPosition(0); final int version = p.readInt(); - if (version != mStats.VERSION) { + if (version != BatteryStatsImpl.VERSION) { return false; } // skip historyBaseTime field. diff --git a/core/java/com/android/internal/os/BatteryStatsHistoryIterator.java b/core/java/com/android/internal/os/BatteryStatsHistoryIterator.java new file mode 100644 index 000000000000..1871ac5074c9 --- /dev/null +++ b/core/java/com/android/internal/os/BatteryStatsHistoryIterator.java @@ -0,0 +1,264 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.internal.os; + +import android.annotation.NonNull; +import android.os.BatteryManager; +import android.os.BatteryStats; +import android.os.Parcel; +import android.util.Slog; + +import java.util.List; + +/** + * An iterator for {@link BatteryStats.HistoryItem}'s. + */ +public class BatteryStatsHistoryIterator { + private static final boolean DEBUG = false; + private static final String TAG = "BatteryStatsHistoryItr"; + private final BatteryStatsHistory mBatteryStatsHistory; + private final BatteryStats.HistoryStepDetails mReadHistoryStepDetails = + new BatteryStats.HistoryStepDetails(); + private final String[] mReadHistoryStrings; + private final int[] mReadHistoryUids; + + public BatteryStatsHistoryIterator(@NonNull BatteryStatsHistory history, + @NonNull List<BatteryStats.HistoryTag> historyTagPool) { + mBatteryStatsHistory = history; + + mBatteryStatsHistory.startIteratingHistory(); + + mReadHistoryStrings = new String[historyTagPool.size()]; + mReadHistoryUids = new int[historyTagPool.size()]; + for (int i = historyTagPool.size() - 1; i >= 0; i--) { + BatteryStats.HistoryTag tag = historyTagPool.get(i); + final int idx = tag.poolIdx; + mReadHistoryStrings[idx] = tag.string; + mReadHistoryUids[idx] = tag.uid; + } + } + + /** + * Retrieves the next HistoryItem from battery history, if available. Returns false if there + * are no more items. + */ + public boolean next(BatteryStats.HistoryItem out) { + Parcel p = mBatteryStatsHistory.getNextParcel(out); + if (p == null) { + mBatteryStatsHistory.finishIteratingHistory(); + return false; + } + + final long lastRealtimeMs = out.time; + final long lastWalltimeMs = out.currentTime; + readHistoryDelta(p, out); + if (out.cmd != BatteryStats.HistoryItem.CMD_CURRENT_TIME + && out.cmd != BatteryStats.HistoryItem.CMD_RESET && lastWalltimeMs != 0) { + out.currentTime = lastWalltimeMs + (out.time - lastRealtimeMs); + } + return true; + } + + void readHistoryDelta(Parcel src, BatteryStats.HistoryItem cur) { + int firstToken = src.readInt(); + int deltaTimeToken = firstToken & BatteryStatsImpl.DELTA_TIME_MASK; + cur.cmd = BatteryStats.HistoryItem.CMD_UPDATE; + cur.numReadInts = 1; + if (DEBUG) { + Slog.i(TAG, "READ DELTA: firstToken=0x" + Integer.toHexString(firstToken) + + " deltaTimeToken=" + deltaTimeToken); + } + + if (deltaTimeToken < BatteryStatsImpl.DELTA_TIME_ABS) { + cur.time += deltaTimeToken; + } else if (deltaTimeToken == BatteryStatsImpl.DELTA_TIME_ABS) { + cur.readFromParcel(src); + if (DEBUG) Slog.i(TAG, "READ DELTA: ABS time=" + cur.time); + return; + } else if (deltaTimeToken == BatteryStatsImpl.DELTA_TIME_INT) { + int delta = src.readInt(); + cur.time += delta; + cur.numReadInts += 1; + if (DEBUG) Slog.i(TAG, "READ DELTA: time delta=" + delta + " new time=" + cur.time); + } else { + long delta = src.readLong(); + if (DEBUG) Slog.i(TAG, "READ DELTA: time delta=" + delta + " new time=" + cur.time); + cur.time += delta; + cur.numReadInts += 2; + } + + final int batteryLevelInt; + if ((firstToken & BatteryStatsImpl.DELTA_BATTERY_LEVEL_FLAG) != 0) { + batteryLevelInt = src.readInt(); + readBatteryLevelInt(batteryLevelInt, cur); + cur.numReadInts += 1; + if (DEBUG) { + Slog.i(TAG, "READ DELTA: batteryToken=0x" + + Integer.toHexString(batteryLevelInt) + + " batteryLevel=" + cur.batteryLevel + + " batteryTemp=" + cur.batteryTemperature + + " batteryVolt=" + (int) cur.batteryVoltage); + } + } else { + batteryLevelInt = 0; + } + + if ((firstToken & BatteryStatsImpl.DELTA_STATE_FLAG) != 0) { + int stateInt = src.readInt(); + cur.states = (firstToken & BatteryStatsImpl.DELTA_STATE_MASK) | (stateInt + & (~BatteryStatsImpl.STATE_BATTERY_MASK)); + cur.batteryStatus = (byte) ((stateInt >> BatteryStatsImpl.STATE_BATTERY_STATUS_SHIFT) + & BatteryStatsImpl.STATE_BATTERY_STATUS_MASK); + cur.batteryHealth = (byte) ((stateInt >> BatteryStatsImpl.STATE_BATTERY_HEALTH_SHIFT) + & BatteryStatsImpl.STATE_BATTERY_HEALTH_MASK); + cur.batteryPlugType = (byte) ((stateInt >> BatteryStatsImpl.STATE_BATTERY_PLUG_SHIFT) + & BatteryStatsImpl.STATE_BATTERY_PLUG_MASK); + switch (cur.batteryPlugType) { + case 1: + cur.batteryPlugType = BatteryManager.BATTERY_PLUGGED_AC; + break; + case 2: + cur.batteryPlugType = BatteryManager.BATTERY_PLUGGED_USB; + break; + case 3: + cur.batteryPlugType = BatteryManager.BATTERY_PLUGGED_WIRELESS; + break; + } + cur.numReadInts += 1; + if (DEBUG) { + Slog.i(TAG, "READ DELTA: stateToken=0x" + + Integer.toHexString(stateInt) + + " batteryStatus=" + cur.batteryStatus + + " batteryHealth=" + cur.batteryHealth + + " batteryPlugType=" + cur.batteryPlugType + + " states=0x" + Integer.toHexString(cur.states)); + } + } else { + cur.states = (firstToken & BatteryStatsImpl.DELTA_STATE_MASK) | (cur.states + & (~BatteryStatsImpl.STATE_BATTERY_MASK)); + } + + if ((firstToken & BatteryStatsImpl.DELTA_STATE2_FLAG) != 0) { + cur.states2 = src.readInt(); + if (DEBUG) { + Slog.i(TAG, "READ DELTA: states2=0x" + + Integer.toHexString(cur.states2)); + } + } + + if ((firstToken & BatteryStatsImpl.DELTA_WAKELOCK_FLAG) != 0) { + int indexes = src.readInt(); + int wakeLockIndex = indexes & 0xffff; + int wakeReasonIndex = (indexes >> 16) & 0xffff; + if (wakeLockIndex != 0xffff) { + cur.wakelockTag = cur.localWakelockTag; + readHistoryTag(wakeLockIndex, cur.wakelockTag); + if (DEBUG) { + Slog.i(TAG, "READ DELTA: wakelockTag=#" + cur.wakelockTag.poolIdx + + " " + cur.wakelockTag.uid + ":" + cur.wakelockTag.string); + } + } else { + cur.wakelockTag = null; + } + if (wakeReasonIndex != 0xffff) { + cur.wakeReasonTag = cur.localWakeReasonTag; + readHistoryTag(wakeReasonIndex, cur.wakeReasonTag); + if (DEBUG) { + Slog.i(TAG, "READ DELTA: wakeReasonTag=#" + cur.wakeReasonTag.poolIdx + + " " + cur.wakeReasonTag.uid + ":" + cur.wakeReasonTag.string); + } + } else { + cur.wakeReasonTag = null; + } + cur.numReadInts += 1; + } else { + cur.wakelockTag = null; + cur.wakeReasonTag = null; + } + + if ((firstToken & BatteryStatsImpl.DELTA_EVENT_FLAG) != 0) { + cur.eventTag = cur.localEventTag; + final int codeAndIndex = src.readInt(); + cur.eventCode = (codeAndIndex & 0xffff); + final int index = ((codeAndIndex >> 16) & 0xffff); + readHistoryTag(index, cur.eventTag); + cur.numReadInts += 1; + if (DEBUG) { + Slog.i(TAG, "READ DELTA: event=" + cur.eventCode + " tag=#" + + cur.eventTag.poolIdx + " " + cur.eventTag.uid + ":" + + cur.eventTag.string); + } + } else { + cur.eventCode = BatteryStats.HistoryItem.EVENT_NONE; + } + + if ((batteryLevelInt & BatteryStatsImpl.BATTERY_DELTA_LEVEL_FLAG) != 0) { + cur.stepDetails = mReadHistoryStepDetails; + cur.stepDetails.readFromParcel(src); + } else { + cur.stepDetails = null; + } + + if ((firstToken & BatteryStatsImpl.DELTA_BATTERY_CHARGE_FLAG) != 0) { + cur.batteryChargeUah = src.readInt(); + } + cur.modemRailChargeMah = src.readDouble(); + cur.wifiRailChargeMah = src.readDouble(); + } + + int getHistoryStringPoolSize() { + return mReadHistoryStrings.length; + } + + int getHistoryStringPoolBytes() { + int totalChars = 0; + for (int i = mReadHistoryStrings.length - 1; i >= 0; i--) { + if (mReadHistoryStrings[i] != null) { + totalChars += mReadHistoryStrings[i].length() + 1; + } + } + + // Each entry is a fixed 12 bytes: 4 for index, 4 for uid, 4 for string size + // Each string character is 2 bytes. + return (mReadHistoryStrings.length * 12) + (totalChars * 2); + } + + String getHistoryTagPoolString(int index) { + return mReadHistoryStrings[index]; + } + + int getHistoryTagPoolUid(int index) { + return mReadHistoryUids[index]; + } + + private void readHistoryTag(int index, BatteryStats.HistoryTag tag) { + if (index < mReadHistoryStrings.length) { + tag.string = mReadHistoryStrings[index]; + tag.uid = mReadHistoryUids[index]; + } else { + tag.string = null; + tag.uid = 0; + } + tag.poolIdx = index; + } + + private static void readBatteryLevelInt(int batteryLevelInt, BatteryStats.HistoryItem out) { + out.batteryLevel = (byte) ((batteryLevelInt & 0xfe000000) >>> 25); + out.batteryTemperature = (short) ((batteryLevelInt & 0x01ff8000) >>> 15); + out.batteryVoltage = (char) ((batteryLevelInt & 0x00007ffe) >>> 1); + } +} diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java index 62e1ee19b25e..73527d4a80d8 100644 --- a/core/java/com/android/internal/os/BatteryStatsImpl.java +++ b/core/java/com/android/internal/os/BatteryStatsImpl.java @@ -81,7 +81,6 @@ import android.util.IndentingPrintWriter; import android.util.IntArray; import android.util.KeyValueListParser; import android.util.Log; -import android.util.LogWriter; import android.util.LongSparseArray; import android.util.LongSparseLongArray; import android.util.MutableInt; @@ -108,7 +107,6 @@ import com.android.internal.os.SystemServerCpuThreadReader.SystemServiceCpuThrea import com.android.internal.power.MeasuredEnergyStats; import com.android.internal.power.MeasuredEnergyStats.StandardEnergyBucket; import com.android.internal.util.ArrayUtils; -import com.android.internal.util.FastPrintWriter; import com.android.internal.util.FrameworkStatsLog; import com.android.internal.util.XmlUtils; import com.android.net.module.util.NetworkCapabilitiesUtils; @@ -164,7 +162,6 @@ public class BatteryStatsImpl extends BatteryStats { private static final boolean DEBUG_BINDER_STATS = false; private static final boolean DEBUG_MEMORY = false; private static final boolean DEBUG_HISTORY = false; - private static final boolean USE_OLD_HISTORY = false; // for debugging. // TODO: remove "tcp" from network methods, since we measure total stats. @@ -172,7 +169,7 @@ public class BatteryStatsImpl extends BatteryStats { private static final int MAGIC = 0xBA757475; // 'BATSTATS' // Current on-disk Parcel version - static final int VERSION = 193 + (USE_OLD_HISTORY ? 1000 : 0); + static final int VERSION = 193; // The maximum number of names wakelocks we will keep track of // per uid; once the limit is reached, we batch the remaining wakelocks @@ -740,15 +737,11 @@ public class BatteryStatsImpl extends BatteryStats { protected boolean mRecordingHistory = false; int mNumHistoryItems; + final HashMap<HistoryTag, Integer> mHistoryTagPool = new HashMap<>(); final Parcel mHistoryBuffer = Parcel.obtain(); final HistoryItem mHistoryLastWritten = new HistoryItem(); final HistoryItem mHistoryLastLastWritten = new HistoryItem(); - final HistoryItem mHistoryReadTmp = new HistoryItem(); final HistoryItem mHistoryAddTmp = new HistoryItem(); - final HashMap<HistoryTag, Integer> mHistoryTagPool = new HashMap<>(); - String[] mReadHistoryStrings; - int[] mReadHistoryUids; - int mReadHistoryChars; int mNextHistoryTagIdx = 0; int mNumHistoryTagChars = 0; int mHistoryBufferLastPos = -1; @@ -789,6 +782,7 @@ public class BatteryStatsImpl extends BatteryStats { private final HashMap<Integer, PowerForUid> mUidToPower = ENABLE_FOREGROUND_STATS_COLLECTION ? new HashMap<>() : null; + @NonNull final BatteryStatsHistory mBatteryStatsHistory; final HistoryItem mHistoryCur = new HistoryItem(); @@ -831,9 +825,9 @@ public class BatteryStatsImpl extends BatteryStats { long mCurStepStatSoftIrqTimeMs; long mCurStepStatIdleTimeMs; + private BatteryStatsHistoryIterator mBatteryStatsHistoryIterator; private HistoryItem mHistoryIterator; private boolean mReadOverflow; - private boolean mIteratingHistory; int mStartCount; @@ -1197,7 +1191,7 @@ public class BatteryStatsImpl extends BatteryStats { mStatsFile = null; mCheckinFile = null; mDailyFile = null; - mBatteryStatsHistory = null; + mBatteryStatsHistory = new BatteryStatsHistory(mHistoryBuffer); mHandler = null; mPlatformIdleStateCallback = null; mMeasuredEnergyRetriever = null; @@ -3244,17 +3238,6 @@ public class BatteryStatsImpl extends BatteryStats { return idx; } - private void readHistoryTag(int index, HistoryTag tag) { - if (index < mReadHistoryStrings.length) { - tag.string = mReadHistoryStrings[index]; - tag.uid = mReadHistoryUids[index]; - } else { - tag.string = null; - tag.uid = 0; - } - tag.poolIdx = index; - } - /* The history delta format uses flags to denote further data in subsequent ints in the parcel. @@ -3631,137 +3614,6 @@ public class BatteryStatsImpl extends BatteryStats { mLastStepStatIdleTimeMs = mCurStepStatIdleTimeMs; } - public void readHistoryDelta(Parcel src, HistoryItem cur) { - int firstToken = src.readInt(); - int deltaTimeToken = firstToken&DELTA_TIME_MASK; - cur.cmd = HistoryItem.CMD_UPDATE; - cur.numReadInts = 1; - if (DEBUG) Slog.i(TAG, "READ DELTA: firstToken=0x" + Integer.toHexString(firstToken) - + " deltaTimeToken=" + deltaTimeToken); - - if (deltaTimeToken < DELTA_TIME_ABS) { - cur.time += deltaTimeToken; - } else if (deltaTimeToken == DELTA_TIME_ABS) { - cur.readFromParcel(src); - if (DEBUG) Slog.i(TAG, "READ DELTA: ABS time=" + cur.time); - return; - } else if (deltaTimeToken == DELTA_TIME_INT) { - int delta = src.readInt(); - cur.time += delta; - cur.numReadInts += 1; - if (DEBUG) Slog.i(TAG, "READ DELTA: time delta=" + delta + " new time=" + cur.time); - } else { - long delta = src.readLong(); - if (DEBUG) Slog.i(TAG, "READ DELTA: time delta=" + delta + " new time=" + cur.time); - cur.time += delta; - cur.numReadInts += 2; - } - - final int batteryLevelInt; - if ((firstToken&DELTA_BATTERY_LEVEL_FLAG) != 0) { - batteryLevelInt = src.readInt(); - readBatteryLevelInt(batteryLevelInt, cur); - cur.numReadInts += 1; - if (DEBUG) Slog.i(TAG, "READ DELTA: batteryToken=0x" - + Integer.toHexString(batteryLevelInt) - + " batteryLevel=" + cur.batteryLevel - + " batteryTemp=" + cur.batteryTemperature - + " batteryVolt=" + (int)cur.batteryVoltage); - } else { - batteryLevelInt = 0; - } - - if ((firstToken&DELTA_STATE_FLAG) != 0) { - int stateInt = src.readInt(); - cur.states = (firstToken&DELTA_STATE_MASK) | (stateInt&(~STATE_BATTERY_MASK)); - cur.batteryStatus = (byte)((stateInt>>STATE_BATTERY_STATUS_SHIFT) - & STATE_BATTERY_STATUS_MASK); - cur.batteryHealth = (byte)((stateInt>>STATE_BATTERY_HEALTH_SHIFT) - & STATE_BATTERY_HEALTH_MASK); - cur.batteryPlugType = (byte)((stateInt>>STATE_BATTERY_PLUG_SHIFT) - & STATE_BATTERY_PLUG_MASK); - switch (cur.batteryPlugType) { - case 1: - cur.batteryPlugType = BatteryManager.BATTERY_PLUGGED_AC; - break; - case 2: - cur.batteryPlugType = BatteryManager.BATTERY_PLUGGED_USB; - break; - case 3: - cur.batteryPlugType = BatteryManager.BATTERY_PLUGGED_WIRELESS; - break; - } - cur.numReadInts += 1; - if (DEBUG) Slog.i(TAG, "READ DELTA: stateToken=0x" - + Integer.toHexString(stateInt) - + " batteryStatus=" + cur.batteryStatus - + " batteryHealth=" + cur.batteryHealth - + " batteryPlugType=" + cur.batteryPlugType - + " states=0x" + Integer.toHexString(cur.states)); - } else { - cur.states = (firstToken&DELTA_STATE_MASK) | (cur.states&(~STATE_BATTERY_MASK)); - } - - if ((firstToken&DELTA_STATE2_FLAG) != 0) { - cur.states2 = src.readInt(); - if (DEBUG) Slog.i(TAG, "READ DELTA: states2=0x" - + Integer.toHexString(cur.states2)); - } - - if ((firstToken&DELTA_WAKELOCK_FLAG) != 0) { - int indexes = src.readInt(); - int wakeLockIndex = indexes&0xffff; - int wakeReasonIndex = (indexes>>16)&0xffff; - if (wakeLockIndex != 0xffff) { - cur.wakelockTag = cur.localWakelockTag; - readHistoryTag(wakeLockIndex, cur.wakelockTag); - if (DEBUG) Slog.i(TAG, "READ DELTA: wakelockTag=#" + cur.wakelockTag.poolIdx - + " " + cur.wakelockTag.uid + ":" + cur.wakelockTag.string); - } else { - cur.wakelockTag = null; - } - if (wakeReasonIndex != 0xffff) { - cur.wakeReasonTag = cur.localWakeReasonTag; - readHistoryTag(wakeReasonIndex, cur.wakeReasonTag); - if (DEBUG) Slog.i(TAG, "READ DELTA: wakeReasonTag=#" + cur.wakeReasonTag.poolIdx - + " " + cur.wakeReasonTag.uid + ":" + cur.wakeReasonTag.string); - } else { - cur.wakeReasonTag = null; - } - cur.numReadInts += 1; - } else { - cur.wakelockTag = null; - cur.wakeReasonTag = null; - } - - if ((firstToken&DELTA_EVENT_FLAG) != 0) { - cur.eventTag = cur.localEventTag; - final int codeAndIndex = src.readInt(); - cur.eventCode = (codeAndIndex&0xffff); - final int index = ((codeAndIndex>>16)&0xffff); - readHistoryTag(index, cur.eventTag); - cur.numReadInts += 1; - if (DEBUG) Slog.i(TAG, "READ DELTA: event=" + cur.eventCode + " tag=#" - + cur.eventTag.poolIdx + " " + cur.eventTag.uid + ":" - + cur.eventTag.string); - } else { - cur.eventCode = HistoryItem.EVENT_NONE; - } - - if ((batteryLevelInt&BATTERY_DELTA_LEVEL_FLAG) != 0) { - cur.stepDetails = mReadHistoryStepDetails; - cur.stepDetails.readFromParcel(src); - } else { - cur.stepDetails = null; - } - - if ((firstToken&DELTA_BATTERY_CHARGE_FLAG) != 0) { - cur.batteryChargeUah = src.readInt(); - } - cur.modemRailChargeMah = src.readDouble(); - cur.wifiRailChargeMah = src.readDouble(); - } - @Override public void commitCurrentHistoryBatchLocked() { mHistoryLastWritten.cmd = HistoryItem.CMD_NULL; @@ -3873,7 +3725,7 @@ public class BatteryStatsImpl extends BatteryStats { } private void addHistoryBufferLocked(long elapsedRealtimeMs, byte cmd, HistoryItem cur) { - if (mIteratingHistory) { + if (mBatteryStatsHistoryIterator != null) { throw new IllegalStateException("Can't do this while iterating history!"); } mHistoryBufferLastPos = mHistoryBuffer.dataPosition(); @@ -3917,44 +3769,6 @@ public class BatteryStatsImpl extends BatteryStats { void addHistoryRecordInnerLocked(long elapsedRealtimeMs, long uptimeMs, HistoryItem cur) { addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, cur); - - if (!USE_OLD_HISTORY) { - return; - } - - if (!mHaveBatteryLevel || !mRecordingHistory) { - return; - } - - // If the current time is basically the same as the last time, - // and no states have since the last recorded entry changed and - // are now resetting back to their original value, then just collapse - // into one record. - if (mHistoryEnd != null && mHistoryEnd.cmd == HistoryItem.CMD_UPDATE - && (mHistoryBaseTimeMs + elapsedRealtimeMs) < (mHistoryEnd.time + 1000) - && ((mHistoryEnd.states^cur.states)&mChangedStates&mActiveHistoryStates) == 0 - && ((mHistoryEnd.states2^cur.states2)&mChangedStates2&mActiveHistoryStates2) == 0) { - // If the current is the same as the one before, then we no - // longer need the entry. - if (mHistoryLastEnd != null && mHistoryLastEnd.cmd == HistoryItem.CMD_UPDATE - && (mHistoryBaseTimeMs + elapsedRealtimeMs) < (mHistoryEnd.time + 500) - && mHistoryLastEnd.sameNonEvent(cur)) { - mHistoryLastEnd.next = null; - mHistoryEnd.next = mHistoryCache; - mHistoryCache = mHistoryEnd; - mHistoryEnd = mHistoryLastEnd; - mHistoryLastEnd = null; - } else { - mChangedStates |= mHistoryEnd.states^(cur.states&mActiveHistoryStates); - mChangedStates2 |= mHistoryEnd.states^(cur.states2&mActiveHistoryStates2); - mHistoryEnd.setTo(mHistoryEnd.time, HistoryItem.CMD_UPDATE, cur); - } - return; - } - - mChangedStates = 0; - mChangedStates2 = 0; - addHistoryBufferLocked(elapsedRealtimeMs, HistoryItem.CMD_UPDATE, cur); } public void addHistoryEventLocked(long elapsedRealtimeMs, long uptimeMs, int code, @@ -3992,15 +3806,6 @@ public class BatteryStatsImpl extends BatteryStats { void clearHistoryLocked() { if (DEBUG_HISTORY) Slog.i(TAG, "********** CLEARING HISTORY!"); - if (USE_OLD_HISTORY) { - if (mHistory != null) { - mHistoryEnd.next = mHistoryCache; - mHistoryCache = mHistory; - mHistory = mHistoryLastEnd = mHistoryEnd = null; - } - mNumHistoryItems = 0; - } - mHistoryBaseTimeMs = 0; mLastHistoryElapsedRealtimeMs = 0; mTrackRunningHistoryElapsedRealtimeMs = 0; @@ -10731,7 +10536,7 @@ public class BatteryStatsImpl extends BatteryStats { if (systemDir == null) { mStatsFile = null; - mBatteryStatsHistory = new BatteryStatsHistory(this, mHistoryBuffer); + mBatteryStatsHistory = new BatteryStatsHistory(mHistoryBuffer); } else { mStatsFile = new AtomicFile(new File(systemDir, "batterystats.bin")); mBatteryStatsHistory = new BatteryStatsHistory(this, systemDir, mHistoryBuffer); @@ -10853,7 +10658,7 @@ public class BatteryStatsImpl extends BatteryStats { mExternalSync = null; mConstants = new Constants(mHandler); clearHistoryLocked(); - mBatteryStatsHistory = new BatteryStatsHistory(this, mHistoryBuffer); + mBatteryStatsHistory = new BatteryStatsHistory(mHistoryBuffer); readFromParcel(p); mPlatformIdleStateCallback = null; mMeasuredEnergyRetriever = null; @@ -11220,60 +11025,6 @@ public class BatteryStatsImpl extends BatteryStats { return mNextMaxDailyDeadlineMs; } - @Override - public boolean startIteratingOldHistoryLocked() { - if (DEBUG_HISTORY) Slog.i(TAG, "ITERATING: buff size=" + mHistoryBuffer.dataSize() - + " pos=" + mHistoryBuffer.dataPosition()); - if ((mHistoryIterator = mHistory) == null) { - return false; - } - mHistoryBuffer.setDataPosition(0); - mHistoryReadTmp.clear(); - mReadOverflow = false; - mIteratingHistory = true; - return true; - } - - @Override - public boolean getNextOldHistoryLocked(HistoryItem out) { - boolean end = mHistoryBuffer.dataPosition() >= mHistoryBuffer.dataSize(); - if (!end) { - readHistoryDelta(mHistoryBuffer, mHistoryReadTmp); - mReadOverflow |= mHistoryReadTmp.cmd == HistoryItem.CMD_OVERFLOW; - } - HistoryItem cur = mHistoryIterator; - if (cur == null) { - if (!mReadOverflow && !end) { - Slog.w(TAG, "Old history ends before new history!"); - } - return false; - } - out.setTo(cur); - mHistoryIterator = cur.next; - if (!mReadOverflow) { - if (end) { - Slog.w(TAG, "New history ends before old history!"); - } else if (!out.same(mHistoryReadTmp)) { - PrintWriter pw = new FastPrintWriter(new LogWriter(android.util.Log.WARN, TAG)); - pw.println("Histories differ!"); - pw.println("Old history:"); - (new HistoryPrinter()).printNextItem(pw, out, 0, false, true); - pw.println("New history:"); - (new HistoryPrinter()).printNextItem(pw, mHistoryReadTmp, 0, false, - true); - pw.flush(); - } - } - return true; - } - - @Override - public void finishIteratingOldHistoryLocked() { - mIteratingHistory = false; - mHistoryBuffer.setDataPosition(mHistoryBuffer.dataSize()); - mHistoryIterator = null; - } - public int getHistoryTotalSize() { return mConstants.MAX_HISTORY_BUFFER * mConstants.MAX_HISTORY_FILES; } @@ -11285,67 +11036,55 @@ public class BatteryStatsImpl extends BatteryStats { @Override @UnsupportedAppUsage public boolean startIteratingHistoryLocked() { - mBatteryStatsHistory.startIteratingHistory(); mReadOverflow = false; - mIteratingHistory = true; - mReadHistoryStrings = new String[mHistoryTagPool.size()]; - mReadHistoryUids = new int[mHistoryTagPool.size()]; - mReadHistoryChars = 0; - for (HashMap.Entry<HistoryTag, Integer> ent : mHistoryTagPool.entrySet()) { - final HistoryTag tag = ent.getKey(); - final int idx = ent.getValue(); - mReadHistoryStrings[idx] = tag.string; - mReadHistoryUids[idx] = tag.uid; - mReadHistoryChars += tag.string.length() + 1; - } + mBatteryStatsHistoryIterator = createBatteryStatsHistoryIterator(); return true; } + /** + * Creates an iterator for battery stats history. + */ + @VisibleForTesting + public BatteryStatsHistoryIterator createBatteryStatsHistoryIterator() { + ArrayList<HistoryTag> tags = new ArrayList<>(mHistoryTagPool.size()); + for (Map.Entry<HistoryTag, Integer> entry: mHistoryTagPool.entrySet()) { + final HistoryTag tag = entry.getKey(); + tag.poolIdx = entry.getValue(); + tags.add(tag); + } + + return new BatteryStatsHistoryIterator(mBatteryStatsHistory, tags); + } + @Override public int getHistoryStringPoolSize() { - return mReadHistoryStrings.length; + return mBatteryStatsHistoryIterator.getHistoryStringPoolSize(); } @Override public int getHistoryStringPoolBytes() { - // Each entry is a fixed 12 bytes: 4 for index, 4 for uid, 4 for string size - // Each string character is 2 bytes. - return (mReadHistoryStrings.length * 12) + (mReadHistoryChars * 2); + return mBatteryStatsHistoryIterator.getHistoryStringPoolBytes(); } @Override public String getHistoryTagPoolString(int index) { - return mReadHistoryStrings[index]; + return mBatteryStatsHistoryIterator.getHistoryTagPoolString(index); } @Override public int getHistoryTagPoolUid(int index) { - return mReadHistoryUids[index]; + return mBatteryStatsHistoryIterator.getHistoryTagPoolUid(index); } @Override @UnsupportedAppUsage public boolean getNextHistoryLocked(HistoryItem out) { - Parcel p = mBatteryStatsHistory.getNextParcel(out); - if (p == null) { - return false; - } - final long lastRealtimeMs = out.time; - final long lastWalltimeMs = out.currentTime; - readHistoryDelta(p, out); - if (out.cmd != HistoryItem.CMD_CURRENT_TIME - && out.cmd != HistoryItem.CMD_RESET && lastWalltimeMs != 0) { - out.currentTime = lastWalltimeMs + (out.time - lastRealtimeMs); - } - return true; + return mBatteryStatsHistoryIterator.next(out); } @Override public void finishIteratingHistoryLocked() { - mBatteryStatsHistory.finishIteratingHistory(); - mIteratingHistory = false; - mReadHistoryStrings = null; - mReadHistoryUids = null; + mBatteryStatsHistoryIterator = null; } @Override @@ -14635,7 +14374,7 @@ public class BatteryStatsImpl extends BatteryStats { Parcel p = Parcel.obtain(); final long start = SystemClock.uptimeMillis(); - writeHistoryBuffer(p, true, true); + writeHistoryBuffer(p, true); if (DEBUG) { Slog.d(TAG, "writeHistoryBuffer duration ms:" + (SystemClock.uptimeMillis() - start) + " bytes:" + p.dataSize()); @@ -14729,7 +14468,7 @@ public class BatteryStatsImpl extends BatteryStats { if (raw.length > 0) { history.unmarshall(raw, 0, raw.length); history.setDataPosition(0); - readHistoryBuffer(history, true); + readHistoryBuffer(history); } if (DEBUG) { Slog.d(TAG, "readLocked history file::" @@ -14753,10 +14492,6 @@ public class BatteryStatsImpl extends BatteryStats { mRecordingHistory = true; final long elapsedRealtimeMs = mClocks.elapsedRealtime(); final long uptimeMs = mClocks.uptimeMillis(); - if (USE_OLD_HISTORY) { - addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs, - HistoryItem.CMD_START, mHistoryCur); - } addHistoryBufferLocked(elapsedRealtimeMs, HistoryItem.CMD_START, mHistoryCur); startRecordingHistory(elapsedRealtimeMs, uptimeMs, false); } @@ -14768,7 +14503,7 @@ public class BatteryStatsImpl extends BatteryStats { return 0; } - void readHistoryBuffer(Parcel in, boolean andOldHistory) throws ParcelFormatException { + void readHistoryBuffer(Parcel in) throws ParcelFormatException { final int version = in.readInt(); if (version != VERSION) { Slog.w("BatteryStats", "readHistoryBuffer: version got " + version @@ -14796,10 +14531,6 @@ public class BatteryStatsImpl extends BatteryStats { in.setDataPosition(curPos + bufSize); } - if (andOldHistory) { - readOldHistory(in); - } - if (DEBUG_HISTORY) { StringBuilder sb = new StringBuilder(128); sb.append("****************** OLD mHistoryBaseTimeMs: "); @@ -14828,18 +14559,7 @@ public class BatteryStatsImpl extends BatteryStats { } } - void readOldHistory(Parcel in) { - if (!USE_OLD_HISTORY) { - return; - } - mHistory = mHistoryEnd = mHistoryCache = null; - while (in.dataAvail() > 0) { - HistoryItem rec = new HistoryItem(in); - addHistoryRecordLocked(rec); - } - } - - void writeHistoryBuffer(Parcel out, boolean inclData, boolean andOldHistory) { + void writeHistoryBuffer(Parcel out, boolean inclData) { if (DEBUG_HISTORY) { StringBuilder sb = new StringBuilder(128); sb.append("****************** WRITING mHistoryBaseTimeMs: "); @@ -14860,22 +14580,6 @@ public class BatteryStatsImpl extends BatteryStats { if (DEBUG_HISTORY) Slog.i(TAG, "***************** WRITING HISTORY: " + mHistoryBuffer.dataSize() + " bytes at " + out.dataPosition()); out.appendFrom(mHistoryBuffer, 0, mHistoryBuffer.dataSize()); - - if (andOldHistory) { - writeOldHistory(out); - } - } - - void writeOldHistory(Parcel out) { - if (!USE_OLD_HISTORY) { - return; - } - HistoryItem rec = mHistory; - while (rec != null) { - if (rec.time >= 0) rec.writeToParcel(out, 0); - rec = rec.next; - } - out.writeLong(-1); } public void readSummaryFromParcel(Parcel in) throws ParcelFormatException { @@ -14888,7 +14592,7 @@ public class BatteryStatsImpl extends BatteryStats { boolean inclHistory = in.readBoolean(); if (inclHistory) { - readHistoryBuffer(in, true); + readHistoryBuffer(in); mBatteryStatsHistory.readFromParcel(in); } @@ -15407,7 +15111,7 @@ public class BatteryStatsImpl extends BatteryStats { out.writeBoolean(inclHistory); if (inclHistory) { - writeHistoryBuffer(out, true, true); + writeHistoryBuffer(out, true); mBatteryStatsHistory.writeToParcel(out); } @@ -15920,7 +15624,7 @@ public class BatteryStatsImpl extends BatteryStats { throw new ParcelFormatException("Bad magic number: #" + Integer.toHexString(magic)); } - readHistoryBuffer(in, false); + readHistoryBuffer(in); mBatteryStatsHistory.readFromParcel(in); mStartCount = in.readInt(); @@ -16159,7 +15863,7 @@ public class BatteryStatsImpl extends BatteryStats { out.writeInt(MAGIC); - writeHistoryBuffer(out, true, false); + writeHistoryBuffer(out, true); mBatteryStatsHistory.writeToParcel(out); out.writeInt(mStartCount); diff --git a/core/java/com/android/internal/os/BatteryUsageStatsProvider.java b/core/java/com/android/internal/os/BatteryUsageStatsProvider.java index 0163acc295fb..15b584d1fd06 100644 --- a/core/java/com/android/internal/os/BatteryUsageStatsProvider.java +++ b/core/java/com/android/internal/os/BatteryUsageStatsProvider.java @@ -30,6 +30,7 @@ import com.android.internal.annotations.VisibleForTesting; import java.util.ArrayList; import java.util.List; +import java.util.Map; /** * Uses accumulated battery stats data and PowerCalculators to produce power @@ -152,6 +153,20 @@ public class BatteryUsageStatsProvider { query); } + if ((query.getFlags() + & BatteryUsageStatsQuery.FLAG_BATTERY_USAGE_STATS_INCLUDE_HISTORY) != 0) { + ArrayList<BatteryStats.HistoryTag> tags = new ArrayList<>( + mStats.mHistoryTagPool.size()); + for (Map.Entry<BatteryStats.HistoryTag, Integer> entry : + mStats.mHistoryTagPool.entrySet()) { + final BatteryStats.HistoryTag tag = entry.getKey(); + tag.poolIdx = entry.getValue(); + tags.add(tag); + } + + batteryUsageStatsBuilder.setBatteryHistory(mStats.mHistoryBuffer, tags); + } + return batteryUsageStatsBuilder.build(); } diff --git a/core/java/com/android/internal/os/KernelCpuUidTimeReader.java b/core/java/com/android/internal/os/KernelCpuUidTimeReader.java index 4299f0936dae..64c68ce0c83b 100644 --- a/core/java/com/android/internal/os/KernelCpuUidTimeReader.java +++ b/core/java/com/android/internal/os/KernelCpuUidTimeReader.java @@ -152,6 +152,10 @@ public abstract class KernelCpuUidTimeReader<T> { */ public void removeUid(int uid) { mLastTimes.delete(uid); + + if (mBpfTimesAvailable) { + mBpfReader.removeUidsInRange(uid, uid); + } } /** diff --git a/core/java/com/android/internal/os/TEST_MAPPING b/core/java/com/android/internal/os/TEST_MAPPING index 9698f190a419..791e9ad5ef9d 100644 --- a/core/java/com/android/internal/os/TEST_MAPPING +++ b/core/java/com/android/internal/os/TEST_MAPPING @@ -1,6 +1,23 @@ { "presubmit": [ { + "file_patterns": ["Battery[^/]*\\.java"], + "name": "FrameworksCoreTests", + "options": [ + { "include-filter": "com.android.internal.os.BatteryStatsTests" }, + { "exclude-annotation": "com.android.internal.os.SkipPresubmit" } + ] + }, + { + "file_patterns": ["Battery[^/]*\\.java"], + "name": "FrameworksServicesTests", + "options": [ + { "include-filter": "com.android.server.am.BatteryStatsServiceTest" }, + { "include-filter": "com.android.server.am.MeasuredEnergySnapshotTest" }, + { "include-filter": "com.android.server.am.BatteryExternalStatsWorkerTest" } + ] + }, + { "name": "FrameworksCoreTests", "options": [ { diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java index b99c953fa4e8..6b1d408bee9a 100644 --- a/core/java/com/android/internal/os/Zygote.java +++ b/core/java/com/android/internal/os/Zygote.java @@ -18,8 +18,8 @@ package com.android.internal.os; import static android.system.OsConstants.O_CLOEXEC; -import static com.android.internal.os.ZygoteConnectionConstants.MAX_ZYGOTE_ARGC; - +import android.annotation.NonNull; +import android.annotation.Nullable; import android.content.pm.ApplicationInfo; import android.net.Credentials; import android.net.LocalServerSocket; @@ -36,17 +36,16 @@ import android.util.Log; import com.android.internal.net.NetworkUtilsInternal; +import dalvik.annotation.optimization.CriticalNative; import dalvik.annotation.optimization.FastNative; import dalvik.system.ZygoteHooks; import libcore.io.IoUtils; -import java.io.BufferedReader; import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.FileDescriptor; import java.io.IOException; -import java.io.InputStreamReader; /** @hide */ public final class Zygote { @@ -238,6 +237,8 @@ public final class Zygote { */ public static final String CHILD_ZYGOTE_UID_RANGE_END = "--uid-range-end="; + private static final String TAG = "Zygote"; + /** Prefix prepended to socket names created by init */ private static final String ANDROID_SOCKET_PREFIX = "ANDROID_SOCKET_"; @@ -408,6 +409,10 @@ public final class Zygote { // Note that this event ends at the end of handleChildProc. Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "PostFork"); + if (gids != null && gids.length > 0) { + NetworkUtilsInternal.setAllowNetworkingForProcess(containsInetGid(gids)); + } + // Set the Java Language thread priority to the default value for new apps. Thread.currentThread().setPriority(Thread.NORM_PRIORITY); @@ -580,114 +585,163 @@ public final class Zygote { private static native int nativeGetUsapPoolEventFD(); /** - * Fork a new unspecialized app process from the zygote + * Fork a new unspecialized app process from the zygote. Adds the Usap to the native + * Usap table. * * @param usapPoolSocket The server socket the USAP will call accept on - * @param sessionSocketRawFDs Anonymous session sockets that are currently open - * @param isPriorityFork Value controlling the process priority level until accept is called - * @return In the Zygote process this function will always return null; in unspecialized app - * processes this function will return a Runnable object representing the new - * application that is passed up from usapMain. + * @param sessionSocketRawFDs Anonymous session sockets that are currently open. + * These are closed in the child. + * @param isPriorityFork Raise the initial process priority level because this is on the + * critical path for application startup. + * @return In the child process, this returns a Runnable that waits for specialization + * info to start an app process. In the sygote/parent process this returns null. */ - static Runnable forkUsap(LocalServerSocket usapPoolSocket, - int[] sessionSocketRawFDs, - boolean isPriorityFork) { - FileDescriptor[] pipeFDs; + static @Nullable Runnable forkUsap(LocalServerSocket usapPoolSocket, + int[] sessionSocketRawFDs, + boolean isPriorityFork) { + FileDescriptor readFD; + FileDescriptor writeFD; try { - pipeFDs = Os.pipe2(O_CLOEXEC); + FileDescriptor[] pipeFDs = Os.pipe2(O_CLOEXEC); + readFD = pipeFDs[0]; + writeFD = pipeFDs[1]; } catch (ErrnoException errnoEx) { throw new IllegalStateException("Unable to create USAP pipe.", errnoEx); } - int pid = - nativeForkUsap(pipeFDs[0].getInt$(), pipeFDs[1].getInt$(), - sessionSocketRawFDs, isPriorityFork); - + int pid = nativeForkApp(readFD.getInt$(), writeFD.getInt$(), + sessionSocketRawFDs, /*argsKnown=*/ false, isPriorityFork); if (pid == 0) { - IoUtils.closeQuietly(pipeFDs[0]); - return usapMain(usapPoolSocket, pipeFDs[1]); + IoUtils.closeQuietly(readFD); + return childMain(null, usapPoolSocket, writeFD); + } else if (pid == -1) { + // Fork failed. + return null; } else { - // The read-end of the pipe will be closed by the native code. - // See removeUsapTableEntry(); - IoUtils.closeQuietly(pipeFDs[1]); + // readFD will be closed by the native code. See removeUsapTableEntry(); + IoUtils.closeQuietly(writeFD); + nativeAddUsapTableEntry(pid, readFD.getInt$()); return null; } } - private static native int nativeForkUsap(int readPipeFD, - int writePipeFD, - int[] sessionSocketRawFDs, - boolean isPriorityFork); + private static native int nativeForkApp(int readPipeFD, + int writePipeFD, + int[] sessionSocketRawFDs, + boolean argsKnown, + boolean isPriorityFork); + + /** + * Add an entry for a new Usap to the table maintained in native code. + */ + @CriticalNative + private static native void nativeAddUsapTableEntry(int pid, int readPipeFD); + + /** + * Fork a new app process from the zygote. argBuffer contains a fork command that + * request neither a child zygote, nor a wrapped process. Continue to accept connections + * on the specified socket, use those to refill argBuffer, and continue to process + * sufficiently simple fork requests. We presume that the only open file descriptors + * requiring special treatment are the session socket embedded in argBuffer, and + * zygoteSocket. + * @param argBuffer containing initial command and the connected socket from which to + * read more + * @param zygoteSocket socket from which to obtain new connections when current argBuffer + * one is disconnected + * @param expectedUId Uid of peer for initial requests. Subsequent requests from a different + * peer will cause us to return rather than perform the requested fork. + * @param minUid Minimum Uid enforced for all but first fork request. The caller checks + * the Uid policy for the initial request. + * @param firstNiceName name of first created process. Used for error reporting only. + * @return A Runnable in each child process, null in the parent. + * If this returns in then argBuffer still contains a command needing to be executed. + */ + static @Nullable Runnable forkSimpleApps(@NonNull ZygoteCommandBuffer argBuffer, + @NonNull FileDescriptor zygoteSocket, + int expectedUid, + int minUid, + @Nullable String firstNiceName) { + boolean in_child = + argBuffer.forkRepeatedly(zygoteSocket, expectedUid, minUid, firstNiceName); + if (in_child) { + return childMain(argBuffer, /*usapPoolSocket=*/null, /*writePipe=*/null); + } else { + return null; + } + } /** - * This function is used by unspecialized app processes to wait for specialization requests from - * the system server. + * Specialize the current process into one described by argBuffer or the command read from + * usapPoolSocket. Exactly one of those must be null. If we are given an argBuffer, we close + * it. Used both for a specializing a USAP process, and for process creation without USAPs. + * In both cases, we specialize the process after first returning to Java code. * * @param writePipe The write end of the reporting pipe used to communicate with the poll loop * of the ZygoteServer. * @return A runnable oject representing the new application. */ - private static Runnable usapMain(LocalServerSocket usapPoolSocket, - FileDescriptor writePipe) { + private static Runnable childMain(@Nullable ZygoteCommandBuffer argBuffer, + @Nullable LocalServerSocket usapPoolSocket, + FileDescriptor writePipe) { final int pid = Process.myPid(); - Process.setArgV0(Process.is64Bit() ? "usap64" : "usap32"); - LocalSocket sessionSocket = null; DataOutputStream usapOutputStream = null; - Credentials peerCredentials = null; ZygoteArguments args = null; - // Change the priority to max before calling accept so we can respond to new specialization - // requests as quickly as possible. This will be reverted to the default priority in the - // native specialization code. - boostUsapPriority(); - - while (true) { - try { - sessionSocket = usapPoolSocket.accept(); - - // Block SIGTERM so we won't be killed if the Zygote flushes the USAP pool. - blockSigTerm(); - - BufferedReader usapReader = - new BufferedReader(new InputStreamReader(sessionSocket.getInputStream())); - usapOutputStream = - new DataOutputStream(sessionSocket.getOutputStream()); + // Block SIGTERM so we won't be killed if the Zygote flushes the USAP pool. + blockSigTerm(); - peerCredentials = sessionSocket.getPeerCredentials(); + LocalSocket sessionSocket = null; + if (argBuffer == null) { + // Read arguments from usapPoolSocket instead. - String[] argStrings = readArgumentList(usapReader); + Process.setArgV0(Process.is64Bit() ? "usap64" : "usap32"); - if (argStrings != null) { - args = new ZygoteArguments(argStrings); + // Change the priority to max before calling accept so we can respond to new + // specialization requests as quickly as possible. This will be reverted to the + // default priority in the native specialization code. + boostUsapPriority(); + while (true) { + ZygoteCommandBuffer tmpArgBuffer = null; + try { + sessionSocket = usapPoolSocket.accept(); + + usapOutputStream = + new DataOutputStream(sessionSocket.getOutputStream()); + Credentials peerCredentials = sessionSocket.getPeerCredentials(); + tmpArgBuffer = new ZygoteCommandBuffer(sessionSocket); + args = ZygoteArguments.getInstance(argBuffer); + applyUidSecurityPolicy(args, peerCredentials); // TODO (chriswailes): Should this only be run for debug builds? validateUsapCommand(args); break; - } else { - Log.e("USAP", "Truncated command received."); - IoUtils.closeQuietly(sessionSocket); - - // Re-enable SIGTERM so the USAP can be flushed from the pool if necessary. - unblockSigTerm(); + } catch (Exception ex) { + Log.e("USAP", ex.getMessage()); } - } catch (Exception ex) { - Log.e("USAP", ex.getMessage()); - IoUtils.closeQuietly(sessionSocket); - // Re-enable SIGTERM so the USAP can be flushed from the pool if necessary. unblockSigTerm(); + IoUtils.closeQuietly(sessionSocket); + IoUtils.closeQuietly(tmpArgBuffer); + blockSigTerm(); } + } else { + try { + args = ZygoteArguments.getInstance(argBuffer); + } catch (Exception ex) { + Log.e("AppStartup", ex.getMessage()); + throw new AssertionError("Failed to parse application start command", ex); + } + // peerCredentials were checked in parent. + } + if (args == null) { + throw new AssertionError("Empty command line"); } - try { - // SIGTERM is blocked on loop exit. This prevents a USAP that is specializing from - // being killed during a pool flush. - - setAppProcessName(args, "USAP"); + // SIGTERM is blocked here. This prevents a USAP that is specializing from being + // killed during a pool flush. - applyUidSecurityPolicy(args, peerCredentials); applyDebuggerSystemProperty(args); int[][] rlimits = null; @@ -696,53 +750,57 @@ public final class Zygote { rlimits = args.mRLimits.toArray(INT_ARRAY_2D); } - // This must happen before the SELinux policy for this process is - // changed when specializing. - try { - // Used by ZygoteProcess.zygoteSendArgsAndGetResult to fill in a - // Process.ProcessStartResult object. - usapOutputStream.writeInt(pid); - } catch (IOException ioEx) { - Log.e("USAP", "Failed to write response to session socket: " - + ioEx.getMessage()); - throw new RuntimeException(ioEx); - } finally { - IoUtils.closeQuietly(sessionSocket); - + if (argBuffer == null) { + // This must happen before the SELinux policy for this process is + // changed when specializing. try { - // This socket is closed using Os.close due to an issue with the implementation - // of LocalSocketImp.close(). Because the raw FD is created by init and then - // loaded from an environment variable (as opposed to being created by the - // LocalSocketImpl itself) the current implementation will not actually close - // the underlying FD. - // - // See b/130309968 for discussion of this issue. - Os.close(usapPoolSocket.getFileDescriptor()); - } catch (ErrnoException ex) { - Log.e("USAP", "Failed to close USAP pool socket"); - throw new RuntimeException(ex); + // Used by ZygoteProcess.zygoteSendArgsAndGetResult to fill in a + // Process.ProcessStartResult object. + usapOutputStream.writeInt(pid); + } catch (IOException ioEx) { + Log.e("USAP", "Failed to write response to session socket: " + + ioEx.getMessage()); + throw new RuntimeException(ioEx); + } finally { + try { + // Since the raw FD is created by init and then loaded from an environment + // variable (as opposed to being created by the LocalSocketImpl itself), + // the LocalSocket/LocalSocketImpl does not own the Os-level socket. See + // the spec for LocalSocket.createConnectedLocalSocket(FileDescriptor fd). + // Thus closing the LocalSocket does not suffice. See b/130309968 for more + // discussion. + FileDescriptor fd = usapPoolSocket.getFileDescriptor(); + usapPoolSocket.close(); + Os.close(fd); + } catch (ErrnoException | IOException ex) { + Log.e("USAP", "Failed to close USAP pool socket"); + throw new RuntimeException(ex); + } } } - try { - ByteArrayOutputStream buffer = - new ByteArrayOutputStream(Zygote.USAP_MANAGEMENT_MESSAGE_BYTES); - DataOutputStream outputStream = new DataOutputStream(buffer); - - // This is written as a long so that the USAP reporting pipe and USAP pool event FD - // handlers in ZygoteServer.runSelectLoop can be unified. These two cases should - // both send/receive 8 bytes. - outputStream.writeLong(pid); - outputStream.flush(); - - Os.write(writePipe, buffer.toByteArray(), 0, buffer.size()); - } catch (Exception ex) { - Log.e("USAP", - String.format("Failed to write PID (%d) to pipe (%d): %s", - pid, writePipe.getInt$(), ex.getMessage())); - throw new RuntimeException(ex); - } finally { - IoUtils.closeQuietly(writePipe); + if (writePipe != null) { + try { + ByteArrayOutputStream buffer = + new ByteArrayOutputStream(Zygote.USAP_MANAGEMENT_MESSAGE_BYTES); + DataOutputStream outputStream = new DataOutputStream(buffer); + + // This is written as a long so that the USAP reporting pipe and USAP pool + // event FD handlers in ZygoteServer.runSelectLoop can be unified. These two + // cases should both send/receive 8 bytes. + // TODO: Needs tweaking to handle the non-Usap invoke-with case, which expects + // a different format. + outputStream.writeLong(pid); + outputStream.flush(); + Os.write(writePipe, buffer.toByteArray(), 0, buffer.size()); + } catch (Exception ex) { + Log.e("USAP", + String.format("Failed to write PID (%d) to pipe (%d): %s", + pid, writePipe.getInt$(), ex.getMessage())); + throw new RuntimeException(ex); + } finally { + IoUtils.closeQuietly(writePipe); + } } specializeAppProcess(args.mUid, args.mGid, args.mGids, @@ -849,13 +907,29 @@ public final class Zygote { return nativeRemoveUsapTableEntry(usapPID); } + @CriticalNative private static native boolean nativeRemoveUsapTableEntry(int usapPID); /** - * uid 1000 (Process.SYSTEM_UID) may specify any uid > 1000 in normal + * Return the minimum child uid that the given peer is allowed to create. + * uid 1000 (Process.SYSTEM_UID) may specify any uid ≥ 1000 in normal * operation. It may also specify any gid and setgroups() list it chooses. * In factory test mode, it may specify any UID. - * + */ + static int minChildUid(Credentials peer) { + if (peer.getUid() == Process.SYSTEM_UID + && FactoryTest.getMode() == FactoryTest.FACTORY_TEST_OFF) { + /* In normal operation, SYSTEM_UID can only specify a restricted + * set of UIDs. In factory test mode, SYSTEM_UID may specify any uid. + */ + return Process.SYSTEM_UID; + } else { + return 0; + } + } + + /* + * Adjust uid and gid arguments, ensuring that the security policy is satisfied. * @param args non-null; zygote spawner arguments * @param peer non-null; peer credentials * @throws ZygoteSecurityException Indicates a security issue when applying the UID based @@ -864,17 +938,10 @@ public final class Zygote { static void applyUidSecurityPolicy(ZygoteArguments args, Credentials peer) throws ZygoteSecurityException { - if (peer.getUid() == Process.SYSTEM_UID) { - /* In normal operation, SYSTEM_UID can only specify a restricted - * set of UIDs. In factory test mode, SYSTEM_UID may specify any uid. - */ - boolean uidRestricted = FactoryTest.getMode() == FactoryTest.FACTORY_TEST_OFF; - - if (uidRestricted && args.mUidSpecified && (args.mUid < Process.SYSTEM_UID)) { - throw new ZygoteSecurityException( - "System UID may not launch process with UID < " - + Process.SYSTEM_UID); - } + if (args.mUidSpecified && (args.mUid < minChildUid(peer))) { + throw new ZygoteSecurityException( + "System UID may not launch process with UID < " + + Process.SYSTEM_UID); } // If not otherwise specified, uid and gid are inherited from peer @@ -960,45 +1027,6 @@ public final class Zygote { } /** - * Reads an argument list from the provided socket - * @return Argument list or null if EOF is reached - * @throws IOException passed straight through - */ - static String[] readArgumentList(BufferedReader socketReader) throws IOException { - int argc; - - try { - String argc_string = socketReader.readLine(); - - if (argc_string == null) { - // EOF reached. - return null; - } - argc = Integer.parseInt(argc_string); - - } catch (NumberFormatException ex) { - Log.e("Zygote", "Invalid Zygote wire format: non-int at argc"); - throw new IOException("Invalid wire format"); - } - - // See bug 1092107: large argc can be used for a DOS attack - if (argc > MAX_ZYGOTE_ARGC) { - throw new IOException("Max arg count exceeded"); - } - - String[] args = new String[argc]; - for (int arg_index = 0; arg_index < argc; arg_index++) { - args[arg_index] = socketReader.readLine(); - if (args[arg_index] == null) { - // We got an unexpected EOF. - throw new IOException("Truncated request"); - } - } - - return args; - } - - /** * Creates a managed LocalServerSocket object using a file descriptor * created by an init.rc script. The init scripts that specify the * sockets name can be found in system/core/rootdir. The socket is bound diff --git a/core/java/com/android/internal/os/ZygoteArguments.java b/core/java/com/android/internal/os/ZygoteArguments.java index 32b808ab2528..65b454d47db2 100644 --- a/core/java/com/android/internal/os/ZygoteArguments.java +++ b/core/java/com/android/internal/os/ZygoteArguments.java @@ -16,8 +16,8 @@ package com.android.internal.os; +import java.io.EOFException; import java.util.ArrayList; -import java.util.Arrays; /** * Handles argument parsing for args related to the zygote spawner. @@ -245,20 +245,34 @@ class ZygoteArguments { /** * Constructs instance and parses args * - * @param args zygote command-line args + * @param args zygote command-line args as ZygoteCommandBuffer, positioned after argument count. */ - ZygoteArguments(String[] args) throws IllegalArgumentException { - parseArgs(args); + private ZygoteArguments(ZygoteCommandBuffer args, int argCount) + throws IllegalArgumentException, EOFException { + parseArgs(args, argCount); + } + + /** + * Return a new ZygoteArguments reflecting the contents of the given ZygoteCommandBuffer. Return + * null if the ZygoteCommandBuffer was positioned at EOF. Assumes the buffer is initially + * positioned at the beginning of the command. + */ + public static ZygoteArguments getInstance(ZygoteCommandBuffer args) + throws IllegalArgumentException, EOFException { + int argCount = args.getCount(); + return argCount == 0 ? null : new ZygoteArguments(args, argCount); } /** * Parses the commandline arguments intended for the Zygote spawner (such as "--setuid=" and - * "--setgid=") and creates an array containing the remaining args. + * "--setgid=") and creates an array containing the remaining args. Return false if we were + * at EOF. * * Per security review bug #1112214, duplicate args are disallowed in critical cases to make * injection harder. */ - private void parseArgs(String[] args) throws IllegalArgumentException { + private void parseArgs(ZygoteCommandBuffer args, int argCount) + throws IllegalArgumentException, EOFException { /* * See android.os.ZygoteProcess.zygoteSendArgsAndGetResult() * Presently the wire format to the zygote process is: @@ -269,13 +283,13 @@ class ZygoteArguments { * the child or -1 on failure. */ - int curArg = 0; - + String unprocessedArg = null; + int curArg = 0; // Index of arg boolean seenRuntimeArgs = false; - boolean expectRuntimeArgs = true; - for ( /* curArg */ ; curArg < args.length; curArg++) { - String arg = args[curArg]; + + for ( /* curArg */ ; curArg < argCount; ++curArg) { + String arg = args.nextArg(); if (arg.equals("--")) { curArg++; @@ -367,7 +381,8 @@ class ZygoteArguments { "Duplicate arg specified"); } try { - mInvokeWith = args[++curArg]; + ++curArg; + mInvokeWith = args.nextArg(); } catch (IndexOutOfBoundsException ex) { throw new IllegalArgumentException( "--invoke-with requires argument"); @@ -397,12 +412,14 @@ class ZygoteArguments { } else if (arg.startsWith("--app-data-dir=")) { mAppDataDir = getAssignmentValue(arg); } else if (arg.equals("--preload-app")) { - mPreloadApp = args[++curArg]; + ++curArg; + mPreloadApp = args.nextArg(); } else if (arg.equals("--preload-package")) { - mPreloadPackage = args[++curArg]; - mPreloadPackageLibs = args[++curArg]; - mPreloadPackageLibFileName = args[++curArg]; - mPreloadPackageCacheKey = args[++curArg]; + curArg += 4; + mPreloadPackage = args.nextArg(); + mPreloadPackageLibs = args.nextArg(); + mPreloadPackageLibFileName = args.nextArg(); + mPreloadPackageCacheKey = args.nextArg(); } else if (arg.equals("--preload-default")) { mPreloadDefault = true; expectRuntimeArgs = false; @@ -411,8 +428,11 @@ class ZygoteArguments { } else if (arg.equals("--set-api-denylist-exemptions")) { // consume all remaining args; this is a stand-alone command, never included // with the regular fork command. - mApiDenylistExemptions = Arrays.copyOfRange(args, curArg + 1, args.length); - curArg = args.length; + mApiDenylistExemptions = new String[argCount - curArg - 1]; + ++curArg; + for (int i = 0; curArg < argCount; ++curArg, ++i) { + mApiDenylistExemptions[i] = args.nextArg(); + } expectRuntimeArgs = false; } else if (arg.startsWith("--hidden-api-log-sampling-rate=")) { String rateStr = getAssignmentValue(arg); @@ -462,35 +482,46 @@ class ZygoteArguments { } else if (arg.equals(Zygote.BIND_MOUNT_APP_DATA_DIRS)) { mBindMountAppDataDirs = true; } else { + unprocessedArg = arg; break; } } + // curArg is the index of the first unprocessed argument. That argument is either referenced + // by unprocessedArg or not read yet. if (mBootCompleted) { - if (args.length - curArg > 0) { + if (argCount > curArg) { throw new IllegalArgumentException("Unexpected arguments after --boot-completed"); } } else if (mAbiListQuery || mPidQuery) { - if (args.length - curArg > 0) { + if (argCount > curArg) { throw new IllegalArgumentException("Unexpected arguments after --query-abi-list."); } } else if (mPreloadPackage != null) { - if (args.length - curArg > 0) { + if (argCount > curArg) { throw new IllegalArgumentException( "Unexpected arguments after --preload-package."); } } else if (mPreloadApp != null) { - if (args.length - curArg > 0) { + if (argCount > curArg) { throw new IllegalArgumentException( "Unexpected arguments after --preload-app."); } } else if (expectRuntimeArgs) { if (!seenRuntimeArgs) { - throw new IllegalArgumentException("Unexpected argument : " + args[curArg]); + throw new IllegalArgumentException("Unexpected argument : " + + (unprocessedArg == null ? args.nextArg() : unprocessedArg)); } - mRemainingArgs = new String[args.length - curArg]; - System.arraycopy(args, curArg, mRemainingArgs, 0, mRemainingArgs.length); + mRemainingArgs = new String[argCount - curArg]; + int i = 0; + if (unprocessedArg != null) { + mRemainingArgs[0] = unprocessedArg; + ++i; + } + for (; i < argCount - curArg; ++i) { + mRemainingArgs[i] = args.nextArg(); + } } if (mStartChildZygote) { diff --git a/core/java/com/android/internal/os/ZygoteCommandBuffer.java b/core/java/com/android/internal/os/ZygoteCommandBuffer.java new file mode 100644 index 000000000000..b61ae7acfacd --- /dev/null +++ b/core/java/com/android/internal/os/ZygoteCommandBuffer.java @@ -0,0 +1,187 @@ +/* + * 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.internal.os; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.net.LocalSocket; + +import java.io.FileDescriptor; +import java.lang.ref.Reference; // For reachabilityFence. + +/** + * A native-accessible buffer for Zygote commands. Designed to support repeated forking + * of applications without intervening memory allocation, thus keeping zygote memory + * as stable as possible. + * A ZygoteCommandBuffer may have an associated socket from which it can be refilled. + * Otherwise the contents are explicitly set by getInstance(). + * + * NOT THREAD-SAFE. No methods may be called concurrently from multiple threads. + * + * Only one ZygoteCommandBuffer can exist at a time. + * Must be explicitly closed before being dropped. + * @hide + */ +class ZygoteCommandBuffer implements AutoCloseable { + private long mNativeBuffer; // Not final so that we can clear it in close(). + + /** + * The command socket. + * + * mSocket is retained in the child process in "peer wait" mode, so + * that it closes when the child process terminates. In other cases, + * it is closed in the peer. + */ + private final LocalSocket mSocket; + private final int mNativeSocket; + + /** + * Constructs instance from file descriptor from which the command will be read. + * Only a single instance may be live in a given process. The native code checks. + * + * @param fd file descriptor to read from. The setCommand() method may be used if and only if + * fd is null. + */ + ZygoteCommandBuffer(@Nullable LocalSocket socket) { + mSocket = socket; + if (socket == null) { + mNativeSocket = -1; + } else { + mNativeSocket = mSocket.getFileDescriptor().getInt$(); + } + mNativeBuffer = getNativeBuffer(mNativeSocket); + } + + /** + * Constructs an instance with explicitly supplied arguments and an invalid + * file descriptor. Can only be used for a single command. + */ + ZygoteCommandBuffer(@NonNull String[] args) { + this((LocalSocket) null); + setCommand(args); + } + + + private static native long getNativeBuffer(int fd); + + /** + * Deallocate native resources associated with the one and only command buffer, and prevent + * reuse. Subsequent calls to getInstance() will yield a new buffer. + * We do not close the associated socket, if any. + */ + @Override + public void close() { + freeNativeBuffer(mNativeBuffer); + mNativeBuffer = 0; + } + + private static native void freeNativeBuffer(long /* NativeCommandBuffer* */ nbuffer); + + /** + * Read at least the first line of the next command into the buffer, return the argument count + * from that line. Assumes we are initially positioned at the beginning of the first line of + * the command. Leave the buffer positioned at the beginning of the second command line, i.e. + * the first argument. If the buffer has no associated file descriptor, we just reposition to + * the beginning of the buffer, and reread existing contents. Returns zero if we started out + * at EOF. + */ + int getCount() { + try { + return nativeGetCount(mNativeBuffer); + } finally { + // Make sure the mNativeSocket doesn't get closed due to early finalization. + Reference.reachabilityFence(mSocket); + } + } + + private static native int nativeGetCount(long /* NativeCommandBuffer* */ nbuffer); + + + /* + * Set the buffer to contain the supplied sequence of arguments. + */ + private void setCommand(String[] command) { + int nArgs = command.length; + insert(mNativeBuffer, Integer.toString(nArgs)); + for (String s: command) { + insert(mNativeBuffer, s); + } + // Native code checks there is no socket; hence no reachabilityFence. + } + + private static native void insert(long /* NativeCommandBuffer* */ nbuffer, String s); + + /** + * Retrieve the next argument/line from the buffer, filling the buffer as necessary. + */ + String nextArg() { + try { + return nativeNextArg(mNativeBuffer); + } finally { + Reference.reachabilityFence(mSocket); + } + } + + private static native String nativeNextArg(long /* NativeCommandBuffer* */ nbuffer); + + void readFullyAndReset() { + try { + nativeReadFullyAndReset(mNativeBuffer); + } finally { + Reference.reachabilityFence(mSocket); + } + } + + private static native void nativeReadFullyAndReset(long /* NativeCommandBuffer* */ nbuffer); + + /** + * Fork a child as specified by the current command in the buffer, and repeat this process + * after refilling the buffer, so long as the buffer clearly contains another fork command. + * + * @param zygoteSocket socket from which to obtain new connections when current one is + * disconnected + * @param expectedUid Peer UID for current connection. We refuse to deal with requests from + * a different UID. + * @param minUid the smallest uid that may be request for the child process. + * @param firstNiceName The name for the initial process to be forked. Used only for error + * reporting. + * + * @return true in the child, false in the parent. In the parent case, the buffer is positioned + * at the beginning of a command that still needs to be processed. + */ + boolean forkRepeatedly(FileDescriptor zygoteSocket, int expectedUid, int minUid, + String firstNiceName) { + try { + return nativeForkRepeatedly(mNativeBuffer, zygoteSocket.getInt$(), + expectedUid, minUid, firstNiceName); + } finally { + Reference.reachabilityFence(mSocket); + Reference.reachabilityFence(zygoteSocket); + } + } + + /* + * Repeatedly fork children as above. It commonly does not return in the parent, but it may. + * @return true in the chaild, false in the parent if we encounter a command we couldn't handle. + */ + private static native boolean nativeForkRepeatedly(long /* NativeCommandBuffer* */ nbuffer, + int zygoteSocketRawFd, + int expectedUid, + int minUid, + String firstNiceName); + +} diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java index 5a576ebbc442..37c75907061c 100644 --- a/core/java/com/android/internal/os/ZygoteConnection.java +++ b/core/java/com/android/internal/os/ZygoteConnection.java @@ -36,16 +36,15 @@ import android.system.StructPollfd; import android.util.Log; import dalvik.system.VMRuntime; +import dalvik.system.ZygoteHooks; import libcore.io.IoUtils; -import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.FileDescriptor; import java.io.IOException; -import java.io.InputStreamReader; import java.nio.charset.StandardCharsets; import java.util.Base64; import java.util.concurrent.TimeUnit; @@ -67,7 +66,6 @@ class ZygoteConnection { private final LocalSocket mSocket; @UnsupportedAppUsage private final DataOutputStream mSocketOutStream; - private final BufferedReader mSocketReader; @UnsupportedAppUsage private final Credentials peer; private final String abiList; @@ -85,9 +83,6 @@ class ZygoteConnection { this.abiList = abiList; mSocketOutStream = new DataOutputStream(socket.getOutputStream()); - mSocketReader = - new BufferedReader( - new InputStreamReader(socket.getInputStream()), Zygote.SOCKET_BUFFER_SIZE); mSocket.setSoTimeout(CONNECTION_TIMEOUT_MILLIS); @@ -111,178 +106,216 @@ class ZygoteConnection { } /** - * Reads one start command from the command socket. If successful, a child is forked and a + * Reads a command from the command socket. If a child is successfully forked, a * {@code Runnable} that calls the childs main method (or equivalent) is returned in the child * process. {@code null} is always returned in the parent process (the zygote). + * If multipleOK is set, we may keep processing additional fork commands before returning. * * If the client closes the socket, an {@code EOF} condition is set, which callers can test * for by calling {@code ZygoteConnection.isClosedByPeer}. */ - Runnable processOneCommand(ZygoteServer zygoteServer) { - String[] args; - - try { - args = Zygote.readArgumentList(mSocketReader); - } catch (IOException ex) { - throw new IllegalStateException("IOException on command socket", ex); - } - - // readArgumentList returns null only when it has reached EOF with no available - // data to read. This will only happen when the remote socket has disconnected. - if (args == null) { - isEof = true; - return null; - } - - int pid; - FileDescriptor childPipeFd = null; - FileDescriptor serverPipeFd = null; - - ZygoteArguments parsedArgs = new ZygoteArguments(args); - - if (parsedArgs.mBootCompleted) { - handleBootCompleted(); - return null; - } - - if (parsedArgs.mAbiListQuery) { - handleAbiListQuery(); - return null; - } - - if (parsedArgs.mPidQuery) { - handlePidQuery(); - return null; - } + Runnable processCommand(ZygoteServer zygoteServer, boolean multipleOK) { + ZygoteArguments parsedArgs; + + try (ZygoteCommandBuffer argBuffer = new ZygoteCommandBuffer(mSocket)) { + while (true) { + try { + parsedArgs = ZygoteArguments.getInstance(argBuffer); + // Keep argBuffer around, since we need it to fork. + } catch (IOException ex) { + throw new IllegalStateException("IOException on command socket", ex); + } + if (parsedArgs == null) { + isEof = true; + return null; + } - if (parsedArgs.mUsapPoolStatusSpecified) { - return handleUsapPoolStatusChange(zygoteServer, parsedArgs.mUsapPoolEnabled); - } + int pid; + FileDescriptor childPipeFd = null; + FileDescriptor serverPipeFd = null; - if (parsedArgs.mPreloadDefault) { - handlePreload(); - return null; - } + if (parsedArgs.mBootCompleted) { + handleBootCompleted(); + return null; + } - if (parsedArgs.mPreloadPackage != null) { - handlePreloadPackage(parsedArgs.mPreloadPackage, parsedArgs.mPreloadPackageLibs, - parsedArgs.mPreloadPackageLibFileName, parsedArgs.mPreloadPackageCacheKey); - return null; - } + if (parsedArgs.mAbiListQuery) { + handleAbiListQuery(); + return null; + } - if (canPreloadApp() && parsedArgs.mPreloadApp != null) { - byte[] rawParcelData = Base64.getDecoder().decode(parsedArgs.mPreloadApp); - Parcel appInfoParcel = Parcel.obtain(); - appInfoParcel.unmarshall(rawParcelData, 0, rawParcelData.length); - appInfoParcel.setDataPosition(0); - ApplicationInfo appInfo = ApplicationInfo.CREATOR.createFromParcel(appInfoParcel); - appInfoParcel.recycle(); - if (appInfo != null) { - handlePreloadApp(appInfo); - } else { - throw new IllegalArgumentException("Failed to deserialize --preload-app"); - } - return null; - } + if (parsedArgs.mPidQuery) { + handlePidQuery(); + return null; + } - if (parsedArgs.mApiDenylistExemptions != null) { - return handleApiDenylistExemptions(zygoteServer, parsedArgs.mApiDenylistExemptions); - } + if (parsedArgs.mUsapPoolStatusSpecified) { + // Handle this once we've released the argBuffer, to avoid opening a second one. + break; + } - if (parsedArgs.mHiddenApiAccessLogSampleRate != -1 - || parsedArgs.mHiddenApiAccessStatslogSampleRate != -1) { - return handleHiddenApiAccessLogSampleRate(zygoteServer, - parsedArgs.mHiddenApiAccessLogSampleRate, - parsedArgs.mHiddenApiAccessStatslogSampleRate); - } + if (parsedArgs.mPreloadDefault) { + handlePreload(); + return null; + } - if (parsedArgs.mPermittedCapabilities != 0 || parsedArgs.mEffectiveCapabilities != 0) { - throw new ZygoteSecurityException("Client may not specify capabilities: " - + "permitted=0x" + Long.toHexString(parsedArgs.mPermittedCapabilities) - + ", effective=0x" + Long.toHexString(parsedArgs.mEffectiveCapabilities)); - } + if (parsedArgs.mPreloadPackage != null) { + handlePreloadPackage(parsedArgs.mPreloadPackage, + parsedArgs.mPreloadPackageLibs, + parsedArgs.mPreloadPackageLibFileName, + parsedArgs.mPreloadPackageCacheKey); + return null; + } - Zygote.applyUidSecurityPolicy(parsedArgs, peer); - Zygote.applyInvokeWithSecurityPolicy(parsedArgs, peer); + if (canPreloadApp() && parsedArgs.mPreloadApp != null) { + byte[] rawParcelData = Base64.getDecoder().decode(parsedArgs.mPreloadApp); + Parcel appInfoParcel = Parcel.obtain(); + appInfoParcel.unmarshall(rawParcelData, 0, rawParcelData.length); + appInfoParcel.setDataPosition(0); + ApplicationInfo appInfo = + ApplicationInfo.CREATOR.createFromParcel(appInfoParcel); + appInfoParcel.recycle(); + if (appInfo != null) { + handlePreloadApp(appInfo); + } else { + throw new IllegalArgumentException("Failed to deserialize --preload-app"); + } + return null; + } - Zygote.applyDebuggerSystemProperty(parsedArgs); - Zygote.applyInvokeWithSystemProperty(parsedArgs); + if (parsedArgs.mApiDenylistExemptions != null) { + return handleApiDenylistExemptions(zygoteServer, + parsedArgs.mApiDenylistExemptions); + } - int[][] rlimits = null; + if (parsedArgs.mHiddenApiAccessLogSampleRate != -1 + || parsedArgs.mHiddenApiAccessStatslogSampleRate != -1) { + return handleHiddenApiAccessLogSampleRate(zygoteServer, + parsedArgs.mHiddenApiAccessLogSampleRate, + parsedArgs.mHiddenApiAccessStatslogSampleRate); + } - if (parsedArgs.mRLimits != null) { - rlimits = parsedArgs.mRLimits.toArray(Zygote.INT_ARRAY_2D); - } + if (parsedArgs.mPermittedCapabilities != 0 + || parsedArgs.mEffectiveCapabilities != 0) { + throw new ZygoteSecurityException("Client may not specify capabilities: " + + "permitted=0x" + Long.toHexString(parsedArgs.mPermittedCapabilities) + + ", effective=0x" + + Long.toHexString(parsedArgs.mEffectiveCapabilities)); + } - int[] fdsToIgnore = null; + Zygote.applyUidSecurityPolicy(parsedArgs, peer); + Zygote.applyInvokeWithSecurityPolicy(parsedArgs, peer); - if (parsedArgs.mInvokeWith != null) { - try { - FileDescriptor[] pipeFds = Os.pipe2(O_CLOEXEC); - childPipeFd = pipeFds[1]; - serverPipeFd = pipeFds[0]; - Os.fcntlInt(childPipeFd, F_SETFD, 0); - fdsToIgnore = new int[]{childPipeFd.getInt$(), serverPipeFd.getInt$()}; - } catch (ErrnoException errnoEx) { - throw new IllegalStateException("Unable to set up pipe for invoke-with", errnoEx); - } - } + Zygote.applyDebuggerSystemProperty(parsedArgs); + Zygote.applyInvokeWithSystemProperty(parsedArgs); - /* - * In order to avoid leaking descriptors to the Zygote child, - * the native code must close the two Zygote socket descriptors - * in the child process before it switches from Zygote-root to - * the UID and privileges of the application being launched. - * - * In order to avoid "bad file descriptor" errors when the - * two LocalSocket objects are closed, the Posix file - * descriptors are released via a dup2() call which closes - * the socket and substitutes an open descriptor to /dev/null. - */ + int[][] rlimits = null; - int [] fdsToClose = { -1, -1 }; + if (parsedArgs.mRLimits != null) { + rlimits = parsedArgs.mRLimits.toArray(Zygote.INT_ARRAY_2D); + } - FileDescriptor fd = mSocket.getFileDescriptor(); + int[] fdsToIgnore = null; + + if (parsedArgs.mInvokeWith != null) { + try { + FileDescriptor[] pipeFds = Os.pipe2(O_CLOEXEC); + childPipeFd = pipeFds[1]; + serverPipeFd = pipeFds[0]; + Os.fcntlInt(childPipeFd, F_SETFD, 0); + fdsToIgnore = new int[]{childPipeFd.getInt$(), serverPipeFd.getInt$()}; + } catch (ErrnoException errnoEx) { + throw new IllegalStateException("Unable to set up pipe for invoke-with", + errnoEx); + } + } - if (fd != null) { - fdsToClose[0] = fd.getInt$(); - } + /* + * In order to avoid leaking descriptors to the Zygote child, + * the native code must close the two Zygote socket descriptors + * in the child process before it switches from Zygote-root to + * the UID and privileges of the application being launched. + * + * In order to avoid "bad file descriptor" errors when the + * two LocalSocket objects are closed, the Posix file + * descriptors are released via a dup2() call which closes + * the socket and substitutes an open descriptor to /dev/null. + */ - fd = zygoteServer.getZygoteSocketFileDescriptor(); + int [] fdsToClose = { -1, -1 }; - if (fd != null) { - fdsToClose[1] = fd.getInt$(); - } + FileDescriptor fd = mSocket.getFileDescriptor(); - pid = Zygote.forkAndSpecialize(parsedArgs.mUid, parsedArgs.mGid, parsedArgs.mGids, - parsedArgs.mRuntimeFlags, rlimits, parsedArgs.mMountExternal, parsedArgs.mSeInfo, - parsedArgs.mNiceName, fdsToClose, fdsToIgnore, parsedArgs.mStartChildZygote, - parsedArgs.mInstructionSet, parsedArgs.mAppDataDir, parsedArgs.mIsTopApp, - parsedArgs.mPkgDataInfoList, parsedArgs.mWhitelistedDataInfoList, - parsedArgs.mBindMountAppDataDirs, parsedArgs.mBindMountAppStorageDirs); + if (fd != null) { + fdsToClose[0] = fd.getInt$(); + } - try { - if (pid == 0) { - // in child - zygoteServer.setForkChild(); + FileDescriptor zygoteFd = zygoteServer.getZygoteSocketFileDescriptor(); - zygoteServer.closeServerSocket(); - IoUtils.closeQuietly(serverPipeFd); - serverPipeFd = null; + if (zygoteFd != null) { + fdsToClose[1] = zygoteFd.getInt$(); + } - return handleChildProc(parsedArgs, childPipeFd, parsedArgs.mStartChildZygote); - } else { - // In the parent. A pid < 0 indicates a failure and will be handled in - // handleParentProc. - IoUtils.closeQuietly(childPipeFd); - childPipeFd = null; - handleParentProc(pid, serverPipeFd); - return null; + if (parsedArgs.mInvokeWith != null || parsedArgs.mStartChildZygote + || !multipleOK || peer.getUid() != Process.SYSTEM_UID) { + // Continue using old code for now. TODO: Handle these cases in the other path. + pid = Zygote.forkAndSpecialize(parsedArgs.mUid, parsedArgs.mGid, + parsedArgs.mGids, parsedArgs.mRuntimeFlags, rlimits, + parsedArgs.mMountExternal, parsedArgs.mSeInfo, parsedArgs.mNiceName, + fdsToClose, fdsToIgnore, parsedArgs.mStartChildZygote, + parsedArgs.mInstructionSet, parsedArgs.mAppDataDir, + parsedArgs.mIsTopApp, parsedArgs.mPkgDataInfoList, + parsedArgs.mWhitelistedDataInfoList, parsedArgs.mBindMountAppDataDirs, + parsedArgs.mBindMountAppStorageDirs); + + try { + if (pid == 0) { + // in child + zygoteServer.setForkChild(); + + zygoteServer.closeServerSocket(); + IoUtils.closeQuietly(serverPipeFd); + serverPipeFd = null; + + return handleChildProc(parsedArgs, childPipeFd, + parsedArgs.mStartChildZygote); + } else { + // In the parent. A pid < 0 indicates a failure and will be handled in + // handleParentProc. + IoUtils.closeQuietly(childPipeFd); + childPipeFd = null; + handleParentProc(pid, serverPipeFd); + return null; + } + } finally { + IoUtils.closeQuietly(childPipeFd); + IoUtils.closeQuietly(serverPipeFd); + } + } else { + ZygoteHooks.preFork(); + Runnable result = Zygote.forkSimpleApps(argBuffer, + zygoteServer.getZygoteSocketFileDescriptor(), + peer.getUid(), Zygote.minChildUid(peer), parsedArgs.mNiceName); + if (result == null) { + // parent; we finished some number of forks. Result is Boolean. + // We already did the equivalent of handleParentProc(). + ZygoteHooks.postForkCommon(); + // argBuffer contains a command not understood by forksimpleApps. + continue; + } else { + // child; result is a Runnable. + zygoteServer.setForkChild(); + Zygote.setAppProcessName(parsedArgs, TAG); // ??? Necessary? + return result; + } + } } - } finally { - IoUtils.closeQuietly(childPipeFd); - IoUtils.closeQuietly(serverPipeFd); } + if (parsedArgs.mUsapPoolStatusSpecified) { + // Now that we've released argBuffer: + return handleUsapPoolStatusChange(zygoteServer, parsedArgs.mUsapPoolEnabled); + } + throw new AssertionError("Shouldn't get here"); } private void handleAbiListQuery() { @@ -557,7 +590,7 @@ class ZygoteConnection { if (res > 0) { if ((fds[0].revents & POLLIN) != 0) { - // Only read one byte, so as not to block. + // Only read one byte, so as not to block. Really needed? int readBytes = android.system.Os.read(pipeFd, data, dataIndex, 1); if (readBytes < 0) { throw new RuntimeException("Some error"); diff --git a/core/java/com/android/internal/os/ZygoteConnectionConstants.java b/core/java/com/android/internal/os/ZygoteConnectionConstants.java index 506e39f30617..0c1cd6de1bb4 100644 --- a/core/java/com/android/internal/os/ZygoteConnectionConstants.java +++ b/core/java/com/android/internal/os/ZygoteConnectionConstants.java @@ -31,9 +31,6 @@ public class ZygoteConnectionConstants { */ public static final int CONNECTION_TIMEOUT_MILLIS = 1000; - /** max number of arguments that a connection can specify */ - public static final int MAX_ZYGOTE_ARGC = 1024; - /** * Wait time for a wrapped app to report back its pid. * diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java index f2ed50ef6a07..d5b778e9c9e1 100644 --- a/core/java/com/android/internal/os/ZygoteInit.java +++ b/core/java/com/android/internal/os/ZygoteInit.java @@ -65,6 +65,7 @@ import dalvik.system.ZygoteHooks; import libcore.io.IoUtils; import java.io.BufferedReader; +import java.io.EOFException; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; @@ -782,7 +783,13 @@ public class ZygoteInit { int pid; try { - parsedArgs = new ZygoteArguments(args); + ZygoteCommandBuffer commandBuffer = new ZygoteCommandBuffer(args); + try { + parsedArgs = ZygoteArguments.getInstance(commandBuffer); + } catch (EOFException e) { + throw new AssertionError("Unexpected argument error for forking system server", e); + } + commandBuffer.close(); Zygote.applyDebuggerSystemProperty(parsedArgs); Zygote.applyInvokeWithSystemProperty(parsedArgs); @@ -861,7 +868,7 @@ public class ZygoteInit { * into new processes are required to either set the priority to the default value or terminate * before executing any non-system code. The native side of this occurs in SpecializeCommon, * while the Java Language priority is changed in ZygoteInit.handleSystemServerProcess, - * ZygoteConnection.handleChildProc, and Zygote.usapMain. + * ZygoteConnection.handleChildProc, and Zygote.childMain. * * @param argv Command line arguments used to specify the Zygote's configuration. */ diff --git a/core/java/com/android/internal/os/ZygoteServer.java b/core/java/com/android/internal/os/ZygoteServer.java index 585ddf6ddf98..f71b31493035 100644 --- a/core/java/com/android/internal/os/ZygoteServer.java +++ b/core/java/com/android/internal/os/ZygoteServer.java @@ -337,7 +337,7 @@ class ZygoteServer { * @param sessionSocketRawFDs Anonymous session sockets that are currently open * @return In the Zygote process this function will always return null; in unspecialized app * processes this function will return a Runnable object representing the new - * application that is passed up from usapMain. + * application that is passed up from childMain (the usap's main wait loop). */ Runnable fillUsapPool(int[] sessionSocketRawFDs, boolean isPriorityRefill) { @@ -420,6 +420,7 @@ class ZygoteServer { * Runs the zygote process's select loop. Accepts new connections as * they happen, and reads commands from connections one spawn-request's * worth at a time. + * @param abiList list of ABIs supported by this zygote. */ Runnable runSelectLoop(String abiList) { ArrayList<FileDescriptor> socketFDs = new ArrayList<>(); @@ -537,22 +538,23 @@ class ZygoteServer { if (pollIndex == 0) { // Zygote server socket - ZygoteConnection newPeer = acceptCommandPeer(abiList); peers.add(newPeer); socketFDs.add(newPeer.getFileDescriptor()); - } else if (pollIndex < usapPoolEventFDIndex) { // Session socket accepted from the Zygote server socket try { ZygoteConnection connection = peers.get(pollIndex); - final Runnable command = connection.processOneCommand(this); + boolean multipleForksOK = !isUsapPoolEnabled() + && ZygoteHooks.indefiniteThreadSuspensionOK(); + final Runnable command = + connection.processCommand(this, multipleForksOK); // TODO (chriswailes): Is this extra check necessary? if (mIsForkChild) { // We're in the child. We should always have a command to run at - // this stage if processOneCommand hasn't called "exec". + // this stage if processCommand hasn't called "exec". if (command == null) { throw new IllegalStateException("command == null"); } @@ -565,7 +567,7 @@ class ZygoteServer { } // We don't know whether the remote side of the socket was closed or - // not until we attempt to read from it from processOneCommand. This + // not until we attempt to read from it from processCommand. This // shows up as a regular POLLIN event in our regular processing // loop. if (connection.isClosedByPeer()) { diff --git a/core/java/com/android/internal/power/TEST_MAPPING b/core/java/com/android/internal/power/TEST_MAPPING new file mode 100644 index 000000000000..96f31bcbe5b2 --- /dev/null +++ b/core/java/com/android/internal/power/TEST_MAPPING @@ -0,0 +1,19 @@ +{ + "presubmit": [ + { + "name": "FrameworksCoreTests", + "options": [ + { "include-filter": "com.android.internal.os.BatteryStatsTests" }, + { "exclude-annotation": "com.android.internal.os.SkipPresubmit" } + ] + }, + { + "name": "FrameworksServicesTests", + "options": [ + { "include-filter": "com.android.server.am.BatteryStatsServiceTest" }, + { "include-filter": "com.android.server.am.MeasuredEnergySnapshotTest" }, + { "include-filter": "com.android.server.am.BatteryExternalStatsWorkerTest" } + ] + } + ] +} diff --git a/core/java/com/android/internal/view/OWNERS b/core/java/com/android/internal/view/OWNERS index eb2478f6550a..851d1f37522a 100644 --- a/core/java/com/android/internal/view/OWNERS +++ b/core/java/com/android/internal/view/OWNERS @@ -18,7 +18,3 @@ per-file AppearanceRegion = file:/services/core/java/com/android/server/wm/OWNER per-file BaseIWIndow.java = file:/services/core/java/com/android/server/wm/OWNERS per-file RotationPolicy.java = file:/services/core/java/com/android/server/wm/OWNERS per-file WindowManagerPolicyThread.java = file:/services/core/java/com/android/server/wm/OWNERS - -# Scroll Capture -per-file *ScrollCapture*.java = file:/packages/SystemUI/src/com/android/systemui/screenshot/OWNERS -per-file *CaptureHelper*.java = file:/packages/SystemUI/src/com/android/systemui/screenshot/OWNERS diff --git a/core/java/com/android/internal/widget/NotificationVanishingFrameLayout.java b/core/java/com/android/internal/widget/NotificationVanishingFrameLayout.java new file mode 100644 index 000000000000..742bdfdde756 --- /dev/null +++ b/core/java/com/android/internal/widget/NotificationVanishingFrameLayout.java @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.internal.widget; + +import android.annotation.Nullable; +import android.content.Context; +import android.util.AttributeSet; +import android.view.View; +import android.widget.FrameLayout; +import android.widget.RemoteViews; + +/** + * This view will measure itself as having 0 size if all of its children are {@link #GONE}. + * Otherwise it acts like a normal {@link FrameLayout}. + */ +@RemoteViews.RemoteView +public class NotificationVanishingFrameLayout extends FrameLayout { + public NotificationVanishingFrameLayout(Context context) { + this(context, null, 0, 0); + } + + public NotificationVanishingFrameLayout(Context context, @Nullable AttributeSet attrs) { + this(context, attrs, 0, 0); + } + + public NotificationVanishingFrameLayout(Context context, @Nullable AttributeSet attrs, + int defStyleAttr) { + this(context, attrs, defStyleAttr, 0); + } + + public NotificationVanishingFrameLayout(Context context, AttributeSet attrs, int defStyleAttr, + int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + if (allChildrenGone()) { + int zeroSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.EXACTLY); + super.onMeasure(zeroSpec, zeroSpec); + } else { + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + } + } + + private boolean allChildrenGone() { + final int childCount = getChildCount(); + for (int i = 0; i < childCount; i++) { + final View child = getChildAt(i); + if (child != null && child.getVisibility() != GONE) { + return false; + } + } + return true; + } +} diff --git a/core/java/com/android/server/OWNERS b/core/java/com/android/server/OWNERS new file mode 100644 index 000000000000..1262925447b9 --- /dev/null +++ b/core/java/com/android/server/OWNERS @@ -0,0 +1 @@ +per-file SystemConfig.java = toddke@google.com diff --git a/core/jni/Android.bp b/core/jni/Android.bp index b485f0f4fb62..2287900795a5 100644 --- a/core/jni/Android.bp +++ b/core/jni/Android.bp @@ -211,6 +211,7 @@ cc_library_shared { "com_android_internal_os_KernelSingleProcessCpuThreadReader.cpp", "com_android_internal_os_KernelSingleUidTimeReader.cpp", "com_android_internal_os_Zygote.cpp", + "com_android_internal_os_ZygoteCommandBuffer.cpp", "com_android_internal_os_ZygoteInit.cpp", "hwbinder/EphemeralStorage.cpp", "fd_utils.cpp", diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp index dc77bba44607..ddd861380fab 100644 --- a/core/jni/AndroidRuntime.cpp +++ b/core/jni/AndroidRuntime.cpp @@ -198,6 +198,7 @@ extern int register_com_android_internal_os_KernelCpuUidBpfMapReader(JNIEnv *env extern int register_com_android_internal_os_KernelSingleProcessCpuThreadReader(JNIEnv* env); extern int register_com_android_internal_os_KernelSingleUidTimeReader(JNIEnv *env); extern int register_com_android_internal_os_Zygote(JNIEnv *env); +extern int register_com_android_internal_os_ZygoteCommandBuffer(JNIEnv *env); extern int register_com_android_internal_os_ZygoteInit(JNIEnv *env); extern int register_com_android_internal_util_VirtualRefBasePtr(JNIEnv *env); @@ -1531,6 +1532,7 @@ static const RegJNIRec gRegJNI[] = { REG_JNI(register_com_android_internal_net_NetworkUtilsInternal), REG_JNI(register_com_android_internal_os_ClassLoaderFactory), REG_JNI(register_com_android_internal_os_Zygote), + REG_JNI(register_com_android_internal_os_ZygoteCommandBuffer), REG_JNI(register_com_android_internal_os_ZygoteInit), REG_JNI(register_com_android_internal_util_VirtualRefBasePtr), REG_JNI(register_android_hardware_Camera), diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp index e8017253fc29..c9062d8a50bc 100644 --- a/core/jni/com_android_internal_os_Zygote.cpp +++ b/core/jni/com_android_internal_os_Zygote.cpp @@ -17,6 +17,8 @@ #define LOG_TAG "Zygote" #define ATRACE_TAG ATRACE_TAG_DALVIK +#include "com_android_internal_os_Zygote.h" + #include <async_safe/log.h> // sys/mount.h has to come before linux/fs.h due to redefinition of MS_RDONLY, MS_BIND, etc @@ -91,19 +93,6 @@ #include "nativebridge/native_bridge.h" -/* Functions in the callchain during the fork shall not be protected with - Armv8.3-A Pointer Authentication, otherwise child will not be able to return. */ -#ifdef __ARM_FEATURE_PAC_DEFAULT -#ifdef __ARM_FEATURE_BTI_DEFAULT -#define NO_PAC_FUNC __attribute__((target("branch-protection=bti"))) -#else -#define NO_PAC_FUNC __attribute__((target("branch-protection=none"))) -#endif /* __ARM_FEATURE_BTI_DEFAULT */ -#else /* !__ARM_FEATURE_PAC_DEFAULT */ -#define NO_PAC_FUNC -#endif /* __ARM_FEATURE_PAC_DEFAULT */ - - namespace { // TODO (chriswailes): Add a function to initialize native Zygote data. @@ -118,8 +107,7 @@ using android::base::StringPrintf; using android::base::WriteStringToFile; using android::base::GetBoolProperty; -#define CREATE_ERROR(...) StringPrintf("%s:%d: ", __FILE__, __LINE__). \ - append(StringPrintf(__VA_ARGS__)) +using android::zygote::ZygoteFailure; // This type is duplicated in fd_utils.h typedef const std::function<void(std::string)>& fail_fn_t; @@ -214,7 +202,7 @@ class UsapTableEntry { static constexpr EntryStorage INVALID_ENTRY_VALUE = {-1, -1}; std::atomic<EntryStorage> mStorage; - static_assert(decltype(mStorage)::is_always_lock_free); + static_assert(decltype(mStorage)::is_always_lock_free); // Accessed from signal handler. public: constexpr UsapTableEntry() : mStorage(INVALID_ENTRY_VALUE) {} @@ -917,36 +905,6 @@ void SetThreadName(const std::string& thread_name) { } /** - * A failure function used to report fatal errors to the managed runtime. This - * function is often curried with the process name information and then passed - * to called functions. - * - * @param env Managed runtime environment - * @param process_name A native representation of the process name - * @param managed_process_name A managed representation of the process name - * @param msg The error message to be reported - */ -[[noreturn]] -static void ZygoteFailure(JNIEnv* env, - const char* process_name, - jstring managed_process_name, - const std::string& msg) { - std::unique_ptr<ScopedUtfChars> scoped_managed_process_name_ptr = nullptr; - if (managed_process_name != nullptr) { - scoped_managed_process_name_ptr.reset(new ScopedUtfChars(env, managed_process_name)); - if (scoped_managed_process_name_ptr->c_str() != nullptr) { - process_name = scoped_managed_process_name_ptr->c_str(); - } - } - - const std::string& error_msg = - (process_name == nullptr) ? msg : StringPrintf("(%s) %s", process_name, msg.c_str()); - - env->FatalError(error_msg.c_str()); - __builtin_unreachable(); -} - -/** * A helper method for converting managed strings to native strings. A fatal * error is generated if a problem is encountered in extracting a non-null * string. @@ -1073,86 +1031,6 @@ static void PAuthKeyChange(JNIEnv* env) { #endif } -// Utility routine to fork a process from the zygote. -NO_PAC_FUNC -static pid_t ForkCommon(JNIEnv* env, bool is_system_server, - const std::vector<int>& fds_to_close, - const std::vector<int>& fds_to_ignore, - bool is_priority_fork) { - SetSignalHandlers(); - - // Curry a failure function. - auto fail_fn = std::bind(ZygoteFailure, env, is_system_server ? "system_server" : "zygote", - nullptr, _1); - - // Temporarily block SIGCHLD during forks. The SIGCHLD handler might - // log, which would result in the logging FDs we close being reopened. - // This would cause failures because the FDs are not allowlisted. - // - // Note that the zygote process is single threaded at this point. - BlockSignal(SIGCHLD, fail_fn); - - // Close any logging related FDs before we start evaluating the list of - // file descriptors. - __android_log_close(); - AStatsSocket_close(); - - // If this is the first fork for this zygote, create the open FD table. If - // it isn't, we just need to check whether the list of open files has changed - // (and it shouldn't in the normal case). - if (gOpenFdTable == nullptr) { - gOpenFdTable = FileDescriptorTable::Create(fds_to_ignore, fail_fn); - } else { - gOpenFdTable->Restat(fds_to_ignore, fail_fn); - } - - android_fdsan_error_level fdsan_error_level = android_fdsan_get_error_level(); - - // Purge unused native memory in an attempt to reduce the amount of false - // sharing with the child process. By reducing the size of the libc_malloc - // region shared with the child process we reduce the number of pages that - // transition to the private-dirty state when malloc adjusts the meta-data - // on each of the pages it is managing after the fork. - mallopt(M_PURGE, 0); - - pid_t pid = fork(); - - if (pid == 0) { - if (is_priority_fork) { - setpriority(PRIO_PROCESS, 0, PROCESS_PRIORITY_MAX); - } else { - setpriority(PRIO_PROCESS, 0, PROCESS_PRIORITY_MIN); - } - - // The child process. - PAuthKeyChange(env); - PreApplicationInit(); - - // Clean up any descriptors which must be closed immediately - DetachDescriptors(env, fds_to_close, fail_fn); - - // Invalidate the entries in the USAP table. - ClearUsapTable(); - - // Re-open all remaining open file descriptors so that they aren't shared - // with the zygote across a fork. - gOpenFdTable->ReopenOrDetach(fail_fn); - - // Turn fdsan back on. - android_fdsan_set_error_level(fdsan_error_level); - - // Reset the fd to the unsolicited zygote socket - gSystemServerSocketFd = -1; - } else { - ALOGD("Forked child process %d", pid); - } - - // We blocked SIGCHLD prior to a fork, we unblock it here. - UnblockSignal(SIGCHLD, fail_fn); - - return pid; -} - // Create an app data directory over tmpfs overlayed CE / DE storage, and bind mount it // from the actual app data directory in data mirror. static bool createAndMountAppData(std::string_view package_name, @@ -1973,9 +1851,10 @@ static void AddUsapTableEntry(pid_t usap_pid, int read_pipe_fd) { static int sUsapTableInsertIndex = 0; int search_index = sUsapTableInsertIndex; - do { if (gUsapTable[search_index].SetIfInvalid(usap_pid, read_pipe_fd)) { + ++gUsapPoolCount; + // Start our next search right after where we finished this one. sUsapTableInsertIndex = (search_index + 1) % gUsapTable.size(); @@ -1993,7 +1872,7 @@ static void AddUsapTableEntry(pid_t usap_pid, int read_pipe_fd) { /** * Invalidates the entry in the USAPTable corresponding to the provided * process ID if it is present. If an entry was removed the USAP pool - * count is decremented. + * count is decremented. May be called from signal handler. * * @param usap_pid Process ID of the USAP entry to invalidate * @return True if an entry was invalidated; false otherwise @@ -2069,6 +1948,121 @@ static void UnmountStorageOnInit(JNIEnv* env) { namespace android { +/** + * A failure function used to report fatal errors to the managed runtime. This + * function is often curried with the process name information and then passed + * to called functions. + * + * @param env Managed runtime environment + * @param process_name A native representation of the process name + * @param managed_process_name A managed representation of the process name + * @param msg The error message to be reported + */ +[[noreturn]] +void zygote::ZygoteFailure(JNIEnv* env, + const char* process_name, + jstring managed_process_name, + const std::string& msg) { + std::unique_ptr<ScopedUtfChars> scoped_managed_process_name_ptr = nullptr; + if (managed_process_name != nullptr) { + scoped_managed_process_name_ptr.reset(new ScopedUtfChars(env, managed_process_name)); + if (scoped_managed_process_name_ptr->c_str() != nullptr) { + process_name = scoped_managed_process_name_ptr->c_str(); + } + } + + const std::string& error_msg = + (process_name == nullptr || process_name[0] == '\0') ? + msg : StringPrintf("(%s) %s", process_name, msg.c_str()); + + env->FatalError(error_msg.c_str()); + __builtin_unreachable(); +} + +// Utility routine to fork a process from the zygote. +NO_PAC_FUNC +pid_t zygote::ForkCommon(JNIEnv* env, bool is_system_server, + const std::vector<int>& fds_to_close, + const std::vector<int>& fds_to_ignore, + bool is_priority_fork, + bool purge) { + SetSignalHandlers(); + + // Curry a failure function. + auto fail_fn = std::bind(zygote::ZygoteFailure, env, + is_system_server ? "system_server" : "zygote", + nullptr, _1); + + // Temporarily block SIGCHLD during forks. The SIGCHLD handler might + // log, which would result in the logging FDs we close being reopened. + // This would cause failures because the FDs are not allowlisted. + // + // Note that the zygote process is single threaded at this point. + BlockSignal(SIGCHLD, fail_fn); + + // Close any logging related FDs before we start evaluating the list of + // file descriptors. + __android_log_close(); + AStatsSocket_close(); + + // If this is the first fork for this zygote, create the open FD table. If + // it isn't, we just need to check whether the list of open files has changed + // (and it shouldn't in the normal case). + if (gOpenFdTable == nullptr) { + gOpenFdTable = FileDescriptorTable::Create(fds_to_ignore, fail_fn); + } else { + gOpenFdTable->Restat(fds_to_ignore, fail_fn); + } + + android_fdsan_error_level fdsan_error_level = android_fdsan_get_error_level(); + + if (purge) { + // Purge unused native memory in an attempt to reduce the amount of false + // sharing with the child process. By reducing the size of the libc_malloc + // region shared with the child process we reduce the number of pages that + // transition to the private-dirty state when malloc adjusts the meta-data + // on each of the pages it is managing after the fork. + mallopt(M_PURGE, 0); + } + + pid_t pid = fork(); + + if (pid == 0) { + if (is_priority_fork) { + setpriority(PRIO_PROCESS, 0, PROCESS_PRIORITY_MAX); + } else { + setpriority(PRIO_PROCESS, 0, PROCESS_PRIORITY_MIN); + } + + // The child process. + PAuthKeyChange(env); + PreApplicationInit(); + + // Clean up any descriptors which must be closed immediately + DetachDescriptors(env, fds_to_close, fail_fn); + + // Invalidate the entries in the USAP table. + ClearUsapTable(); + + // Re-open all remaining open file descriptors so that they aren't shared + // with the zygote across a fork. + gOpenFdTable->ReopenOrDetach(fail_fn); + + // Turn fdsan back on. + android_fdsan_set_error_level(fdsan_error_level); + + // Reset the fd to the unsolicited zygote socket + gSystemServerSocketFd = -1; + } else { + ALOGD("Forked child process %d", pid); + } + + // We blocked SIGCHLD prior to a fork, we unblock it here. + UnblockSignal(SIGCHLD, fail_fn); + + return pid; +} + static void com_android_internal_os_Zygote_nativePreApplicationInit(JNIEnv*, jclass) { PreApplicationInit(); } @@ -2085,7 +2079,8 @@ static jint com_android_internal_os_Zygote_nativeForkAndSpecialize( jlong capabilities = CalculateCapabilities(env, uid, gid, gids, is_child_zygote); if (UNLIKELY(managed_fds_to_close == nullptr)) { - ZygoteFailure(env, "zygote", nice_name, "Zygote received a null fds_to_close vector."); + zygote::ZygoteFailure(env, "zygote", nice_name, + "Zygote received a null fds_to_close vector."); } std::vector<int> fds_to_close = @@ -2111,7 +2106,7 @@ static jint com_android_internal_os_Zygote_nativeForkAndSpecialize( fds_to_ignore.push_back(gSystemServerSocketFd); } - pid_t pid = ForkCommon(env, false, fds_to_close, fds_to_ignore, true); + pid_t pid = zygote::ForkCommon(env, false, fds_to_close, fds_to_ignore, true); if (pid == 0) { SpecializeCommon(env, uid, gid, gids, runtime_flags, rlimits, @@ -2146,10 +2141,10 @@ static jint com_android_internal_os_Zygote_nativeForkSystemServer( fds_to_ignore.push_back(gSystemServerSocketFd); } - pid_t pid = ForkCommon(env, true, - fds_to_close, - fds_to_ignore, - true); + pid_t pid = zygote::ForkCommon(env, true, + fds_to_close, + fds_to_ignore, + true); if (pid == 0) { // System server prcoess does not need data isolation so no need to // know pkg_data_info_list. @@ -2189,58 +2184,74 @@ static jint com_android_internal_os_Zygote_nativeForkSystemServer( * ensuring proper file descriptor hygiene. * * @param env Managed runtime environment - * @param read_pipe_fd The read FD for the USAP reporting pipe. Manually closed by blastlas - * in managed code. + * @param read_pipe_fd The read FD for the USAP reporting pipe. Manually closed by the child + * in managed code. -1 indicates none. * @param write_pipe_fd The write FD for the USAP reporting pipe. Manually closed by the - * zygote in managed code. + * zygote in managed code. -1 indicates none. * @param managed_session_socket_fds A list of anonymous session sockets that must be ignored by * the FD hygiene code and automatically "closed" in the new USAP. + * @param args_known Arguments for specialization are available; no need to read from a socket * @param is_priority_fork Controls the nice level assigned to the newly created process - * @return + * @return child pid in the parent, 0 in the child */ NO_PAC_FUNC -static jint com_android_internal_os_Zygote_nativeForkUsap(JNIEnv* env, - jclass, - jint read_pipe_fd, - jint write_pipe_fd, - jintArray managed_session_socket_fds, - jboolean is_priority_fork) { - std::vector<int> fds_to_close(MakeUsapPipeReadFDVector()), - fds_to_ignore(fds_to_close); - +static jint com_android_internal_os_Zygote_nativeForkApp(JNIEnv* env, + jclass, + jint read_pipe_fd, + jint write_pipe_fd, + jintArray managed_session_socket_fds, + jboolean args_known, + jboolean is_priority_fork) { std::vector<int> session_socket_fds = ExtractJIntArray(env, "USAP", nullptr, managed_session_socket_fds) .value_or(std::vector<int>()); + return zygote::forkApp(env, read_pipe_fd, write_pipe_fd, session_socket_fds, + args_known == JNI_TRUE, is_priority_fork == JNI_TRUE, true); +} - // The USAP Pool Event FD is created during the initialization of the - // USAP pool and should always be valid here. +NO_PAC_FUNC +int zygote::forkApp(JNIEnv* env, + int read_pipe_fd, + int write_pipe_fd, + const std::vector<int>& session_socket_fds, + bool args_known, + bool is_priority_fork, + bool purge) { + + std::vector<int> fds_to_close(MakeUsapPipeReadFDVector()), + fds_to_ignore(fds_to_close); fds_to_close.push_back(gZygoteSocketFD); - fds_to_close.push_back(gUsapPoolEventFD); - fds_to_close.insert(fds_to_close.end(), session_socket_fds.begin(), session_socket_fds.end()); if (gSystemServerSocketFd != -1) { fds_to_close.push_back(gSystemServerSocketFd); } + if (args_known) { + fds_to_close.push_back(gUsapPoolSocketFD); + } + fds_to_close.insert(fds_to_close.end(), session_socket_fds.begin(), session_socket_fds.end()); - fds_to_ignore.push_back(gZygoteSocketFD); fds_to_ignore.push_back(gUsapPoolSocketFD); - fds_to_ignore.push_back(gUsapPoolEventFD); - fds_to_ignore.push_back(read_pipe_fd); - fds_to_ignore.push_back(write_pipe_fd); + fds_to_ignore.push_back(gZygoteSocketFD); + if (read_pipe_fd != -1) { + fds_to_ignore.push_back(read_pipe_fd); + } + if (write_pipe_fd != -1) { + fds_to_ignore.push_back(write_pipe_fd); + } fds_to_ignore.insert(fds_to_ignore.end(), session_socket_fds.begin(), session_socket_fds.end()); + + if (gUsapPoolEventFD != -1) { + fds_to_close.push_back(gUsapPoolEventFD); + fds_to_ignore.push_back(gUsapPoolEventFD); + } if (gSystemServerSocketFd != -1) { + if (args_known) { + fds_to_close.push_back(gSystemServerSocketFd); + } fds_to_ignore.push_back(gSystemServerSocketFd); } - - pid_t usap_pid = ForkCommon(env, /* is_system_server= */ false, fds_to_close, fds_to_ignore, - is_priority_fork == JNI_TRUE); - - if (usap_pid != 0) { - ++gUsapPoolCount; - AddUsapTableEntry(usap_pid, read_pipe_fd); - } - - return usap_pid; + return zygote::ForkCommon(env, /* is_system_server= */ false, fds_to_close, + fds_to_ignore, is_priority_fork == JNI_TRUE, purge); } static void com_android_internal_os_Zygote_nativeAllowFileAcrossFork( @@ -2354,7 +2365,7 @@ static void com_android_internal_os_Zygote_nativeInitNativeState(JNIEnv* env, jc */ if (!SetTaskProfiles(0, {})) { - ZygoteFailure(env, "zygote", nullptr, "Zygote SetTaskProfiles failed"); + zygote::ZygoteFailure(env, "zygote", nullptr, "Zygote SetTaskProfiles failed"); } } @@ -2372,15 +2383,21 @@ static jintArray com_android_internal_os_Zygote_nativeGetUsapPipeFDs(JNIEnv* env return managed_usap_fds; } +/* + * Add the given pid and file descriptor to the Usap table. CriticalNative method. + */ +static void com_android_internal_os_Zygote_nativeAddUsapTableEntry(jint pid, jint read_pipe_fd) { + AddUsapTableEntry(pid, read_pipe_fd); +} + /** - * A JNI wrapper around RemoveUsapTableEntry. + * A JNI wrapper around RemoveUsapTableEntry. CriticalNative method. * * @param env Managed runtime environment * @param usap_pid Process ID of the USAP entry to invalidate * @return True if an entry was invalidated; false otherwise. */ -static jboolean com_android_internal_os_Zygote_nativeRemoveUsapTableEntry(JNIEnv* env, jclass, - jint usap_pid) { +static jboolean com_android_internal_os_Zygote_nativeRemoveUsapTableEntry(jint usap_pid) { return RemoveUsapTableEntry(usap_pid); } @@ -2395,7 +2412,8 @@ static jboolean com_android_internal_os_Zygote_nativeRemoveUsapTableEntry(JNIEnv static jint com_android_internal_os_Zygote_nativeGetUsapPoolEventFD(JNIEnv* env, jclass) { if (gUsapPoolEventFD == -1) { if ((gUsapPoolEventFD = eventfd(0, 0)) == -1) { - ZygoteFailure(env, "zygote", nullptr, StringPrintf("Unable to create eventfd: %s", strerror(errno))); + zygote::ZygoteFailure(env, "zygote", nullptr, + StringPrintf("Unable to create eventfd: %s", strerror(errno))); } } @@ -2438,12 +2456,12 @@ static void com_android_internal_os_Zygote_nativeEmptyUsapPool(JNIEnv* env, jcla } static void com_android_internal_os_Zygote_nativeBlockSigTerm(JNIEnv* env, jclass) { - auto fail_fn = std::bind(ZygoteFailure, env, "usap", nullptr, _1); + auto fail_fn = std::bind(zygote::ZygoteFailure, env, "usap", nullptr, _1); BlockSignal(SIGTERM, fail_fn); } static void com_android_internal_os_Zygote_nativeUnblockSigTerm(JNIEnv* env, jclass) { - auto fail_fn = std::bind(ZygoteFailure, env, "usap", nullptr, _1); + auto fail_fn = std::bind(zygote::ZygoteFailure, env, "usap", nullptr, _1); UnblockSignal(SIGTERM, fail_fn); } @@ -2549,7 +2567,10 @@ static const JNINativeMethod gMethods[] = { (void*)com_android_internal_os_Zygote_nativePreApplicationInit}, {"nativeInstallSeccompUidGidFilter", "(II)V", (void*)com_android_internal_os_Zygote_nativeInstallSeccompUidGidFilter}, - {"nativeForkUsap", "(II[IZ)I", (void*)com_android_internal_os_Zygote_nativeForkUsap}, + {"nativeForkApp", "(II[IZZ)I", (void*)com_android_internal_os_Zygote_nativeForkApp}, + // @CriticalNative + {"nativeAddUsapTableEntry", "(II)V", + (void*)com_android_internal_os_Zygote_nativeAddUsapTableEntry}, {"nativeSpecializeAppProcess", "(II[II[[IILjava/lang/String;Ljava/lang/String;ZLjava/lang/String;Ljava/lang/" "String;Z[Ljava/lang/String;[Ljava/lang/String;ZZ)V", @@ -2558,6 +2579,10 @@ static const JNINativeMethod gMethods[] = { (void*)com_android_internal_os_Zygote_nativeInitNativeState}, {"nativeGetUsapPipeFDs", "()[I", (void*)com_android_internal_os_Zygote_nativeGetUsapPipeFDs}, + // @CriticalNative + {"nativeAddUsapTableEntry", "(II)V", + (void*)com_android_internal_os_Zygote_nativeAddUsapTableEntry}, + // @CriticalNative {"nativeRemoveUsapTableEntry", "(I)Z", (void*)com_android_internal_os_Zygote_nativeRemoveUsapTableEntry}, {"nativeGetUsapPoolEventFD", "()I", diff --git a/core/jni/com_android_internal_os_Zygote.h b/core/jni/com_android_internal_os_Zygote.h new file mode 100644 index 000000000000..d2da91476bc7 --- /dev/null +++ b/core/jni/com_android_internal_os_Zygote.h @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _COM_ANDROID_INTERNAL_OS_ZYGOTE_H +#define _COM_ANDROID_INTERNAL_OS_ZYGOTE_H + +#define LOG_TAG "Zygote" +#define ATRACE_TAG ATRACE_TAG_DALVIK + +/* Functions in the callchain during the fork shall not be protected with + Armv8.3-A Pointer Authentication, otherwise child will not be able to return. */ +#ifdef __ARM_FEATURE_PAC_DEFAULT +#ifdef __ARM_FEATURE_BTI_DEFAULT +#define NO_PAC_FUNC __attribute__((target("branch-protection=bti"))) +#else +#define NO_PAC_FUNC __attribute__((target("branch-protection=none"))) +#endif /* __ARM_FEATURE_BTI_DEFAULT */ +#else /* !__ARM_FEATURE_PAC_DEFAULT */ +#define NO_PAC_FUNC +#endif /* __ARM_FEATURE_PAC_DEFAULT */ + +#include <jni.h> +#include <vector> +#include <android-base/stringprintf.h> + +#define CREATE_ERROR(...) StringPrintf("%s:%d: ", __FILE__, __LINE__). \ + append(StringPrintf(__VA_ARGS__)) + +namespace android { +namespace zygote { + +NO_PAC_FUNC +pid_t ForkCommon(JNIEnv* env,bool is_system_server, + const std::vector<int>& fds_to_close, + const std::vector<int>& fds_to_ignore, + bool is_priority_fork, + bool purge = true); + +/** + * Fork a process. The pipe fds are used for usap communication, or -1 in + * other cases. Session_socket_fds are FDs used for zygote communication that must be dealt + * with hygienically, but are not otherwise used here. Args_known indicates that the process + * will be immediately specialized with arguments that are already known, so no usap + * communication is required. Is_priority_fork should be true if this is on the app startup + * critical path. Purge specifies that unused pages should be purged before the fork. + */ +NO_PAC_FUNC +int forkApp(JNIEnv* env, + int read_pipe_fd, + int write_pipe_fd, + const std::vector<int>& session_socket_fds, + bool args_known, + bool is_priority_fork, + bool purge); + +[[noreturn]] +void ZygoteFailure(JNIEnv* env, + const char* process_name, + jstring managed_process_name, + const std::string& msg); + +} // namespace zygote +} // namespace android + +#endif // _COM_ANDROID_INTERNAL_OS_ZYGOTE_ diff --git a/core/jni/com_android_internal_os_ZygoteCommandBuffer.cpp b/core/jni/com_android_internal_os_ZygoteCommandBuffer.cpp new file mode 100644 index 000000000000..011e8f8f1b8c --- /dev/null +++ b/core/jni/com_android_internal_os_ZygoteCommandBuffer.cpp @@ -0,0 +1,512 @@ +/* + * 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. + */ + +#include "com_android_internal_os_Zygote.h" + +#include <algorithm> +#include <android-base/logging.h> +#include <async_safe/log.h> +#include <cctype> +#include <chrono> +#include <core_jni_helpers.h> +#include <errno.h> +#include <fcntl.h> +#include <jni.h> +#include <nativehelper/JNIHelp.h> +#include <optional> +#include <poll.h> +#include <unistd.h> +#include <utility> +#include <utils/misc.h> +#include <sys/mman.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <vector> + +namespace android { + +using namespace std::placeholders; +using android::base::StringPrintf; +using android::zygote::ZygoteFailure; + +// WARNING: Knows a little about the wire protocol used to communicate with Zygote. +// TODO: Fix error handling. + +constexpr size_t MAX_COMMAND_BYTES = 12200; +constexpr size_t NICE_NAME_BYTES = 50; + +// A buffer optionally bundled with a file descriptor from which we can fill it. +// Does not own the file descriptor; destroying a NativeCommandBuffer does not +// close the descriptor. +class NativeCommandBuffer { + public: + NativeCommandBuffer(int sourceFd): mEnd(0), mNext(0), mLinesLeft(0), mFd(sourceFd) {} + + // Read mNext line from mFd, filling mBuffer from file descriptor, as needed. + // Return a pair of pointers pointing to the first character, and one past the + // mEnd of the line, i.e. at the newline. Returns nothing on failure. + template<class FailFn> + std::optional<std::pair<char*, char*>> readLine(FailFn fail_fn) { + char* result = mBuffer + mNext; + while (true) { + if (mNext == mEnd) { + if (mEnd == MAX_COMMAND_BYTES) { + return {}; + } + if (mFd == -1) { + fail_fn("ZygoteCommandBuffer.readLine attempted to read from mFd -1"); + } + ssize_t nread = TEMP_FAILURE_RETRY(read(mFd, mBuffer + mEnd, MAX_COMMAND_BYTES - mEnd)); + if (nread <= 0) { + if (nread == 0) { + return {}; + } + fail_fn(CREATE_ERROR("session socket read failed: %s", strerror(errno))); + } else if (nread == MAX_COMMAND_BYTES - mEnd) { + // This is pessimistic by one character, but close enough. + fail_fn("ZygoteCommandBuffer overflowed: command too long"); + } + mEnd += nread; + } + // UTF-8 does not allow newline to occur as part of a multibyte character. + char* nl = static_cast<char *>(memchr(mBuffer + mNext, '\n', mEnd - mNext)); + if (nl == nullptr) { + mNext = mEnd; + } else { + mNext = nl - mBuffer + 1; + if (--mLinesLeft < 0) { + fail_fn("ZygoteCommandBuffer.readLine attempted to read past mEnd of command"); + } + return std::make_pair(result, nl); + } + } + } + + void reset() { + mNext = 0; + } + + // Make sure the current command is fully buffered, without reading past the current command. + template<class FailFn> + void readAllLines(FailFn fail_fn) { + while (mLinesLeft > 0) { + readLine(fail_fn); + } + } + + void clear() { + // Don't bother to actually clear the buffer; it'll be unmapped in the child anyway. + reset(); + mNiceName[0] = '\0'; + mEnd = 0; + } + + // Insert line into the mBuffer. Checks that the mBuffer is not associated with an mFd. + // Implicitly adds newline separators. Allows mBuffer contents to be explicitly set. + void insert(const char* line, size_t lineLen) { + DCHECK(mFd == -1); + CHECK(mEnd + lineLen < MAX_COMMAND_BYTES); + strncpy(mBuffer + mEnd, line, lineLen); + mBuffer[mEnd + lineLen] = '\n'; + mEnd += lineLen + 1; + } + + // Clear mBuffer, start reading new command, return the number of arguments, leaving mBuffer + // positioned at the beginning of first argument. Return 0 on EOF. + template<class FailFn> + int getCount(FailFn fail_fn) { + mLinesLeft = 1; + auto line = readLine(fail_fn); + if (!line.has_value()) { + return 0; + } + char* countString = line.value().first; // Newline terminated. + long nArgs = atol(countString); + if (nArgs <= 0 || nArgs >= MAX_COMMAND_BYTES / 2) { + fail_fn(CREATE_ERROR("Unreasonable argument count %ld", nArgs)); + } + mLinesLeft = nArgs; + return static_cast<int>(nArgs); + } + + // Is the mBuffer a simple fork command? + // We disallow request to wrap the child process, child zygotes, anything that + // mentions capabilities or requests uid < minUid. + // We insist that --setuid and --setgid arguments are explicitly included and that the + // command starts with --runtime-args. + // Assumes we are positioned at the beginning of the command after the argument count, + // and leaves the position at some indeterminate position in the buffer. + // As a side effect, this sets mNiceName to a non-empty string, if possible. + template<class FailFn> + bool isSimpleForkCommand(int minUid, FailFn fail_fn) { + if (mLinesLeft <= 0 || mLinesLeft >= MAX_COMMAND_BYTES / 2) { + return false; + } + static const char* RUNTIME_ARGS = "--runtime-args"; + static const char* INVOKE_WITH = "--invoke-with"; + static const char* CHILD_ZYGOTE = "--start-child-zygote"; + static const char* SETUID = "--setuid="; + static const char* SETGID = "--setgid="; + static const char* CAPABILITIES = "--capabilities"; + static const char* NICE_NAME = "--nice-name="; + static const size_t RA_LENGTH = strlen(RUNTIME_ARGS); + static const size_t IW_LENGTH = strlen(INVOKE_WITH); + static const size_t CZ_LENGTH = strlen(CHILD_ZYGOTE); + static const size_t SU_LENGTH = strlen(SETUID); + static const size_t SG_LENGTH = strlen(SETGID); + static const size_t CA_LENGTH = strlen(CAPABILITIES); + static const size_t NN_LENGTH = strlen(NICE_NAME); + + bool saw_setuid = false, saw_setgid = false; + bool saw_runtime_args = false; + + while (mLinesLeft > 0) { + auto read_result = readLine(fail_fn); + if (!read_result.has_value()) { + return false; + } + auto [arg_start, arg_end] = read_result.value(); + if (arg_end - arg_start == RA_LENGTH + && strncmp(arg_start, RUNTIME_ARGS, RA_LENGTH) == 0) { + saw_runtime_args = true; + continue; + } + if (arg_end - arg_start >= NN_LENGTH + && strncmp(arg_start, NICE_NAME, NN_LENGTH) == 0) { + size_t name_len = arg_end - (arg_start + NN_LENGTH); + size_t copy_len = std::min(name_len, NICE_NAME_BYTES - 1); + memcpy(mNiceName, arg_start + NN_LENGTH, copy_len); + mNiceName[copy_len] = '\0'; + continue; + } + if (arg_end - arg_start == IW_LENGTH + && strncmp(arg_start, INVOKE_WITH, IW_LENGTH) == 0) { + // This also removes the need for invoke-with security checks here. + return false; + } + if (arg_end - arg_start == CZ_LENGTH + && strncmp(arg_start, CHILD_ZYGOTE, CZ_LENGTH) == 0) { + return false; + } + if (arg_end - arg_start >= CA_LENGTH + && strncmp(arg_start, CAPABILITIES, CA_LENGTH) == 0) { + return false; + } + if (arg_end - arg_start >= SU_LENGTH + && strncmp(arg_start, SETUID, SU_LENGTH) == 0) { + int uid = digitsVal(arg_start + SU_LENGTH, arg_end); + if (uid < minUid) { + return false; + } + saw_setuid = true; + continue; + } + if (arg_end - arg_start >= SG_LENGTH + && strncmp(arg_start, SETGID, SG_LENGTH) == 0) { + int gid = digitsVal(arg_start + SG_LENGTH, arg_end); + if (gid == -1) { + return false; + } + saw_setgid = true; + } + } + return saw_runtime_args && saw_setuid && saw_setgid; + } + + void setFd(int new_fd) { + mFd = new_fd; + } + + int getFd() const { + return mFd; + } + + const char* niceNameAddr() const { + return mNiceName; + } + + // Debug only: + void logState() const { + ALOGD("mbuffer starts with %c%c, nice name is %s, " + "mEnd = %u, mNext = %u, mLinesLeft = %d, mFd = %d", + mBuffer[0], (mBuffer[1] == '\n' ? ' ' : mBuffer[1]), + niceNameAddr(), + static_cast<unsigned>(mEnd), static_cast<unsigned>(mNext), + static_cast<int>(mLinesLeft), mFd); + } + + private: + // Picky version of atoi(). No sign or unexpected characters allowed. Return -1 on failure. + static int digitsVal(char* start, char* end) { + int result = 0; + if (end - start > 6) { + return -1; + } + for (char* dp = start; dp < end; ++dp) { + if (*dp < '0' || *dp > '9') { + ALOGW("Argument failed integer format check"); + return -1; + } + result = 10 * result + (*dp - '0'); + } + return result; + } + + uint32_t mEnd; // Index of first empty byte in the mBuffer. + uint32_t mNext; // Index of first character past last line returned by readLine. + int32_t mLinesLeft; // Lines in current command that haven't yet been read. + int mFd; // Open file descriptor from which we can read more. -1 if none. + char mNiceName[NICE_NAME_BYTES]; + char mBuffer[MAX_COMMAND_BYTES]; +}; + +static_assert(sizeof(NativeCommandBuffer) < 3 * 4096); + +static int buffersAllocd(0); + +// Get a new NativeCommandBuffer. Can only be called once between freeNativeBuffer calls, +// so that only one buffer exists at a time. +jlong com_android_internal_os_ZygoteCommandBuffer_getNativeBuffer(JNIEnv* env, jclass, jint fd) { + CHECK(buffersAllocd == 0); + ++buffersAllocd; + // MMap explicitly to get it page aligned. + void *bufferMem = mmap(NULL, sizeof(NativeCommandBuffer), PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_PRIVATE | MAP_POPULATE, -1, 0); + // Currently we mmap and unmap one for every request handled by the Java code. + // That could be improved, but unclear it matters. + if (bufferMem == MAP_FAILED) { + ZygoteFailure(env, nullptr, nullptr, "Failed to map argument buffer"); + } + return (jlong) new(bufferMem) NativeCommandBuffer(fd); +} + +// Delete native command buffer. +void com_android_internal_os_ZygoteCommandBuffer_freeNativeBuffer(JNIEnv* env, jclass, + jlong j_buffer) { + CHECK(buffersAllocd == 1); + NativeCommandBuffer* n_buffer = reinterpret_cast<NativeCommandBuffer*>(j_buffer); + n_buffer->~NativeCommandBuffer(); + if (munmap(n_buffer, sizeof(NativeCommandBuffer)) != 0) { + ZygoteFailure(env, nullptr, nullptr, "Failed to unmap argument buffer"); + } + --buffersAllocd; +} + +// Clear the buffer, read the line containing the count, and return the count. +jint com_android_internal_os_ZygoteCommandBuffer_nativeGetCount(JNIEnv* env, jclass, + jlong j_buffer) { + NativeCommandBuffer* n_buffer = reinterpret_cast<NativeCommandBuffer*>(j_buffer); + auto fail_fn = std::bind(ZygoteFailure, env, nullptr, nullptr, _1); + return n_buffer->getCount(fail_fn); +} + +// Explicitly insert a string as the last line (argument) of the buffer. +void com_android_internal_os_ZygoteCommandBuffer_insert(JNIEnv* env, jclass, jlong j_buffer, + jstring line) { + NativeCommandBuffer* n_buffer = reinterpret_cast<NativeCommandBuffer*>(j_buffer); + size_t lineLen = static_cast<size_t>(env->GetStringUTFLength(line)); + const char* cstring = env->GetStringUTFChars(line, NULL); + n_buffer->insert(cstring, lineLen); + env->ReleaseStringUTFChars(line, cstring); +} + +// Read a line from the buffer, refilling as necessary. +jstring com_android_internal_os_ZygoteCommandBuffer_nativeNextArg(JNIEnv* env, jclass, + jlong j_buffer) { + NativeCommandBuffer* n_buffer = reinterpret_cast<NativeCommandBuffer*>(j_buffer); + auto fail_fn = std::bind(ZygoteFailure, env, n_buffer->niceNameAddr(), nullptr, _1); + auto line = n_buffer->readLine(fail_fn); + if (!line.has_value()) { + fail_fn("Incomplete zygote command"); + } + auto [cresult, endp] = line.value(); + // OK to temporarily clobber the buffer, since this is not thread safe, and we're modifying + // the buffer anyway. + *endp = '\0'; + jstring result = env->NewStringUTF(cresult); + *endp = '\n'; + return result; +} + +// Read all lines from the current command into the buffer, and then reset the buffer, so +// we will start reading again at the beginning of the command, starting with the argument +// count. And we don't need access to the fd to do so. +void com_android_internal_os_ZygoteCommandBuffer_nativeReadFullyAndReset(JNIEnv* env, jclass, + jlong j_buffer) { + NativeCommandBuffer* n_buffer = reinterpret_cast<NativeCommandBuffer*>(j_buffer); + auto fail_fn = std::bind(ZygoteFailure, env, n_buffer->niceNameAddr(), nullptr, _1); + n_buffer->readAllLines(fail_fn); + n_buffer->reset(); +} + +// Fork a child as specified by the current command buffer, and refill the command +// buffer from the given socket. So long as the result is another simple fork command, +// repeat this process. +// It must contain a fork command, which is currently restricted not to fork another +// zygote or involve a wrapper process. +// The initial buffer should be partially or entirely read; we read it fully and reset it. +// When we return, the buffer contains the command we couldn't handle, and has been reset(). +// We return false in the parent when we see a command we didn't understand, and thus the +// command in the buffer still needs to be executed. +// We return true in each child. +// We only process fork commands if the peer uid matches expected_uid. +// For every fork command after the first, we check that the requested uid is at +// least minUid. +NO_PAC_FUNC +jboolean com_android_internal_os_ZygoteCommandBuffer_nativeForkRepeatedly( + JNIEnv* env, + jclass, + jlong j_buffer, + jint zygote_socket_fd, + jint expected_uid, + jint minUid, + jstring managed_nice_name) { + + NativeCommandBuffer* n_buffer = reinterpret_cast<NativeCommandBuffer*>(j_buffer); + int session_socket = n_buffer->getFd(); + std::vector<int> session_socket_fds {session_socket}; + auto fail_fn_1 = std::bind(ZygoteFailure, env, static_cast<const char*>(nullptr), + static_cast<jstring>(managed_nice_name), _1); + // This binds to the nice name address; the actual names are updated by isSimpleForkCommand: + auto fail_fn_n = std::bind(ZygoteFailure, env, n_buffer->niceNameAddr(), + static_cast<jstring>(nullptr), _1); + auto fail_fn_z = std::bind(ZygoteFailure, env, "zygote", nullptr, _1); + + struct pollfd fd_structs[2]; + static const int ZYGOTE_IDX = 0; + static const int SESSION_IDX = 1; + fd_structs[ZYGOTE_IDX].fd = zygote_socket_fd; + fd_structs[ZYGOTE_IDX].events = POLLIN; + fd_structs[SESSION_IDX].fd = session_socket; + fd_structs[SESSION_IDX].events = POLLIN; + + struct timeval timeout; + socklen_t timeout_size = sizeof timeout; + if (getsockopt(session_socket, SOL_SOCKET, SO_RCVTIMEO, &timeout, &timeout_size) != 0) { + fail_fn_z("Failed to retrieve session socket timeout"); + } + + struct ucred credentials; + socklen_t cred_size = sizeof credentials; + if (getsockopt(n_buffer->getFd(), SOL_SOCKET, SO_PEERCRED, &credentials, &cred_size) == -1 + || cred_size != sizeof credentials) { + fail_fn_1("ForkMany failed to get initial credentials, %s", strerror(errno)); + } + + bool first_time = true; + do { + if (credentials.uid != expected_uid) { + return JNI_FALSE; + } + n_buffer->readAllLines(first_time ? fail_fn_1 : fail_fn_n); + n_buffer->reset(); + int pid = zygote::forkApp(env, /* no pipe FDs */ -1, -1, session_socket_fds, + /*args_known=*/ true, /*is_priority_fork=*/ true, + /*purge=*/ first_time); + if (pid == 0) { + return JNI_TRUE; + } + // We're in the parent. Write big-endian pid, followed by a boolean. + char pid_buf[5]; + int tmp_pid = pid; + for (int i = 3; i >= 0; --i) { + pid_buf[i] = tmp_pid & 0xff; + tmp_pid >>= 8; + } + pid_buf[4] = 0; // Process is not wrapped. + int res = write(session_socket, pid_buf, 5); + if (res != 5) { + if (res == -1) { + (first_time ? fail_fn_1 : fail_fn_n) + (CREATE_ERROR("Pid write error %d: %s", errno, strerror(errno))); + } else { + (first_time ? fail_fn_1 : fail_fn_n) + (CREATE_ERROR("Write unexpectedly returned short: %d < 5", res)); + } + } + // Clear buffer and get count from next command. + n_buffer->clear(); + for (;;) { + // Poll isn't strictly necessary for now. But without it, disconnect is hard to detect. + int poll_res = TEMP_FAILURE_RETRY(poll(fd_structs, 2, -1 /* infinite timeout */)); + if ((fd_structs[SESSION_IDX].revents & POLLIN) != 0) { + if (n_buffer->getCount(fail_fn_z) != 0) { + break; + } // else disconnected; + } else if (poll_res == 0 || (fd_structs[ZYGOTE_IDX].revents & POLLIN) == 0) { + fail_fn_z( + CREATE_ERROR("Poll returned with no descriptors ready! Poll returned %d", poll_res)); + } + // We've now seen either a disconnect or connect request. + close(session_socket); + int new_fd = accept(zygote_socket_fd, nullptr, nullptr); + if (new_fd == -1) { + fail_fn_z("Accept(%d) failed: %s", zygote_socket_fd, strerror(errno)); + } + if (new_fd != session_socket) { + // Move new_fd back to the old value, so that we don't have to change Java-level data + // structures to reflect a change. This implicitly closes the old one. + if (dup2(new_fd, session_socket) != session_socket) { + fail_fn_z(CREATE_ERROR("Failed to move fd %d to %d: %s", + new_fd, session_socket, strerror(errno))); + } + close(new_fd); + } + // If we ever return, we effectively reuse the old Java ZygoteConnection. + // None of its state needs to change. + if (setsockopt(session_socket, SOL_SOCKET, SO_RCVTIMEO, &timeout, timeout_size) != 0) { + fail_fn_z(CREATE_ERROR("Failed to set receive timeout for socket %d: %s", + session_socket, strerror(errno))); + } + if (setsockopt(session_socket, SOL_SOCKET, SO_SNDTIMEO, &timeout, timeout_size) != 0) { + fail_fn_z(CREATE_ERROR("Failed to set send timeout for socket %d: %s", + session_socket, strerror(errno))); + } + if (getsockopt(session_socket, SOL_SOCKET, SO_PEERCRED, &credentials, &cred_size) == -1) { + fail_fn_z(CREATE_ERROR("ForkMany failed to get credentials: %s", strerror(errno))); + } + if (cred_size != sizeof credentials) { + fail_fn_z(CREATE_ERROR("ForkMany credential size = %d, should be %d", + cred_size, static_cast<int>(sizeof credentials))); + } + } + first_time = false; + } while (n_buffer->isSimpleForkCommand(minUid, fail_fn_n)); + ALOGW("forkRepeatedly terminated due to non-simple command"); + n_buffer->logState(); + n_buffer->reset(); + return JNI_FALSE; +} + +#define METHOD_NAME(m) com_android_internal_os_ZygoteCommandBuffer_ ## m + +static const JNINativeMethod gMethods[] = { + {"getNativeBuffer", "(I)J", (void *) METHOD_NAME(getNativeBuffer)}, + {"freeNativeBuffer", "(J)V", (void *) METHOD_NAME(freeNativeBuffer)}, + {"insert", "(JLjava/lang/String;)V", (void *) METHOD_NAME(insert)}, + {"nativeNextArg", "(J)Ljava/lang/String;", (void *) METHOD_NAME(nativeNextArg)}, + {"nativeReadFullyAndReset", "(J)V", (void *) METHOD_NAME(nativeReadFullyAndReset)}, + {"nativeGetCount", "(J)I", (void *) METHOD_NAME(nativeGetCount)}, + {"nativeForkRepeatedly", "(JIIILjava/lang/String;)Z", + (void *) METHOD_NAME(nativeForkRepeatedly)}, +}; + +int register_com_android_internal_os_ZygoteCommandBuffer(JNIEnv* env) { + return RegisterMethodsOrDie(env, "com/android/internal/os/ZygoteCommandBuffer", gMethods, + NELEM(gMethods)); +} + +} // namespace android diff --git a/core/proto/android/service/netstats.proto b/core/proto/android/service/netstats.proto index 8ebb4a9f6649..c8cdfddc3985 100644 --- a/core/proto/android/service/netstats.proto +++ b/core/proto/android/service/netstats.proto @@ -80,6 +80,8 @@ message NetworkIdentityProto { optional bool metered = 5; optional bool default_network = 6; + + optional int32 oem_managed_network = 7; } // Corresponds to NetworkStatsRecorder. diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 2150efef61e8..d5f5d28aa7a2 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -1284,15 +1284,15 @@ android:backgroundPermission="android.permission.RECORD_BACKGROUND_AUDIO" android:protectionLevel="dangerous|instant" /> - <!-- Allows an application to record audio while in the background. - <p>Protection level: dangerous - --> + <!-- @SystemApi @TestApi Allows an application to record audio while in the background. + This permission is not intended to be held by apps. + <p>Protection level: internal + @hide --> <permission android:name="android.permission.RECORD_BACKGROUND_AUDIO" android:permissionGroup="android.permission-group.UNDEFINED" android:label="@string/permlab_recordBackgroundAudio" android:description="@string/permdesc_recordBackgroundAudio" - android:permissionFlags="hardRestricted|installerExemptIgnored" - android:protectionLevel="dangerous" /> + android:protectionLevel="internal" /> <!-- ====================================================================== --> <!-- Permissions for activity recognition --> @@ -1368,15 +1368,15 @@ android:backgroundPermission="android.permission.BACKGROUND_CAMERA" android:protectionLevel="dangerous|instant" /> - <!-- Required to be able to access the camera device in the background. - <p>Protection level: dangerous - --> + <!-- @SystemApi @TestApi Required to be able to access the camera device in the background. + This permission is not intended to be held by apps. + <p>Protection level: internal + @hide --> <permission android:name="android.permission.BACKGROUND_CAMERA" android:permissionGroup="android.permission-group.UNDEFINED" android:label="@string/permlab_backgroundCamera" android:description="@string/permdesc_backgroundCamera" - android:permissionFlags="hardRestricted|installerExemptIgnored" - android:protectionLevel="dangerous" /> + android:protectionLevel="internal" /> <!-- @SystemApi Required in addition to android.permission.CAMERA to be able to access system only camera devices. diff --git a/core/res/res/layout/notification_template_conversation_header.xml b/core/res/res/layout/notification_template_conversation_header.xml index 302a388cf1b2..e01d8035fe35 100644 --- a/core/res/res/layout/notification_template_conversation_header.xml +++ b/core/res/res/layout/notification_template_conversation_header.xml @@ -99,13 +99,26 @@ android:visibility="gone" /> + <TextView + android:id="@+id/verification_divider" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:textAppearance="@style/TextAppearance.DeviceDefault.Notification.Info" + android:layout_marginStart="@dimen/notification_conversation_header_separating_margin" + android:layout_marginEnd="@dimen/notification_conversation_header_separating_margin" + android:text="@string/notification_header_divider_symbol" + android:layout_gravity="center" + android:paddingTop="1sp" + android:singleLine="true" + android:visibility="gone" + /> + <ImageView android:id="@+id/verification_icon" android:layout_width="@dimen/notification_verification_icon_size" android:layout_height="@dimen/notification_verification_icon_size" android:layout_gravity="center" android:layout_marginStart="4dp" - android:contentDescription="@string/notification_alerted_content_description" android:paddingTop="2dp" android:scaleType="fitCenter" android:src="@drawable/ic_notifications_alerted" diff --git a/core/res/res/layout/notification_template_material_base.xml b/core/res/res/layout/notification_template_material_base.xml index d79cb74a3d53..b83611bcc177 100644 --- a/core/res/res/layout/notification_template_material_base.xml +++ b/core/res/res/layout/notification_template_material_base.xml @@ -91,26 +91,11 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center_vertical" - android:layout_marginBottom="@dimen/notification_headerless_margin_minimum" - android:layout_marginTop="@dimen/notification_headerless_margin_minimum" + android:layout_marginBottom="@dimen/notification_headerless_margin_twoline" + android:layout_marginTop="@dimen/notification_headerless_margin_twoline" android:orientation="vertical" > - <!-- - This invisible FrameLayout is here as a collapsible padding. Having a layout_weight=1 is - what causes this view (and it's counterpart at the opposite end) to collapse before the - actual content views do. - This pair of 10dp collapsible paddings (plus the 16dp fixed margins) allow us to support - headerless notifications of 1-3 lines (where each line is 20dp tall) where the 1-line - variant is 56dp and the 2- and 3-line variants are both 76dp. - --> - <FrameLayout - android:id="@+id/notification_headerless_margin_extra_top" - android:layout_width="match_parent" - android:layout_height="@dimen/notification_headerless_margin_extra" - android:layout_weight="1" - /> - <!-- extends ViewGroup --> <NotificationTopLineView android:id="@+id/notification_top_line" @@ -153,12 +138,20 @@ android:orientation="vertical" > - <include - layout="@layout/notification_template_text" + <com.android.internal.widget.NotificationVanishingFrameLayout android:layout_width="match_parent" android:layout_height="@dimen/notification_headerless_line_height" - android:layout_marginTop="0dp" - /> + > + <!-- This is the simplest way to keep this text vertically centered without using + gravity="center_vertical" which causes jumpiness in expansion animations. --> + <include + layout="@layout/notification_template_text" + android:layout_width="match_parent" + android:layout_height="@dimen/notification_text_height" + android:layout_gravity="center_vertical" + android:layout_marginTop="0dp" + /> + </com.android.internal.widget.NotificationVanishingFrameLayout> <include layout="@layout/notification_template_progress" @@ -168,21 +161,6 @@ </LinearLayout> - <!-- - This invisible FrameLayout is here as a collapsible padding. Having a layout_weight=1 is - what causes this view (and it's counterpart at the opposite end) to collapse before the - actual content views do. - This pair of 10dp collapsible paddings (plus the 16dp fixed margins) allow us to support - headerless notifications of 1-3 lines (where each line is 20dp tall) where the 1-line - variant is 56dp and the 2- and 3-line variants are both 76dp. - --> - <FrameLayout - android:id="@+id/notification_headerless_margin_extra_bottom" - android:layout_width="match_parent" - android:layout_height="@dimen/notification_headerless_margin_extra" - android:layout_weight="1" - /> - </LinearLayout> </com.android.internal.widget.NotificationMaxHeightFrameLayout> diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml index aa4baf3c94c0..4b591bf63e7b 100644 --- a/core/res/res/values-af/strings.xml +++ b/core/res/res/values-af/strings.xml @@ -606,7 +606,8 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"Kan nie meer gesig herken nie. Probeer weer."</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"Te eenders. Verander asseblief jou pose."</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"Draai jou kop \'n bietjie minder."</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"Draai jou kop \'n bietjie minder."</string> + <!-- no translation found for face_acquired_tilt_too_extreme (8618210742620248049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"Draai jou kop \'n bietjie minder."</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"Verwyder enigiets wat jou gesig versteek."</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"Maak die bokant van jou skerm skoon, insluitend die swart balk"</string> @@ -1667,7 +1668,8 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Gebruik kortpad"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Kleuromkering"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Kleurkorreksie"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Verminder helderheid"</string> + <!-- no translation found for reduce_bright_colors_feature_name (8978255324027479398) --> + <skip /> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Het volumesleutels ingehou. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> aangeskakel."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Het volumesleutels ingehou. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> is afgeskakel"</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Druk en hou albei volumesleutels drie sekondes lank om <xliff:g id="SERVICE_NAME">%1$s</xliff:g> te gebruik"</string> @@ -1871,8 +1873,7 @@ <string name="stk_cc_ss_to_dial_video" msgid="1324194624384312664">"SS-versoek is na video-oproep toe verander"</string> <string name="stk_cc_ss_to_ussd" msgid="8417905193112944760">"SS-versoek is na USSD-versoek toe verander"</string> <string name="stk_cc_ss_to_ss" msgid="132040645206514450">"Na nuwe SS-versoek toe verander"</string> - <!-- no translation found for notification_phishing_alert_content_description (494227305355958790) --> - <skip /> + <string name="notification_phishing_alert_content_description" msgid="494227305355958790">"Uitvissingwaarskuwing"</string> <string name="notification_work_profile_content_description" msgid="5296477955677725799">"Werkprofiel"</string> <string name="notification_alerted_content_description" msgid="6139691253611265992">"Kennisgewing gegee"</string> <string name="expand_button_content_description_collapsed" msgid="3873368935659010279">"Vou uit"</string> @@ -2220,4 +2221,8 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"Om voort te gaan, moet <b><xliff:g id="APP">%s</xliff:g></b> toegang tot jou toestel se kamera hê."</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Skakel aan"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Sensorprivaatheid"</string> + <!-- no translation found for splash_screen_view_icon_description (180638751260598187) --> + <skip /> + <!-- no translation found for splash_screen_view_branding_description (7911129347402728216) --> + <skip /> </resources> diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml index 9b11350ba686..a43b29a56131 100644 --- a/core/res/res/values-am/strings.xml +++ b/core/res/res/values-am/strings.xml @@ -606,7 +606,8 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"ከእንግዲህ ፊትን ለይቶ ማወቅ አይችልም። እንደገና ይሞክሩ።"</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"በጣም ይመሳሰላል፣ እባክዎ የእርስዎን ፎቶ አነሳስ ይለውጡ"</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"ጭንቅላትዎን ትንሽ ብቻ ያዙሩት።"</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"ጭንቅላትዎን ትንሽ ብቻ ያዙሩት።"</string> + <!-- no translation found for face_acquired_tilt_too_extreme (8618210742620248049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"ጭንቅላትዎን ትንሽ ብቻ ያዙሩት።"</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"የእርስዎን ፊት የሚደብቀውን ሁሉንም ነገር በማስወገድ ላይ"</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"የማያ ገጽዎን አናት ያጽዱት፣ ጥቁር አሞሌውን ጨምሮ"</string> @@ -1667,7 +1668,8 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"አቋራጭ ይጠቀሙ"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"ተቃራኒ ቀለም"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"የቀለም ማስተካከያ"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"ብሩህነትን ይቀንሱ"</string> + <!-- no translation found for reduce_bright_colors_feature_name (8978255324027479398) --> + <skip /> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"የድምፅ ቁልፎችን ይዟል። <xliff:g id="SERVICE_NAME">%1$s</xliff:g> በርቷል።"</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"የድምፅ ቁልፎችን ይዟል። <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ጠፍተዋል።"</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>ን ለመጠቀም ለሦስት ሰከንዶች ሁለቱንም የድምፅ ቁልፎች ተጭነው ይያዙ"</string> @@ -1871,8 +1873,7 @@ <string name="stk_cc_ss_to_dial_video" msgid="1324194624384312664">"የSS ጥያቄ ወደ የቪዲዮ ጥሪ ተለውጧል"</string> <string name="stk_cc_ss_to_ussd" msgid="8417905193112944760">"የSS ጥያቄ ወደ የUSSD ጥያቄ ተለውጧል"</string> <string name="stk_cc_ss_to_ss" msgid="132040645206514450">"ወደ አዲስ የSS ጥያቄ ተለውጧል"</string> - <!-- no translation found for notification_phishing_alert_content_description (494227305355958790) --> - <skip /> + <string name="notification_phishing_alert_content_description" msgid="494227305355958790">"የማስገር ማንቂያ"</string> <string name="notification_work_profile_content_description" msgid="5296477955677725799">"የስራ መገለጫ"</string> <string name="notification_alerted_content_description" msgid="6139691253611265992">"ነቅተዋል"</string> <string name="expand_button_content_description_collapsed" msgid="3873368935659010279">"ዘርጋ"</string> @@ -2220,4 +2221,8 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"ለመቀጠል፣ <b><xliff:g id="APP">%s</xliff:g></b> የመሣሪያዎን ካሜራ መድረስ ይፈልጋል።"</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"አብራ"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"ዳሳሽ ግላዊነት"</string> + <!-- no translation found for splash_screen_view_icon_description (180638751260598187) --> + <skip /> + <!-- no translation found for splash_screen_view_branding_description (7911129347402728216) --> + <skip /> </resources> diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml index bbf30fe42104..3990bab4447b 100644 --- a/core/res/res/values-ar/strings.xml +++ b/core/res/res/values-ar/strings.xml @@ -618,7 +618,8 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"لم يعُد يمكن التعرّف على الوجه. حاول مرة أخرى."</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"الوجه مشابه جدًا، يُرجى تغيير وضعيتك."</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"حرّك رأسك قليلاً نحو الأمام مباشرة."</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"حرّك رأسك قليلاً نحو الأمام مباشرة."</string> + <!-- no translation found for face_acquired_tilt_too_extreme (8618210742620248049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"حرّك رأسك قليلاً نحو الوسط."</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"عليك بإزالة أي شيء يُخفي وجهك."</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"يُرجى تنظيف الجزء العلوي من الشاشة، بما في ذلك الشريط الأسود."</string> @@ -1755,7 +1756,8 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"استخدام الاختصار"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"قلب الألوان"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"تصحيح الألوان"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"تقليل السطوع"</string> + <!-- no translation found for reduce_bright_colors_feature_name (8978255324027479398) --> + <skip /> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"تم الضغط مع الاستمرار على مفتاحَي التحكّم في مستوى الصوت. تم تفعيل <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"تم الضغط مع الاستمرار على مفتاحَي التحكّم في مستوى الصوت. تم إيقاف <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"اضغط مع الاستمرار على مفتاحي مستوى الصوت لمدة 3 ثوانٍ لاستخدام <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string> @@ -1995,8 +1997,7 @@ <string name="stk_cc_ss_to_dial_video" msgid="1324194624384312664">"تم تغيير طلب SS إلى مكالمة فيديو."</string> <string name="stk_cc_ss_to_ussd" msgid="8417905193112944760">"تم تغيير طلب SS إلى طلب USSD."</string> <string name="stk_cc_ss_to_ss" msgid="132040645206514450">"تم التغيير إلى طلب SS الجديد."</string> - <!-- no translation found for notification_phishing_alert_content_description (494227305355958790) --> - <skip /> + <string name="notification_phishing_alert_content_description" msgid="494227305355958790">"تنبيه بشأن تصيّد احتيالي"</string> <string name="notification_work_profile_content_description" msgid="5296477955677725799">"الملف الشخصي للعمل"</string> <string name="notification_alerted_content_description" msgid="6139691253611265992">"تمّ تفعيل التنبيه"</string> <string name="expand_button_content_description_collapsed" msgid="3873368935659010279">"توسيع"</string> @@ -2356,4 +2357,8 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"للمتابعة، يحتاج تطبيق <b><xliff:g id="APP">%s</xliff:g></b> إلى الوصول إلى كاميرا الجهاز."</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"تفعيل"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"الخصوصية في جهاز الاستشعار"</string> + <!-- no translation found for splash_screen_view_icon_description (180638751260598187) --> + <skip /> + <!-- no translation found for splash_screen_view_branding_description (7911129347402728216) --> + <skip /> </resources> diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml index e4f657fb5aec..28af8a3b24e0 100644 --- a/core/res/res/values-as/strings.xml +++ b/core/res/res/values-as/strings.xml @@ -606,7 +606,8 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"মুখমণ্ডল আৰু চিনাক্ত কৰিব নোৱাৰি। আকৌ চেষ্টা কৰক।"</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"একে ধৰণৰ হৈছে, অনুগ্ৰহ কৰি আপোনাৰ প’জটো সলনি কৰক।"</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"আপোনাৰ মূৰটো সামান্য কমকৈ ঘূৰাওক।"</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"আপোনাৰ মূৰটো সামান্য কমকৈ ঘূৰাওক।"</string> + <!-- no translation found for face_acquired_tilt_too_extreme (8618210742620248049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"আপোনাৰ মূৰটো সামান্য কমকৈ ঘূৰাওক।"</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"আপোনাৰ মুখখন ঢাকি ৰখা বস্তুবোৰ আঁতৰাওক।"</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"ক’লা বাৰডালকে ধৰি আপোনাৰ স্ক্রীণৰ ওপৰৰ অংশ চাফা কৰক"</string> @@ -1667,7 +1668,8 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"শ্বৰ্টকাট ব্যৱহাৰ কৰক"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"ৰং বিপৰীতকৰণ"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"ৰং শুধৰণী"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"উজ্জ্বলতা কমাওক"</string> + <!-- no translation found for reduce_bright_colors_feature_name (8978255324027479398) --> + <skip /> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"ভলিউম কীসমূহ ধৰি ৰাখক। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> অন কৰা হ\'ল।"</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"ভলিউম কী ধৰি ৰাখিছিল। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> অফ কৰা হ\'ল।"</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> ব্যৱহাৰ কৰিবলৈ দুয়োটা ভলিউম বুটাম তিনি ছেকেণ্ডৰ বাবে হেঁচি ৰাখক"</string> @@ -2219,4 +2221,8 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"অব্যাহত ৰাখিবলৈ <b><xliff:g id="APP">%s</xliff:g></b>এ আপোনাৰ ডিভাইচৰ কেমেৰা এক্সেছ কৰাৰ আৱশ্যক।"</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"অন কৰক"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"ছেন্সৰ সম্পৰ্কীয় গোপনীয়তাৰ নীতি"</string> + <!-- no translation found for splash_screen_view_icon_description (180638751260598187) --> + <skip /> + <!-- no translation found for splash_screen_view_branding_description (7911129347402728216) --> + <skip /> </resources> diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml index 549784d95765..8459403ff291 100644 --- a/core/res/res/values-az/strings.xml +++ b/core/res/res/values-az/strings.xml @@ -606,7 +606,8 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"Üzü artıq tanımaq olmur. Yenidən cəhd edin."</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"Digəri ilə oxşardır, pozanızı dəyişin."</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"Başınızı bir az döndərin."</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"Başınızı bir az döndərin."</string> + <!-- no translation found for face_acquired_tilt_too_extreme (8618210742620248049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"Başınızı bir az döndərin."</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"Üzünüzü gizlədən maneələri kənarlaşdırın."</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"Qara panel daxil olmaqla, ekranın yuxarısını təmizləyin"</string> @@ -1667,7 +1668,8 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Qısayol İstifadə edin"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Rəng İnversiyası"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Rəng korreksiyası"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Parlaqlığı Azaldın"</string> + <!-- no translation found for reduce_bright_colors_feature_name (8978255324027479398) --> + <skip /> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Səs səviyyəsi düymələrinə basıb saxlayın. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> aktiv edildi."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Səs səviyyəsi düymələrinə basılaraq saxlanıb. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> deaktiv edilib."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> istifadə etmək üçün hər iki səs düyməsini üç saniyə basıb saxlayın"</string> @@ -1871,8 +1873,7 @@ <string name="stk_cc_ss_to_dial_video" msgid="1324194624384312664">"SS sorğusu video zəngə dəyişdirildi"</string> <string name="stk_cc_ss_to_ussd" msgid="8417905193112944760">"SS sorğusu USSD sorğusuna dəyişdirildi"</string> <string name="stk_cc_ss_to_ss" msgid="132040645206514450">"Yeni SS sorğusuna dəyişdirildi"</string> - <!-- no translation found for notification_phishing_alert_content_description (494227305355958790) --> - <skip /> + <string name="notification_phishing_alert_content_description" msgid="494227305355958790">"Fişinq siqnalı"</string> <string name="notification_work_profile_content_description" msgid="5296477955677725799">"İş profili"</string> <string name="notification_alerted_content_description" msgid="6139691253611265992">"Xəbərdarlıq edildi"</string> <string name="expand_button_content_description_collapsed" msgid="3873368935659010279">"Genişləndirin"</string> @@ -2220,4 +2221,8 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"Davam etmək üçün <b><xliff:g id="APP">%s</xliff:g></b> tətbiqi cihazın kamerasına giriş tələb edir."</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Aktiv edin"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Sensor Məxfiliyi"</string> + <!-- no translation found for splash_screen_view_icon_description (180638751260598187) --> + <skip /> + <!-- no translation found for splash_screen_view_branding_description (7911129347402728216) --> + <skip /> </resources> diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml index 5709e3d5f445..a7f6433b4977 100644 --- a/core/res/res/values-b+sr+Latn/strings.xml +++ b/core/res/res/values-b+sr+Latn/strings.xml @@ -609,7 +609,8 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"Više ne može da se prepozna lice. Probajte ponovo."</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"Previše je slično, promenite pozu."</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"Malo manje pomerite glavu."</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"Malo manje pomerite glavu."</string> + <!-- no translation found for face_acquired_tilt_too_extreme (8618210742620248049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"Malo manje pomerite glavu."</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"Uklonite sve što vam zaklanja lice."</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"Očistite gornji deo ekrana, uključujući crnu traku"</string> @@ -1689,7 +1690,8 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Koristi prečicu"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Inverzija boja"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Korekcija boja"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Smanjite osvetljenost"</string> + <!-- no translation found for reduce_bright_colors_feature_name (8978255324027479398) --> + <skip /> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Držali ste tastere za jačinu zvuka. Usluga <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je uključena."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Držali ste tastere za jačinu zvuka. Usluga <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je isključena."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Pritisnite i zadržite oba tastera za jačinu zvuka tri sekunde da biste koristili <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string> @@ -2253,4 +2255,8 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"<b><xliff:g id="APP">%s</xliff:g></b> zahteva pristup kameri uređaja radi nastavljanja."</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Uključi"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Privatnost senzora"</string> + <!-- no translation found for splash_screen_view_icon_description (180638751260598187) --> + <skip /> + <!-- no translation found for splash_screen_view_branding_description (7911129347402728216) --> + <skip /> </resources> diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml index 880c9860b244..1022cef7fbc8 100644 --- a/core/res/res/values-be/strings.xml +++ b/core/res/res/values-be/strings.xml @@ -612,7 +612,8 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"Не ўдаецца распазнаць твар. Паўтарыце спробу."</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"Не бачна розніцы. Памяняйце позу."</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"Вы занадта моцна павярнулі галаву."</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"Галава не ў цэнтры."</string> + <!-- no translation found for face_acquired_tilt_too_extreme (8618210742620248049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"Вы занадта моцна павярнулі галаву."</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"Прыміце ўсё, што закрывае ваш твар."</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"Ачысціце ад бруду верхнюю частку экрана, у тым ліку чорную панэль"</string> @@ -793,7 +794,7 @@ <string name="eventTypeAnniversary" msgid="4684702412407916888">"Гадавіна"</string> <string name="eventTypeOther" msgid="530671238533887997">"Іншае"</string> <string name="emailTypeCustom" msgid="1809435350482181786">"Карыстальніцкая"</string> - <string name="emailTypeHome" msgid="1597116303154775999">"Хатні"</string> + <string name="emailTypeHome" msgid="1597116303154775999">"Асабістая"</string> <string name="emailTypeWork" msgid="2020095414401882111">"Працоўная"</string> <string name="emailTypeOther" msgid="5131130857030897465">"Іншая"</string> <string name="emailTypeMobile" msgid="787155077375364230">"Мабільны"</string> @@ -1711,7 +1712,8 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Выкарыстоўваць камбінацыю хуткага доступу"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Інверсія колеру"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Карэкцыя колеру"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Паменшыць яркасць"</string> + <!-- no translation found for reduce_bright_colors_feature_name (8978255324027479398) --> + <skip /> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Клавішы гучнасці ўтрымліваліся націснутымі. Уключана служба \"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>\"."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Клавішы гучнасці ўтрымліваліся націснутымі. Служба \"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>\" выключана."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Каб карыстацца сэрвісам \"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>\", націсніце і ўтрымлівайце на працягу трох секунд абедзве клавішы гучнасці"</string> @@ -1933,8 +1935,7 @@ <string name="stk_cc_ss_to_dial_video" msgid="1324194624384312664">"SS-запыт заменены на відэавыклік"</string> <string name="stk_cc_ss_to_ussd" msgid="8417905193112944760">"SS-запыт заменены на USSD-запыт"</string> <string name="stk_cc_ss_to_ss" msgid="132040645206514450">"Зроблена замена на новы SS-запыт"</string> - <!-- no translation found for notification_phishing_alert_content_description (494227305355958790) --> - <skip /> + <string name="notification_phishing_alert_content_description" msgid="494227305355958790">"Абвестка пра фішынг"</string> <string name="notification_work_profile_content_description" msgid="5296477955677725799">"Працоўны профіль"</string> <string name="notification_alerted_content_description" msgid="6139691253611265992">"З гукам"</string> <string name="expand_button_content_description_collapsed" msgid="3873368935659010279">"Разгарнуць"</string> @@ -2288,4 +2289,8 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"Каб працягнуць, дайце праграме <b><xliff:g id="APP">%s</xliff:g></b> доступ да камеры прылады."</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Уключыць"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Прыватнасць інфармацыі з датчыка"</string> + <!-- no translation found for splash_screen_view_icon_description (180638751260598187) --> + <skip /> + <!-- no translation found for splash_screen_view_branding_description (7911129347402728216) --> + <skip /> </resources> diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml index 2ed363fca997..ef20bade3275 100644 --- a/core/res/res/values-bg/strings.xml +++ b/core/res/res/values-bg/strings.xml @@ -606,7 +606,8 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"Лицето не бе разпознато. Опитайте отново."</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"Позата ви е сходна с предишна. Моля, променете я."</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"Не завъртайте главата си толкова много."</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"Не завъртайте главата си толкова много."</string> + <!-- no translation found for face_acquired_tilt_too_extreme (8618210742620248049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"Не завъртайте главата си толкова много."</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"Премахнете всичко, което закрива лицето ви."</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"Почистете горната част на екрана си, включително черната лента"</string> @@ -1667,7 +1668,8 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Използване на пряк път"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Инвертиране на цветовете"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Коригиране на цветовете"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Намаляване на яркостта"</string> + <!-- no translation found for reduce_bright_colors_feature_name (8978255324027479398) --> + <skip /> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Задържахте бутоните за силата на звука. Услугата <xliff:g id="SERVICE_NAME">%1$s</xliff:g> е включена."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Задържахте бутоните за силата на звука. Услугата <xliff:g id="SERVICE_NAME">%1$s</xliff:g> е изключена."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"За да използвате <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, натиснете двата бутона за силата на звука и ги задръжте за 3 секунди"</string> @@ -2219,4 +2221,8 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"За да продължите, <b><xliff:g id="APP">%s</xliff:g></b> се нуждае от достъп до камерата на устройството ви."</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Включване"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Поверителност на сензорните данни"</string> + <!-- no translation found for splash_screen_view_icon_description (180638751260598187) --> + <skip /> + <!-- no translation found for splash_screen_view_branding_description (7911129347402728216) --> + <skip /> </resources> diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml index dd38e9aac67f..0e30c046e2f8 100644 --- a/core/res/res/values-bn/strings.xml +++ b/core/res/res/values-bn/strings.xml @@ -606,7 +606,8 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"আর মুখ চিনতে পারবেন না। আবার চেষ্টা করুন।"</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"একই ধরনের দেখতে, একটু অন্যদিকে ঘুরে দাঁড়ান।"</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"আপনার মাথাটি নিচের দিকে সামান্য নামান।"</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"আপনার মাথাটি নিচের দিকে সামান্য নামান।"</string> + <!-- no translation found for face_acquired_tilt_too_extreme (8618210742620248049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"আপনার মাথাটি সামান্য ঘোরান।"</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"আপনার ফেসকে আড়াল করে এমন সব কিছু সরিয়ে দিন।"</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"ব্ল্যাক বার সহ আপনার স্ক্রিনের উপরের অংশ মুছে ফেলুন"</string> @@ -1667,7 +1668,8 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"শর্টকাট ব্যবহার করুন"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"রঙ উল্টানো"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"রঙ সংশোধন"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"উজ্জ্বলতা কমান"</string> + <!-- no translation found for reduce_bright_colors_feature_name (8978255324027479398) --> + <skip /> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"ভলিউম কী ধরে ছিলেন। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> চালু করা হয়েছে।"</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"ভলিউম কী ধরে ছিলেন। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> বন্ধ করা হয়েছে।"</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> ব্যবহার করতে ভলিউম কী বোতাম ৩ সেকেন্ডের জন্য চেপে ধরে রাখুন"</string> @@ -1871,8 +1873,7 @@ <string name="stk_cc_ss_to_dial_video" msgid="1324194624384312664">"SS অনুরোধ ভিডিও কলে পরিবর্তন করা হয়েছে"</string> <string name="stk_cc_ss_to_ussd" msgid="8417905193112944760">"SS অনুরোধ USSD অনুরোধে পরিবর্তন করা হয়েছে"</string> <string name="stk_cc_ss_to_ss" msgid="132040645206514450">"নতুন SS অনুরোধে পরিবর্তন করা হয়েছে"</string> - <!-- no translation found for notification_phishing_alert_content_description (494227305355958790) --> - <skip /> + <string name="notification_phishing_alert_content_description" msgid="494227305355958790">"ফিশিংয়ের সতর্কতা"</string> <string name="notification_work_profile_content_description" msgid="5296477955677725799">"কর্মস্থলের প্রোফাইল"</string> <string name="notification_alerted_content_description" msgid="6139691253611265992">"সতর্ক করা হয়েছে"</string> <string name="expand_button_content_description_collapsed" msgid="3873368935659010279">"বড় করুন"</string> @@ -2220,4 +2221,8 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"চালিয়ে যেতে, <b><xliff:g id="APP">%s</xliff:g></b> আপনার ডিভাইসের ক্যামেরা অ্যাক্সেস করতে চায়।"</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"চালু করুন"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"সেন্সর গোপনীয়তা"</string> + <!-- no translation found for splash_screen_view_icon_description (180638751260598187) --> + <skip /> + <!-- no translation found for splash_screen_view_branding_description (7911129347402728216) --> + <skip /> </resources> diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml index d5b10d52db2d..77b64b52e04a 100644 --- a/core/res/res/values-bs/strings.xml +++ b/core/res/res/values-bs/strings.xml @@ -609,7 +609,8 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"Više nije moguće prepoznati lice. Pokušajte opet."</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"Previše slično, promijenite položaj."</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"Malo manje zakrenite glavu."</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"Malo manje zakrenite glavu."</string> + <!-- no translation found for face_acquired_tilt_too_extreme (8618210742620248049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"Malo manje zakrenite glavu."</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"Uklonite prepreke koje blokiraju vaše lice."</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"Očistite vrh ekrana, uključujući crnu traku"</string> @@ -689,7 +690,7 @@ <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"pokrenuti korištenje odobrenja za pregled"</string> <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Dozvoljava vlasniku da pokrene korištenje odobrenja za aplikaciju. Ne bi trebalo biti potrebno za obične aplikacije."</string> <string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"pristup podacima senzora velikom brzinom uzorkovanja"</string> - <string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"Dozvoljava aplikaciji da uzorkuje podatke senzora većom brzinom od 200 Hz"</string> + <string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"Dozvoljava aplikaciji da uzorkuje podatke senzora brzinom većom od 200 Hz"</string> <string name="policylab_limitPassword" msgid="4851829918814422199">"Postavljanje pravila za lozinke"</string> <string name="policydesc_limitPassword" msgid="4105491021115793793">"Kontrolira dužinu i znakove koji su dozvoljeni u lozinkama za zaključavanje ekrana i PIN-ovima."</string> <string name="policylab_watchLogin" msgid="7599669460083719504">"Prati pokušaje otključavanja ekrana"</string> @@ -1689,7 +1690,8 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Koristi prečicu"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Inverzija boja"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Ispravka boja"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Smanjenje osvjetljenja"</string> + <!-- no translation found for reduce_bright_colors_feature_name (8978255324027479398) --> + <skip /> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Držali ste tipke za jačinu zvuka. Usluga <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je uključena."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Držali ste tipke za jačinu zvuka. Usluga <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je isključena."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Pritisnite obje tipke za podešavanje jačine zvuka i držite ih pritisnutim tri sekunde da koristite uslugu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string> @@ -2253,4 +2255,8 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"Da nastavite, aplikaciji <b><xliff:g id="APP">%s</xliff:g></b> je potreban pristup kameri vašeg uređaja."</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Uključi"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Privatnost senzora"</string> + <!-- no translation found for splash_screen_view_icon_description (180638751260598187) --> + <skip /> + <!-- no translation found for splash_screen_view_branding_description (7911129347402728216) --> + <skip /> </resources> diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml index 280fe1ab030f..a226ac3bc3c2 100644 --- a/core/res/res/values-ca/strings.xml +++ b/core/res/res/values-ca/strings.xml @@ -606,7 +606,8 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"Ja no es reconeix la teva cara. Torna-ho a provar."</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"És massa semblant; canvia de postura."</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"No giris tant el cap."</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"No inclinis tant el cap."</string> + <!-- no translation found for face_acquired_tilt_too_extreme (8618210742620248049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"No giris tant el cap."</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"Suprimeix qualsevol cosa que amagui la teva cara."</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"Neteja la part superior de la pantalla, inclosa la barra negra"</string> @@ -1667,7 +1668,8 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Utilitza la drecera"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Inversió de colors"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Correcció de color"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Reducció de la brillantor"</string> + <!-- no translation found for reduce_bright_colors_feature_name (8978255324027479398) --> + <skip /> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"S\'han mantingut premudes les tecles de volum. S\'ha activat <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"S\'han mantingut premudes les tecles de volum. S\'ha desactivat <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Mantén premudes les dues tecles de volum durant 3 segons per fer servir <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string> @@ -2219,4 +2221,8 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"Per continuar, <b><xliff:g id="APP">%s</xliff:g></b> necessita accedir a la càmera del dispositiu."</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Activa"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Privadesa dels sensors"</string> + <!-- no translation found for splash_screen_view_icon_description (180638751260598187) --> + <skip /> + <!-- no translation found for splash_screen_view_branding_description (7911129347402728216) --> + <skip /> </resources> diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml index 091ed836a37c..fdb2ff1b83f2 100644 --- a/core/res/res/values-cs/strings.xml +++ b/core/res/res/values-cs/strings.xml @@ -612,7 +612,8 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"Obličej už nelze rozpoznat. Zkuste to znovu."</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"Příliš podobné, změňte výraz."</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"Natočte hlavu o něco méně."</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"Natočte hlavu o něco méně."</string> + <!-- no translation found for face_acquired_tilt_too_extreme (8618210742620248049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"Natočte hlavu o něco méně."</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"Odstraňte vše, co vám zakrývá obličej."</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"Očistěte horní část obrazovky včetně černé části"</string> @@ -1711,7 +1712,8 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Použít zkratku"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Převrácení barev"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Oprava barev"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Snížit jas"</string> + <!-- no translation found for reduce_bright_colors_feature_name (8978255324027479398) --> + <skip /> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Byla podržena tlačítka hlasitosti. Služba <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je zapnutá."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Byla podržena tlačítka hlasitosti. Služba <xliff:g id="SERVICE_NAME">%1$s</xliff:g> byla vypnuta."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Chcete-li používat službu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, tři sekundy podržte stisknutá obě tlačítka hlasitosti"</string> @@ -1933,8 +1935,7 @@ <string name="stk_cc_ss_to_dial_video" msgid="1324194624384312664">"Požadavek SS byl změněn na videohovor"</string> <string name="stk_cc_ss_to_ussd" msgid="8417905193112944760">"Požadavek SS byl změněn na požadavek USSD"</string> <string name="stk_cc_ss_to_ss" msgid="132040645206514450">"Změněno na nový požadavek SS"</string> - <!-- no translation found for notification_phishing_alert_content_description (494227305355958790) --> - <skip /> + <string name="notification_phishing_alert_content_description" msgid="494227305355958790">"Upozornění na phishing"</string> <string name="notification_work_profile_content_description" msgid="5296477955677725799">"Pracovní profil"</string> <string name="notification_alerted_content_description" msgid="6139691253611265992">"Upozorněno"</string> <string name="expand_button_content_description_collapsed" msgid="3873368935659010279">"Rozbalit"</string> @@ -2288,4 +2289,8 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"Než budete pokračovat, udělte aplikaci <b><xliff:g id="APP">%s</xliff:g></b> přístup k fotoaparátu na zařízení."</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Zapnout"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Ochrana soukromí – senzor"</string> + <!-- no translation found for splash_screen_view_icon_description (180638751260598187) --> + <skip /> + <!-- no translation found for splash_screen_view_branding_description (7911129347402728216) --> + <skip /> </resources> diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml index 8e191003ca9d..dddc07037201 100644 --- a/core/res/res/values-da/strings.xml +++ b/core/res/res/values-da/strings.xml @@ -608,7 +608,8 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"Ansigtet kan ikke længere genkendes. Prøv igen."</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"Det minder for meget om et andet. Skift stilling."</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"Du skal ikke dreje hovedet så meget."</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"Du skal ikke dreje hovedet så meget."</string> + <!-- no translation found for face_acquired_tilt_too_extreme (8618210742620248049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"Du skal ikke dreje hovedet så meget."</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"Hvis noget skjuler dit ansigt, skal du fjerne det."</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"Rengør toppen af din skærm, inkl. den sorte bjælke"</string> @@ -1669,7 +1670,8 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Brug genvej"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Ombytning af farver"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Korriger farve"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Reducer lysstyrken"</string> + <!-- no translation found for reduce_bright_colors_feature_name (8978255324027479398) --> + <skip /> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Lydstyrkeknapperne blev holdt nede. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> er aktiveret."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Lydstyrkeknapperne blev holdt nede. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> er deaktiveret."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Hold begge lydstyrkeknapper nede i tre sekunder for at bruge <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string> @@ -1873,8 +1875,7 @@ <string name="stk_cc_ss_to_dial_video" msgid="1324194624384312664">"SS-anmodningen blev ændret til et videoopkald"</string> <string name="stk_cc_ss_to_ussd" msgid="8417905193112944760">"SS-anmodningen blev ændret til en USSD-anmodning"</string> <string name="stk_cc_ss_to_ss" msgid="132040645206514450">"Ændret til en SS-anmodning"</string> - <!-- no translation found for notification_phishing_alert_content_description (494227305355958790) --> - <skip /> + <string name="notification_phishing_alert_content_description" msgid="494227305355958790">"Phishingadvarsel"</string> <string name="notification_work_profile_content_description" msgid="5296477955677725799">"Arbejdsprofil"</string> <string name="notification_alerted_content_description" msgid="6139691253611265992">"Underrettet"</string> <string name="expand_button_content_description_collapsed" msgid="3873368935659010279">"Udvid"</string> @@ -2222,4 +2223,8 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"<b><xliff:g id="APP">%s</xliff:g></b> skal have adgang til din enheds kamera, før den kan fortsætte."</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Aktivér"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Beskyttelse af sensoroplysninger"</string> + <!-- no translation found for splash_screen_view_icon_description (180638751260598187) --> + <skip /> + <!-- no translation found for splash_screen_view_branding_description (7911129347402728216) --> + <skip /> </resources> diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml index d9710e6eee64..472f1d216f15 100644 --- a/core/res/res/values-de/strings.xml +++ b/core/res/res/values-de/strings.xml @@ -606,7 +606,8 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"Gesicht wird nicht mehr erkannt. Erneut versuchen."</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"Zu ähnlich. Bitte dreh deinen Kopf etwas."</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"Dreh den Kopf etwas weniger zur Seite."</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"Neig den Kopf etwas weniger stark."</string> + <!-- no translation found for face_acquired_tilt_too_extreme (8618210742620248049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"Neig den Kopf etwas weniger stark."</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"Entferne alles, was dein Gesicht verdeckt."</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"Reinige den oberen Teil deines Bildschirms, einschließlich der schwarzen Leiste"</string> @@ -1667,7 +1668,8 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Verknüpfung verwenden"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Farbumkehr"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Farbkorrektur"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Helligkeit verringern"</string> + <!-- no translation found for reduce_bright_colors_feature_name (8978255324027479398) --> + <skip /> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Lautstärketasten wurden gedrückt gehalten. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ist aktiviert."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Lautstärketasten wurden gedrückt gehalten. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ist deaktiviert."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Halten Sie beide Lautstärketasten drei Sekunden lang gedrückt, um <xliff:g id="SERVICE_NAME">%1$s</xliff:g> zu verwenden"</string> @@ -2219,4 +2221,8 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"Zum Fortfahren benötigt <b><xliff:g id="APP">%s</xliff:g></b> Zugriff auf die Kamera deines Geräts."</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Aktivieren"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Datenschutz für Sensoren"</string> + <!-- no translation found for splash_screen_view_icon_description (180638751260598187) --> + <skip /> + <!-- no translation found for splash_screen_view_branding_description (7911129347402728216) --> + <skip /> </resources> diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml index 358a1f192cd0..22b3401cf89b 100644 --- a/core/res/res/values-el/strings.xml +++ b/core/res/res/values-el/strings.xml @@ -606,7 +606,8 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"Αδύνατη η αναγνώριση του προσώπου. Επανάληψη."</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"Πολύ παρόμοιο, αλλάξτε την πόζα σας."</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"Στρέψτε λιγότερο το κεφάλι σας."</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"Στρέψτε λιγότερο το κεφάλι σας."</string> + <!-- no translation found for face_acquired_tilt_too_extreme (8618210742620248049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"Στρέψτε λιγότερο το κεφάλι σας."</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"Απομακρύνετε οτιδήποτε κρύβει το πρόσωπό σας."</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"Καθαρίστε το επάνω μέρος της οθόνης σας, συμπεριλαμβανομένης της μαύρης γραμμής"</string> @@ -1667,7 +1668,8 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Χρήση συντόμευσης"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Αντιστροφή χρωμάτων"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Διόρθωση χρωμάτων"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Μείωση φωτεινότητας"</string> + <!-- no translation found for reduce_bright_colors_feature_name (8978255324027479398) --> + <skip /> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Τα πλήκτρα έντασης είναι πατημένα. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ενεργοποιήθηκε."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Τα πλήκτρα έντασης είναι πατημένα. <xliff:g id="SERVICE_NAME">%1$s</xliff:g>: απενεργοποιημένο"</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Πατήστε παρατεταμένα και τα δύο κουμπιά έντασης ήχου για τρία δευτερόλεπτα, ώστε να χρησιμοποιήσετε την υπηρεσία <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string> @@ -1871,8 +1873,7 @@ <string name="stk_cc_ss_to_dial_video" msgid="1324194624384312664">"Το αίτημα SS τροποποιήθηκε σε βιντεοκλήση"</string> <string name="stk_cc_ss_to_ussd" msgid="8417905193112944760">"Το αίτημα SS τροποποιήθηκε σε αίτημα USSD"</string> <string name="stk_cc_ss_to_ss" msgid="132040645206514450">"Τροποποιήθηκε σε νέο αίτημα SS"</string> - <!-- no translation found for notification_phishing_alert_content_description (494227305355958790) --> - <skip /> + <string name="notification_phishing_alert_content_description" msgid="494227305355958790">"Ειδοποίηση ηλεκτρονικού ψαρέματος (phishing)"</string> <string name="notification_work_profile_content_description" msgid="5296477955677725799">"Προφίλ εργασίας"</string> <string name="notification_alerted_content_description" msgid="6139691253611265992">"Ειδοποιήθηκε"</string> <string name="expand_button_content_description_collapsed" msgid="3873368935659010279">"Ανάπτυξη"</string> @@ -2220,4 +2221,8 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"Για να συνεχίσετε, η εφαρμογή <b><xliff:g id="APP">%s</xliff:g></b> χρειάζεται πρόσβαση στην κάμερα της συσκευής σας."</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Ενεργοποίηση"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Απόρρητο αισθητήρα"</string> + <!-- no translation found for splash_screen_view_icon_description (180638751260598187) --> + <skip /> + <!-- no translation found for splash_screen_view_branding_description (7911129347402728216) --> + <skip /> </resources> diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml index 058ae7748dab..f2cbb75f6580 100644 --- a/core/res/res/values-en-rAU/strings.xml +++ b/core/res/res/values-en-rAU/strings.xml @@ -606,7 +606,7 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"No longer able to recognise face. Try again."</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"Too similar, please change your pose."</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"Turn your head a little less."</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"Turn your head a little less."</string> + <string name="face_acquired_tilt_too_extreme" msgid="8618210742620248049">"Tilt your head a little less."</string> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"Turn your head a little less."</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"Remove anything hiding your face."</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"Clean the top of your screen, including the black bar"</string> @@ -1667,7 +1667,7 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Use Shortcut"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Colour Inversion"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Colour correction"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Reduce Brightness"</string> + <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"Reduce brightness"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Held volume keys. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> turned on."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Held volume keys. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> turned off."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Press and hold both volume keys for three seconds to use <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string> @@ -2219,4 +2219,6 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"To continue, <b><xliff:g id="APP">%s</xliff:g></b> needs access to your device’s camera."</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Turn on"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Sensor privacy"</string> + <string name="splash_screen_view_icon_description" msgid="180638751260598187">"Application icon"</string> + <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Application branding image"</string> </resources> diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml index d91b3d0ed4ed..f440c8ac2263 100644 --- a/core/res/res/values-en-rCA/strings.xml +++ b/core/res/res/values-en-rCA/strings.xml @@ -606,7 +606,7 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"No longer able to recognise face. Try again."</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"Too similar, please change your pose."</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"Turn your head a little less."</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"Turn your head a little less."</string> + <string name="face_acquired_tilt_too_extreme" msgid="8618210742620248049">"Tilt your head a little less."</string> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"Turn your head a little less."</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"Remove anything hiding your face."</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"Clean the top of your screen, including the black bar"</string> @@ -1667,7 +1667,7 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Use Shortcut"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Colour inversion"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Colour correction"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Reduce Brightness"</string> + <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"Reduce brightness"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Held volume keys. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> turned on."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Held volume keys. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> turned off."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Press and hold both volume keys for three seconds to use <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string> @@ -2219,4 +2219,6 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"To continue, <b><xliff:g id="APP">%s</xliff:g></b> needs access to your device’s camera."</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Turn on"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Sensor privacy"</string> + <string name="splash_screen_view_icon_description" msgid="180638751260598187">"Application icon"</string> + <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Application branding image"</string> </resources> diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml index 60950ee208b4..93881e992d84 100644 --- a/core/res/res/values-en-rGB/strings.xml +++ b/core/res/res/values-en-rGB/strings.xml @@ -606,7 +606,7 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"No longer able to recognise face. Try again."</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"Too similar, please change your pose."</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"Turn your head a little less."</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"Turn your head a little less."</string> + <string name="face_acquired_tilt_too_extreme" msgid="8618210742620248049">"Tilt your head a little less."</string> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"Turn your head a little less."</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"Remove anything hiding your face."</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"Clean the top of your screen, including the black bar"</string> @@ -1667,7 +1667,7 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Use Shortcut"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Colour Inversion"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Colour correction"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Reduce Brightness"</string> + <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"Reduce brightness"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Held volume keys. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> turned on."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Held volume keys. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> turned off."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Press and hold both volume keys for three seconds to use <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string> @@ -2219,4 +2219,6 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"To continue, <b><xliff:g id="APP">%s</xliff:g></b> needs access to your device’s camera."</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Turn on"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Sensor privacy"</string> + <string name="splash_screen_view_icon_description" msgid="180638751260598187">"Application icon"</string> + <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Application branding image"</string> </resources> diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml index 1915d45370f8..a7fa30ebc2d9 100644 --- a/core/res/res/values-en-rIN/strings.xml +++ b/core/res/res/values-en-rIN/strings.xml @@ -606,7 +606,7 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"No longer able to recognise face. Try again."</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"Too similar, please change your pose."</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"Turn your head a little less."</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"Turn your head a little less."</string> + <string name="face_acquired_tilt_too_extreme" msgid="8618210742620248049">"Tilt your head a little less."</string> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"Turn your head a little less."</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"Remove anything hiding your face."</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"Clean the top of your screen, including the black bar"</string> @@ -1667,7 +1667,7 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Use Shortcut"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Colour Inversion"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Color correction"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Reduce Brightness"</string> + <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"Reduce brightness"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Held volume keys. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> turned on."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Held volume keys. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> turned off."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Press and hold both volume keys for three seconds to use <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string> @@ -2219,4 +2219,6 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"To continue, <b><xliff:g id="APP">%s</xliff:g></b> needs access to your device’s camera."</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Turn on"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Sensor privacy"</string> + <string name="splash_screen_view_icon_description" msgid="180638751260598187">"Application icon"</string> + <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Application branding image"</string> </resources> diff --git a/core/res/res/values-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml index 0a90aeacfd77..ce9a915f9c2a 100644 --- a/core/res/res/values-en-rXC/strings.xml +++ b/core/res/res/values-en-rXC/strings.xml @@ -606,7 +606,7 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"No longer able to recognize face. Try again."</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"Too similar, please change your pose."</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"Turn your head a little less."</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"Turn your head a little less."</string> + <string name="face_acquired_tilt_too_extreme" msgid="8618210742620248049">"Tilt your head a little less."</string> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"Turn your head a little less."</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"Remove anything hiding your face."</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"Clean the top of your screen, including the black bar"</string> @@ -1667,7 +1667,7 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Use Shortcut"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Color Inversion"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Color Correction"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Reduce Brightness"</string> + <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"Reduce brightness"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Held volume keys. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> turned on."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Held volume keys. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> turned off."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Press and hold both volume keys for three seconds to use <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string> @@ -2219,4 +2219,6 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"To continue, <b><xliff:g id="APP">%s</xliff:g></b> needs access to your device’s camera."</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Turn on"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Sensor Privacy"</string> + <string name="splash_screen_view_icon_description" msgid="180638751260598187">"Application icon"</string> + <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Application branding image"</string> </resources> diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml index e81d6d158fe6..01d0c7e06c73 100644 --- a/core/res/res/values-es-rUS/strings.xml +++ b/core/res/res/values-es-rUS/strings.xml @@ -606,7 +606,8 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"Ya no se reconoce el rostro. Vuelve a intentarlo."</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"Es muy similar a la anterior. Haz otra pose."</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"Gira la cabeza un poco menos."</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"Gira la cabeza un poco menos."</string> + <!-- no translation found for face_acquired_tilt_too_extreme (8618210742620248049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"Gira la cabeza un poco menos."</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"Quítate cualquier objeto que te cubra el rostro."</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"Limpia la parte superior de la pantalla, incluida la barra negra"</string> @@ -1667,7 +1668,8 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Usar acceso directo"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Inversión de color"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Corrección de color"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Reducir el brillo"</string> + <!-- no translation found for reduce_bright_colors_feature_name (8978255324027479398) --> + <skip /> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Como mantuviste presionadas las teclas de volumen, se activó <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Se presionaron las teclas de volumen. Se desactivó <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Mantén presionadas ambas teclas de volumen durante tres segundos para usar <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string> @@ -1871,8 +1873,7 @@ <string name="stk_cc_ss_to_dial_video" msgid="1324194624384312664">"Se cambió la solicitud SS por una videollamada"</string> <string name="stk_cc_ss_to_ussd" msgid="8417905193112944760">"Se cambió la solicitud SS por una solicitud USSD"</string> <string name="stk_cc_ss_to_ss" msgid="132040645206514450">"Se cambió a una nueva solicitud SS"</string> - <!-- no translation found for notification_phishing_alert_content_description (494227305355958790) --> - <skip /> + <string name="notification_phishing_alert_content_description" msgid="494227305355958790">"Alerta de suplantación de identidad (phishing)"</string> <string name="notification_work_profile_content_description" msgid="5296477955677725799">"Perfil de trabajo"</string> <string name="notification_alerted_content_description" msgid="6139691253611265992">"Alerta enviada"</string> <string name="expand_button_content_description_collapsed" msgid="3873368935659010279">"Expandir"</string> @@ -2220,4 +2221,8 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"Para continuar, <b><xliff:g id="APP">%s</xliff:g></b&gt necesita acceso a la cámara del dispositivo."</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Activar"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Privacidad del sensor"</string> + <!-- no translation found for splash_screen_view_icon_description (180638751260598187) --> + <skip /> + <!-- no translation found for splash_screen_view_branding_description (7911129347402728216) --> + <skip /> </resources> diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml index 70cac4a58781..28ff5fb61b22 100644 --- a/core/res/res/values-es/strings.xml +++ b/core/res/res/values-es/strings.xml @@ -606,7 +606,8 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"No puede reconocer tu cara. Vuelve a intentarlo."</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"Se parece mucha a la anterior. Pon otra cara."</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"Gira la cabeza un poco menos."</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"Gira la cabeza un poco menos."</string> + <!-- no translation found for face_acquired_tilt_too_extreme (8618210742620248049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"No gires tanto la cabeza."</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"Retira cualquier objeto que te tape la cara."</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"Limpia la parte superior de la pantalla, incluida la barra de color negro"</string> @@ -1667,7 +1668,8 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Utilizar acceso directo"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Inversión de color"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Corrección de color"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Reducir brillo"</string> + <!-- no translation found for reduce_bright_colors_feature_name (8978255324027479398) --> + <skip /> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Al mantener pulsadas las teclas de volumen, se ha activado <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Se han mantenido pulsadas las teclas de volumen. Se ha desactivado <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Para utilizar <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, mantén pulsadas ambas teclas de volumen durante 3 segundos"</string> @@ -1871,8 +1873,7 @@ <string name="stk_cc_ss_to_dial_video" msgid="1324194624384312664">"Se ha cambiado la solicitud de SS a una videollamada"</string> <string name="stk_cc_ss_to_ussd" msgid="8417905193112944760">"Se ha cambiado la solicitud de SS a una solicitud de USSD"</string> <string name="stk_cc_ss_to_ss" msgid="132040645206514450">"Se ha cambiado a una nueva solicitud de SS"</string> - <!-- no translation found for notification_phishing_alert_content_description (494227305355958790) --> - <skip /> + <string name="notification_phishing_alert_content_description" msgid="494227305355958790">"Alerta de phishing"</string> <string name="notification_work_profile_content_description" msgid="5296477955677725799">"Perfil de trabajo"</string> <string name="notification_alerted_content_description" msgid="6139691253611265992">"Con sonido"</string> <string name="expand_button_content_description_collapsed" msgid="3873368935659010279">"Mostrar"</string> @@ -2220,4 +2221,8 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"Para continuar, <b><xliff:g id="APP">%s</xliff:g></b> necesita tener acceso a la cámara del dispositivo."</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Activar"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Privacidad del sensor"</string> + <!-- no translation found for splash_screen_view_icon_description (180638751260598187) --> + <skip /> + <!-- no translation found for splash_screen_view_branding_description (7911129347402728216) --> + <skip /> </resources> diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml index 2a2db3af8f43..cb2bcdc3d463 100644 --- a/core/res/res/values-et/strings.xml +++ b/core/res/res/values-et/strings.xml @@ -606,7 +606,8 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"Nägu ei õnnestu enam tuvastada. Proovige uuesti."</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"Liiga sarnane, palun muutke oma asendit."</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"Pöörake oma pead veidi vähem."</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"Pöörake oma pead veidi vähem."</string> + <!-- no translation found for face_acquired_tilt_too_extreme (8618210742620248049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"Pöörake oma pead veidi vähem."</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"Eemaldage kõik, mis varjab teie nägu."</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"Puhastage ekraani ülaosa, sh musta värvi riba"</string> @@ -1667,7 +1668,8 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Kasuta otseteed"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Värvide ümberpööramine"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Värvide korrigeerimine"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Ereduse vähendamine"</string> + <!-- no translation found for reduce_bright_colors_feature_name (8978255324027479398) --> + <skip /> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Helitugevuse klahve hoiti all. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> lülitati sisse."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Helitugevuse klahve hoiti all. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> lülitati välja."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Teenuse <xliff:g id="SERVICE_NAME">%1$s</xliff:g> kasutamiseks hoidke kolm sekundit all mõlemat helitugevuse klahvi"</string> @@ -1871,8 +1873,7 @@ <string name="stk_cc_ss_to_dial_video" msgid="1324194624384312664">"SS-taotlus muudeti videokõneks"</string> <string name="stk_cc_ss_to_ussd" msgid="8417905193112944760">"SS-taotlus muudeti USSD-taotluseks"</string> <string name="stk_cc_ss_to_ss" msgid="132040645206514450">"Muudeti uueks SS-taotluseks"</string> - <!-- no translation found for notification_phishing_alert_content_description (494227305355958790) --> - <skip /> + <string name="notification_phishing_alert_content_description" msgid="494227305355958790">"Andmepüügihoiatus"</string> <string name="notification_work_profile_content_description" msgid="5296477955677725799">"Tööprofiil"</string> <string name="notification_alerted_content_description" msgid="6139691253611265992">"Teavitatud"</string> <string name="expand_button_content_description_collapsed" msgid="3873368935659010279">"Laienda"</string> @@ -2220,4 +2221,8 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"Jätkamiseks vajab rakendus <b><xliff:g id="APP">%s</xliff:g></b> juurdepääsu teie seadme kaamerale."</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Lülita sisse"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Anduri privaatsus"</string> + <!-- no translation found for splash_screen_view_icon_description (180638751260598187) --> + <skip /> + <!-- no translation found for splash_screen_view_branding_description (7911129347402728216) --> + <skip /> </resources> diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml index 901d8661e411..f95c2796557c 100644 --- a/core/res/res/values-eu/strings.xml +++ b/core/res/res/values-eu/strings.xml @@ -451,7 +451,7 @@ <string name="permdesc_camera" msgid="5240801376168647151">"Aplikazioak abian den bitartean erabil dezake kamera argazkiak ateratzeko eta bideoak grabatzeko."</string> <string name="permlab_backgroundCamera" msgid="7549917926079731681">"Argazkiak atera eta bideoak grabatu atzeko planoan."</string> <string name="permdesc_backgroundCamera" msgid="1615291686191138250">"Aplikazioak edonoiz erabil dezake kamera argazkiak ateratzeko eta bideoak grabatzeko."</string> - <string name="permlab_systemCamera" msgid="3642917457796210580">"onartu aplikazio edo zerbitzu bati sistemako kamerak atzitzea argazkiak eta bideoak ateratzeko"</string> + <string name="permlab_systemCamera" msgid="3642917457796210580">"eman sistemako kamerak atzitzeko baimena aplikazio edo zerbitzu bati argazkiak ateratzeko eta bideoak grabatzeko"</string> <string name="permdesc_systemCamera" msgid="5938360914419175986">"Pribilegioa duen edo sistemakoa den aplikazio honek edonoiz erabil dezake kamera argazkiak ateratzeko eta bideoak grabatzeko. Halaber, android.permission.CAMERA baimena izan behar du aplikazioak."</string> <string name="permlab_cameraOpenCloseListener" msgid="5548732769068109315">"eman jakinarazpenak jasotzeko baimena aplikazioari edo zerbitzuari kamerak ireki edo ixten direnean."</string> <string name="permdesc_cameraOpenCloseListener" msgid="2002636131008772908">"Kamera ireki edo itxi dela (eta zer aplikaziorekin) dioten jakinarazpenak jaso ditzake aplikazio honek."</string> @@ -606,7 +606,8 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"Ez dugu ezagutzen aurpegi hori. Saiatu berriro."</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"Jarrera berdintsuegia da. Alda ezazu."</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"Biratu burua pixka bat gutxiago."</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"Biratu burua pixka bat gutxiago."</string> + <!-- no translation found for face_acquired_tilt_too_extreme (8618210742620248049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"Biratu burua pixka bat gutxiago."</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"Kendu aurpegia estaltzen dizuten gauzak."</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"Garbitu pantailaren goialdea, barra beltza barne"</string> @@ -1667,7 +1668,8 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Erabili lasterbidea"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Koloreen alderantzikatzea"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Koloreen zuzenketa"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Murriztu distira"</string> + <!-- no translation found for reduce_bright_colors_feature_name (8978255324027479398) --> + <skip /> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Bolumen-botoiak sakatuta eduki direnez, <xliff:g id="SERVICE_NAME">%1$s</xliff:g> aktibatu egin da."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Bolumen-botoiak sakatuta eduki direnez, <xliff:g id="SERVICE_NAME">%1$s</xliff:g> desaktibatu egin da."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> erabiltzeko, eduki sakatuta bi bolumen-botoiak hiru segundoz"</string> @@ -2219,4 +2221,8 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"Aurrera egiteko, gailuaren kamera atzitzeko baimena behar du <b><xliff:g id="APP">%s</xliff:g></b> aplikazioak."</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Aktibatu"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Sentsoreen pribatutasuna"</string> + <!-- no translation found for splash_screen_view_icon_description (180638751260598187) --> + <skip /> + <!-- no translation found for splash_screen_view_branding_description (7911129347402728216) --> + <skip /> </resources> diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml index ec195e53364b..714b5e4635ad 100644 --- a/core/res/res/values-fa/strings.xml +++ b/core/res/res/values-fa/strings.xml @@ -606,7 +606,8 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"دیگر چهره را تشخیص نمیدهد. دوباره امتحان کنید."</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"بسیار شبیه قبلی است، لطفاً قیافه دیگری بگیرید."</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"سرتان را کمی صاف بگیرید."</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"سرتان را کمی صاف بگیرید."</string> + <!-- no translation found for face_acquired_tilt_too_extreme (8618210742620248049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"سرتان را کمی صاف بگیرید."</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"هرچیزی را که حائل چهرهتان است بردارید."</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"بالای صفحه و همچنین نوار مشکی را تمیز کنید."</string> @@ -1667,7 +1668,8 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"استفاده از میانبر"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"وارونگی رنگ"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"تصحیح رنگ"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"کاهش روشنایی"</string> + <!-- no translation found for reduce_bright_colors_feature_name (8978255324027479398) --> + <skip /> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"کلیدهای میزان صدا پایین نگه داشته شد. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> روشن شد."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"کلیدهای میزان صدا پایین نگه داشته شد. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> خاموش شد."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"برای استفاده از <xliff:g id="SERVICE_NAME">%1$s</xliff:g>، هر دو کلید صدا را فشار دهید و سه ثانیه نگه دارید"</string> @@ -1871,8 +1873,7 @@ <string name="stk_cc_ss_to_dial_video" msgid="1324194624384312664">"درخواست SS به تماس تصویری تغییر کرد"</string> <string name="stk_cc_ss_to_ussd" msgid="8417905193112944760">"درخواست SS به درخواست USSD تغییر کرد"</string> <string name="stk_cc_ss_to_ss" msgid="132040645206514450">"به درخواست SS جدید تغییر کرد"</string> - <!-- no translation found for notification_phishing_alert_content_description (494227305355958790) --> - <skip /> + <string name="notification_phishing_alert_content_description" msgid="494227305355958790">"هشدار رمزگیری"</string> <string name="notification_work_profile_content_description" msgid="5296477955677725799">"نمایه کاری"</string> <string name="notification_alerted_content_description" msgid="6139691253611265992">"هشدار ارسال شد"</string> <string name="expand_button_content_description_collapsed" msgid="3873368935659010279">"بزرگ کردن"</string> @@ -2220,4 +2221,8 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"برای ادامه دادن، <b><xliff:g id="APP">%s</xliff:g></b> باید به دوربین دستگاه دسترسی داشته باشد."</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"روشن کردن"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"حریمخصوصی حسگر"</string> + <!-- no translation found for splash_screen_view_icon_description (180638751260598187) --> + <skip /> + <!-- no translation found for splash_screen_view_branding_description (7911129347402728216) --> + <skip /> </resources> diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml index 6773dde66de5..ef872e98f6c3 100644 --- a/core/res/res/values-fi/strings.xml +++ b/core/res/res/values-fi/strings.xml @@ -606,7 +606,8 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"Ei enää tunnista kasvoja. Yritä uudelleen."</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"Liian samanlainen, vaihda asentoa."</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"Käännä päätä vähän vähemmän."</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"Käännä päätä vähän vähemmän."</string> + <!-- no translation found for face_acquired_tilt_too_extreme (8618210742620248049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"Käännä päätä vähän vähemmän."</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"Poista esteet kasvojesi edestä."</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"Puhdista näytön yläreuna, mukaan lukien musta palkki"</string> @@ -1667,7 +1668,8 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Käytä pikanäppäintä"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Käänteiset värit"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Värinkorjaus"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Vähennä kirkkautta"</string> + <!-- no translation found for reduce_bright_colors_feature_name (8978255324027479398) --> + <skip /> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Äänenvoimakkuuspainikkeita painettiin pitkään. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> laitettiin päälle."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Äänenvoimakkuuspainikkeita painettiin pitkään. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> laitettiin pois päältä."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Voit käyttää palvelua <xliff:g id="SERVICE_NAME">%1$s</xliff:g> painamalla molempia äänenvoimakkuuspainikkeita kolmen sekunnin ajan"</string> @@ -1871,8 +1873,7 @@ <string name="stk_cc_ss_to_dial_video" msgid="1324194624384312664">"SS-pyyntö vaihdettu videopuheluksi"</string> <string name="stk_cc_ss_to_ussd" msgid="8417905193112944760">"SS-pyyntö vaihdettu USSD-pyynnöksi"</string> <string name="stk_cc_ss_to_ss" msgid="132040645206514450">"Vaihdettu uudeksi SS-pyynnöksi"</string> - <!-- no translation found for notification_phishing_alert_content_description (494227305355958790) --> - <skip /> + <string name="notification_phishing_alert_content_description" msgid="494227305355958790">"Varoitus tietojenkalastelusta"</string> <string name="notification_work_profile_content_description" msgid="5296477955677725799">"Työprofiili"</string> <string name="notification_alerted_content_description" msgid="6139691253611265992">"Hälytti"</string> <string name="expand_button_content_description_collapsed" msgid="3873368935659010279">"Laajenna"</string> @@ -2220,4 +2221,8 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"Jotta voit jatkaa, <b><xliff:g id="APP">%s</xliff:g></b> tarvitsee pääsyn laitteesi kameraan."</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Laita päälle"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Anturin tietosuoja"</string> + <!-- no translation found for splash_screen_view_icon_description (180638751260598187) --> + <skip /> + <!-- no translation found for splash_screen_view_branding_description (7911129347402728216) --> + <skip /> </resources> diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml index 9c4f92a0bc44..7cc316077b1f 100644 --- a/core/res/res/values-fr-rCA/strings.xml +++ b/core/res/res/values-fr-rCA/strings.xml @@ -606,7 +606,8 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"Ce visage ne sera plus reconnu. Réessayez."</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"Trop similaire. Changez de pose."</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"Tournez un peu moins votre tête."</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"Tournez un peu moins votre tête."</string> + <!-- no translation found for face_acquired_tilt_too_extreme (8618210742620248049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"Tournez un peu moins votre tête."</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"Retirez tout ce qui pourrait couvrir votre visage."</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"Nettoyez le haut de l\'écran, y compris la barre noire"</string> @@ -1667,7 +1668,8 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Utiliser le raccourci"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Inversion des couleurs"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Correction des couleurs"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Réduire la luminosité"</string> + <!-- no translation found for reduce_bright_colors_feature_name (8978255324027479398) --> + <skip /> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Touches de volume maintenues enfoncées. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> activé."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Touches de volume maintenues enfoncées. Service <xliff:g id="SERVICE_NAME">%1$s</xliff:g> désactivé."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Maintenez enfoncées les deux touches de volume pendant trois secondes pour utiliser <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string> @@ -1871,8 +1873,7 @@ <string name="stk_cc_ss_to_dial_video" msgid="1324194624384312664">"La demande SS a été remplacée par une demande d\'appel vidéo"</string> <string name="stk_cc_ss_to_ussd" msgid="8417905193112944760">"La demande SS a été remplacée par une demande USSD"</string> <string name="stk_cc_ss_to_ss" msgid="132040645206514450">"La demande a été remplacée par une nouvelle demande SS"</string> - <!-- no translation found for notification_phishing_alert_content_description (494227305355958790) --> - <skip /> + <string name="notification_phishing_alert_content_description" msgid="494227305355958790">"Alerte d\'hameçonnage"</string> <string name="notification_work_profile_content_description" msgid="5296477955677725799">"Profil professionnel"</string> <string name="notification_alerted_content_description" msgid="6139691253611265992">"Alerté"</string> <string name="expand_button_content_description_collapsed" msgid="3873368935659010279">"Développer"</string> @@ -2220,4 +2221,8 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"Pour continuer, vous devez accorder l\'accès à l\'appareil photo de votre appareil à l\'application <b><xliff:g id="APP">%s</xliff:g></b>."</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Activer"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Confidentialité des capteurs"</string> + <!-- no translation found for splash_screen_view_icon_description (180638751260598187) --> + <skip /> + <!-- no translation found for splash_screen_view_branding_description (7911129347402728216) --> + <skip /> </resources> diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml index 78af86f06b34..a3c0badee9b4 100644 --- a/core/res/res/values-fr/strings.xml +++ b/core/res/res/values-fr/strings.xml @@ -606,7 +606,8 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"Impossible de reconnaître le visage. Réessayez."</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"Ressemble à un visage existant, changez de pose."</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"Tournez un peu moins la tête."</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"Tournez un peu moins la tête."</string> + <!-- no translation found for face_acquired_tilt_too_extreme (8618210742620248049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"Tournez un peu moins la tête."</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"Retirez tout ce qui cache votre visage."</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"Nettoyez la partie supérieure de l\'écran, y compris la barre noire"</string> @@ -1667,7 +1668,8 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Utiliser le raccourci"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Inversion des couleurs"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Correction des couleurs"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Réduire la luminosité"</string> + <!-- no translation found for reduce_bright_colors_feature_name (8978255324027479398) --> + <skip /> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Touches de volume appuyées de manière prolongée. Service <xliff:g id="SERVICE_NAME">%1$s</xliff:g> activé."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Touches de volume appuyées de manière prolongée. Service <xliff:g id="SERVICE_NAME">%1$s</xliff:g> désactivé."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Appuyez de manière prolongée sur les deux touches de volume pendant trois secondes pour utiliser <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string> @@ -1871,8 +1873,7 @@ <string name="stk_cc_ss_to_dial_video" msgid="1324194624384312664">"Requête SS transformée en appel vidéo"</string> <string name="stk_cc_ss_to_ussd" msgid="8417905193112944760">"Requête SS transformée en requête USSD"</string> <string name="stk_cc_ss_to_ss" msgid="132040645206514450">"Remplacement par une nouvelle requête SS"</string> - <!-- no translation found for notification_phishing_alert_content_description (494227305355958790) --> - <skip /> + <string name="notification_phishing_alert_content_description" msgid="494227305355958790">"Alerte de hameçonnage"</string> <string name="notification_work_profile_content_description" msgid="5296477955677725799">"Profil professionnel"</string> <string name="notification_alerted_content_description" msgid="6139691253611265992">"Alerte envoyée"</string> <string name="expand_button_content_description_collapsed" msgid="3873368935659010279">"Développer"</string> @@ -2068,7 +2069,7 @@ <string name="accessibility_system_action_back_label" msgid="4205361367345537608">"Retour"</string> <string name="accessibility_system_action_recents_label" msgid="4782875610281649728">"Applications récentes"</string> <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"Notifications"</string> - <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"Configuration rapide"</string> + <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"Réglages rapides"</string> <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"Boîte de dialogue Marche/Arrêt"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Verrouiller l\'écran"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Capture d\'écran"</string> @@ -2220,4 +2221,8 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"Pour continuer, <b><xliff:g id="APP">%s</xliff:g></b> a besoin d\'accéder à l\'appareil photo de votre appareil."</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Activer"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Confidentialité du capteur"</string> + <!-- no translation found for splash_screen_view_icon_description (180638751260598187) --> + <skip /> + <!-- no translation found for splash_screen_view_branding_description (7911129347402728216) --> + <skip /> </resources> diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml index 949e48629d4f..72a799ede92f 100644 --- a/core/res/res/values-gl/strings.xml +++ b/core/res/res/values-gl/strings.xml @@ -606,7 +606,8 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"Xa non se pode recoñecer a cara. Téntao de novo."</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"É moi similar. Cambia a pose."</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"Xira a cabeza un pouco menos."</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"Xira a cabeza un pouco menos."</string> + <!-- no translation found for face_acquired_tilt_too_extreme (8618210742620248049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"Xira a cabeza un pouco menos."</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"Quita todo o que oculte a túa cara."</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"Limpa a parte superior da pantalla, incluída a barra de cor negra"</string> @@ -1667,7 +1668,8 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Utilizar atallo"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Inversión de cor"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Corrección de cor"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Reducir brillo"</string> + <!-- no translation found for reduce_bright_colors_feature_name (8978255324027479398) --> + <skip /> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Teclas de volume premidas. Activouse o servizo <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Teclas de volume premidas. Desactivouse <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Mantén premidas as teclas do volume durante tres segudos para usar <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string> @@ -1871,8 +1873,7 @@ <string name="stk_cc_ss_to_dial_video" msgid="1324194624384312664">"A solicitude SS transformouse nunha videochamada"</string> <string name="stk_cc_ss_to_ussd" msgid="8417905193112944760">"A solicitude SS transformouse nunha solicitude USSD"</string> <string name="stk_cc_ss_to_ss" msgid="132040645206514450">"Transformouse nunha nova solicitude SS"</string> - <!-- no translation found for notification_phishing_alert_content_description (494227305355958790) --> - <skip /> + <string name="notification_phishing_alert_content_description" msgid="494227305355958790">"Alerta de phishing"</string> <string name="notification_work_profile_content_description" msgid="5296477955677725799">"Perfil de traballo"</string> <string name="notification_alerted_content_description" msgid="6139691253611265992">"Con son"</string> <string name="expand_button_content_description_collapsed" msgid="3873368935659010279">"Despregar"</string> @@ -2220,4 +2221,8 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"Para continuar, <b><xliff:g id="APP">%s</xliff:g></b> precisa acceder á cámara do dispositivo."</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Activar"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Privacidade do sensor"</string> + <!-- no translation found for splash_screen_view_icon_description (180638751260598187) --> + <skip /> + <!-- no translation found for splash_screen_view_branding_description (7911129347402728216) --> + <skip /> </resources> diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml index 29ce76bd8e7c..7a2527f50cba 100644 --- a/core/res/res/values-gu/strings.xml +++ b/core/res/res/values-gu/strings.xml @@ -606,7 +606,8 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"ચહેરો ઓળખી શકાતો નથી. ફરી પ્રયાસ કરો."</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"ઘણી સમાનતા ધરાવે છે, કૃપા કરીને તમારો પોઝ બદલો."</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"તમારું માથું થોડું ફેરવો."</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"તમારું માથું થોડું ફેરવો."</string> + <!-- no translation found for face_acquired_tilt_too_extreme (8618210742620248049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"તમારું માથું થોડું ઓછું ફેરવો."</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"તમારા ચહેરાને છુપાવતી કંઈપણ વસ્તુ દૂર કરો."</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"કાળી પટ્ટી સહિત, તમારી સ્ક્રીનની ટોચ સાફ કરો"</string> @@ -1667,7 +1668,8 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"શૉર્ટકટનો ઉપયોગ કરો"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"વિપરીત રંગમાં બદલવું"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"રંગ સુધારણા"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"બ્રાઇટનેસ ઘટાડો"</string> + <!-- no translation found for reduce_bright_colors_feature_name (8978255324027479398) --> + <skip /> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"વૉલ્યૂમ કી દબાવી રાખો. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ચાલુ કરી."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"વૉલ્યૂમ કી દબાવી રાખો. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> બંધ કરી."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>નો ઉપયોગ કરવા માટે બન્ને વૉલ્યૂમ કીને ત્રણ સેકન્ડ સુધી દબાવી રાખો"</string> @@ -1871,8 +1873,7 @@ <string name="stk_cc_ss_to_dial_video" msgid="1324194624384312664">"SS વિનંતીને વીડિઓ કૉલમાં બદલવામાં આવી છે"</string> <string name="stk_cc_ss_to_ussd" msgid="8417905193112944760">"SS વિનંતીને USSD વિનંતીમાં બદલવામાં આવી છે"</string> <string name="stk_cc_ss_to_ss" msgid="132040645206514450">"નવી SS વિનંતીમાં બદલવામાં આવી છે"</string> - <!-- no translation found for notification_phishing_alert_content_description (494227305355958790) --> - <skip /> + <string name="notification_phishing_alert_content_description" msgid="494227305355958790">"ફિશિંગ અલર્ટ"</string> <string name="notification_work_profile_content_description" msgid="5296477955677725799">"ઑફિસની પ્રોફાઇલ"</string> <string name="notification_alerted_content_description" msgid="6139691253611265992">"અલર્ટ કરેલ"</string> <string name="expand_button_content_description_collapsed" msgid="3873368935659010279">"વિસ્તૃત કરો"</string> @@ -2220,4 +2221,8 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"ચાલુ રાખવા માટે, <b><xliff:g id="APP">%s</xliff:g></b>ને તમારા ડિવાઇસના કૅમેરાના ઍક્સેસની જરૂર છે."</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"ચાલુ કરો"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"સેન્સર પ્રાઇવસી સંબંધિત નોટિફિકેશન"</string> + <!-- no translation found for splash_screen_view_icon_description (180638751260598187) --> + <skip /> + <!-- no translation found for splash_screen_view_branding_description (7911129347402728216) --> + <skip /> </resources> diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml index 15bb461fbb66..f108aa7fdcd0 100644 --- a/core/res/res/values-hi/strings.xml +++ b/core/res/res/values-hi/strings.xml @@ -606,7 +606,8 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"अब चेहरे की पहचान नहीं कर पा रहा. फिर से कोशिश करें."</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"चेहरा काफ़ी मिलता-जुलता है, कृपया अपना पोज़ बदलें."</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"अपना सिर थोड़ा कम घुमाएं."</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"अपना सिर थोड़ा कम घुमाएं."</string> + <!-- no translation found for face_acquired_tilt_too_extreme (8618210742620248049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"अपना सिर थोड़ा कम घुमाएं."</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"आपके चेहरे को छिपाने वाली सभी चीज़ों को हटाएं."</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"अपनी स्क्रीन के सबसे ऊपरी हिस्से को साफ़ करें, जिसमें काले रंग वाला बार भी शामिल है"</string> @@ -685,7 +686,7 @@ <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"ऐप को परेशान न करें कॉन्फ़िगरेशन पढ़ने और लिखने देती है."</string> <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"देखने की अनुमतियां चालू करें"</string> <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"इस्तेमाल करने वाले को किसी ऐप्लिकेशन के लिए अनुमतियों का इस्तेमाल शुरू करने देता है. सामान्य ऐप्लिकेशन के लिए इसकी ज़रूरत कभी नहीं पड़ती."</string> - <string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"सेंसर डेटा को नमूने लेने की तेज़ दर पर ऐक्सेस करें"</string> + <string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"सेंसर डेटा को, नमूने लेने की तेज़ दर पर ऐक्सेस करें"</string> <string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"यह अनुमति मिलने पर ऐप्लिकेशन, 200 हर्ट्ज़ से ज़्यादा की दर पर सेंसर डेटा का नमूना ले पाएगा"</string> <string name="policylab_limitPassword" msgid="4851829918814422199">"पासवर्ड नियम सेट करना"</string> <string name="policydesc_limitPassword" msgid="4105491021115793793">"स्क्रीन लॉक पासवर्ड और पिन की लंबाई और उनमें स्वीकृत वर्णों को नियंत्रित करना."</string> @@ -1667,7 +1668,8 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"शॉर्टकट का उपयोग करें"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"रंग बदलने की सुविधा"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"रंग में सुधार करने की सुविधा"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"स्क्रीन की चमक कम करें"</string> + <!-- no translation found for reduce_bright_colors_feature_name (8978255324027479398) --> + <skip /> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"आवाज़ कम-ज़्यादा करने वाले दोनों बटन दबाकर रखें. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> को चालू कर दिया गया."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"आवाज़ कम-ज़्यादा करने वाले दोनों बटन दबाकर रखें. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> को बंद कर दिया गया."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> इस्तेमाल करने के लिए आवाज़ वाले दोनों बटन तीन सेकंड तक दबाकर रखें"</string> @@ -2219,4 +2221,8 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"जारी रखने के लिए, <b><xliff:g id="APP">%s</xliff:g></b> को आपके डिवाइस का कैमरा ऐक्सेस करने की ज़रूरत है."</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"चालू करें"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"सेंसर से जुड़ी निजता के बारे में सूचना"</string> + <!-- no translation found for splash_screen_view_icon_description (180638751260598187) --> + <skip /> + <!-- no translation found for splash_screen_view_branding_description (7911129347402728216) --> + <skip /> </resources> diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml index 6e7c3300becd..91073d445ac6 100644 --- a/core/res/res/values-hr/strings.xml +++ b/core/res/res/values-hr/strings.xml @@ -609,7 +609,8 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"Lice nije prepoznato. Pokušajte ponovo."</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"Previše slično, promijenite pozu."</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"Nagnite glavu malo manje."</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"Nagnite glavu malo manje."</string> + <!-- no translation found for face_acquired_tilt_too_extreme (8618210742620248049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"Nagnite glavu malo manje."</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"Uklonite sve što vam zakriva lice."</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"Očistite vrh zaslona, uključujući crnu traku"</string> @@ -1689,7 +1690,8 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Upotrijebi prečac"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Inverzija boja"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Korekcija boje"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Smanjenje svjetline"</string> + <!-- no translation found for reduce_bright_colors_feature_name (8978255324027479398) --> + <skip /> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Držali ste tipke za glasnoću. Uključila se usluga <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Držali ste tipke za glasnoću. Isključila se usluga <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Pritisnite i zadržite tipke za glasnoću na tri sekunde da biste koristili uslugu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string> @@ -2253,4 +2255,8 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"Da bi nastavila s radom, aplikacija <b><xliff:g id="APP">%s</xliff:g></b> treba pristupiti fotoaparatu vašeg uređaja."</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Uključi"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Privatnost senzora"</string> + <!-- no translation found for splash_screen_view_icon_description (180638751260598187) --> + <skip /> + <!-- no translation found for splash_screen_view_branding_description (7911129347402728216) --> + <skip /> </resources> diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml index d966249f7fb4..32f33dfaea4e 100644 --- a/core/res/res/values-hu/strings.xml +++ b/core/res/res/values-hu/strings.xml @@ -606,7 +606,8 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"Már nem lehet felismerni az arcát. Próbálja újra."</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"Túlságosan hasonló, változtasson a pózon."</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"Kicsit kevésbé fordítsa el a fejét."</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"Kicsit kevésbé fordítsa el a fejét."</string> + <!-- no translation found for face_acquired_tilt_too_extreme (8618210742620248049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"Kicsit kevésbé fordítsa el a fejét."</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"Távolítson el mindent, ami takarja az arcát."</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"Tisztítsa meg a képernyő tetejét, a fekete sávot is beleértve."</string> @@ -1667,7 +1668,8 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Billentyűparancs használata"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Színek invertálása"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Színkorrekció"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Fényerő csökkentése"</string> + <!-- no translation found for reduce_bright_colors_feature_name (8978255324027479398) --> + <skip /> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Nyomva tartotta a hangerőgombokat. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> bekapcsolva."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Nyomva tartotta a hangerőgombokat. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> kikapcsolva."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"A(z) <xliff:g id="SERVICE_NAME">%1$s</xliff:g> használatához tartsa lenyomva három másodpercig a két hangerőgombot"</string> @@ -1871,8 +1873,7 @@ <string name="stk_cc_ss_to_dial_video" msgid="1324194624384312664">"Az SS-kérés módosítva videohívásra"</string> <string name="stk_cc_ss_to_ussd" msgid="8417905193112944760">"Az SS-kérés módosítva USSD-kérésre"</string> <string name="stk_cc_ss_to_ss" msgid="132040645206514450">"Új SS-kérésre módosítva"</string> - <!-- no translation found for notification_phishing_alert_content_description (494227305355958790) --> - <skip /> + <string name="notification_phishing_alert_content_description" msgid="494227305355958790">"Adathalászati figyelmeztetés"</string> <string name="notification_work_profile_content_description" msgid="5296477955677725799">"Munkaprofil"</string> <string name="notification_alerted_content_description" msgid="6139691253611265992">"Értesítve"</string> <string name="expand_button_content_description_collapsed" msgid="3873368935659010279">"Kibontás"</string> @@ -2220,4 +2221,8 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"A folytatáshoz a(z) <b><xliff:g id="APP">%s</xliff:g></b> alkalmazásnak hozzáférésre van szüksége az eszköze kamerájához."</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Bekapcsolás"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Érzékelőkkel kapcsolatos adatvédelem"</string> + <!-- no translation found for splash_screen_view_icon_description (180638751260598187) --> + <skip /> + <!-- no translation found for splash_screen_view_branding_description (7911129347402728216) --> + <skip /> </resources> diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml index 6110be3b91d9..cd1bbb11d468 100644 --- a/core/res/res/values-hy/strings.xml +++ b/core/res/res/values-hy/strings.xml @@ -606,7 +606,8 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"Չհաջողվեց ճանաչել դեմքը։ Նորից փորձեք:"</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"Շատ նման է նախորդին։ Փոխեք ձեր դիրքը։"</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"Գլուխն ուղիղ պահեք։"</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"Գլուխն ուղիղ պահեք։"</string> + <!-- no translation found for face_acquired_tilt_too_extreme (8618210742620248049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"Գլուխն ուղիղ պահեք։"</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"Հեռացրեք այն ամենը, ինչը թաքցնում է ձեր երեսը:"</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"Մաքրեք էկրանի վերևի մասը, ներառյալ սև գոտին"</string> @@ -686,7 +687,7 @@ <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"թույլտվությունների մասին տվյալների հասանելիություն"</string> <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Հավելվածին հասանելի կդառնան թույլտվությունների մասին տվյալները։ Այս թույլտվությունն անհրաժեշտ չէ սովորական հավելվածներին։"</string> <string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"օգտագործել սենսորների տվյալները բարձր հաճախականության վրա"</string> - <string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"Թույլ է տալիս հավելվածին փորձել սենսորների տվյալները 200 Հց-ից ավել հաճախականության վրա"</string> + <string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"Թույլ է տալիս հավելվածին փորձել սենսորների տվյալները 200 Հց-ից բարձր հաճախականության վրա"</string> <string name="policylab_limitPassword" msgid="4851829918814422199">"Սահմանել գաղտնաբառի կանոնները"</string> <string name="policydesc_limitPassword" msgid="4105491021115793793">"Կառավարել էկրանի ապակողպման գաղտնաբառերի և PIN կոդերի թույլատրելի երկարությունն ու գրանշանները:"</string> <string name="policylab_watchLogin" msgid="7599669460083719504">"Վերահսկել էկրանի ապակողպման փորձերը"</string> @@ -1667,7 +1668,8 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Օգտագործել դյուրանցումը"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Գունաշրջում"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Գունաշտկում"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Նվազեցնել պայծառությունը"</string> + <!-- no translation found for reduce_bright_colors_feature_name (8978255324027479398) --> + <skip /> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Ձայնի կարգավորման կոճակները սեղմվեցին։ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ծառայությունը միացավ։"</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Ձայնի կարգավորման կոճակները սեղմվեցին։ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ծառայությունն անջատվեց։"</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"«<xliff:g id="SERVICE_NAME">%1$s</xliff:g>» ծառայությունն օգտագործելու համար սեղմեք և 3 վայրկյան պահեք ձայնի ուժգնության երկու կոճակները"</string> @@ -1871,8 +1873,7 @@ <string name="stk_cc_ss_to_dial_video" msgid="1324194624384312664">"SS հարցումը փոխվել է տեսազանգի"</string> <string name="stk_cc_ss_to_ussd" msgid="8417905193112944760">"SS հարցումը փոխվել է USSD հարցման"</string> <string name="stk_cc_ss_to_ss" msgid="132040645206514450">"Փոխվել է նոր SS հարցման"</string> - <!-- no translation found for notification_phishing_alert_content_description (494227305355958790) --> - <skip /> + <string name="notification_phishing_alert_content_description" msgid="494227305355958790">"Ֆիշինգի մասին զգուշացում"</string> <string name="notification_work_profile_content_description" msgid="5296477955677725799">"Աշխատանքային պրոֆիլ"</string> <string name="notification_alerted_content_description" msgid="6139691253611265992">"Ուղարկվել է զգուշացում"</string> <string name="expand_button_content_description_collapsed" msgid="3873368935659010279">"Ընդարձակել"</string> @@ -2220,4 +2221,8 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"Շարունակելու համար <b><xliff:g id="APP">%s</xliff:g></b> հավելվածին անհրաժեշտ է ձեր սարքի տեսախցիկի օգտագործման թույլտվություն։"</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Միացնել"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Տվիչների գաղտնիություն"</string> + <!-- no translation found for splash_screen_view_icon_description (180638751260598187) --> + <skip /> + <!-- no translation found for splash_screen_view_branding_description (7911129347402728216) --> + <skip /> </resources> diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml index 3335f599b50a..f7fe38457a56 100644 --- a/core/res/res/values-in/strings.xml +++ b/core/res/res/values-in/strings.xml @@ -606,7 +606,8 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"Tidak lagi dapat mengenali wajah. Coba lagi."</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"Terlalu mirip, ubah pose Anda."</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"Putar sedikit kepala Anda."</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"Putar sedikit kepala Anda."</string> + <!-- no translation found for face_acquired_tilt_too_extreme (8618210742620248049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"Putar sedikit kepala Anda."</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"Singkirkan apa saja yang menutupi wajah Anda."</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"Bersihkan bagian atas layar, termasuk kotak hitam"</string> @@ -1667,7 +1668,8 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Gunakan Pintasan"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Inversi Warna"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Koreksi Warna"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Kurangi Kecerahan"</string> + <!-- no translation found for reduce_bright_colors_feature_name (8978255324027479398) --> + <skip /> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Tombol volume ditahan. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> diaktifkan."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Tombol volume ditahan. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> dinonaktifkan."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Tekan dan tahan kedua tombol volume selama tiga detik untuk menggunakan <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string> @@ -1871,8 +1873,7 @@ <string name="stk_cc_ss_to_dial_video" msgid="1324194624384312664">"Permintaan SS diubah ke panggilan video"</string> <string name="stk_cc_ss_to_ussd" msgid="8417905193112944760">"Permintaan SS diubah ke permintaan USSD"</string> <string name="stk_cc_ss_to_ss" msgid="132040645206514450">"Diubah ke permintaan SS baru"</string> - <!-- no translation found for notification_phishing_alert_content_description (494227305355958790) --> - <skip /> + <string name="notification_phishing_alert_content_description" msgid="494227305355958790">"Peringatan phishing"</string> <string name="notification_work_profile_content_description" msgid="5296477955677725799">"Profil kerja"</string> <string name="notification_alerted_content_description" msgid="6139691253611265992">"Diingatkan"</string> <string name="expand_button_content_description_collapsed" msgid="3873368935659010279">"Luaskan"</string> @@ -2220,4 +2221,8 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"Untuk melanjutkan, <b><xliff:g id="APP">%s</xliff:g></b> memerlukan akses ke kamera perangkat."</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Aktifkan"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Privasi Sensor"</string> + <!-- no translation found for splash_screen_view_icon_description (180638751260598187) --> + <skip /> + <!-- no translation found for splash_screen_view_branding_description (7911129347402728216) --> + <skip /> </resources> diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml index 86a4638a6633..5824c3a64843 100644 --- a/core/res/res/values-is/strings.xml +++ b/core/res/res/values-is/strings.xml @@ -606,7 +606,8 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"Andlit þekkist ekki lengur. Reyndu aftur."</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"Of svipað. Stilltu þér öðruvísi upp."</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"Snúðu höfðinu aðeins minna."</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"Hallaðu höfðinu aðeins minna."</string> + <!-- no translation found for face_acquired_tilt_too_extreme (8618210742620248049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"Snúðu höfðinu aðeins minna."</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"Fjarlægðu það sem kann að hylja andlitið."</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"Hreinsaðu efsta hluta skjásins þíns, þ.m.t. svörtu stikuna"</string> @@ -1667,7 +1668,8 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Nota flýtileið"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Umsnúningur lita"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Litaleiðrétting"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Draga úr birtu"</string> + <!-- no translation found for reduce_bright_colors_feature_name (8978255324027479398) --> + <skip /> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Hljóðstyrkstökkum haldið inni. Kveikt á <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Hljóðstyrkstökkum haldið inni. Slökkt á <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Haltu báðum hljóðstyrkstökkunum inni í þrjár sekúndur til að nota <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string> @@ -1871,8 +1873,7 @@ <string name="stk_cc_ss_to_dial_video" msgid="1324194624384312664">"SS-beiðni breytt í myndsímtal"</string> <string name="stk_cc_ss_to_ussd" msgid="8417905193112944760">"SS-beiðni breytt í USSD-beiðni"</string> <string name="stk_cc_ss_to_ss" msgid="132040645206514450">"Breytt í nýja SS-beiðni"</string> - <!-- no translation found for notification_phishing_alert_content_description (494227305355958790) --> - <skip /> + <string name="notification_phishing_alert_content_description" msgid="494227305355958790">"Viðvörun um vefveiðar"</string> <string name="notification_work_profile_content_description" msgid="5296477955677725799">"Vinnusnið"</string> <string name="notification_alerted_content_description" msgid="6139691253611265992">"Tilkynnt"</string> <string name="expand_button_content_description_collapsed" msgid="3873368935659010279">"Stækka"</string> @@ -2220,4 +2221,8 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"Til að halda áfram þarf <b><xliff:g id="APP">%s</xliff:g></b> aðgang að myndavél tækisins."</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Kveikja"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Persónuvernd skynjara"</string> + <!-- no translation found for splash_screen_view_icon_description (180638751260598187) --> + <skip /> + <!-- no translation found for splash_screen_view_branding_description (7911129347402728216) --> + <skip /> </resources> diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml index fa6b46110d4c..d435a253ad22 100644 --- a/core/res/res/values-it/strings.xml +++ b/core/res/res/values-it/strings.xml @@ -606,7 +606,8 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"Non è più possibile riconoscere il volto. Riprova."</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"Troppo simile; cambia posa."</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"Gira un po\' meno la testa."</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"Gira un po\' meno la testa."</string> + <!-- no translation found for face_acquired_tilt_too_extreme (8618210742620248049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"Gira un po\' meno la testa."</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"Rimuovi tutto ciò che ti nasconde il viso."</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"Pulisci la parte superiore dello schermo, inclusa la barra nera"</string> @@ -1667,7 +1668,8 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Usa scorciatoia"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Inversione dei colori"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Correzione del colore"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Riduci la luminosità"</string> + <!-- no translation found for reduce_bright_colors_feature_name (8978255324027479398) --> + <skip /> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Tieni premuti i tasti del volume. Servizio <xliff:g id="SERVICE_NAME">%1$s</xliff:g> attivato."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Tieni premuti i tasti del volume. Servizio <xliff:g id="SERVICE_NAME">%1$s</xliff:g> disattivato."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Tieni premuti entrambi i tasti del volume per tre secondi per utilizzare <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string> @@ -1871,8 +1873,7 @@ <string name="stk_cc_ss_to_dial_video" msgid="1324194624384312664">"Richiesta SS modificata in videochiamata"</string> <string name="stk_cc_ss_to_ussd" msgid="8417905193112944760">"Richiesta SS modificata in richiesta USSD"</string> <string name="stk_cc_ss_to_ss" msgid="132040645206514450">"Modificata in nuova richiesta SS"</string> - <!-- no translation found for notification_phishing_alert_content_description (494227305355958790) --> - <skip /> + <string name="notification_phishing_alert_content_description" msgid="494227305355958790">"Allerta phishing"</string> <string name="notification_work_profile_content_description" msgid="5296477955677725799">"Profilo di lavoro"</string> <string name="notification_alerted_content_description" msgid="6139691253611265992">"Avviso inviato"</string> <string name="expand_button_content_description_collapsed" msgid="3873368935659010279">"Espandi"</string> @@ -2220,4 +2221,8 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"Per continuare, l\'app <b><xliff:g id="APP">%s</xliff:g></b> deve accedere alla videocamera del dispositivo."</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Attiva"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Privacy relativa ai sensori"</string> + <!-- no translation found for splash_screen_view_icon_description (180638751260598187) --> + <skip /> + <!-- no translation found for splash_screen_view_branding_description (7911129347402728216) --> + <skip /> </resources> diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml index d9b889ebe436..ee771df1b51c 100644 --- a/core/res/res/values-iw/strings.xml +++ b/core/res/res/values-iw/strings.xml @@ -612,7 +612,8 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"כבר לא ניתן לזהות פנים. יש לנסות שוב."</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"דומה מדי, יש לשנות תנוחה."</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"עליך ליישר קצת את הראש."</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"עליך ליישר קצת את הראש."</string> + <!-- no translation found for face_acquired_tilt_too_extreme (8618210742620248049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"עליך ליישר קצת את הראש."</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"יש להסיר כל דבר שמסתיר את הפנים."</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"עליך לנקות את החלק העליון של המסך, כולל הסרגל השחור"</string> @@ -1711,7 +1712,8 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"השתמש בקיצור הדרך"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"היפוך צבעים"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"תיקון צבעים"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"הפחתה של עוצמת הבהירות"</string> + <!-- no translation found for reduce_bright_colors_feature_name (8978255324027479398) --> + <skip /> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"לחצני עוצמת הקול נלחצו בלחיצה ארוכה. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> הופעל."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"לחצני עוצמת הקול נלחצו בלחיצה ארוכה. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> הושבת."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"יש ללחוץ לחיצה ארוכה על שני לחצני עוצמת הקול למשך שלוש שניות כדי להשתמש בשירות <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string> @@ -1933,8 +1935,7 @@ <string name="stk_cc_ss_to_dial_video" msgid="1324194624384312664">"בקשת SS שונתה לשיחת וידאו"</string> <string name="stk_cc_ss_to_ussd" msgid="8417905193112944760">"בקשת SS שונתה לבקשת USSD"</string> <string name="stk_cc_ss_to_ss" msgid="132040645206514450">"היה שינוי לבקשת SS חדשה"</string> - <!-- no translation found for notification_phishing_alert_content_description (494227305355958790) --> - <skip /> + <string name="notification_phishing_alert_content_description" msgid="494227305355958790">"התראה על פישינג"</string> <string name="notification_work_profile_content_description" msgid="5296477955677725799">"פרופיל עבודה"</string> <string name="notification_alerted_content_description" msgid="6139691253611265992">"נשלחה התראה"</string> <string name="expand_button_content_description_collapsed" msgid="3873368935659010279">"הרחב"</string> @@ -2288,4 +2289,8 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"כדי להמשיך, האפליקציה <b><xliff:g id="APP">%s</xliff:g></b> צריכה גישה למצלמה של המכשיר שלך."</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"הפעלה"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"פרטיות חיישנים"</string> + <!-- no translation found for splash_screen_view_icon_description (180638751260598187) --> + <skip /> + <!-- no translation found for splash_screen_view_branding_description (7911129347402728216) --> + <skip /> </resources> diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml index 68213defda29..b03f94ca5117 100644 --- a/core/res/res/values-ja/strings.xml +++ b/core/res/res/values-ja/strings.xml @@ -538,10 +538,10 @@ <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"このアプリに画面ロックの複雑さレベル(高、中、低、なし)を認識することを許可します。複雑さレベルは、画面ロックの文字数の範囲やタイプを示すものです。アプリから一定レベルまで画面ロックを更新するよう推奨されることもありますが、ユーザーは無視したり別の操作を行ったりできます。画面ロックは平文で保存されないため、アプリが正確なパスワードを知ることはありません。"</string> <string name="permlab_useBiometric" msgid="6314741124749633786">"生体認証ハードウェアの使用"</string> <string name="permdesc_useBiometric" msgid="7502858732677143410">"生体認証ハードウェアを認証に使用することをアプリに許可します"</string> - <string name="permlab_manageFingerprint" msgid="7432667156322821178">"指紋ハードウェアの管理"</string> + <string name="permlab_manageFingerprint" msgid="7432667156322821178">"指紋認証ハードウェアの管理"</string> <string name="permdesc_manageFingerprint" msgid="2025616816437339865">"使用する指紋テンプレートの追加や削除を行う方法の呼び出しをアプリに許可します。"</string> - <string name="permlab_useFingerprint" msgid="1001421069766751922">"指紋ハードウェアの使用"</string> - <string name="permdesc_useFingerprint" msgid="412463055059323742">"指紋ハードウェアを認証に使用することをアプリに許可します"</string> + <string name="permlab_useFingerprint" msgid="1001421069766751922">"指紋認証ハードウェアの使用"</string> + <string name="permdesc_useFingerprint" msgid="412463055059323742">"指紋認証ハードウェアを認証に使用することをアプリに許可します"</string> <string name="permlab_audioWrite" msgid="8501705294265669405">"音楽コレクションの変更"</string> <string name="permdesc_audioWrite" msgid="8057399517013412431">"音楽コレクションの変更をアプリに許可します。"</string> <string name="permlab_videoWrite" msgid="5940738769586451318">"動画コレクションの変更"</string> @@ -567,7 +567,7 @@ <string name="fingerprint_authenticated" msgid="2024862866860283100">"指紋認証を完了しました"</string> <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"顔を認証しました"</string> <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"顔を認証しました。[確認] を押してください"</string> - <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"指紋ハードウェアは使用できません。"</string> + <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"指紋認証ハードウェアは使用できません。"</string> <string name="fingerprint_error_no_space" msgid="6126456006769817485">"指紋を保存できません。既存の指紋を削除してください。"</string> <string name="fingerprint_error_timeout" msgid="2946635815726054226">"指紋の読み取りがタイムアウトになりました。もう一度お試しください。"</string> <string name="fingerprint_error_canceled" msgid="540026881380070750">"指紋の操作をキャンセルしました。"</string> @@ -606,7 +606,8 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"顔を認識できなくなりました。もう一度お試しください。"</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"似すぎています。ポーズを変えてください。"</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"顔の向きを少し戻してください。"</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"顔の向きを少し戻してください。"</string> + <!-- no translation found for face_acquired_tilt_too_extreme (8618210742620248049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"顔の向きを少し戻してください。"</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"顔を隠しているものをすべて外してください"</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"黒いバーを含め、画面の上部をきれいにしてください"</string> @@ -1667,7 +1668,8 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"ショートカットを使用"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"色反転"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"色補正"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"明るさを下げる"</string> + <!-- no translation found for reduce_bright_colors_feature_name (8978255324027479398) --> + <skip /> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"音量ボタンを長押ししました。<xliff:g id="SERVICE_NAME">%1$s</xliff:g> が ON になりました。"</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"音量ボタンを長押ししました。<xliff:g id="SERVICE_NAME">%1$s</xliff:g> が OFF になりました。"</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> を使用するには、音量大と音量小の両方のボタンを 3 秒間長押ししてください"</string> @@ -2219,4 +2221,8 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"続行するには、<b><xliff:g id="APP">%s</xliff:g></b> にデバイスのカメラへのアクセスを許可する必要があります。"</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"ON にする"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"センサー プライバシー"</string> + <!-- no translation found for splash_screen_view_icon_description (180638751260598187) --> + <skip /> + <!-- no translation found for splash_screen_view_branding_description (7911129347402728216) --> + <skip /> </resources> diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml index 3c764544a5c4..c25bd5757526 100644 --- a/core/res/res/values-ka/strings.xml +++ b/core/res/res/values-ka/strings.xml @@ -606,7 +606,8 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"სახის ამოცნობა ვეღარ ხერხდება. ცადეთ ხელახლა."</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"მეტისმეტად მსგავსია. გთხოვთ, შეცვალოთ პოზა."</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"თავი ცოტა ნაკლებად მიაბრუნეთ."</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"თავი ცოტა ნაკლებად მიაბრუნეთ."</string> + <!-- no translation found for face_acquired_tilt_too_extreme (8618210742620248049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"თავი ცოტა ნაკლებად მიაბრუნეთ."</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"მოაშორეთ ყველაფერი, რაც სახეს გიფარავთ."</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"გაწმინდეთ ეკრანის ზედა ნაწილი, შავი ზოლის ჩათვლით."</string> @@ -1667,7 +1668,8 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"მალსახმობის გამოყენება"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"ფერთა ინვერსია"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"ფერთა კორექცია"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"სიკაშკაშის შემცირება"</string> + <!-- no translation found for reduce_bright_colors_feature_name (8978255324027479398) --> + <skip /> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"ხანგრძლივად დააჭირეთ ხმის ღილაკებს. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ჩართულია."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"ხანგრძლივად დააჭირეთ ხმის ღილაკებს. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> გამორთულია."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> რომ გამოიყენოთ, დააჭირეთ ხმის ორივე ღილაკზე 3 წამის განმავლობაში"</string> @@ -1871,8 +1873,7 @@ <string name="stk_cc_ss_to_dial_video" msgid="1324194624384312664">"SS მოთხოვნა შეიცვალა ვიდეოზარის მოთხოვნით"</string> <string name="stk_cc_ss_to_ussd" msgid="8417905193112944760">"SS მოთხოვნა შეიცვალა USSD მოთხოვნით"</string> <string name="stk_cc_ss_to_ss" msgid="132040645206514450">"შეიცვალა ახალი SS მოთხოვნით"</string> - <!-- no translation found for notification_phishing_alert_content_description (494227305355958790) --> - <skip /> + <string name="notification_phishing_alert_content_description" msgid="494227305355958790">"გაფრთხილება ფიშინგის შესახებ"</string> <string name="notification_work_profile_content_description" msgid="5296477955677725799">"სამსახურის პროფილი"</string> <string name="notification_alerted_content_description" msgid="6139691253611265992">"გაფრთხილებით"</string> <string name="expand_button_content_description_collapsed" msgid="3873368935659010279">"გაშლა"</string> @@ -2220,4 +2221,8 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"გასაგრძელებლად <b><xliff:g id="APP">%s</xliff:g></b>-ს თქვენი მოწყობილობის კამერაზე წვდომა სჭირდება."</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"ჩართვა"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"სენსორის კონფიდენციალურობა"</string> + <!-- no translation found for splash_screen_view_icon_description (180638751260598187) --> + <skip /> + <!-- no translation found for splash_screen_view_branding_description (7911129347402728216) --> + <skip /> </resources> diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml index 38f947524edc..68edfeac6eb1 100644 --- a/core/res/res/values-kk/strings.xml +++ b/core/res/res/values-kk/strings.xml @@ -606,7 +606,8 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"Енді бет анықтау мүмкін емес. Әрекетті қайталаңыз."</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"Алдыңғысына тым ұқсас, басқаша қалыпта түсіңіз."</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"Басыңызды түзурек ұстаңыз."</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"Басыңызды түзурек ұстаңыз."</string> + <!-- no translation found for face_acquired_tilt_too_extreme (8618210742620248049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"Басыңызды кішкене бұрыңыз."</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"Бетіңізді жауып тұрған нәрсені алып тастаңыз."</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"Экранның жоғарғы жағын, сонымен қатар қара жолақты өшіріңіз."</string> @@ -1667,7 +1668,8 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Төте жолды пайдалану"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Түстер инверсиясы"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Түсті түзету"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Жарықтығын азайту"</string> + <!-- no translation found for reduce_bright_colors_feature_name (8978255324027479398) --> + <skip /> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Пайдаланушы дыбыс деңгейі пернелерін басып ұстап тұрды. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> қосулы."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Дыбыс деңгейі пернелерін басып тұрған соң, <xliff:g id="SERVICE_NAME">%1$s</xliff:g> өшірілді."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> қызметін пайдалану үшін дыбыс деңгейін реттейтін екі түймені де 3 секунд басып тұрыңыз"</string> @@ -1871,8 +1873,7 @@ <string name="stk_cc_ss_to_dial_video" msgid="1324194624384312664">"SS сұрауы бейне қоңырауға өзгертілді"</string> <string name="stk_cc_ss_to_ussd" msgid="8417905193112944760">"SS сұрауы USSD сұрауына өзгертілді"</string> <string name="stk_cc_ss_to_ss" msgid="132040645206514450">"Жаңа SS сұрауына өзгертілді"</string> - <!-- no translation found for notification_phishing_alert_content_description (494227305355958790) --> - <skip /> + <string name="notification_phishing_alert_content_description" msgid="494227305355958790">"Фишинг ескертуі"</string> <string name="notification_work_profile_content_description" msgid="5296477955677725799">"Жұмыс профилі"</string> <string name="notification_alerted_content_description" msgid="6139691253611265992">"Ескертілді"</string> <string name="expand_button_content_description_collapsed" msgid="3873368935659010279">"Жаю"</string> @@ -2220,4 +2221,8 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"Жалғастыру үшін <b><xliff:g id="APP">%s</xliff:g></b> қолданбасы құрылғыңыздың камерасына рұқсат алу керек."</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Қосу"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Датчикке қатысты құпиялылық"</string> + <!-- no translation found for splash_screen_view_icon_description (180638751260598187) --> + <skip /> + <!-- no translation found for splash_screen_view_branding_description (7911129347402728216) --> + <skip /> </resources> diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml index 5bde7332aad7..b3516d5c353c 100644 --- a/core/res/res/values-km/strings.xml +++ b/core/res/res/values-km/strings.xml @@ -606,7 +606,8 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"មិនអាចសម្គាល់មុខបានទៀតទេ។ សូមព្យាយាមម្ដងទៀត។"</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"ស្រដៀងគ្នាពេក សូមផ្លាស់ប្ដូរកាយវិការរបស់អ្នក។"</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"ងាកក្បាលរបស់អ្នកតិចជាងមុនបន្តិច។"</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"ងាកក្បាលរបស់អ្នកតិចជាងមុនបន្តិច។"</string> + <!-- no translation found for face_acquired_tilt_too_extreme (8618210742620248049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"ងាកក្បាលរបស់អ្នកបន្តិចទៀត។"</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"យកអ្វីដែលបាំងមុខរបស់អ្នកចេញ។"</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"សម្អាតផ្នែកខាងលើនៃអេក្រង់របស់អ្នក រួមទាំងរបារខ្មៅ"</string> @@ -1667,7 +1668,8 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"ប្រើប្រាស់ផ្លូវកាត់"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"បញ្ច្រាសពណ៌"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"ការកែពណ៌"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"បន្ថយពន្លឺ"</string> + <!-- no translation found for reduce_bright_colors_feature_name (8978255324027479398) --> + <skip /> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"បានសង្កត់គ្រាប់ចុចកម្រិតសំឡេងជាប់។ បានបើក <xliff:g id="SERVICE_NAME">%1$s</xliff:g>។"</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"បានសង្កត់គ្រាប់ចុចកម្រិតសំឡេងជាប់។ បានបិទ <xliff:g id="SERVICE_NAME">%1$s</xliff:g>។"</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"ចុចគ្រាប់ចុចកម្រិតសំឡេងទាំងពីរឱ្យជាប់រយៈពេលបីវិនាទី ដើម្បីប្រើ <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string> @@ -2219,4 +2221,8 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"ដើម្បីបន្ត <b><xliff:g id="APP">%s</xliff:g></b> ត្រូវការសិទ្ធិចូលប្រើកាមេរ៉ារបស់ឧបករណ៍អ្នក។"</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"បើក"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"ឯកជនភាពឧបករណ៍ចាប់សញ្ញា"</string> + <!-- no translation found for splash_screen_view_icon_description (180638751260598187) --> + <skip /> + <!-- no translation found for splash_screen_view_branding_description (7911129347402728216) --> + <skip /> </resources> diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml index cf0f644cb27b..22bdd772856a 100644 --- a/core/res/res/values-kn/strings.xml +++ b/core/res/res/values-kn/strings.xml @@ -606,7 +606,8 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"ಮುಖ ಗುರುತಿಸಲು ಸಾಧ್ಯವಾಗುವುದಿಲ್ಲ. ಪುನಃ ಪ್ರಯತ್ನಿಸಿ."</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"ತುಂಬಾ ಸಮಾನ, ನಿಮ್ಮ ಪೋಸ್ ಬದಲಾಯಿಸಿ."</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"ನಿಮ್ಮ ತಲೆಯನ್ನು ಹೆಚ್ಚು ತಿರುಗಿಸಬೇಡಿ."</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"ನಿಮ್ಮ ತಲೆಯನ್ನು ಹೆಚ್ಚು ತಿರುಗಿಸಬೇಡಿ."</string> + <!-- no translation found for face_acquired_tilt_too_extreme (8618210742620248049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"ನಿಮ್ಮ ತಲೆಯನ್ನು ಸ್ವಲ್ಪ ಕಡಿಮೆ ತಿರುಗಿಸಿ."</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"ನಿಮ್ಮ ಮುಖವನ್ನು ಮರೆಮಾಡುವ ಯಾವುದನ್ನಾದರೂ ತೆಗೆದುಹಾಕಿ."</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"ಬ್ಲ್ಯಾಕ್ ಬಾರ್ ಸೇರಿದಂತೆ ನಿಮ್ಮ ಸ್ಕ್ರೀನ್ನ ಮೇಲ್ಭಾಗವನ್ನು ತೆರವುಗೊಳಿಸಿ"</string> @@ -1667,7 +1668,8 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"ಶಾರ್ಟ್ಕಟ್ ಬಳಸಿ"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"ಬಣ್ಣ ವಿಲೋಮ"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"ಬಣ್ಣ ತಿದ್ದುಪಡಿ"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"ಪ್ರಖರತೆಯನ್ನು ಕಡಿಮೆ ಮಾಡಿ"</string> + <!-- no translation found for reduce_bright_colors_feature_name (8978255324027479398) --> + <skip /> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"ವಾಲ್ಯೂಮ್ ಕೀಗಳನ್ನು ಹಿಡಿದುಕೊಳ್ಳಿ. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ಅನ್ನು ಆನ್ ಮಾಡಲಾಗಿದೆ."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"ವಾಲ್ಯೂಮ್ ಕೀಗಳನ್ನು ಹಿಡಿದಿಟ್ಟುಕೊಳ್ಳಲಾಗಿದೆ. <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, ಆಫ್ ಮಾಡಲಾಗಿದೆ."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> ಅನ್ನು ಬಳಸಲು ಎರಡೂ ಧ್ವನಿ ಕೀಗಳನ್ನು ಮೂರು ಸೆಕೆಂಡ್ಗಳ ಕಾಲ ಒತ್ತಿ ಹಿಡಿದುಕೊಳ್ಳಿ"</string> @@ -1871,8 +1873,7 @@ <string name="stk_cc_ss_to_dial_video" msgid="1324194624384312664">"SS ವಿನಂತಿಯನ್ನು ವೀಡಿಯೊ ಕರೆಗೆ ಬದಲಾಯಿಸಲಾಗಿದೆ"</string> <string name="stk_cc_ss_to_ussd" msgid="8417905193112944760">"SS ವಿನಂತಿಯನ್ನು USSD ವಿನಂತಿಗೆ ಬದಲಾಯಿಸಲಾಗಿದೆ"</string> <string name="stk_cc_ss_to_ss" msgid="132040645206514450">"ಹೊಸ SS ವಿನಂತಿಗೆ ಬದಲಾಯಿಸಲಾಗಿದೆ"</string> - <!-- no translation found for notification_phishing_alert_content_description (494227305355958790) --> - <skip /> + <string name="notification_phishing_alert_content_description" msgid="494227305355958790">"ಫಿಶಿಂಗ್ ಕುರಿತು ಎಚ್ಚರಿಕೆ"</string> <string name="notification_work_profile_content_description" msgid="5296477955677725799">"ಉದ್ಯೋಗ ಪ್ರೊಫೈಲ್"</string> <string name="notification_alerted_content_description" msgid="6139691253611265992">"ಎಚ್ಚರಿಕೆ ನೀಡಲಾಗಿದೆ"</string> <string name="expand_button_content_description_collapsed" msgid="3873368935659010279">"ವಿಸ್ತೃತಗೊಳಿಸಿ"</string> @@ -2220,4 +2221,8 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"ಮುಂದುವರಿಯಲು, <b><xliff:g id="APP">%s</xliff:g></b> ಗೆ ನಿಮ್ಮ ಸಾಧನದ ಕ್ಯಾಮರಾದ ಪ್ರವೇಶದ ಅಗತ್ಯವಿದೆ."</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"ಆನ್ ಮಾಡಿ"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"ಸೆನ್ಸರ್ ಗೌಪ್ಯತೆ"</string> + <!-- no translation found for splash_screen_view_icon_description (180638751260598187) --> + <skip /> + <!-- no translation found for splash_screen_view_branding_description (7911129347402728216) --> + <skip /> </resources> diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml index 8fde34c190a3..52f0a7c9c2ae 100644 --- a/core/res/res/values-ko/strings.xml +++ b/core/res/res/values-ko/strings.xml @@ -606,7 +606,8 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"더 이상 얼굴을 인식할 수 없습니다. 다시 시도하세요."</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"너무 비슷합니다. 다른 포즈를 취해 보세요."</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"고개를 조금 덜 돌려 보세요."</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"고개를 조금 덜 돌려 보세요."</string> + <!-- no translation found for face_acquired_tilt_too_extreme (8618210742620248049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"고개를 조금 덜 돌려 보세요."</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"얼굴이 가려지지 않도록 해 주세요."</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"검은색 바를 포함한 화면 상단을 청소하세요."</string> @@ -1667,7 +1668,8 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"단축키 사용"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"색상 반전"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"색상 보정"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"밝기 낮추기"</string> + <!-- no translation found for reduce_bright_colors_feature_name (8978255324027479398) --> + <skip /> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"볼륨 키를 길게 눌렀습니다. <xliff:g id="SERVICE_NAME">%1$s</xliff:g>이(가) 사용 설정되었습니다."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"볼륨 키를 길게 눌렀습니다. <xliff:g id="SERVICE_NAME">%1$s</xliff:g>이(가) 사용 중지되었습니다."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> 서비스를 사용하려면 두 볼륨 키를 3초 동안 길게 누르세요"</string> @@ -1871,8 +1873,7 @@ <string name="stk_cc_ss_to_dial_video" msgid="1324194624384312664">"SS 요청이 화상 통화로 변경됨"</string> <string name="stk_cc_ss_to_ussd" msgid="8417905193112944760">"SS 요청이 USSD 요청으로 변경됨"</string> <string name="stk_cc_ss_to_ss" msgid="132040645206514450">"새 SS 요청으로 변경됨"</string> - <!-- no translation found for notification_phishing_alert_content_description (494227305355958790) --> - <skip /> + <string name="notification_phishing_alert_content_description" msgid="494227305355958790">"피싱 알림"</string> <string name="notification_work_profile_content_description" msgid="5296477955677725799">"직장 프로필"</string> <string name="notification_alerted_content_description" msgid="6139691253611265992">"알림 전송됨"</string> <string name="expand_button_content_description_collapsed" msgid="3873368935659010279">"펼치기"</string> @@ -2220,4 +2221,8 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"계속하려면 <b><xliff:g id="APP">%s</xliff:g></b>에서 기기 카메라에 액세스해야 합니다."</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"사용"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"센서 개인정보 보호"</string> + <!-- no translation found for splash_screen_view_icon_description (180638751260598187) --> + <skip /> + <!-- no translation found for splash_screen_view_branding_description (7911129347402728216) --> + <skip /> </resources> diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml index aa5d01c1a946..4d8888ebdb9a 100644 --- a/core/res/res/values-ky/strings.xml +++ b/core/res/res/values-ky/strings.xml @@ -606,7 +606,8 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"Жүз таанылган жок. Кайталап көрүңүз."</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"Мурункуга окшош болуп калды, башкача туруңуз."</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"Башыңызды бир аз гана эңкейтиңиз."</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"Башыңызды бир аз гана эңкейтиңиз."</string> + <!-- no translation found for face_acquired_tilt_too_extreme (8618210742620248049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"Башыңызды бир аз гана эңкейтиңиз."</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"Жүзүңүздү жашырып турган нерселерди алып салыңыз."</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"Экраныңыздын жогору жагын, анын ичинде тилкени да тазалаңыз"</string> @@ -1206,7 +1207,7 @@ <string name="unsupported_compile_sdk_check_update" msgid="1103639989147664456">"Жаңыртууну издөө"</string> <string name="smv_application" msgid="3775183542777792638">"<xliff:g id="APPLICATION">%1$s</xliff:g> колдонмосу (<xliff:g id="PROCESS">%2$s</xliff:g> процесси) өз алдынча иштеткен StrictMode саясатын бузду."</string> <string name="smv_process" msgid="1398801497130695446">"<xliff:g id="PROCESS">%1$s</xliff:g> процесси өзүнүн мажбурланган StrictMode саясатын бузуп койду."</string> - <string name="android_upgrading_title" product="default" msgid="7279077384220829683">"Телефон жаңыртылууда…"</string> + <string name="android_upgrading_title" product="default" msgid="7279077384220829683">"Телефон жаңырууда…"</string> <string name="android_upgrading_title" product="tablet" msgid="4268417249079938805">"Планшет жаңыртылууда…"</string> <string name="android_upgrading_title" product="device" msgid="6774767702998149762">"Түзмөк жаңыртылууда…"</string> <string name="android_start_title" product="default" msgid="4036708252778757652">"Телефон күйгүзүлүүдө…"</string> @@ -1216,7 +1217,7 @@ <string name="android_upgrading_fstrim" msgid="3259087575528515329">"Сактагыч ыңгайлаштырылууда."</string> <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"Тутумду жаңыртуу аяктоодо…"</string> <string name="app_upgrading_toast" msgid="1016267296049455585">"<xliff:g id="APPLICATION">%1$s</xliff:g> жаңыртылууда..."</string> - <string name="android_upgrading_apk" msgid="1339564803894466737">"<xliff:g id="NUMBER_1">%2$d</xliff:g> ичинен <xliff:g id="NUMBER_0">%1$d</xliff:g> колдонмо ыңгайлаштырылууда."</string> + <string name="android_upgrading_apk" msgid="1339564803894466737">"<xliff:g id="NUMBER_1">%2$d</xliff:g> ичинен <xliff:g id="NUMBER_0">%1$d</xliff:g> колдонмо оптималдаштырылууда."</string> <string name="android_preparing_apk" msgid="589736917792300956">"<xliff:g id="APPNAME">%1$s</xliff:g> даярдалууда."</string> <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Колдонмолорду иштетип баштоо"</string> <string name="android_upgrading_complete" msgid="409800058018374746">"Жүктөлүүдө"</string> @@ -1667,7 +1668,8 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Кыска жолду колдонуу"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Түстү инверсиялоо"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Түсүн тууралоо"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Экрандын жарыктыгын төмөндөтүү"</string> + <!-- no translation found for reduce_bright_colors_feature_name (8978255324027479398) --> + <skip /> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Үндү катуулатуу/акырындатуу баскычтары басылып, <xliff:g id="SERVICE_NAME">%1$s</xliff:g> күйгүзүлдү."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Үндү катуулатуу/акырындатуу баскычтары басылып, <xliff:g id="SERVICE_NAME">%1$s</xliff:g> өчүрүлдү."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> кызматын колдонуу үчүн үнүн чоңойтуп/кичирейтүү баскычтарын үч секунд коё бербей басып туруңуз"</string> @@ -1871,8 +1873,7 @@ <string name="stk_cc_ss_to_dial_video" msgid="1324194624384312664">"SS сурамы видео чалууга өзгөртүлдү"</string> <string name="stk_cc_ss_to_ussd" msgid="8417905193112944760">"SS сурамы USSD сурамына өзгөртүлдү"</string> <string name="stk_cc_ss_to_ss" msgid="132040645206514450">"Жаңы SS сурамына өзгөртүлдү"</string> - <!-- no translation found for notification_phishing_alert_content_description (494227305355958790) --> - <skip /> + <string name="notification_phishing_alert_content_description" msgid="494227305355958790">"Фишинг жөнүндө эскертүү"</string> <string name="notification_work_profile_content_description" msgid="5296477955677725799">"Жумуш профили"</string> <string name="notification_alerted_content_description" msgid="6139691253611265992">"Эскертилди"</string> <string name="expand_button_content_description_collapsed" msgid="3873368935659010279">"Жайып көрсөтүү"</string> @@ -2220,4 +2221,8 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"Улантуу үчүн <b><xliff:g id="APP">%s</xliff:g></b> колдонмосуна түзмөгүңүздүн камерасын пайдаланууга уруксат беришиңиз керек."</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Күйгүзүү"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Сенсордун купуялыгы"</string> + <!-- no translation found for splash_screen_view_icon_description (180638751260598187) --> + <skip /> + <!-- no translation found for splash_screen_view_branding_description (7911129347402728216) --> + <skip /> </resources> diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml index 806a5e2922c5..87c2cebe78fa 100644 --- a/core/res/res/values-lo/strings.xml +++ b/core/res/res/values-lo/strings.xml @@ -606,7 +606,8 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"ບໍ່ສາມາດຈຳແນກໃບໜ້າໄດ້ອີກຕໍ່ໄປ. ກະລຸນາລອງໃໝ່."</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"ຄ້າຍກັນເກີນໄປ, ກະລຸນາປ່ຽນທ່າຂອງທ່ານ."</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"ອຽງຫົວຂອງທ່ານໜ້ອຍໜຶ່ງ."</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"ອຽງຫົວຂອງທ່ານໜ້ອຍໜຶ່ງ."</string> + <!-- no translation found for face_acquired_tilt_too_extreme (8618210742620248049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"ອຽງຫົວຂອງທ່ານໜ້ອຍໜຶ່ງ."</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"ນຳສິ່ງທີ່ກີດຂວາງໃບໜ້າທ່ານອອກ."</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"ທຳຄວາມສະອາດສ່ວນເທິງສຸດຂອງໜ້າຈໍທ່ານ, ຮວມທັງແຖບດຳນຳ"</string> @@ -1667,7 +1668,8 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"ໃຊ້ປຸ່ມລັດ"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"ການປີ້ນສີ"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"ການແກ້ໄຂຄ່າສີ"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"ຫຼຸດຄວາມສະຫວ່າງ"</string> + <!-- no translation found for reduce_bright_colors_feature_name (8978255324027479398) --> + <skip /> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"ກົດປຸ່ມລະດັບສຽງຄ້າງໄວ້. ເປີດໃຊ້ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ແລ້ວ."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"ກົດປຸ່ມລະດັບສຽງຄ້າງໄວ້. ປິດ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ໄວ້ແລ້ວ."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"ກົດປຸ່ມສຽງທັງສອງພ້ອມກັນຄ້າງໄວ້ສາມວິນາທີເພື່ອໃຊ້ <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string> @@ -2219,4 +2221,8 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"ເພື່ອດຳເນີນການຕໍ່, <b><xliff:g id="APP">%s</xliff:g></b> ຕ້ອງການສິດເຂົ້າເຖິງກ້ອງຖ່າຍຮູບຂອງອຸປະກອນທ່ານ."</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"ເປີດໃຊ້"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"ຄວາມເປັນສ່ວນຕົວເຊັນເຊີ"</string> + <!-- no translation found for splash_screen_view_icon_description (180638751260598187) --> + <skip /> + <!-- no translation found for splash_screen_view_branding_description (7911129347402728216) --> + <skip /> </resources> diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml index 8f64bddc6bf0..2c3742baeae6 100644 --- a/core/res/res/values-lt/strings.xml +++ b/core/res/res/values-lt/strings.xml @@ -612,7 +612,8 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"Nebegalima atpažinti veido. Bandykite dar kartą."</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"Per daug panašu, pakeiskite veido išraišką."</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"Nesukite tiek galvos."</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"Nesukite tiek galvos."</string> + <!-- no translation found for face_acquired_tilt_too_extreme (8618210742620248049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"Nesukite tiek galvos."</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"Patraukite viską, kas užstoja jūsų veidą."</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"Išvalykite ekrano viršų, įskaitant juodą juostą"</string> @@ -1711,7 +1712,8 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Naudoti spartųjį klavišą"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Spalvų inversija"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Spalvų taisymas"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Šviesumo mažinimas"</string> + <!-- no translation found for reduce_bright_colors_feature_name (8978255324027479398) --> + <skip /> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Laikomi garsumo klavišai. „<xliff:g id="SERVICE_NAME">%1$s</xliff:g>“ įjungta."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Laikomi garsumo klavišai. „<xliff:g id="SERVICE_NAME">%1$s</xliff:g>“ išjungta."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Jei norite naudoti „<xliff:g id="SERVICE_NAME">%1$s</xliff:g>“, paspauskite abu garsumo klavišus ir palaikykite tris sekundes"</string> @@ -1933,8 +1935,7 @@ <string name="stk_cc_ss_to_dial_video" msgid="1324194624384312664">"SS užklausa pakeista į vaizdo skambutį"</string> <string name="stk_cc_ss_to_ussd" msgid="8417905193112944760">"SS užklausa pakeista į USSD užklausą"</string> <string name="stk_cc_ss_to_ss" msgid="132040645206514450">"Pakeista į naują SS užklausą"</string> - <!-- no translation found for notification_phishing_alert_content_description (494227305355958790) --> - <skip /> + <string name="notification_phishing_alert_content_description" msgid="494227305355958790">"Įspėjimas apie sukčiavimą"</string> <string name="notification_work_profile_content_description" msgid="5296477955677725799">"Darbo profilis"</string> <string name="notification_alerted_content_description" msgid="6139691253611265992">"Įspėjimas išsiųstas"</string> <string name="expand_button_content_description_collapsed" msgid="3873368935659010279">"Išskleisti"</string> @@ -2288,4 +2289,8 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"Kad būtų galima tęsti, <b><xliff:g id="APP">%s</xliff:g></b> reikalinga prieiga prie įrenginio fotoaparato."</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Įjungti"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Jutiklių privatumas"</string> + <!-- no translation found for splash_screen_view_icon_description (180638751260598187) --> + <skip /> + <!-- no translation found for splash_screen_view_branding_description (7911129347402728216) --> + <skip /> </resources> diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml index 346ade469828..8d6ce865ec7c 100644 --- a/core/res/res/values-lv/strings.xml +++ b/core/res/res/values-lv/strings.xml @@ -609,7 +609,8 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"Seju vairs nevar atpazīt. Mēģiniet vēlreiz."</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"Pārāk līdzīgi. Lūdzu, mainiet pozu."</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"Pagrieziet galvu nedaudz mazāk."</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"Pagrieziet galvu nedaudz mazāk."</string> + <!-- no translation found for face_acquired_tilt_too_extreme (8618210742620248049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"Pagrieziet galvu nedaudz mazāk."</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"Noņemiet visu, kas aizsedz jūsu seju."</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"Notīriet ekrāna augšdaļu, tostarp melno joslu."</string> @@ -1689,7 +1690,8 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Izmantot saīsni"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Krāsu inversija"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Krāsu korekcija"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Spilgtuma samazināšana"</string> + <!-- no translation found for reduce_bright_colors_feature_name (8978255324027479398) --> + <skip /> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Turējāt nospiestas skaļuma pogas. Pakalpojums <xliff:g id="SERVICE_NAME">%1$s</xliff:g> tika ieslēgts."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Turējāt nospiestas skaļuma pogas. Pakalpojums <xliff:g id="SERVICE_NAME">%1$s</xliff:g> tika izslēgts."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Lai izmantotu pakalpojumu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, nospiediet abus skaļuma taustiņus un turiet tos trīs sekundes."</string> @@ -1902,8 +1904,7 @@ <string name="stk_cc_ss_to_dial_video" msgid="1324194624384312664">"SS pieprasījums mainīts uz videozvanu"</string> <string name="stk_cc_ss_to_ussd" msgid="8417905193112944760">"SS pieprasījums mainīts uz USSD pieprasījumu"</string> <string name="stk_cc_ss_to_ss" msgid="132040645206514450">"Mainīts uz jaunu SS pieprasījumu"</string> - <!-- no translation found for notification_phishing_alert_content_description (494227305355958790) --> - <skip /> + <string name="notification_phishing_alert_content_description" msgid="494227305355958790">"Brīdinājums par pikšķerēšanu"</string> <string name="notification_work_profile_content_description" msgid="5296477955677725799">"Darba profils"</string> <string name="notification_alerted_content_description" msgid="6139691253611265992">"Brīdināts"</string> <string name="expand_button_content_description_collapsed" msgid="3873368935659010279">"Izvērst"</string> @@ -2254,4 +2255,8 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"Lai turpinātu, lietotnei <b><xliff:g id="APP">%s</xliff:g></b> nepieciešama piekļuve jūsu ierīces kamerai."</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Ieslēgt"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Sensoru konfidencialitāte"</string> + <!-- no translation found for splash_screen_view_icon_description (180638751260598187) --> + <skip /> + <!-- no translation found for splash_screen_view_branding_description (7911129347402728216) --> + <skip /> </resources> diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml index 8d176ad552a3..af3ce0065ff5 100644 --- a/core/res/res/values-mk/strings.xml +++ b/core/res/res/values-mk/strings.xml @@ -606,7 +606,8 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"Ликот не се препознава. Обидете се повторно."</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"Премногу слично, сменете ја позата."</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"Не вртете ја главата толку многу."</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"Не вртете ја главата толку многу."</string> + <!-- no translation found for face_acquired_tilt_too_extreme (8618210742620248049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"Не вртете ја главата толку многу."</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"Отстранете ги работите што ви го покриваат лицето."</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"Исчистете го врвот на екранот, вклучувајќи ја црната лента"</string> @@ -1667,7 +1668,8 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Користи кратенка"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Инверзија на бои"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Корекција на бои"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Намалете ја осветленоста"</string> + <!-- no translation found for reduce_bright_colors_feature_name (8978255324027479398) --> + <skip /> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Ги задржавте копчињата за јачина на звук. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> е вклучена."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Ги задржавте копчињата за јачина на звук. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> е исклучена."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Притиснете ги и задржете ги двете копчиња за јачина на звукот во траење од три секунди за да користите <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string> @@ -1871,8 +1873,7 @@ <string name="stk_cc_ss_to_dial_video" msgid="1324194624384312664">"Барањето SS е изменето во видео повик"</string> <string name="stk_cc_ss_to_ussd" msgid="8417905193112944760">"Барањето SS е изменето во барање USSD"</string> <string name="stk_cc_ss_to_ss" msgid="132040645206514450">"Променето на ново барање SS"</string> - <!-- no translation found for notification_phishing_alert_content_description (494227305355958790) --> - <skip /> + <string name="notification_phishing_alert_content_description" msgid="494227305355958790">"Предупредување за фишинг"</string> <string name="notification_work_profile_content_description" msgid="5296477955677725799">"Работен профил"</string> <string name="notification_alerted_content_description" msgid="6139691253611265992">"Предупредено"</string> <string name="expand_button_content_description_collapsed" msgid="3873368935659010279">"Прошири"</string> @@ -2220,4 +2221,8 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"За да продолжи, на <b><xliff:g id="APP">%s</xliff:g></b> ѝ е потребен пристап до камерата на уредот."</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Вклучи"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Приватност на сензорот"</string> + <!-- no translation found for splash_screen_view_icon_description (180638751260598187) --> + <skip /> + <!-- no translation found for splash_screen_view_branding_description (7911129347402728216) --> + <skip /> </resources> diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml index fd61768347d3..aaab7b59837b 100644 --- a/core/res/res/values-ml/strings.xml +++ b/core/res/res/values-ml/strings.xml @@ -606,7 +606,8 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"ഇനി മുഖം തിരിച്ചറിയാനാവില്ല. വീണ്ടും ശ്രമിക്കൂ."</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"വളരെയധികം സമാനത, നിങ്ങളുടെ പോസ് മാറ്റുക."</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"നിങ്ങളുടെ തല ഇത്ര തിരിക്കേണ്ട."</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"നിങ്ങളുടെ തല ഇത്ര തിരിക്കേണ്ട."</string> + <!-- no translation found for face_acquired_tilt_too_extreme (8618210742620248049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"നിങ്ങളുടെ തല ഇത്ര തിരിക്കേണ്ട."</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"നിങ്ങളുടെ മുഖം മറയ്ക്കുന്നത് എല്ലാം നീക്കം ചെയ്യൂ."</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"കറുപ്പ് ബാർ ഉൾപ്പെടെ നിങ്ങളുടെ സ്ക്രീനിന്റെ മുകൾഭാഗം വൃത്തിയാക്കുക"</string> @@ -685,10 +686,8 @@ <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"\'ശല്യപ്പെടുത്തരുത്\' കോൺഫിഗറേഷൻ വായിക്കുന്നതിനും എഴുതുന്നതിനും ആപ്പിനെ അനുവദിക്കുന്നു."</string> <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"അനുമതി ഉപയോഗം കാണാൻ ആരംഭിക്കുക"</string> <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"ഒരു ആപ്പിനുള്ള അനുമതി ഉപയോഗം ആരംഭിക്കാൻ ഹോൾഡറിനെ അനുവദിക്കുന്നു. സാധാരണ ആപ്പുകൾക്ക് ഒരിക്കലും ആവശ്യമില്ല."</string> - <!-- no translation found for permlab_highSamplingRateSensors (3941068435726317070) --> - <skip /> - <!-- no translation found for permdesc_highSamplingRateSensors (8430061978931155995) --> - <skip /> + <string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"ഉയർന്ന സാംപ്ലിംഗ് റേറ്റിൽ സെൻസർ ഡാറ്റ ആക്സസ് ചെയ്യുക"</string> + <string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"200 Hz-നേക്കാൾ ഉയർന്ന റേറ്റിൽ സെൻസർ ഡാറ്റ സാമ്പിൾ ചെയ്യാൻ ആപ്പിനെ അനുവദിക്കുന്നു"</string> <string name="policylab_limitPassword" msgid="4851829918814422199">"പാസ്വേഡ് നിയമങ്ങൾ സജ്ജീകരിക്കുക"</string> <string name="policydesc_limitPassword" msgid="4105491021115793793">"സ്ക്രീൻ ലോക്ക് പാസ്വേഡുകളിലും PIN-കളിലും അനുവദിച്ചിരിക്കുന്ന ദൈർഘ്യവും പ്രതീകങ്ങളും നിയന്ത്രിക്കുക."</string> <string name="policylab_watchLogin" msgid="7599669460083719504">"സ്ക്രീൻ അൺലോക്ക് ശ്രമങ്ങൾ നിരീക്ഷിക്കുക"</string> @@ -1669,7 +1668,8 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"കുറുക്കുവഴി ഉപയോഗിക്കുക"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"വർണ്ണ വിപര്യയം"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"നിറം ക്രമീകരിക്കൽ"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"തെളിച്ചം കുറയ്ക്കുക"</string> + <!-- no translation found for reduce_bright_colors_feature_name (8978255324027479398) --> + <skip /> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"വോളിയം കീകൾ പിടിച്ചു. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ഓണാക്കി."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"വോളിയം കീകൾ അമർത്തിപ്പിടിച്ചു. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ഓഫാക്കി."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> ഉപയോഗിക്കാൻ, രണ്ട് വോളിയം കീകളും മൂന്ന് സെക്കൻഡ് അമർത്തിപ്പിടിക്കുക"</string> @@ -1873,8 +1873,7 @@ <string name="stk_cc_ss_to_dial_video" msgid="1324194624384312664">"SS അഭ്യർത്ഥന, വീഡിയോ കോളിലേക്ക് മാറ്റി"</string> <string name="stk_cc_ss_to_ussd" msgid="8417905193112944760">"SS അഭ്യർത്ഥന, USSD അഭ്യർത്ഥനയിലേക്ക് മാറ്റി"</string> <string name="stk_cc_ss_to_ss" msgid="132040645206514450">"പുതിയ SS അഭ്യർത്ഥനയിലേക്ക് മാറ്റി"</string> - <!-- no translation found for notification_phishing_alert_content_description (494227305355958790) --> - <skip /> + <string name="notification_phishing_alert_content_description" msgid="494227305355958790">"ഫിഷിംഗ് മുന്നറിയിപ്പ്"</string> <string name="notification_work_profile_content_description" msgid="5296477955677725799">"ഔദ്യോഗിക പ്രൊഫൈൽ"</string> <string name="notification_alerted_content_description" msgid="6139691253611265992">"മുന്നറിയിപ്പ് നൽകി"</string> <string name="expand_button_content_description_collapsed" msgid="3873368935659010279">"വികസിപ്പിക്കുക"</string> @@ -2222,4 +2221,8 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"തുടരാൻ, <b><xliff:g id="APP">%s</xliff:g></b> ആപ്പിന് നിങ്ങളുടെ ഉപകരണത്തിന്റെ ക്യാമറയിലേക്ക് ആക്സസ് നൽകേണ്ടതുണ്ട്."</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"ഓണാക്കുക"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"സെൻസർ സ്വകാര്യത"</string> + <!-- no translation found for splash_screen_view_icon_description (180638751260598187) --> + <skip /> + <!-- no translation found for splash_screen_view_branding_description (7911129347402728216) --> + <skip /> </resources> diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml index d5937d364788..c69928546143 100644 --- a/core/res/res/values-mn/strings.xml +++ b/core/res/res/values-mn/strings.xml @@ -606,7 +606,8 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"Царайг таних боломжгүй боллоо. Дахин оролдоно уу."</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"Хэт адилхан байгаа тул байрлалаа өөрчилнө үү."</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"Толгойгоо арай багаар эргүүлнэ үү."</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"Толгойгоо арай багаар эргүүлнэ үү."</string> + <!-- no translation found for face_acquired_tilt_too_extreme (8618210742620248049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"Толгойгоо арай багаар эргүүлнэ үү."</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"Таны нүүрийг далдалж буй аливаа зүйлийг хасна уу."</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"Хар хэсэг зэрэг дэлгэцийнхээ дээд хэсгийг цэвэрлэнэ үү"</string> @@ -1667,7 +1668,8 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Товчлол ашиглах"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Өнгө хувиргалт"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Өнгөний засвар"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Гэрэлтүүлгийг багасгах"</string> + <!-- no translation found for reduce_bright_colors_feature_name (8978255324027479398) --> + <skip /> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Дууны түвшний түлхүүрийг удаан дарсан. <xliff:g id="SERVICE_NAME">%1$s</xliff:g>-г асаалаа."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Дууны түвшний түлхүүрийг удаан дарсан. <xliff:g id="SERVICE_NAME">%1$s</xliff:g>-г унтраалаа."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>-г ашиглахын тулд дууны түвшнийг ихэсгэх, багасгах түлхүүрийг 3 секундийн турш зэрэг дарна уу"</string> @@ -1871,8 +1873,7 @@ <string name="stk_cc_ss_to_dial_video" msgid="1324194624384312664">"SS хүсэлтийг видео дуудлага болгон өөрчилсөн"</string> <string name="stk_cc_ss_to_ussd" msgid="8417905193112944760">"SS хүсэлтийг USSD хүсэлт болгон өөрчилсөн"</string> <string name="stk_cc_ss_to_ss" msgid="132040645206514450">"Шинэ SS хүсэлт болгон өөрчилсөн"</string> - <!-- no translation found for notification_phishing_alert_content_description (494227305355958790) --> - <skip /> + <string name="notification_phishing_alert_content_description" msgid="494227305355958790">"Фишинг сэрэмжлүүлэг"</string> <string name="notification_work_profile_content_description" msgid="5296477955677725799">"Ажлын профайл"</string> <string name="notification_alerted_content_description" msgid="6139691253611265992">"Мэдэгдсэн"</string> <string name="expand_button_content_description_collapsed" msgid="3873368935659010279">"Дэлгэх"</string> @@ -2220,4 +2221,8 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"Үргэлжлүүлэхийн тулд <b><xliff:g id="APP">%s</xliff:g></b> таны төхөөрөмжийн камерт хандах шаардлагатай."</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Асаах"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Мэдрэгчийн нууцлал"</string> + <!-- no translation found for splash_screen_view_icon_description (180638751260598187) --> + <skip /> + <!-- no translation found for splash_screen_view_branding_description (7911129347402728216) --> + <skip /> </resources> diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml index 5f4d5fd916f6..a31951a3f5ac 100644 --- a/core/res/res/values-mr/strings.xml +++ b/core/res/res/values-mr/strings.xml @@ -606,7 +606,8 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"चेहरा ओळखू शकत नाही. पुन्हा प्रयत्न करा."</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"एकाच प्रकारची पोझ देत आहात कृपया तुमची पोझ बदला."</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"तुमचे डोके थोडे कमी फिरवा."</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"तुमचे डोके थोडे कमी फिरवा."</string> + <!-- no translation found for face_acquired_tilt_too_extreme (8618210742620248049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"तुमचे डोके थोडे कमी फिरवा."</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"तुमचा चहेरा लपवणारे काहीही काढून टाका."</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"ब्लॅक बार सह तुमच्या स्क्रीनची वरची बाजू साफ करा"</string> @@ -685,10 +686,8 @@ <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"व्यत्यय आणू नका कॉंफिगरेशन वाचण्यासाठी आणि लिहिण्यासाठी ॲपला अनुमती देते."</string> <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"व्ह्यू परवानगी वापर सुरू करा"</string> <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"धारकास अॅपसाठी परवानगी वापरणे सुरू करण्याची अनुमती देते. सामान्य अॅप्ससाठी कधीही आवश्यकता नसते."</string> - <!-- no translation found for permlab_highSamplingRateSensors (3941068435726317070) --> - <skip /> - <!-- no translation found for permdesc_highSamplingRateSensors (8430061978931155995) --> - <skip /> + <string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"उच्च नमुना दराने सेन्सर डेटा अॅक्सेस करते"</string> + <string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"ॲपला २०० Hz पेक्षा जास्त दराने सेन्सर डेटाचा नमुना तयार करण्याची अनुमती देते"</string> <string name="policylab_limitPassword" msgid="4851829918814422199">"पासवर्ड नियम सेट करा"</string> <string name="policydesc_limitPassword" msgid="4105491021115793793">"स्क्रीन लॉक पासवर्ड आणि पिन मध्ये अनुमती दिलेले लांबी आणि वर्ण नियंत्रित करा."</string> <string name="policylab_watchLogin" msgid="7599669460083719504">"स्क्रीन अनलॉक प्रयत्नांचे परीक्षण करा"</string> @@ -1669,7 +1668,8 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"शॉर्टकट वापरा"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"रंगांची उलटापालट"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"रंग सुधारणा"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"ब्राइटनेस कमी करा"</string> + <!-- no translation found for reduce_bright_colors_feature_name (8978255324027479398) --> + <skip /> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"धरून ठेवलेल्या व्हॉल्यूम की. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> सुरू केला आहे."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"धरून ठेवलेल्या व्हॉल्यूम की. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> बंद केले आहे."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> वापरण्यासाठी दोन्ही व्हॉल्युम की तीन सेकंद दाबा आणि धरून ठेवा"</string> @@ -1873,8 +1873,7 @@ <string name="stk_cc_ss_to_dial_video" msgid="1324194624384312664">"SS विनंती व्हिडिओ कॉलवर बदलली"</string> <string name="stk_cc_ss_to_ussd" msgid="8417905193112944760">"SS विनंती USSD विनंतीवर बदलली"</string> <string name="stk_cc_ss_to_ss" msgid="132040645206514450">"नवीन SS विनंतीवर बदलली"</string> - <!-- no translation found for notification_phishing_alert_content_description (494227305355958790) --> - <skip /> + <string name="notification_phishing_alert_content_description" msgid="494227305355958790">"फिशिंगशी संबंधित सूचना"</string> <string name="notification_work_profile_content_description" msgid="5296477955677725799">"कार्य प्रोफाईल"</string> <string name="notification_alerted_content_description" msgid="6139691253611265992">"सूचना दिल्या"</string> <string name="expand_button_content_description_collapsed" msgid="3873368935659010279">"विस्तृत करा"</string> @@ -2222,4 +2221,8 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"पुढे सुरू ठेवण्यासाठी, <b><xliff:g id="APP">%s</xliff:g></b> ला तुमच्या डिव्हाइसचा कॅमेरा अॅक्सेस करण्याची आवश्यकता आहे."</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"सुरू करा"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"सेन्सरशी संबंधित गोपनीयतेबाबत सूचना"</string> + <!-- no translation found for splash_screen_view_icon_description (180638751260598187) --> + <skip /> + <!-- no translation found for splash_screen_view_branding_description (7911129347402728216) --> + <skip /> </resources> diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml index 27b1d60ba652..5e5b29f8e4e0 100644 --- a/core/res/res/values-ms/strings.xml +++ b/core/res/res/values-ms/strings.xml @@ -606,7 +606,8 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"Tidak lagi dapat mengecam wajah. Cuba lagi."</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"Terlalu serupa, sila ubah lagak gaya anda."</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"Pusingkan kepala anda kurang sedikit."</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"Pusingkan kepala anda kurang sedikit."</string> + <!-- no translation found for face_acquired_tilt_too_extreme (8618210742620248049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"Pusingkan kepala anda kurang sedikit."</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"Alih keluar apa saja yang melindungi wajah anda."</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"Bersihkan bahagian atas skrin anda, termasuk bar hitam"</string> @@ -1667,7 +1668,8 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Gunakan Pintasan"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Penyongsangan Warna"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Pembetulan Warna"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Kurangkan Kecerahan"</string> + <!-- no translation found for reduce_bright_colors_feature_name (8978255324027479398) --> + <skip /> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Kekunci kelantangan ditahan. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> dihidupkan."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Kekunci kelantangan ditahan. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> dimatikan."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Tekan dan tahan kedua-dua kekunci kelantangan selama tiga saat untuk menggunakan <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string> @@ -2219,4 +2221,8 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"Untuk meneruskan proses, <b><xliff:g id="APP">%s</xliff:g></b> memerlukan akses kepada kamera peranti anda."</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Hidupkan"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Privasi Penderia"</string> + <!-- no translation found for splash_screen_view_icon_description (180638751260598187) --> + <skip /> + <!-- no translation found for splash_screen_view_branding_description (7911129347402728216) --> + <skip /> </resources> diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml index 9e1bd7394d41..137c138cba97 100644 --- a/core/res/res/values-my/strings.xml +++ b/core/res/res/values-my/strings.xml @@ -606,7 +606,8 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"မျက်နှာ မမှတ်သားနိုင်တော့ပါ။ ထပ်စမ်းကြည့်ပါ။"</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"ဆင်တူနေသည်၊ အမူအရာ ပြောင်းပါ။"</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"ခေါင်းကို သိပ်မလှည့်ပါနှင့်။"</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"ခေါင်းကို သိပ်မလှည့်ပါနှင့်။"</string> + <!-- no translation found for face_acquired_tilt_too_extreme (8618210742620248049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"ခေါင်းကို သိပ်မလှည့်ပါနှင့်။"</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"သင့်မျက်နှာကို ကွယ်နေသည့်အရာအားလုံး ဖယ်ပါ။"</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"အနက်ရောင်ဘားအပါအဝင် ဖန်သားပြင်ထိပ်ကို သန့်ရှင်းရေး လုပ်ပါ"</string> @@ -1667,7 +1668,8 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"ဖြတ်လမ်းလင့်ခ်ကို သုံးရန်"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"အရောင် ပြောင်းပြန်လှန်ခြင်း"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"အရောင်ပြင်ဆင်ခြင်း"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"တောက်ပမှုကို လျှော့ခြင်း"</string> + <!-- no translation found for reduce_bright_colors_feature_name (8978255324027479398) --> + <skip /> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"အသံခလုတ်များကို ဖိထားသည်။ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ဖွင့်လိုက်သည်။"</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"အသံခလုတ်များကို ဖိထားသည်။ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ပိတ်လိုက်သည်။"</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> ကို သုံးရန် အသံအတိုးအလျှော့ ခလုတ်နှစ်ခုလုံးကို သုံးစက္ကန့်ကြာ ဖိထားပါ"</string> @@ -2219,4 +2221,8 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"ဆက်လက်လုပ်ဆောင်ရန် <b><xliff:g id="APP">%s</xliff:g></b> က သင့်စက်၏ ကင်မရာကို အသုံးပြုခွင့်ရရန် လိုအပ်သည်။"</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"ဖွင့်ရန်"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"အာရုံခံကိရိယာ လုံခြုံရေး"</string> + <!-- no translation found for splash_screen_view_icon_description (180638751260598187) --> + <skip /> + <!-- no translation found for splash_screen_view_branding_description (7911129347402728216) --> + <skip /> </resources> diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml index c84670154549..de71c39a05d0 100644 --- a/core/res/res/values-nb/strings.xml +++ b/core/res/res/values-nb/strings.xml @@ -606,7 +606,8 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"Kan ikke gjenkjenne ansiktet lenger. Prøv igjen."</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"For likt – endre posituren din."</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"Vri hodet ditt litt mindre."</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"Vri hodet ditt litt mindre."</string> + <!-- no translation found for face_acquired_tilt_too_extreme (8618210742620248049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"Vri hodet ditt litt mindre."</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"Fjern alt som skjuler ansiktet ditt."</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"Rengjør den øverste delen av skjermen, inkludert den svarte linjen"</string> @@ -1667,7 +1668,8 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Bruk snarveien"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Fargeinvertering"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Fargekorrigering"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Reduser lysstyrken"</string> + <!-- no translation found for reduce_bright_colors_feature_name (8978255324027479398) --> + <skip /> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Volumtastene holdes inne. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> er slått på."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Volumtastene holdes inne. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> er slått av."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Trykk og hold inne begge volumtastene i tre sekunder for å bruke <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string> @@ -1871,8 +1873,7 @@ <string name="stk_cc_ss_to_dial_video" msgid="1324194624384312664">"SS-forespørsel endret til videoanrop"</string> <string name="stk_cc_ss_to_ussd" msgid="8417905193112944760">"SS-forespørsel endret til USSD-forespørsel"</string> <string name="stk_cc_ss_to_ss" msgid="132040645206514450">"Endret til ny SS-forespørsel"</string> - <!-- no translation found for notification_phishing_alert_content_description (494227305355958790) --> - <skip /> + <string name="notification_phishing_alert_content_description" msgid="494227305355958790">"Varsel om nettfisking"</string> <string name="notification_work_profile_content_description" msgid="5296477955677725799">"Arbeidsprofil"</string> <string name="notification_alerted_content_description" msgid="6139691253611265992">"Varslet"</string> <string name="expand_button_content_description_collapsed" msgid="3873368935659010279">"Vis"</string> @@ -2220,4 +2221,8 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"For å fortsette må <b><xliff:g id="APP">%s</xliff:g></b> ha tilgang til enhetskameraet."</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Slå på"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Sensorpersonvern"</string> + <!-- no translation found for splash_screen_view_icon_description (180638751260598187) --> + <skip /> + <!-- no translation found for splash_screen_view_branding_description (7911129347402728216) --> + <skip /> </resources> diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml index 9af472aa3322..83c03a4361c0 100644 --- a/core/res/res/values-ne/strings.xml +++ b/core/res/res/values-ne/strings.xml @@ -606,7 +606,8 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"अब उप्रान्त अनुहार पहिचान गर्न सकिएन। फेरि प्रयास गर्नुहोस्।"</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"अनुहार उस्तै भयो, कृपया आफ्नो पोज बदल्नुहोस्।"</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"आफ्नो टाउको अलि थोरै घुमाउनुहोस्।"</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"आफ्नो टाउको अलि थोरै घुमाउनुहोस्।"</string> + <!-- no translation found for face_acquired_tilt_too_extreme (8618210742620248049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"आफ्नो टाउको अलि थोरै घुमाउनुहोस्।"</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"तपाईंको अनुहार लुकाउने सबै कुरा लुकाउनुहोस्।"</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"कालो रङको पट्टीलगायत आफ्नो स्क्रिनको माथिल्लो भाग सफा गर्नुहोस्"</string> @@ -685,10 +686,8 @@ <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"बाधा नपुर्याउँनुहोस् कन्फिगरेसन पढ्न र लेख्नको लागि एपलाई अनुमति दिनुहोस्।"</string> <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"हेर्ने अनुमतिको प्रयोग सुरु गर्नुहोस्"</string> <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"वाहकलाई कुनै एपसम्बन्धी अनुमतिको प्रयोग सुरु गर्न दिन्छ। साधारण एपहरूलाई कहिल्यै आवश्यक नपर्नु पर्ने हो।"</string> - <!-- no translation found for permlab_highSamplingRateSensors (3941068435726317070) --> - <skip /> - <!-- no translation found for permdesc_highSamplingRateSensors (8430061978931155995) --> - <skip /> + <string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"नमुना लिने उच्च दरमा सेन्सरसम्बन्धी डेटा प्रयोग गर्ने"</string> + <string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"यो अनुमति दिइएमा एपले २०० हर्जभन्दा बढी दरमा सेन्सरसम्बन्धी डेटाको नमुना लिन सक्छ"</string> <string name="policylab_limitPassword" msgid="4851829918814422199">"पासवर्ड नियमहरू मिलाउनुहोस्"</string> <string name="policydesc_limitPassword" msgid="4105491021115793793">"स्क्रिन लक पासवर्ड र PIN हरूमा अनुमति दिइएको लम्बाइ र वर्णहरूको नियन्त्रण गर्नुहोस्।"</string> <string name="policylab_watchLogin" msgid="7599669460083719504">"मनिटरको स्क्रिन अनलक गर्ने प्रयासहरू"</string> @@ -1669,7 +1668,8 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"सर्टकट प्रयोग गर्नुहोस्"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"रङ्ग उल्टाउने सुविधा"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"रङ्ग सच्याउने सुविधा"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"स्क्रिनको चमक घटाउनुहोस्"</string> + <!-- no translation found for reduce_bright_colors_feature_name (8978255324027479398) --> + <skip /> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"तपाईंले भोल्युम बटनहरू थिचिराख्नुभयो। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> अन भयो।"</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"तपाईंले भोल्युम बटनहरू थिचिराख्नुभयो। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> अफ भयो।"</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> प्रयोग गर्न दुवै भोल्युम कुञ्जीहरूलाई तीन सेकेन्डसम्म थिचिराख्नुहोस्"</string> @@ -1873,8 +1873,7 @@ <string name="stk_cc_ss_to_dial_video" msgid="1324194624384312664">"SS अनुरोधलाई भिडियो कलमा परिवर्तन गरियो"</string> <string name="stk_cc_ss_to_ussd" msgid="8417905193112944760">"SS अनुरोधलाई USSD अनुरोधमा परिवर्तन गरियो"</string> <string name="stk_cc_ss_to_ss" msgid="132040645206514450">"नयाँ SS अनुरोधमा परिवर्तन गरियो"</string> - <!-- no translation found for notification_phishing_alert_content_description (494227305355958790) --> - <skip /> + <string name="notification_phishing_alert_content_description" msgid="494227305355958790">"फिसिङसम्बन्धी अलर्ट"</string> <string name="notification_work_profile_content_description" msgid="5296477955677725799">"कार्य प्रोफाइल"</string> <string name="notification_alerted_content_description" msgid="6139691253611265992">"सतर्कता गरियो"</string> <string name="expand_button_content_description_collapsed" msgid="3873368935659010279">"विस्तृत गर्नुहोस्"</string> @@ -2222,4 +2221,8 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"जारी राख्न <b><xliff:g id="APP">%s</xliff:g></b> लाई तपाईंको यन्त्रको क्यामेरा प्रयोग गर्ने अनुमति दिनु पर्ने हुन्छ।"</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"अन गर्नुहोस्"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"सेन्सरसम्बन्धी गोपनीयता"</string> + <!-- no translation found for splash_screen_view_icon_description (180638751260598187) --> + <skip /> + <!-- no translation found for splash_screen_view_branding_description (7911129347402728216) --> + <skip /> </resources> diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml index d76d32a8d6b2..e2be98d723fa 100644 --- a/core/res/res/values-nl/strings.xml +++ b/core/res/res/values-nl/strings.xml @@ -606,7 +606,8 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"Herkent gezicht niet meer. Probeer het nog eens."</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"Lijkt te veel op elkaar. Verander je pose."</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"Draai je hoofd iets minder."</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"Draai je hoofd iets minder."</string> + <!-- no translation found for face_acquired_tilt_too_extreme (8618210742620248049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"Draai je hoofd iets minder."</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"Zorg dat je gezicht volledig zichtbaar is."</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"Reinig de bovenkant van je scherm, inclusief de zwarte balk"</string> @@ -1667,7 +1668,8 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Sneltoets gebruiken"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Kleurinversie"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Kleurcorrectie"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Helderheid verlagen"</string> + <!-- no translation found for reduce_bright_colors_feature_name (8978255324027479398) --> + <skip /> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Volumetoetsen ingedrukt gehouden. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> is ingeschakeld."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Volumetoetsen ingedrukt gehouden. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> uitgeschakeld."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Houd beide volumetoetsen drie seconden ingedrukt om <xliff:g id="SERVICE_NAME">%1$s</xliff:g> te gebruiken"</string> @@ -2219,4 +2221,8 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"<b><xliff:g id="APP">%s</xliff:g></b> heeft toegang tot de camera van je apparaat nodig om door te gaan."</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Aanzetten"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Sensorprivacy"</string> + <!-- no translation found for splash_screen_view_icon_description (180638751260598187) --> + <skip /> + <!-- no translation found for splash_screen_view_branding_description (7911129347402728216) --> + <skip /> </resources> diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml index f42d8abbcee2..bc761429b4c7 100644 --- a/core/res/res/values-or/strings.xml +++ b/core/res/res/values-or/strings.xml @@ -606,7 +606,8 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"ଆଉ ମୁହଁ ଚିହ୍ନଟ କରିହେଲା ନାହିଁ। ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।"</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"ଅତ୍ୟନ୍ତ ସମପରି, ଦୟାକରି ଆପଣଙ୍କର ପୋଜ୍ ବଦଳାନ୍ତୁ।"</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"ଆପଣଙ୍କର ମୁଣ୍ଡକୁ ଟିକିଏ ବୁଲାନ୍ତୁ।"</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"ଆପଣଙ୍କର ମୁଣ୍ଡକୁ ଟିକିଏ ବୁଲାନ୍ତୁ।"</string> + <!-- no translation found for face_acquired_tilt_too_extreme (8618210742620248049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"ଆପଣଙ୍କର ମୁଣ୍ଡକୁ ଟିକିଏ ବୁଲାନ୍ତୁ।"</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"ଆପଣଙ୍କର ମୁହଁ ଲୁଚାଉଥିବା ଜିନିଷକୁ କାଢ଼ି ଦିଅନ୍ତୁ।"</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"କଳା ବାର୍ ସମେତ ଆପଣଙ୍କ ସ୍କ୍ରିନ୍ର ଶୀର୍ଷକୁ ସଫା କରନ୍ତୁ"</string> @@ -1667,7 +1668,8 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"ଶର୍ଟକଟ୍ ବ୍ୟବହାର କରନ୍ତୁ"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"ରଙ୍ଗ ବଦଳାଇବାର ସୁବିଧା"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"ରଙ୍ଗ ସଂଶୋଧନ"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"ଉଜ୍ଜ୍ୱଳତା କମାନ୍ତୁ"</string> + <!-- no translation found for reduce_bright_colors_feature_name (8978255324027479398) --> + <skip /> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"ଭଲ୍ୟୁମ୍ କୀ\'ଗୁଡ଼ିକୁ ଧରି ରଖାଯାଇଛି। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ଚାଲୁ ହୋଇଛି।"</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"ଭଲ୍ୟୁମ୍ କୀ\'ଗୁଡ଼ିକୁ ଧରି ରଖାଯାଇଛି। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ବନ୍ଦ ହୋଇଛି।"</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> ବ୍ୟବହାର କରିବାକୁ ତିନି ସେକେଣ୍ଡ ପାଇଁ ଉଭୟ ଭଲ୍ୟୁମ୍ କୀ ଦବାଇ ଧରି ରଖନ୍ତୁ"</string> @@ -1871,8 +1873,7 @@ <string name="stk_cc_ss_to_dial_video" msgid="1324194624384312664">"SSଙ୍କ ଅନୁରୋଧକୁ ଭିଡିଓ କଲ୍ରେ ପରିବର୍ତ୍ତନ କରାଗଲା"</string> <string name="stk_cc_ss_to_ussd" msgid="8417905193112944760">"SS ଅନୁରୋଧ, USSD ଅନୁରୋଧକୁ ପରିବର୍ତ୍ତନ ହେଲା"</string> <string name="stk_cc_ss_to_ss" msgid="132040645206514450">"ନୂତନ SS ଅନୁରୋଧରେ ପରିବର୍ତ୍ତନ ହେଲା"</string> - <!-- no translation found for notification_phishing_alert_content_description (494227305355958790) --> - <skip /> + <string name="notification_phishing_alert_content_description" msgid="494227305355958790">"ଫିସିଂ ଆଲର୍ଟ"</string> <string name="notification_work_profile_content_description" msgid="5296477955677725799">"ୱର୍କ ପ୍ରୋଫାଇଲ୍"</string> <string name="notification_alerted_content_description" msgid="6139691253611265992">"ଆଲର୍ଟ କରାଯାଇଛି"</string> <string name="expand_button_content_description_collapsed" msgid="3873368935659010279">"ବଢ଼ାନ୍ତୁ"</string> @@ -2220,4 +2221,8 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"ଜାରି ରଖିବାକୁ, <b><xliff:g id="APP">%s</xliff:g></b> ଆପଣଙ୍କ ଡିଭାଇସର କ୍ୟାମେରାକୁ ଆକ୍ସେସ୍ ଆବଶ୍ୟକ କରେ।"</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"ଚାଲୁ କରନ୍ତୁ"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"ସେନ୍ସର୍ ଗୋପନୀୟତା"</string> + <!-- no translation found for splash_screen_view_icon_description (180638751260598187) --> + <skip /> + <!-- no translation found for splash_screen_view_branding_description (7911129347402728216) --> + <skip /> </resources> diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml index 17a4944c1b14..c9f57efc0c29 100644 --- a/core/res/res/values-pa/strings.xml +++ b/core/res/res/values-pa/strings.xml @@ -606,7 +606,8 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"ਹੁਣ ਚਿਹਰਾ ਪਛਾਣਿਆ ਨਹੀਂ ਜਾ ਸਕਦਾ। ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"ਬਹੁਤ ਮਿਲਦਾ-ਜੁਲਦਾ ਹੈ, ਕਿਰਪਾ ਕਰਕੇ ਆਪਣਾ ਅੰਦਾਜ਼ ਬਦਲੋ।"</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"ਆਪਣਾ ਸਿਰ ਥੋੜਾ ਜਿਹਾ ਝੁਕਾਓ।"</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"ਆਪਣਾ ਸਿਰ ਥੋੜਾ ਜਿਹਾ ਝੁਕਾਓ।"</string> + <!-- no translation found for face_acquired_tilt_too_extreme (8618210742620248049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"ਆਪਣਾ ਸਿਰ ਥੋੜਾ ਜਿਹਾ ਝੁਕਾਓ।"</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"ਤੁਹਾਡਾ ਚਿਹਰਾ ਲੁਕਾਉਣ ਵਾਲੀ ਕੋਈ ਵੀ ਚੀਜ਼ ਹਟਾਓ।"</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"ਕਾਲੀ ਪੱਟੀ ਸਮੇਤ, ਆਪਣੀ ਸਕ੍ਰੀਨ ਦੇ ਸਿਖਰ ਨੂੰ ਸਾਫ਼ ਕਰੋ"</string> @@ -685,10 +686,8 @@ <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"ਐਪ ਨੂੰ ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ ਕੌਂਫਿਗਰੇਸ਼ਨ ਨੂੰ ਪੜ੍ਹਨ ਅਤੇ ਲਿਖਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string> <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"ਇਜਾਜ਼ਤ ਵਰਤੋਂ ਦੇਖਣਾ ਸ਼ੁਰੂ ਕਰੋ"</string> <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"ਧਾਰਕ ਨੂੰ ਕਿਸੇ ਹੋਰ ਐਪ ਲਈ ਇਜਾਜ਼ਤ ਵਰਤੋਂ ਨੂੰ ਸ਼ੁਰੂ ਕਰਨ ਦਿੰਦਾ ਹੈ। ਸਧਾਰਨ ਐਪਾਂ ਲਈ ਕਦੇ ਵੀ ਲੋੜੀਂਦਾ ਨਹੀਂ ਹੋਵੇਗਾ।"</string> - <!-- no translation found for permlab_highSamplingRateSensors (3941068435726317070) --> - <skip /> - <!-- no translation found for permdesc_highSamplingRateSensors (8430061978931155995) --> - <skip /> + <string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"ਉੱਚ ਸੈਂਪਲਿੰਗ ਰੇਟ \'ਤੇ ਸੈਂਸਰ ਡਾਟਾ ਤੱਕ ਪਹੁੰਚ ਕਰੋ"</string> + <string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"ਐਪ ਨੂੰ 200 Hz ਤੋਂ ਵੱਧ ਦੀ ਦਰ \'ਤੇ ਸੈਂਸਰ ਡਾਟੇ ਦਾ ਨਮੂਨਾ ਲੈਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ"</string> <string name="policylab_limitPassword" msgid="4851829918814422199">"ਪਾਸਵਰਡ ਨਿਯਮ ਸੈੱਟ ਕਰੋ"</string> <string name="policydesc_limitPassword" msgid="4105491021115793793">"ਸਕ੍ਰੀਨ ਲਾਕ ਪਾਸਵਰਡਾਂ ਅਤੇ ਪਿੰਨ ਵਿੱਚ ਆਗਿਆ ਦਿੱਤੀ ਲੰਮਾਈ ਅਤੇ ਅੱਖਰਾਂ ਤੇ ਨਿਯੰਤਰਣ ਪਾਓ।"</string> <string name="policylab_watchLogin" msgid="7599669460083719504">"ਸਕ੍ਰੀਨ ਅਣਲਾਕ ਕਰਨ ਦੀਆਂ ਕੋਸ਼ਿਸ਼ਾਂ \'ਤੇ ਨਿਗਰਾਨੀ ਰੱਖੋ"</string> @@ -1669,7 +1668,8 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"ਸ਼ਾਰਟਕੱਟ ਦੀ ਵਰਤੋਂ ਕਰੋ"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"ਰੰਗ ਪਲਟਨਾ"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"ਰੰਗ ਸੁਧਾਈ"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"ਚਮਕ ਘਟਾਓ"</string> + <!-- no translation found for reduce_bright_colors_feature_name (8978255324027479398) --> + <skip /> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"ਅਵਾਜ਼ੀ ਕੁੰਜੀਆਂ ਦਬਾ ਕੇ ਰੱਖੀਆਂ ਗਈਆਂ। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ਨੂੰ ਚਾਲੂ ਕੀਤਾ ਗਿਆ।"</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"ਅਵਾਜ਼ੀ ਕੁੰਜੀਆਂ ਦਬਾ ਕੇ ਰੱਖੀਆਂ ਗਈਆਂ। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ਨੂੰ ਬੰਦ ਕੀਤਾ ਗਿਆ।"</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> ਦੀ ਵਰਤੋਂ ਕਰਨ ਲਈ ਦੋਵੇਂ ਅਵਾਜ਼ ਕੁੰਜੀਆਂ ਨੂੰ 3 ਸਕਿੰਟਾਂ ਲਈ ਦਬਾਈ ਰੱਖੋ"</string> @@ -1873,8 +1873,7 @@ <string name="stk_cc_ss_to_dial_video" msgid="1324194624384312664">"SS ਬੇਨਤੀ ਨੂੰ ਵੀਡੀਓ ਕਾਲ ਵਿੱਚ ਬਦਲਿਆ ਗਿਆ"</string> <string name="stk_cc_ss_to_ussd" msgid="8417905193112944760">"SS ਬੇਨਤੀ ਨੂੰ USSD ਬੇਨਤੀ ਵਿੱਚ ਬਦਲਿਆ ਗਿਆ"</string> <string name="stk_cc_ss_to_ss" msgid="132040645206514450">"ਨਵੀਂ SS ਬੇਨਤੀ ਵਿੱਚ ਬਦਲਿਆ ਗਿਆ"</string> - <!-- no translation found for notification_phishing_alert_content_description (494227305355958790) --> - <skip /> + <string name="notification_phishing_alert_content_description" msgid="494227305355958790">"ਫ਼ਿਸ਼ਿੰਗ ਸੰਬੰਧੀ ਸੁਚੇਤਨਾ"</string> <string name="notification_work_profile_content_description" msgid="5296477955677725799">"ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ"</string> <string name="notification_alerted_content_description" msgid="6139691253611265992">"ਸੁਚੇਤਨਾਵਾਂ"</string> <string name="expand_button_content_description_collapsed" msgid="3873368935659010279">"ਵਿਸਤਾਰ ਕਰੋ"</string> @@ -2222,4 +2221,8 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"ਜਾਰੀ ਰੱਖਣ ਲਈ, <b><xliff:g id="APP">%s</xliff:g></b> ਨੂੰ ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਦੇ ਕੈਮਰਾ ਤੱਕ ਪਹੁੰਚ ਦੀ ਲੋੜ ਹੈ।"</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"ਚਾਲੂ ਕਰੋ"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"ਸੈਂਸਰ ਪਰਦੇਦਾਰੀ"</string> + <!-- no translation found for splash_screen_view_icon_description (180638751260598187) --> + <skip /> + <!-- no translation found for splash_screen_view_branding_description (7911129347402728216) --> + <skip /> </resources> diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml index 14ca2b9d8a18..6c12366d932a 100644 --- a/core/res/res/values-pl/strings.xml +++ b/core/res/res/values-pl/strings.xml @@ -612,7 +612,8 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"Nie można już rozpoznać twarzy. Spróbuj ponownie."</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"Za mała różnica. Zmień pozycję."</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"Trochę mniej obróć głowę."</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"Trochę mniej obróć głowę."</string> + <!-- no translation found for face_acquired_tilt_too_extreme (8618210742620248049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"Trochę mniej obróć głowę."</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"Usuń wszystko, co zasłania Ci twarz."</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"Wyczyść górną krawędź ekranu, w tym czarny pasek"</string> @@ -1711,7 +1712,8 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Użyj skrótu"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Odwrócenie kolorów"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Korekcja kolorów"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Zmniejsz jasność"</string> + <!-- no translation found for reduce_bright_colors_feature_name (8978255324027479398) --> + <skip /> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Przytrzymano klawisze głośności. Usługa <xliff:g id="SERVICE_NAME">%1$s</xliff:g> została włączona."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Przytrzymano klawisze głośności. Usługa <xliff:g id="SERVICE_NAME">%1$s</xliff:g> została wyłączona."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Naciśnij i przytrzymaj oba przyciski głośności przez trzy sekundy, by użyć usługi <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string> @@ -1933,8 +1935,7 @@ <string name="stk_cc_ss_to_dial_video" msgid="1324194624384312664">"Żądanie SS zmienione na rozmowę wideo"</string> <string name="stk_cc_ss_to_ussd" msgid="8417905193112944760">"Żądanie SS zmienione na żądanie USSD"</string> <string name="stk_cc_ss_to_ss" msgid="132040645206514450">"Zmieniono na nowe żądanie SS"</string> - <!-- no translation found for notification_phishing_alert_content_description (494227305355958790) --> - <skip /> + <string name="notification_phishing_alert_content_description" msgid="494227305355958790">"Alert o phishingu"</string> <string name="notification_work_profile_content_description" msgid="5296477955677725799">"Profil służbowy"</string> <string name="notification_alerted_content_description" msgid="6139691253611265992">"Alert"</string> <string name="expand_button_content_description_collapsed" msgid="3873368935659010279">"Rozwiń"</string> @@ -2288,4 +2289,8 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"Aby kontynuować, musisz przyznać aplikacji „<xliff:g id="APP">%s</xliff:g>” dostęp do aparatu urządzenia."</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Włącz"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Poufność danych z czujników"</string> + <!-- no translation found for splash_screen_view_icon_description (180638751260598187) --> + <skip /> + <!-- no translation found for splash_screen_view_branding_description (7911129347402728216) --> + <skip /> </resources> diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml index 3fbfd7ebc075..d5cec263b6b9 100644 --- a/core/res/res/values-pt-rBR/strings.xml +++ b/core/res/res/values-pt-rBR/strings.xml @@ -606,7 +606,8 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"O rosto não é mais reconhecido. Tente novamente."</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"Muito parecido, mude de posição."</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"Incline a cabeça um pouco menos."</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"Incline a cabeça um pouco menos."</string> + <!-- no translation found for face_acquired_tilt_too_extreme (8618210742620248049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"Incline a cabeça um pouco menos."</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"Remova tudo que esteja ocultando seu rosto."</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"Limpe a parte superior da tela, inclusive a barra preta"</string> @@ -867,7 +868,7 @@ <string name="lockscreen_transport_pause_description" msgid="6705284702135372494">"Pausar"</string> <string name="lockscreen_transport_play_description" msgid="106868788691652733">"Reproduzir"</string> <string name="lockscreen_transport_stop_description" msgid="1449552232598355348">"Parar"</string> - <string name="lockscreen_transport_rew_description" msgid="7680106856221622779">"Retroceder"</string> + <string name="lockscreen_transport_rew_description" msgid="7680106856221622779">"Voltar"</string> <string name="lockscreen_transport_ffw_description" msgid="4763794746640196772">"Avançar"</string> <string name="emergency_calls_only" msgid="3057351206678279851">"Só chamadas de emergência"</string> <string name="lockscreen_network_locked_message" msgid="2814046965899249635">"Rede bloqueada"</string> @@ -1667,7 +1668,8 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Usar atalho"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Inversão de cores"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Correção de cor"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Reduzir brilho"</string> + <!-- no translation found for reduce_bright_colors_feature_name (8978255324027479398) --> + <skip /> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Teclas de volume pressionadas. Serviço <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ativado."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Teclas de volume pressionadas. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> desativado."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Toque nos dois botões de volume e os mantenha pressionados por três segundo para usar o <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string> @@ -2219,4 +2221,8 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"Para continuar, o app <b><xliff:g id="APP">%s</xliff:g></b> precisa acessar a câmera do dispositivo."</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Ativar"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Privacidade do sensor"</string> + <!-- no translation found for splash_screen_view_icon_description (180638751260598187) --> + <skip /> + <!-- no translation found for splash_screen_view_branding_description (7911129347402728216) --> + <skip /> </resources> diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml index eb09af88f69a..686795065c61 100644 --- a/core/res/res/values-pt-rPT/strings.xml +++ b/core/res/res/values-pt-rPT/strings.xml @@ -606,7 +606,8 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"Impossível reconhecer o rosto. Tente novamente."</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"Muito parecida, mude de pose."</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"Rode a cabeça um pouco menos."</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"Rode a cabeça um pouco menos."</string> + <!-- no translation found for face_acquired_tilt_too_extreme (8618210742620248049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"Rode a cabeça um pouco menos."</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"Remova tudo o que esteja a ocultar o seu rosto."</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"Limpe a parte superior do ecrã, incluindo a barra preta."</string> @@ -1667,7 +1668,8 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Utilizar atalho"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Inversão de cores"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Correção da cor"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Reduzir o brilho"</string> + <!-- no translation found for reduce_bright_colors_feature_name (8978255324027479398) --> + <skip /> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Teclas do volume premidas. Serviço <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ativado."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Teclas de volume premidas. Serviço <xliff:g id="SERVICE_NAME">%1$s</xliff:g> desativado."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Prima sem soltar as teclas de volume durante três segundos para utilizar o serviço <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string> @@ -1871,8 +1873,7 @@ <string name="stk_cc_ss_to_dial_video" msgid="1324194624384312664">"O pedido SS foi alterado para uma videochamada."</string> <string name="stk_cc_ss_to_ussd" msgid="8417905193112944760">"O pedido SS foi alterado para um novo pedido USSD."</string> <string name="stk_cc_ss_to_ss" msgid="132040645206514450">"Foi alterado para um novo pedido SS."</string> - <!-- no translation found for notification_phishing_alert_content_description (494227305355958790) --> - <skip /> + <string name="notification_phishing_alert_content_description" msgid="494227305355958790">"Alerta de phishing."</string> <string name="notification_work_profile_content_description" msgid="5296477955677725799">"Perfil de trabalho"</string> <string name="notification_alerted_content_description" msgid="6139691253611265992">"Alertado"</string> <string name="expand_button_content_description_collapsed" msgid="3873368935659010279">"Expandir"</string> @@ -2220,4 +2221,8 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"Para continuar, a app <b><xliff:g id="APP">%s</xliff:g></b> precisa de acesso à câmara do dispositivo."</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Ativar"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Privacidade dos sensores"</string> + <!-- no translation found for splash_screen_view_icon_description (180638751260598187) --> + <skip /> + <!-- no translation found for splash_screen_view_branding_description (7911129347402728216) --> + <skip /> </resources> diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml index bad102e5e0b8..d5cec263b6b9 100644 --- a/core/res/res/values-pt/strings.xml +++ b/core/res/res/values-pt/strings.xml @@ -606,7 +606,8 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"O rosto não é mais reconhecido. Tente novamente."</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"Muito parecido, mude de posição."</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"Incline a cabeça um pouco menos."</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"Incline a cabeça um pouco menos."</string> + <!-- no translation found for face_acquired_tilt_too_extreme (8618210742620248049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"Incline a cabeça um pouco menos."</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"Remova tudo que esteja ocultando seu rosto."</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"Limpe a parte superior da tela, inclusive a barra preta"</string> @@ -867,7 +868,7 @@ <string name="lockscreen_transport_pause_description" msgid="6705284702135372494">"Pausar"</string> <string name="lockscreen_transport_play_description" msgid="106868788691652733">"Reproduzir"</string> <string name="lockscreen_transport_stop_description" msgid="1449552232598355348">"Parar"</string> - <string name="lockscreen_transport_rew_description" msgid="7680106856221622779">"Retroceder"</string> + <string name="lockscreen_transport_rew_description" msgid="7680106856221622779">"Voltar"</string> <string name="lockscreen_transport_ffw_description" msgid="4763794746640196772">"Avançar"</string> <string name="emergency_calls_only" msgid="3057351206678279851">"Só chamadas de emergência"</string> <string name="lockscreen_network_locked_message" msgid="2814046965899249635">"Rede bloqueada"</string> @@ -1667,7 +1668,8 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Usar atalho"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Inversão de cores"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Correção de cor"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Reduzir brilho"</string> + <!-- no translation found for reduce_bright_colors_feature_name (8978255324027479398) --> + <skip /> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Teclas de volume pressionadas. Serviço <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ativado."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Teclas de volume pressionadas. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> desativado."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Toque nos dois botões de volume e os mantenha pressionados por três segundo para usar o <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string> @@ -1871,8 +1873,7 @@ <string name="stk_cc_ss_to_dial_video" msgid="1324194624384312664">"Solicitação SS alterada para videochamada"</string> <string name="stk_cc_ss_to_ussd" msgid="8417905193112944760">"Solicitação SS alterada para solicitação USSD"</string> <string name="stk_cc_ss_to_ss" msgid="132040645206514450">"Alterada para uma nova solicitação SS"</string> - <!-- no translation found for notification_phishing_alert_content_description (494227305355958790) --> - <skip /> + <string name="notification_phishing_alert_content_description" msgid="494227305355958790">"Alerta de phishing"</string> <string name="notification_work_profile_content_description" msgid="5296477955677725799">"Perfil de trabalho"</string> <string name="notification_alerted_content_description" msgid="6139691253611265992">"Alertado"</string> <string name="expand_button_content_description_collapsed" msgid="3873368935659010279">"Expandir"</string> @@ -2220,4 +2221,8 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"Para continuar, o app <b><xliff:g id="APP">%s</xliff:g></b> precisa acessar a câmera do dispositivo."</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Ativar"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Privacidade do sensor"</string> + <!-- no translation found for splash_screen_view_icon_description (180638751260598187) --> + <skip /> + <!-- no translation found for splash_screen_view_branding_description (7911129347402728216) --> + <skip /> </resources> diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml index 1e789e448955..690884a452f9 100644 --- a/core/res/res/values-ro/strings.xml +++ b/core/res/res/values-ro/strings.xml @@ -609,7 +609,8 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"Nu se mai poate recunoaște fața. Încercați din nou."</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"Prea asemănător, schimbați poziția."</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"Întoarceți capul mai puțin."</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"Întoarceți capul mai puțin."</string> + <!-- no translation found for face_acquired_tilt_too_extreme (8618210742620248049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"Întoarceți capul mai puțin."</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"Eliminați orice vă ascunde chipul."</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"Curățați partea de sus a ecranului, inclusiv bara neagră"</string> @@ -1689,7 +1690,8 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Utilizați comanda rapidă"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Inversarea culorilor"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Corecția culorii"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Reduceți luminozitatea"</string> + <!-- no translation found for reduce_bright_colors_feature_name (8978255324027479398) --> + <skip /> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"S-au apăsat lung tastele de volum. S-a activat <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"S-au apăsat lung tastele de volum. S-a dezactivat <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Apăsați ambele butoane de volum timp de trei secunde pentru a folosi <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string> @@ -2253,4 +2255,8 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"Pentru a continua, <b><xliff:g id="APP">%s</xliff:g></b> necesită acces la camera dispozitivului."</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Activați"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Confidențialitatea privind senzorii"</string> + <!-- no translation found for splash_screen_view_icon_description (180638751260598187) --> + <skip /> + <!-- no translation found for splash_screen_view_branding_description (7911129347402728216) --> + <skip /> </resources> diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml index 5cb8a5087321..84752d5bfe5a 100644 --- a/core/res/res/values-ru/strings.xml +++ b/core/res/res/values-ru/strings.xml @@ -612,7 +612,8 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"Не удалось распознать лицо. Повторите попытку."</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"Слишком похожее выражение лица. Измените позу."</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"Держите голову ровнее."</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"Держите голову ровнее."</string> + <!-- no translation found for face_acquired_tilt_too_extreme (8618210742620248049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"Держите голову ровнее."</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"Ваше лицо плохо видно."</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"Протрите верхнюю часть экрана (в том числе черную панель)."</string> @@ -1711,7 +1712,8 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Использовать быстрое включение"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Инверсия цветов"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Коррекция цвета"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Уменьшение яркости"</string> + <!-- no translation found for reduce_bright_colors_feature_name (8978255324027479398) --> + <skip /> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Использован жест с кнопками регулировки громкости. Функция \"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>\" включена."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Использован жест с кнопками регулировки громкости. Функция \"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>\" отключена."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Чтобы использовать сервис \"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>\", нажмите и удерживайте обе клавиши громкости в течение трех секунд."</string> @@ -1933,8 +1935,7 @@ <string name="stk_cc_ss_to_dial_video" msgid="1324194624384312664">"SS-запрос преобразован в видеовызов"</string> <string name="stk_cc_ss_to_ussd" msgid="8417905193112944760">"SS-запрос преобразован в USSD-запрос"</string> <string name="stk_cc_ss_to_ss" msgid="132040645206514450">"Преобразовано в SS-запрос"</string> - <!-- no translation found for notification_phishing_alert_content_description (494227305355958790) --> - <skip /> + <string name="notification_phishing_alert_content_description" msgid="494227305355958790">"Предупреждение о фишинге"</string> <string name="notification_work_profile_content_description" msgid="5296477955677725799">"Рабочий профиль"</string> <string name="notification_alerted_content_description" msgid="6139691253611265992">"Отправлено оповещение"</string> <string name="expand_button_content_description_collapsed" msgid="3873368935659010279">"Развернуть"</string> @@ -2288,4 +2289,8 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"Чтобы продолжить, предоставьте приложению <b><xliff:g id="APP">%s</xliff:g></b> доступ к камере устройства."</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Включить"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Конфиденциальность датчиков"</string> + <!-- no translation found for splash_screen_view_icon_description (180638751260598187) --> + <skip /> + <!-- no translation found for splash_screen_view_branding_description (7911129347402728216) --> + <skip /> </resources> diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml index bd311fb958e0..66547decf56e 100644 --- a/core/res/res/values-si/strings.xml +++ b/core/res/res/values-si/strings.xml @@ -606,7 +606,8 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"තවදුරටත් මුහුණ හඳුනාගත නොහැක. නැවත උත්සාහ කරන්න."</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"ඉතා සමානයි, ඔබේ හැඩ ගැසීම වෙනස් කරන්න."</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"ඔබේ හිස ටිකක් අඩුවෙන් කරකවන්න."</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"ඔබේ හිස ටිකක් අඩුවෙන් කරකවන්න."</string> + <!-- no translation found for face_acquired_tilt_too_extreme (8618210742620248049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"ඔබේ හිස ටිකක් අඩුවෙන් කරකවන්න."</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"ඔබේ මුහුණ සඟවන කිසිවක් ඉවත් කරන්න."</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"කලු තීරුව ඇතුළුව, ඔබේ තිරයෙහි මුදුන පිරිසිදු කරන්න"</string> @@ -1667,7 +1668,8 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"කෙටිමඟ භාවිතා කරන්න"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"වර්ණ අපවර්තනය"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"වර්ණ නිවැරදි කිරීම"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"දීප්තිය අඩු කරන්න"</string> + <!-- no translation found for reduce_bright_colors_feature_name (8978255324027479398) --> + <skip /> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"හඬ පරිමා යතුරු අල්ලා ගන්න <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ක්රියාත්මකයි."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"හඬ පරිමා යතුරු අල්ලා ගන්න <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ක්රියාවිරහිතයි."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> භාවිත කිරීමට හඬ පරිමා යතුරු දෙකම තත්පර තුනකට ඔබාගෙන සිටින්න"</string> @@ -2219,4 +2221,8 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"දිගටම කර ගෙන යාමට, <b><xliff:g id="APP">%s</xliff:g></b> හට ඔබගේ උපාංගයෙහි කැමරාවට ප්රවේශය අවශ්යයි."</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"ක්රියාත්මක කරන්න"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"සංවේදක පෞද්ගලිකත්වය"</string> + <!-- no translation found for splash_screen_view_icon_description (180638751260598187) --> + <skip /> + <!-- no translation found for splash_screen_view_branding_description (7911129347402728216) --> + <skip /> </resources> diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml index 825215b1fae1..487b8181e510 100644 --- a/core/res/res/values-sk/strings.xml +++ b/core/res/res/values-sk/strings.xml @@ -612,7 +612,8 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"Tvár už nie je možné rozpoznať. Skúste to znova."</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"Príliš rovnaké, zmeňte postoj."</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"Otočte hlavu o niečo menej."</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"Otočte hlavu o niečo menej."</string> + <!-- no translation found for face_acquired_tilt_too_extreme (8618210742620248049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"Otočte hlavu o niečo menej."</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"Odstráňte všetko, čo vám zakrýva tvár."</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"Vyčistite hornú časť obrazovky vrátane čierneho panela"</string> @@ -1711,7 +1712,8 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Použiť skratku"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Inverzia farieb"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Úprava farieb"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Zníženie jasu"</string> + <!-- no translation found for reduce_bright_colors_feature_name (8978255324027479398) --> + <skip /> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Pridržali ste tlačidlá hlasitosti. Služba <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je zapnutá."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Pridržali ste tlačidlá hlasitosti. Služba <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je vypnutá."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Ak chcete používať službu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, pridržte tri sekundy oba klávesy hlasitosti"</string> @@ -1933,8 +1935,7 @@ <string name="stk_cc_ss_to_dial_video" msgid="1324194624384312664">"Žiadosť SS bola zmenená na videohovor"</string> <string name="stk_cc_ss_to_ussd" msgid="8417905193112944760">"Žiadosť SS bola zmenená na žiadosť USSD"</string> <string name="stk_cc_ss_to_ss" msgid="132040645206514450">"Zmenené na novú žiadosť SS"</string> - <!-- no translation found for notification_phishing_alert_content_description (494227305355958790) --> - <skip /> + <string name="notification_phishing_alert_content_description" msgid="494227305355958790">"Upozornenie na phishing"</string> <string name="notification_work_profile_content_description" msgid="5296477955677725799">"Pracovný profil"</string> <string name="notification_alerted_content_description" msgid="6139691253611265992">"Upozornené"</string> <string name="expand_button_content_description_collapsed" msgid="3873368935659010279">"Rozbaliť"</string> @@ -2288,4 +2289,8 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"Ak chcete pokračovať, <b><xliff:g id="APP">%s</xliff:g></b> požaduje prístup k fotoaparátu zariadenia."</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Zapnúť"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Ochrana súkromia senzorov"</string> + <!-- no translation found for splash_screen_view_icon_description (180638751260598187) --> + <skip /> + <!-- no translation found for splash_screen_view_branding_description (7911129347402728216) --> + <skip /> </resources> diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml index a27b805c21db..87a66b36b7d7 100644 --- a/core/res/res/values-sl/strings.xml +++ b/core/res/res/values-sl/strings.xml @@ -612,7 +612,8 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"Obraza ni več mogoče prepoznati. Poskusite znova."</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"Preveč podobno, spremenite položaj."</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"Glejte malce bolj naravnost."</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"Malce manj nagnite glavo."</string> + <!-- no translation found for face_acquired_tilt_too_extreme (8618210742620248049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"Glejte malce bolj naravnost."</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"Umaknite vse, kar vam morda zakriva obraz."</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"Očistite vrhnji del zaslona, vključno s črno vrstico"</string> @@ -1711,7 +1712,8 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Uporabi bližnjico"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Inverzija barv"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Popravljanje barv"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Zmanjšanje svetlosti"</string> + <!-- no translation found for reduce_bright_colors_feature_name (8978255324027479398) --> + <skip /> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Tipki za glasnost sta pridržani. Storitev <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je vklopljena."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Tipki za glasnost sta pridržani. Storitev <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je izklopljena."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Za uporabo storitve <xliff:g id="SERVICE_NAME">%1$s</xliff:g> pritisnite obe tipki za glasnost in ju pridržite tri sekunde"</string> @@ -2287,4 +2289,8 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"Za nadaljevanje potrebuje aplikacija <b><xliff:g id="APP">%s</xliff:g></b> dostop do fotoaparata v napravi."</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Vklopi"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Zasebnost pri uporabi tipal"</string> + <!-- no translation found for splash_screen_view_icon_description (180638751260598187) --> + <skip /> + <!-- no translation found for splash_screen_view_branding_description (7911129347402728216) --> + <skip /> </resources> diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml index 823b963c8b62..4c3742493fbb 100644 --- a/core/res/res/values-sq/strings.xml +++ b/core/res/res/values-sq/strings.xml @@ -606,7 +606,8 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"Fytyra nuk mund të njihet më. Provo përsëri."</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"Tepër e ngjashme, ndrysho pozën"</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"Ktheje kokën pak më pak."</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"Ktheje kokën pak më pak."</string> + <!-- no translation found for face_acquired_tilt_too_extreme (8618210742620248049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"Ktheje kokën pak më pak."</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"Hiq gjithçka që fsheh fytyrën tënde."</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"Pastro kreun e ekranit, duke përfshirë shiritin e zi"</string> @@ -1667,7 +1668,8 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Përdor shkurtoren"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Kthimi i ngjyrës"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Korrigjimi i ngjyrës"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Redukto ndriçimin"</string> + <!-- no translation found for reduce_bright_colors_feature_name (8978255324027479398) --> + <skip /> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Tastet e volumit të mbajtura shtypur. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> i aktivizuar."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Tastet e volumit të mbajtura shtypur. U çaktivizua \"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>\"."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Shtyp dhe mbaj shtypur të dy butonat e volumit për tre sekonda për të përdorur <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string> @@ -1871,8 +1873,7 @@ <string name="stk_cc_ss_to_dial_video" msgid="1324194624384312664">"Kërkesa SS u ndryshua në telefonatë me video"</string> <string name="stk_cc_ss_to_ussd" msgid="8417905193112944760">"Kërkesa SS u ndryshua në kërkesë USSD"</string> <string name="stk_cc_ss_to_ss" msgid="132040645206514450">"U ndryshua në kërkesë të re SS"</string> - <!-- no translation found for notification_phishing_alert_content_description (494227305355958790) --> - <skip /> + <string name="notification_phishing_alert_content_description" msgid="494227305355958790">"Sinjalizim për mashtrim"</string> <string name="notification_work_profile_content_description" msgid="5296477955677725799">"Profili i punës"</string> <string name="notification_alerted_content_description" msgid="6139691253611265992">"Sinjalizuar"</string> <string name="expand_button_content_description_collapsed" msgid="3873368935659010279">"Zgjero"</string> @@ -2220,4 +2221,8 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"Për të vazhduar, <b><xliff:g id="APP">%s</xliff:g></b> ka nevojë të qaset në kamerën e pajisjes sate."</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Aktivizo"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Privatësia e sensorit"</string> + <!-- no translation found for splash_screen_view_icon_description (180638751260598187) --> + <skip /> + <!-- no translation found for splash_screen_view_branding_description (7911129347402728216) --> + <skip /> </resources> diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml index 74589a85d700..d061d6f68b9f 100644 --- a/core/res/res/values-sr/strings.xml +++ b/core/res/res/values-sr/strings.xml @@ -609,7 +609,8 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"Више не може да се препозна лице. Пробајте поново."</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"Превише је слично, промените позу."</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"Мало мање померите главу."</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"Мало мање померите главу."</string> + <!-- no translation found for face_acquired_tilt_too_extreme (8618210742620248049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"Мало мање померите главу."</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"Уклоните све што вам заклања лице."</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"Очистите горњи део екрана, укључујући црну траку"</string> @@ -1689,7 +1690,8 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Користи пречицу"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Инверзија боја"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Корекција боја"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Смањите осветљеност"</string> + <!-- no translation found for reduce_bright_colors_feature_name (8978255324027479398) --> + <skip /> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Држали сте тастере за јачину звука. Услуга <xliff:g id="SERVICE_NAME">%1$s</xliff:g> је укључена."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Држали сте тастере за јачину звука. Услуга <xliff:g id="SERVICE_NAME">%1$s</xliff:g> је искључена."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Притисните и задржите оба тастера за јачину звука три секунде да бисте користили <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string> @@ -2253,4 +2255,8 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"<b><xliff:g id="APP">%s</xliff:g></b> захтева приступ камери уређаја ради настављања."</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Укључи"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Приватност сензора"</string> + <!-- no translation found for splash_screen_view_icon_description (180638751260598187) --> + <skip /> + <!-- no translation found for splash_screen_view_branding_description (7911129347402728216) --> + <skip /> </resources> diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml index 47bfe0a00360..8288d413e9c9 100644 --- a/core/res/res/values-sv/strings.xml +++ b/core/res/res/values-sv/strings.xml @@ -606,7 +606,8 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"Ansiktet kan inte längre kännas igen. Försök igen."</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"För likt. Ändra ansiktsposition."</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"Vrid mindre på huvudet."</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"Vrid mindre på huvudet."</string> + <!-- no translation found for face_acquired_tilt_too_extreme (8618210742620248049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"Vrid mindre på huvudet."</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"Ta bort allt som täcker ansiktet."</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"Rengör skärmens överkant, inklusive det svarta fältet"</string> @@ -1667,7 +1668,8 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Använd kortkommandot"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Inverterade färger"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Färgkorrigering"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Minska ljusstyrkan"</string> + <!-- no translation found for reduce_bright_colors_feature_name (8978255324027479398) --> + <skip /> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Volymknapparna har tryckts ned. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> har aktiverats."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Volymknapparna har tryckts ned. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> har inaktiverats."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Tryck och håll båda volymknapparna i tre sekunder för att använda <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string> @@ -1871,8 +1873,7 @@ <string name="stk_cc_ss_to_dial_video" msgid="1324194624384312664">"SS-begäran har ändrats till videosamtal"</string> <string name="stk_cc_ss_to_ussd" msgid="8417905193112944760">"SS-begäran har ändrats till en USSD-begäran"</string> <string name="stk_cc_ss_to_ss" msgid="132040645206514450">"Har ändrats till ny SS-begäran"</string> - <!-- no translation found for notification_phishing_alert_content_description (494227305355958790) --> - <skip /> + <string name="notification_phishing_alert_content_description" msgid="494227305355958790">"Varning om nätfiske"</string> <string name="notification_work_profile_content_description" msgid="5296477955677725799">"Jobbprofil"</string> <string name="notification_alerted_content_description" msgid="6139691253611265992">"Aviserad"</string> <string name="expand_button_content_description_collapsed" msgid="3873368935659010279">"Utöka"</string> @@ -2220,4 +2221,8 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"<b><xliff:g id="APP">%s</xliff:g></b> behöver behörighet till enhetens kamera för att fortsätta."</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Aktivera"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Sensorintegritet"</string> + <!-- no translation found for splash_screen_view_icon_description (180638751260598187) --> + <skip /> + <!-- no translation found for splash_screen_view_branding_description (7911129347402728216) --> + <skip /> </resources> diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml index fcc9c9dca038..6ac7d2a583e2 100644 --- a/core/res/res/values-sw/strings.xml +++ b/core/res/res/values-sw/strings.xml @@ -606,7 +606,8 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"Haiwezi tena kutambua uso. Jaribu tena."</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"Inafanana sana, tafadhali badilisha mkao wako."</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"Geuza kichwa chako kidogo."</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"Geuza kichwa chako kidogo."</string> + <!-- no translation found for face_acquired_tilt_too_extreme (8618210742620248049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"Geuza kichwa chako kidogo."</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"Ondoa kitu chochote kinachoficha uso wako."</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"Safisha sehemu ya juu ya skrini yako, ikiwa ni pamoja na upau mweusi"</string> @@ -1667,7 +1668,8 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Tumia Njia ya Mkato"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Ugeuzaji rangi"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Usahihishaji wa rangi"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Punguza Ung\'aavu"</string> + <!-- no translation found for reduce_bright_colors_feature_name (8978255324027479398) --> + <skip /> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Vitufe vya sauti vilivyoshikiliwa. Umewasha <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Vitufe vya sauti vimeshikiliwa. Umezima <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Bonyeza na ushikilie vitufe vyote viwili vya sauti kwa sekunde tatu ili utumie <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string> @@ -2219,4 +2221,8 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"Ili uendelee, <b><xliff:g id="APP">%s</xliff:g></b> inahitaji ruhusa ya kufikia kamera ya kifaa chako."</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Washa"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Faragha ya Kitambuzi"</string> + <!-- no translation found for splash_screen_view_icon_description (180638751260598187) --> + <skip /> + <!-- no translation found for splash_screen_view_branding_description (7911129347402728216) --> + <skip /> </resources> diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml index 535fb6c45e10..1ac17340e941 100644 --- a/core/res/res/values-ta/strings.xml +++ b/core/res/res/values-ta/strings.xml @@ -606,7 +606,8 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"முகத்தைக் கண்டறிய இயலவில்லை. மீண்டும் முயலவும்."</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"மீண்டும் அதே போஸ் தருகிறீர்கள், வேறு முயலுங்கள்."</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"தலையை லேசாகத் திருப்பவும்."</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"தலையை லேசாகத் திருப்பவும்."</string> + <!-- no translation found for face_acquired_tilt_too_extreme (8618210742620248049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"உங்கள் தலையைச் சற்றுத் திருப்பவும்."</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"உங்கள் முகத்தை மறைக்கும் அனைத்தையும் நீக்குக."</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"திரையையும் அதிலுள்ள கருப்புப் பட்டியையும் சுத்தம் செய்யவும்"</string> @@ -1667,7 +1668,8 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"ஷார்ட்கட்டைப் பயன்படுத்து"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"கலர் இன்வெர்ஷன்"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"வண்ணத் திருத்தம்"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"ஒளிர்வைக் குறைத்தல்"</string> + <!-- no translation found for reduce_bright_colors_feature_name (8978255324027479398) --> + <skip /> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"ஒலியளவுக்கான விசைகளைப் பிடித்திருந்தீர்கள். <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ஆன் செய்யப்பட்டது."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"ஒலியளவுக்கான விசைகளைப் பிடித்திருந்தீர்கள். <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ஆஃப் செய்யப்பட்டது."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>ஐப் பயன்படுத்த 3 விநாடிகளுக்கு இரண்டு ஒலியளவு பட்டன்களையும் அழுத்திப் பிடிக்கவும்"</string> @@ -2219,4 +2221,8 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"தொடர, உங்கள் சாதனத்தின் கேமராவை அணுகுவதற்கு <b><xliff:g id="APP">%s</xliff:g></b> ஆப்ஸுக்கு அனுமதி வேண்டும்."</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"ஆன் செய்"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"சென்சார் தனியுரிமை"</string> + <!-- no translation found for splash_screen_view_icon_description (180638751260598187) --> + <skip /> + <!-- no translation found for splash_screen_view_branding_description (7911129347402728216) --> + <skip /> </resources> diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml index 59d451abae2d..9f822e31260c 100644 --- a/core/res/res/values-te/strings.xml +++ b/core/res/res/values-te/strings.xml @@ -606,7 +606,8 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"ఇక ముఖం గుర్తించలేదు. మళ్లీ ప్రయత్నించండి."</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"ఒకే మాదిరిగా ఉంది, దయచేసి భంగిమను మార్చండి."</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"మీ తలను ఇంకాస్త తక్కువ తిప్పండి."</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"మీ తలను ఇంకాస్త తక్కువ తిప్పండి."</string> + <!-- no translation found for face_acquired_tilt_too_extreme (8618210742620248049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"మీ తలను ఎడమ/కుడి వైపుగా ఇంకాస్త తిప్పండి."</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"మీ ముఖానికి అడ్డుగా ఉన్నవాటిని తీసివేస్తుంది."</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"నల్లని పట్టీతో సహా మీ స్క్రీన్ పైభాగం అంతటినీ శుభ్రంగా తుడవండి"</string> @@ -685,10 +686,8 @@ <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"అంతరాయం కలిగించవద్దు ఎంపిక కాన్ఫిగరేషన్ చదవడానికి మరియు వ్రాయడానికి యాప్ను అనుమతిస్తుంది."</string> <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"వీక్షణ అనుమతి వినియోగాన్ని ప్రారంభించండి"</string> <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"యాప్నకు అనుమతి వినియోగాన్ని ప్రారంభించడానికి హోల్డర్ను అనుమతిస్తుంది. సాధారణ యాప్లకు ఎప్పటికీ ఇటువంటి అనుమతి అవసరం ఉండదు."</string> - <!-- no translation found for permlab_highSamplingRateSensors (3941068435726317070) --> - <skip /> - <!-- no translation found for permdesc_highSamplingRateSensors (8430061978931155995) --> - <skip /> + <string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"అధిక శాంపిల్ రేటు వద్ద సెన్సార్ డేటాను యాక్సెస్ చేయండి"</string> + <string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"200 Hz కంటే ఎక్కువ రేట్ వద్ద శాంపిల్ సెన్సార్ డేటాకు యాప్ను అనుమతిస్తుంది"</string> <string name="policylab_limitPassword" msgid="4851829918814422199">"పాస్వర్డ్ నియమాలను సెట్ చేయండి"</string> <string name="policydesc_limitPassword" msgid="4105491021115793793">"స్క్రీన్ లాక్ పాస్వర్డ్లు మరియు PINల్లో అనుమతించబడిన పొడవు మరియు అక్షరాలను నియంత్రిస్తుంది."</string> <string name="policylab_watchLogin" msgid="7599669460083719504">"స్క్రీన్ అన్లాక్ ప్రయత్నాలను పర్యవేక్షించండి"</string> @@ -1669,7 +1668,8 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"సత్వరమార్గాన్ని ఉపయోగించు"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"కలర్ మార్పిడి"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"కలర్ సరిచేయడం"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"ప్రకాశాన్ని తగ్గించండి"</string> + <!-- no translation found for reduce_bright_colors_feature_name (8978255324027479398) --> + <skip /> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"వాల్యూమ్ కీలు నొక్కి ఉంచబడ్డాయి. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ఆన్ చేయబడింది"</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"వాల్యూమ్ కీలు నొక్కి ఉంచబడ్డాయి. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ఆఫ్ చేయబడింది"</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>ని ఉపయోగించడానికి వాల్యూమ్ కీలు రెండింటినీ 3 సెకన్లు నొక్కి ఉంచండి"</string> @@ -2221,4 +2221,8 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"కొనసాగించడానికి, <b><xliff:g id="APP">%s</xliff:g></b&gtకు మీ పరికరం యొక్క కెమెరా యాక్సెస్ అవసరం."</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"ఆన్ చేయి"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"సెన్సార్ గోప్యత"</string> + <!-- no translation found for splash_screen_view_icon_description (180638751260598187) --> + <skip /> + <!-- no translation found for splash_screen_view_branding_description (7911129347402728216) --> + <skip /> </resources> diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml index cb21c725574b..21865cde4a70 100644 --- a/core/res/res/values-th/strings.xml +++ b/core/res/res/values-th/strings.xml @@ -606,7 +606,8 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"จำใบหน้าไม่ได้แล้ว ลองอีกครั้ง"</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"ใกล้เคียงเกินไป โปรดเปลี่ยนท่าโพส"</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"จัดตำแหน่งศีรษะให้ตรง"</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"จัดตำแหน่งศีรษะให้ตรง"</string> + <!-- no translation found for face_acquired_tilt_too_extreme (8618210742620248049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"จัดตำแหน่งศีรษะให้ตรง"</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"เอาสิ่งที่ปิดบังใบหน้าออก"</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"ทำความสะอาดด้านบนของหน้าจอ รวมถึงแถบสีดำ"</string> @@ -1667,7 +1668,8 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"ใช้ทางลัด"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"การกลับสี"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"การแก้สี"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"ลดความสว่าง"</string> + <!-- no translation found for reduce_bright_colors_feature_name (8978255324027479398) --> + <skip /> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"กดปุ่มปรับระดับเสียงค้างไว้แล้ว เปิด <xliff:g id="SERVICE_NAME">%1$s</xliff:g> แล้ว"</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"กดปุ่มปรับระดับเสียงค้างไว้แล้ว ปิด <xliff:g id="SERVICE_NAME">%1$s</xliff:g> แล้ว"</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"กดปุ่มปรับระดับเสียงทั้ง 2 ปุ่มค้างไว้ 3 วินาทีเพื่อใช้ <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string> @@ -2219,4 +2221,8 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"<b><xliff:g id="APP">%s</xliff:g></b> ต้องได้รับสิทธิ์เข้าถึงกล้องของอุปกรณ์เพื่อดำเนินการต่อ"</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"เปิด"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"ความเป็นส่วนตัวสำหรับเซ็นเซอร์"</string> + <!-- no translation found for splash_screen_view_icon_description (180638751260598187) --> + <skip /> + <!-- no translation found for splash_screen_view_branding_description (7911129347402728216) --> + <skip /> </resources> diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml index 6f00ba8d3e5c..37d06f83284f 100644 --- a/core/res/res/values-tl/strings.xml +++ b/core/res/res/values-tl/strings.xml @@ -606,7 +606,8 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"Hindi na makilala ang mukha. Subukang muli."</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"Masyadong magkatulad, pakibago ang pose mo."</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"Huwag masyadong lumingon."</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"Huwag masyadong tumingala o yumuko."</string> + <!-- no translation found for face_acquired_tilt_too_extreme (8618210742620248049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"Huwag masyadong lumingon."</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"Alisin ang anumang humaharang sa iyong mukha."</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"Linisin ang itaas ng iyong screen, kasama ang itim na bar"</string> @@ -1667,7 +1668,8 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Gamitin ang Shortcut"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Pag-invert ng Kulay"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Pagwawasto ng Kulay"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Bawasan ang Liwanag"</string> + <!-- no translation found for reduce_bright_colors_feature_name (8978255324027479398) --> + <skip /> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Pinindot nang matagal ang volume keys. Na-on ang <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Pinindot nang matagal ang volume keys. Na-off ang <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Pindutin nang matagal ang parehong volume key sa loob ng tatlong segundo para magamit ang <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string> @@ -1871,8 +1873,7 @@ <string name="stk_cc_ss_to_dial_video" msgid="1324194624384312664">"Ginawang video call ang SS na kahilingan"</string> <string name="stk_cc_ss_to_ussd" msgid="8417905193112944760">"Ginawang USSD na kahilingan ang SS na kahilingan"</string> <string name="stk_cc_ss_to_ss" msgid="132040645206514450">"Ginawang bagong SS na kahilingan"</string> - <!-- no translation found for notification_phishing_alert_content_description (494227305355958790) --> - <skip /> + <string name="notification_phishing_alert_content_description" msgid="494227305355958790">"Alerto sa phishing"</string> <string name="notification_work_profile_content_description" msgid="5296477955677725799">"Profile sa trabaho"</string> <string name="notification_alerted_content_description" msgid="6139691253611265992">"Naalertuhan"</string> <string name="expand_button_content_description_collapsed" msgid="3873368935659010279">"Palawakin"</string> @@ -2220,4 +2221,8 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"Para magpatuloy, kailangan ng <b><xliff:g id="APP">%s</xliff:g></b> ng access sa camera ng iyong device."</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"I-on"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Privacy ng Sensor"</string> + <!-- no translation found for splash_screen_view_icon_description (180638751260598187) --> + <skip /> + <!-- no translation found for splash_screen_view_branding_description (7911129347402728216) --> + <skip /> </resources> diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml index 67086d2e1fdc..2132aace6350 100644 --- a/core/res/res/values-tr/strings.xml +++ b/core/res/res/values-tr/strings.xml @@ -606,7 +606,8 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"Yüz artık tanınamıyor. Tekrar deneyin."</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"Duruşunuz çok benzer, lütfen pozunuzu değiştirin."</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"Başınızı biraz daha az çevirin."</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"Başınızı biraz daha az çevirin."</string> + <!-- no translation found for face_acquired_tilt_too_extreme (8618210742620248049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"Başınızı biraz daha az çevirin."</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"Yüzünüzün görünmesini engelleyen şeyleri kaldırın."</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"Siyah çubuk da dahil olmak üzere ekranınızın üst kısmını temizleyin"</string> @@ -1667,7 +1668,8 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Kısayolu Kullan"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Rengi Ters Çevirme"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Renk Düzeltme"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Parlaklığı Azaltma"</string> + <!-- no translation found for reduce_bright_colors_feature_name (8978255324027479398) --> + <skip /> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Ses tuşlarını basılı tuttunuz. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> açıldı."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Ses tuşlarını basılı tuttunuz. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> kapatıldı."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> hizmetini kullanmak için her iki ses tuşunu basılı tutun"</string> @@ -1871,8 +1873,7 @@ <string name="stk_cc_ss_to_dial_video" msgid="1324194624384312664">"SS isteği görüntülü görüşme olarak değişti"</string> <string name="stk_cc_ss_to_ussd" msgid="8417905193112944760">"SS isteği USSD isteği olarak değişti"</string> <string name="stk_cc_ss_to_ss" msgid="132040645206514450">"Yeni SS isteği olarak değişti"</string> - <!-- no translation found for notification_phishing_alert_content_description (494227305355958790) --> - <skip /> + <string name="notification_phishing_alert_content_description" msgid="494227305355958790">"Kimlik avı uyarısı"</string> <string name="notification_work_profile_content_description" msgid="5296477955677725799">"İş profili"</string> <string name="notification_alerted_content_description" msgid="6139691253611265992">"Sesli uyarıldı"</string> <string name="expand_button_content_description_collapsed" msgid="3873368935659010279">"Genişlet"</string> @@ -2220,4 +2221,8 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"Devam etmek için <b><xliff:g id="APP">%s</xliff:g></b> uygulamasının cihazınızın kamerasına erişmesi gerekiyor."</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Aç"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Sensör Gizliliği"</string> + <!-- no translation found for splash_screen_view_icon_description (180638751260598187) --> + <skip /> + <!-- no translation found for splash_screen_view_branding_description (7911129347402728216) --> + <skip /> </resources> diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml index d6a3677b844b..3b9db401be3a 100644 --- a/core/res/res/values-uk/strings.xml +++ b/core/res/res/values-uk/strings.xml @@ -612,7 +612,8 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"Розпізнати обличчя вже не вдається. Повторіть спробу."</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"Надто схоже на попередню спробу, змініть позу."</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"Трохи перемістіть обличчя."</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"Трохи перемістіть обличчя."</string> + <!-- no translation found for face_acquired_tilt_too_extreme (8618210742620248049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"Трохи поверніть обличчя."</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"Приберіть об’єкти, які затуляють ваше обличчя."</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"Очистьте верхню частину екрана, зокрема чорну панель"</string> @@ -1711,7 +1712,8 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Використовувати ярлик"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Інверсія кольорів"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Корекція кольорів"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Зменшення яскравості"</string> + <!-- no translation found for reduce_bright_colors_feature_name (8978255324027479398) --> + <skip /> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Утримано клавіші гучності. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> увімкнено."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Утримано клавіші гучності. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> вимкнено."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Щоб скористатися службою <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, утримуйте обидві клавіші гучності впродовж трьох секунд"</string> @@ -1933,8 +1935,7 @@ <string name="stk_cc_ss_to_dial_video" msgid="1324194624384312664">"Запит SS змінено на відеовиклик"</string> <string name="stk_cc_ss_to_ussd" msgid="8417905193112944760">"Запит SS змінено на запит USSD"</string> <string name="stk_cc_ss_to_ss" msgid="132040645206514450">"Змінено на новий запит SS"</string> - <!-- no translation found for notification_phishing_alert_content_description (494227305355958790) --> - <skip /> + <string name="notification_phishing_alert_content_description" msgid="494227305355958790">"Попередження про фішинг"</string> <string name="notification_work_profile_content_description" msgid="5296477955677725799">"Робочий профіль"</string> <string name="notification_alerted_content_description" msgid="6139691253611265992">"Зі звуком"</string> <string name="expand_button_content_description_collapsed" msgid="3873368935659010279">"Розгорнути"</string> @@ -2288,4 +2289,8 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"Щоб продовжити, надайте додатку <b><xliff:g id="APP">%s</xliff:g></b> доступ до камери пристрою."</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Увімкнути"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Конфіденційність датчиків"</string> + <!-- no translation found for splash_screen_view_icon_description (180638751260598187) --> + <skip /> + <!-- no translation found for splash_screen_view_branding_description (7911129347402728216) --> + <skip /> </resources> diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml index 9a7cb8764670..c10f3e97bca2 100644 --- a/core/res/res/values-ur/strings.xml +++ b/core/res/res/values-ur/strings.xml @@ -606,7 +606,8 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"اب چہرے کی شناخت نہیں کر سکتے۔ پھر آزمائيں۔"</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"کافی ملتا جلتا ہے، براہ کرم اپنا پوز بدلیں۔"</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"اپنا سر تھوڑا کم کریں۔"</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"اپنا سر تھوڑا کم کریں۔"</string> + <!-- no translation found for face_acquired_tilt_too_extreme (8618210742620248049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"اپنا سر تھوڑا کم کریں۔"</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"آپ کے چہرہ کو چھپانے والی ہر چیز کو ہٹائیں۔"</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"سیاہ بار سمیت، اپنی اسکرین کے اوپری حصے کو صاف کریں"</string> @@ -1667,7 +1668,8 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"شارٹ کٹ استعمال کریں"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"رنگوں کی تقلیب"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"رنگ کی تصحیح"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"چمک کم کریں"</string> + <!-- no translation found for reduce_bright_colors_feature_name (8978255324027479398) --> + <skip /> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"والیوم کی کلیدوں کو دبائے رکھا گیا۔ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> آن ہے۔"</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"والیوم کی کلیدوں کو دبائے رکھا گیا۔ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> آف ہے۔"</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> کا استعمال کرنے کے لیے 3 سیکنڈ تک والیوم کی دونوں کلیدوں کو چھوئیں اور دبائے رکھیں"</string> @@ -2219,4 +2221,8 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"جاری رکھنے کیلئے <b><xliff:g id="APP">%s</xliff:g></b> کو آپ کے آلے کے کیمرے تک رسائی درکار ہے۔"</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"آن کریں"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"سینسر کی رازداری"</string> + <!-- no translation found for splash_screen_view_icon_description (180638751260598187) --> + <skip /> + <!-- no translation found for splash_screen_view_branding_description (7911129347402728216) --> + <skip /> </resources> diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml index 60134a477b66..f77de7daad1d 100644 --- a/core/res/res/values-uz/strings.xml +++ b/core/res/res/values-uz/strings.xml @@ -606,7 +606,7 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"Yuz tanilmadi. Qaytadan urining."</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"Yuz ifodasi oldingiday. Holatingizni oʻzgartiring."</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"Boshingizni asta buring."</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"Boshingizni asta buring."</string> + <string name="face_acquired_tilt_too_extreme" msgid="8618210742620248049">"Boshingizni asta qiyalang."</string> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"Boshingizni asta buring."</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"Yuzingizni berkitayotgan narsalarni olib tashlang."</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"Ekranning yuqori qismini, shuningdek, qora panelni ham tozalang"</string> @@ -1667,7 +1667,7 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Tezkor ishga tushirishdan foydalanish"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Ranglarni akslantirish"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Rangni tuzatish"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Yorqinlikni pasaytirish"</string> + <string name="reduce_bright_colors_feature_name" msgid="8978255324027479398">"Yorqinlikni pasaytirish"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Tovush tugmalari bosib turildi. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> yoqildi."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Tovush tugmalari bosib turildi. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> faolsizlantirildi."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> xizmatidan foydalanish uchun ikkala ovoz balandligi tugmalarini uzoq bosib turing"</string> @@ -1871,8 +1871,7 @@ <string name="stk_cc_ss_to_dial_video" msgid="1324194624384312664">"SS talabi video chaqiruvga almashtirildi"</string> <string name="stk_cc_ss_to_ussd" msgid="8417905193112944760">"SS talabi USSD talabiga almashtirildi"</string> <string name="stk_cc_ss_to_ss" msgid="132040645206514450">"Yangi SS talabiga almashtirildi"</string> - <!-- no translation found for notification_phishing_alert_content_description (494227305355958790) --> - <skip /> + <string name="notification_phishing_alert_content_description" msgid="494227305355958790">"Fishing signali"</string> <string name="notification_work_profile_content_description" msgid="5296477955677725799">"Ish profili"</string> <string name="notification_alerted_content_description" msgid="6139691253611265992">"Ogohlantirildi"</string> <string name="expand_button_content_description_collapsed" msgid="3873368935659010279">"Yoyish"</string> @@ -2220,4 +2219,6 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"Davom etish uchun <b><xliff:g id="APP">%s</xliff:g></b> qurilmangiz kamerasiga kirishi kerak."</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Yoqish"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Sensorlar maxfiyligi"</string> + <string name="splash_screen_view_icon_description" msgid="180638751260598187">"Ilova belgisi"</string> + <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Ilova brendining rasmi"</string> </resources> diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml index 25f0644903b5..baf0b86dd1be 100644 --- a/core/res/res/values-vi/strings.xml +++ b/core/res/res/values-vi/strings.xml @@ -606,7 +606,8 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"Không nhận ra khuôn mặt. Hãy thử lại."</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"Khuôn mặt quá giống nhau, vui lòng đổi tư thế."</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"Hãy bớt di chuyển đầu."</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"Hãy bớt di chuyển đầu."</string> + <!-- no translation found for face_acquired_tilt_too_extreme (8618210742620248049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"Hãy bớt di chuyển đầu."</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"Hãy loại bỏ mọi thứ che khuất khuôn mặt bạn."</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"Vệ sinh phần đầu màn hình, bao gồm cả thanh màu đen"</string> @@ -1667,7 +1668,8 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Sử dụng phím tắt"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Đảo màu"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Chỉnh màu"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Giảm độ sáng"</string> + <!-- no translation found for reduce_bright_colors_feature_name (8978255324027479398) --> + <skip /> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Bạn đã giữ các phím âm lượng. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> đã bật."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Bạn đã giữ các phím âm lượng. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> đã tắt."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Nhấn và giữ đồng thời cả hai phím âm lượng trong 3 giây để sử dụng <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string> @@ -1871,8 +1873,7 @@ <string name="stk_cc_ss_to_dial_video" msgid="1324194624384312664">"Yêu cầu SS đã thay đổi thành cuộc gọi video"</string> <string name="stk_cc_ss_to_ussd" msgid="8417905193112944760">"Yêu cầu SS đã thay đổi thành yêu cầu USSD"</string> <string name="stk_cc_ss_to_ss" msgid="132040645206514450">"Đã thay đổi thành yêu cầu SS mới"</string> - <!-- no translation found for notification_phishing_alert_content_description (494227305355958790) --> - <skip /> + <string name="notification_phishing_alert_content_description" msgid="494227305355958790">"Cảnh báo về hành vi lừa đảo"</string> <string name="notification_work_profile_content_description" msgid="5296477955677725799">"Hồ sơ công việc"</string> <string name="notification_alerted_content_description" msgid="6139691253611265992">"Đã phát âm báo"</string> <string name="expand_button_content_description_collapsed" msgid="3873368935659010279">"Mở rộng"</string> @@ -2220,4 +2221,8 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"Để tiếp tục, <b><xliff:g id="APP">%s</xliff:g></b> cần quyền truy cập vào máy ảnh trên thiết bị của bạn."</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Bật"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Quyền riêng tư khi sử dụng cảm biến"</string> + <!-- no translation found for splash_screen_view_icon_description (180638751260598187) --> + <skip /> + <!-- no translation found for splash_screen_view_branding_description (7911129347402728216) --> + <skip /> </resources> diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml index 358367ed2d8b..9345fc82b1d3 100644 --- a/core/res/res/values-zh-rCN/strings.xml +++ b/core/res/res/values-zh-rCN/strings.xml @@ -606,7 +606,8 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"已无法识别人脸,请重试。"</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"与先前的姿势太相近,请换一个姿势。"</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"请将您的头稍微上下倾斜。"</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"请将您的头稍微上下倾斜。"</string> + <!-- no translation found for face_acquired_tilt_too_extreme (8618210742620248049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"请将您的头稍微左右旋转。"</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"请移除所有遮挡您面部的物体。"</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"请将屏幕顶部(包括黑色条栏)清理干净"</string> @@ -1667,7 +1668,8 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"使用快捷方式"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"颜色反转"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"色彩校正"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"调低亮度"</string> + <!-- no translation found for reduce_bright_colors_feature_name (8978255324027479398) --> + <skip /> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"已按住音量键。<xliff:g id="SERVICE_NAME">%1$s</xliff:g>已开启。"</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"已按住音量键。<xliff:g id="SERVICE_NAME">%1$s</xliff:g>已关闭。"</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"同时按住两个音量键 3 秒钟即可使用 <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string> @@ -2219,4 +2221,8 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"如要继续操作,请向<b><xliff:g id="APP">%s</xliff:g></b>授予设备的相机使用权。"</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"开启"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"传感器隐私权"</string> + <!-- no translation found for splash_screen_view_icon_description (180638751260598187) --> + <skip /> + <!-- no translation found for splash_screen_view_branding_description (7911129347402728216) --> + <skip /> </resources> diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml index e4fa2e0c9488..1187f003124d 100644 --- a/core/res/res/values-zh-rHK/strings.xml +++ b/core/res/res/values-zh-rHK/strings.xml @@ -606,7 +606,8 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"無法再識別臉孔。請再試一次。"</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"臉孔位置太相近,請改變您的姿勢。"</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"減少頭部左右轉動幅度。"</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"減少頭部上下轉動幅度。"</string> + <!-- no translation found for face_acquired_tilt_too_extreme (8618210742620248049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"減少頭部左右轉動幅度。"</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"移除遮住您臉孔的任何東西。"</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"請清理螢幕頂部,包括黑色列"</string> @@ -1667,7 +1668,8 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"使用快速鍵"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"色彩反轉"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"色彩校正"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"調低亮度"</string> + <!-- no translation found for reduce_bright_colors_feature_name (8978255324027479398) --> + <skip /> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"已按住音量鍵。<xliff:g id="SERVICE_NAME">%1$s</xliff:g> 已開啟。"</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"已按住音量鍵。<xliff:g id="SERVICE_NAME">%1$s</xliff:g> 已關閉。"</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"㩒住兩個音量鍵 3 秒就可以用 <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string> @@ -2219,4 +2221,8 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"如要繼續,<b><xliff:g id="APP">%s</xliff:g></b> 需要裝置的相機存取權。"</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"開啟"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"感應器私隱"</string> + <!-- no translation found for splash_screen_view_icon_description (180638751260598187) --> + <skip /> + <!-- no translation found for splash_screen_view_branding_description (7911129347402728216) --> + <skip /> </resources> diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml index 49e57b3261dc..949257234918 100644 --- a/core/res/res/values-zh-rTW/strings.xml +++ b/core/res/res/values-zh-rTW/strings.xml @@ -606,7 +606,8 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"已無法辨識臉孔,請再試一次。"</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"與先前的姿勢太相似,請換一個姿勢。"</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"請將你的頭部稍微向左或向右轉動。"</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"請將你的頭部稍微向上或向下傾斜。"</string> + <!-- no translation found for face_acquired_tilt_too_extreme (8618210742620248049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"請將你的頭部稍微向左或向右旋轉。"</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"請移除任何會遮住臉孔的物體。"</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"請清理螢幕頂端,包括黑色橫列"</string> @@ -1667,7 +1668,8 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"使用捷徑"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"色彩反轉"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"色彩校正"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"調低亮度"</string> + <!-- no translation found for reduce_bright_colors_feature_name (8978255324027479398) --> + <skip /> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"已按住音量鍵。「<xliff:g id="SERVICE_NAME">%1$s</xliff:g>」已開啟。"</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"已按住音量鍵。「<xliff:g id="SERVICE_NAME">%1$s</xliff:g>」已關閉。"</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"同時按住調低及調高音量鍵三秒即可使用「<xliff:g id="SERVICE_NAME">%1$s</xliff:g>」"</string> @@ -2219,4 +2221,8 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"如要繼續操作,請將裝置的相機存取權授予「<xliff:g id="APP">%s</xliff:g>」<b></b>。"</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"開啟"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"感應器隱私權"</string> + <!-- no translation found for splash_screen_view_icon_description (180638751260598187) --> + <skip /> + <!-- no translation found for splash_screen_view_branding_description (7911129347402728216) --> + <skip /> </resources> diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml index 9a21e78361a4..e5a026bd6fa5 100644 --- a/core/res/res/values-zu/strings.xml +++ b/core/res/res/values-zu/strings.xml @@ -606,7 +606,8 @@ <string name="face_acquired_too_different" msgid="4699657338753282542">"Ayisakwazi ukubona ubuso. Zama futhi."</string> <string name="face_acquired_too_similar" msgid="7684650785108399370">"Kufana kakhulu, sicela ushintshe ukuma kwakho."</string> <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"Jikisa ikhanda lakho kancane."</string> - <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"Jikisa ikhanda lakho kancane."</string> + <!-- no translation found for face_acquired_tilt_too_extreme (8618210742620248049) --> + <skip /> <string name="face_acquired_roll_too_extreme" msgid="1442830503572636825">"Jikisa ikhanda lakho kancane."</string> <string name="face_acquired_obscured" msgid="4917643294953326639">"Susa noma yini efihle ubuso bakho."</string> <string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"Hlanza okuphezulu kwesikrini sakho, kufaka phakathi ibha emnyama"</string> @@ -1667,7 +1668,8 @@ <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Sebenzisa isinqamuleli"</string> <string name="color_inversion_feature_name" msgid="326050048927789012">"Ukuguqulwa kombala"</string> <string name="color_correction_feature_name" msgid="3655077237805422597">"Ukulungiswa kombala"</string> - <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Nciphisa ukukhanya"</string> + <!-- no translation found for reduce_bright_colors_feature_name (8978255324027479398) --> + <skip /> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Ubambe okhiye bevolumu. I-<xliff:g id="SERVICE_NAME">%1$s</xliff:g> ivuliwe."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Ubambe okhiye bevolumu. I-<xliff:g id="SERVICE_NAME">%1$s</xliff:g> ivaliwe."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Cindezela uphinde ubambe bobabili okhiye bevolumu ngamasekhondi amathathu ukuze usebenzise i-<xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string> @@ -1871,8 +1873,7 @@ <string name="stk_cc_ss_to_dial_video" msgid="1324194624384312664">"Isicelo se-SS sishintshele kukholi yevidiyo"</string> <string name="stk_cc_ss_to_ussd" msgid="8417905193112944760">"Isicelo se-SS sishintshele kusicelo se-USSD"</string> <string name="stk_cc_ss_to_ss" msgid="132040645206514450">"Ishintshele kusicelo esisha se-SS"</string> - <!-- no translation found for notification_phishing_alert_content_description (494227305355958790) --> - <skip /> + <string name="notification_phishing_alert_content_description" msgid="494227305355958790">"Isexwayiso sobugebengu bokweba imininingwane ebucayi"</string> <string name="notification_work_profile_content_description" msgid="5296477955677725799">"Iphrofayela yomsebenzi"</string> <string name="notification_alerted_content_description" msgid="6139691253611265992">"Kuxwayisiwe"</string> <string name="expand_button_content_description_collapsed" msgid="3873368935659010279">"Nweba"</string> @@ -2220,4 +2221,8 @@ <string name="sensor_privacy_start_use_camera_notification_content" msgid="4738005643315863736">"Ukuze uqhubeke, <b>i-<xliff:g id="APP">%s</xliff:g></b> idinga ukufinyelela ikhamera yakho."</string> <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7921147002346108119">"Vula"</string> <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Ubumfihlo Benzwa"</string> + <!-- no translation found for splash_screen_view_icon_description (180638751260598187) --> + <skip /> + <!-- no translation found for splash_screen_view_branding_description (7911129347402728216) --> + <skip /> </resources> diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml index 695a831faf97..c2b6b99dcc1c 100644 --- a/core/res/res/values/dimens.xml +++ b/core/res/res/values/dimens.xml @@ -319,26 +319,22 @@ <!-- The top padding for the notification expand button. --> <dimen name="notification_expand_button_padding_top">1dp</dimen> - <!-- minimum vertical margin for the headerless notification content, when cap = 60dp --> - <dimen name="notification_headerless_margin_minimum">8dp</dimen> + <!-- Vertical margin for the headerless notification content, when content has 1 line --> + <!-- 16 * 2 (margins) + 24 (1 line) = 56 (notification) --> + <dimen name="notification_headerless_margin_oneline">16dp</dimen> - <!-- extra vertical margin for the headerless notification content, when cap = 60dp --> - <dimen name="notification_headerless_margin_extra">10dp</dimen> - - <!-- minimum vertical margin for the headerless notification content, when cap = 48dp --> - <dimen name="notification_headerless_margin_constrained_minimum">14dp</dimen> - - <!-- extra vertical margin for the headerless notification content, when cap = 48dp --> - <dimen name="notification_headerless_margin_constrained_extra">4dp</dimen> + <!-- Vertical margin for the headerless notification content, when content has 2 lines --> + <!-- 20 * 2 (margins) + 24 * 2 (2 lines) = 88 (notification) --> + <dimen name="notification_headerless_margin_twoline">20dp</dimen> <!-- The height of each of the 1 or 2 lines in the headerless notification template --> - <dimen name="notification_headerless_line_height">20sp</dimen> + <dimen name="notification_headerless_line_height">24dp</dimen> <!-- vertical margin for the headerless notification content --> <dimen name="notification_headerless_min_height">56dp</dimen> <!-- Height of a small notification in the status bar --> - <dimen name="notification_min_height">76dp</dimen> + <dimen name="notification_min_height">88dp</dimen> <!-- The width of the big icons in notifications. --> <dimen name="notification_large_icon_width">64dp</dimen> @@ -738,10 +734,11 @@ <!-- The maximum width of a image in a media notification. The images will be reduced to that width in case they are bigger.--> <dimen name="notification_media_image_max_width">280dp</dimen> <!-- The size of the right icon --> - <dimen name="notification_right_icon_size">52dp</dimen> + <dimen name="notification_right_icon_size">48dp</dimen> <!-- The top and bottom margin of the right icon in the normal notification states --> - <dimen name="notification_right_icon_headerless_margin">12dp</dimen> + <dimen name="notification_right_icon_headerless_margin">20dp</dimen> <!-- The top margin of the right icon in the "big" notification states --> + <!-- TODO(b/181048615): Move the large icon below the expander in big states --> <dimen name="notification_right_icon_big_margin_top">16dp</dimen> <!-- The size of the left icon --> <dimen name="notification_left_icon_size">@dimen/notification_icon_circle_size</dimen> diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index 576c44d6d201..71ba44b0ded1 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -4538,7 +4538,7 @@ <string name="color_correction_feature_name">Color Correction</string> <!-- Title of Reduce Brightness feature, shown in the warning dialog about the accessibility shortcut. [CHAR LIMIT=none] --> - <string name="reduce_bright_colors_feature_name">Reduce Brightness</string> + <string name="reduce_bright_colors_feature_name">Reduce brightness</string> <!-- Text in toast to alert the user that the accessibility shortcut turned on an accessibility service. [CHAR LIMIT=none] --> <string name="accessibility_shortcut_enabling_service">Held volume keys. <xliff:g id="service_name" example="TalkBack">%1$s</xliff:g> turned on.</string> @@ -5011,6 +5011,9 @@ <!-- Content description of the alerting icon in the notification. [CHAR_LIMIT=NONE] --> <string name="notification_alerted_content_description">Alerted</string> + <!-- Default content description of the verification icon in the call notification. [CHAR_LIMIT=NONE] --> + <string name="notification_verified_content_description">Verified</string> + <!-- Content description of the expand button icon in the notification when collaped.--> <string name="expand_button_content_description_collapsed">Expand</string> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 7ad05de1bdd0..dbb584dfe293 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -2895,8 +2895,6 @@ <java-symbol type="id" name="alternate_expand_target" /> <java-symbol type="id" name="notification_header" /> <java-symbol type="id" name="notification_top_line" /> - <java-symbol type="id" name="notification_headerless_margin_extra_top" /> - <java-symbol type="id" name="notification_headerless_margin_extra_bottom" /> <java-symbol type="id" name="time_divider" /> <java-symbol type="id" name="header_text_divider" /> <java-symbol type="id" name="header_text_secondary_divider" /> @@ -2918,8 +2916,8 @@ <java-symbol type="dimen" name="notification_header_icon_size" /> <java-symbol type="dimen" name="notification_header_app_name_margin_start" /> <java-symbol type="dimen" name="notification_header_separating_margin" /> - <java-symbol type="dimen" name="notification_headerless_margin_constrained_minimum" /> - <java-symbol type="dimen" name="notification_headerless_margin_constrained_extra" /> + <java-symbol type="dimen" name="notification_headerless_margin_oneline" /> + <java-symbol type="dimen" name="notification_headerless_margin_twoline" /> <java-symbol type="string" name="default_notification_channel_label" /> <java-symbol type="string" name="importance_from_user" /> <java-symbol type="string" name="importance_from_person" /> @@ -3112,8 +3110,10 @@ <java-symbol type="dimen" name="call_notification_collapsible_indent"/> <java-symbol type="drawable" name="ic_call_answer" /> <java-symbol type="drawable" name="ic_call_decline" /> + <java-symbol type="id" name="verification_divider" /> <java-symbol type="id" name="verification_icon" /> <java-symbol type="id" name="verification_text" /> + <java-symbol type="string" name="notification_verified_content_description" /> <!-- Notification handler / dashboard package --> <java-symbol type="string" name="config_notificationHandlerPackage" /> diff --git a/core/tests/coretests/src/android/app/backup/BackupAgentTest.java b/core/tests/coretests/src/android/app/backup/BackupAgentTest.java index ea903f2b61eb..37cf4700c1d0 100644 --- a/core/tests/coretests/src/android/app/backup/BackupAgentTest.java +++ b/core/tests/coretests/src/android/app/backup/BackupAgentTest.java @@ -57,14 +57,6 @@ public class BackupAgentTest { } @Test - public void testGetIncludeExcludeRules_isMigration_returnsEmptyRules() throws Exception { - mBackupAgent = getAgentForOperationType(OperationType.MIGRATION); - - IncludeExcludeRules rules = mBackupAgent.getIncludeExcludeRules(mBackupScheme); - assertThat(rules).isEqualTo(IncludeExcludeRules.emptyRules()); - } - - @Test public void testGetIncludeExcludeRules_isNotMigration_returnsRules() throws Exception { PathWithRequiredFlags path = new PathWithRequiredFlags("path", /* requiredFlags */ 0); Map<String, Set<PathWithRequiredFlags>> includePaths = Collections.singletonMap("test", diff --git a/core/tests/coretests/src/android/view/BlurAggregatorTest.java b/core/tests/coretests/src/android/view/BlurAggregatorTest.java new file mode 100644 index 000000000000..b01f2755efdd --- /dev/null +++ b/core/tests/coretests/src/android/view/BlurAggregatorTest.java @@ -0,0 +1,318 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.view; + +import static androidx.test.InstrumentationRegistry.getInstrumentation; + +import static junit.framework.TestCase.assertEquals; +import static junit.framework.TestCase.assertFalse; +import static junit.framework.TestCase.assertNotNull; +import static junit.framework.TestCase.assertNull; +import static junit.framework.TestCase.assertTrue; + +import android.content.Context; +import android.platform.test.annotations.Presubmit; + +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import com.android.internal.graphics.drawable.BackgroundBlurDrawable; +import com.android.internal.graphics.drawable.BackgroundBlurDrawable.Aggregator; +import com.android.internal.graphics.drawable.BackgroundBlurDrawable.BlurRegion; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +@Presubmit +@RunWith(AndroidJUnit4.class) +public class BlurAggregatorTest { + private static final int TEST_BLUR_RADIUS = 30; + private static final int TEST_FRAME_NUMBER = 1; + + private Context mContext; + + private Aggregator mAggregator; + private BackgroundBlurDrawable mDrawable; + + private ViewRootImpl mViewRoot; + + @Before + public void setUp() { + mContext = getInstrumentation().getTargetContext(); + getInstrumentation().runOnMainSync(() -> { + mViewRoot = new ViewRootImpl(mContext, mContext.getDisplayNoVerify()); + }); + mAggregator = new Aggregator(mViewRoot); + mDrawable = createTestBackgroundBlurDrawable(); + } + + private BackgroundBlurDrawable createTestBackgroundBlurDrawable() { + final BackgroundBlurDrawable drawable = mAggregator.createBackgroundBlurDrawable(mContext); + drawable.setBlurRadius(TEST_BLUR_RADIUS); + final boolean hasUpdates = mAggregator.hasUpdates(); + final BlurRegion[] blurRegions = mAggregator.getBlurRegionsCopyForRT(); + mAggregator.getBlurRegionsToDispatchToSf(TEST_FRAME_NUMBER, blurRegions, hasUpdates); + return drawable; + } + + @Test + public void testBlurRadiusUpdatePropagatesToRenderThreadIfNeeded() { + mDrawable.setBlurRadius(TEST_BLUR_RADIUS); + assertFalse(mAggregator.hasUpdates()); + + mDrawable.setBlurRadius(0); + assertTrue(mAggregator.hasUpdates()); + BlurRegion[] blurRegions = mAggregator.getBlurRegionsCopyForRT(); + assertEquals(0, blurRegions.length); + assertFalse(mAggregator.hasUpdates()); + + mDrawable.setBlurRadius(TEST_BLUR_RADIUS); + assertTrue(mAggregator.hasUpdates()); + blurRegions = mAggregator.getBlurRegionsCopyForRT(); + assertEquals(1, blurRegions.length); + assertEquals(TEST_BLUR_RADIUS, blurRegions[0].blurRadius); + assertFalse(mAggregator.hasUpdates()); + + } + + @Test + public void testAlphaUpdatePropagatesToRenderThreadIfNeeded() { + mDrawable.setAlpha(20); + assertTrue(mAggregator.hasUpdates()); + BlurRegion[] blurRegions = mAggregator.getBlurRegionsCopyForRT(); + assertEquals(1, blurRegions.length); + assertEquals(20 / 255f, blurRegions[0].alpha); + assertFalse(mAggregator.hasUpdates()); + + mDrawable.setAlpha(20); + assertFalse(mAggregator.hasUpdates()); + + mDrawable.setAlpha(0); + assertTrue(mAggregator.hasUpdates()); + blurRegions = mAggregator.getBlurRegionsCopyForRT(); + assertEquals(0, blurRegions.length); + assertFalse(mAggregator.hasUpdates()); + } + + @Test + public void testCornerRadiusUpdatePropagatesToRenderThreadIfNeeded() { + mDrawable.setCornerRadius(1f, 2f, 3f, 4f); + assertTrue(mAggregator.hasUpdates()); + final BlurRegion[] blurRegions = mAggregator.getBlurRegionsCopyForRT(); + assertEquals(1, blurRegions.length); + assertEquals(1f, blurRegions[0].cornerRadiusTL); + assertEquals(2f, blurRegions[0].cornerRadiusTR); + assertEquals(3f, blurRegions[0].cornerRadiusBL); + assertEquals(4f, blurRegions[0].cornerRadiusBR); + assertFalse(mAggregator.hasUpdates()); + } + + @Test + public void testVisibleUpdatePropagatesToRenderThreadIfNeeded() { + mDrawable.setVisible(false, /* restart= */false); + assertTrue(mAggregator.hasUpdates()); + BlurRegion[] blurRegions = mAggregator.getBlurRegionsCopyForRT(); + assertEquals(0, blurRegions.length); + assertFalse(mAggregator.hasUpdates()); + + mDrawable.setVisible(true, /* restart= */ false); + assertTrue(mAggregator.hasUpdates()); + blurRegions = mAggregator.getBlurRegionsCopyForRT(); + assertEquals(1, blurRegions.length); + assertEquals(TEST_BLUR_RADIUS, blurRegions[0].blurRadius); + assertFalse(mAggregator.hasUpdates()); + } + + @Test + public void testBlurRegionCopyForRtIsSameIfNoUiUpdates() { + mDrawable.setBlurRadius(30); + BlurRegion[] blurRegions1 = mAggregator.getBlurRegionsCopyForRT(); + assertEquals(1, blurRegions1.length); + assertEquals(30, blurRegions1[0].blurRadius); + + BlurRegion[] blurRegions2 = mAggregator.getBlurRegionsCopyForRT(); + assertEquals(blurRegions1, blurRegions2); + } + + @Test + public void testPositionUpdateAppearsInBlurRegion() { + BlurRegion[] blurRegions = mAggregator.getBlurRegionsCopyForRT(); + assertEquals(1, blurRegions.length); + + mDrawable.mPositionUpdateListener.positionChanged(TEST_FRAME_NUMBER, 1, 2, 3, 4); + mAggregator.getBlurRegionsToDispatchToSf(TEST_FRAME_NUMBER, blurRegions, + mAggregator.hasUpdates()); + assertEquals(1, blurRegions[0].rect.left); + assertEquals(2, blurRegions[0].rect.top); + assertEquals(3, blurRegions[0].rect.right); + assertEquals(4, blurRegions[0].rect.bottom); + } + + @Test + public void testNoBlurRegionsDispatchedWhenNoUpdates() { + final boolean hasUpdates = mAggregator.hasUpdates(); + assertFalse(hasUpdates); + final BlurRegion[] blurRegions = mAggregator.getBlurRegionsCopyForRT(); + assertEquals(1, blurRegions.length); + + float[][] blurRegionsForSf = mAggregator.getBlurRegionsToDispatchToSf( + TEST_FRAME_NUMBER, blurRegions, hasUpdates); + assertNull(blurRegionsForSf); + } + + @Test + public void testBlurRegionDispatchedIfOnlyDrawableUpdated() { + mDrawable.setBlurRadius(50); + final boolean hasUpdates = mAggregator.hasUpdates(); + assertTrue(hasUpdates); + final BlurRegion[] blurRegions = mAggregator.getBlurRegionsCopyForRT(); + assertEquals(1, blurRegions.length); + + float[][] blurRegionsForSf = mAggregator.getBlurRegionsToDispatchToSf( + TEST_FRAME_NUMBER, blurRegions, hasUpdates); + assertNotNull(blurRegionsForSf); + assertEquals(1, blurRegionsForSf.length); + assertEquals(50f, blurRegionsForSf[0][0]); + } + + @Test + public void testBlurRegionDispatchedIfOnlyPositionUpdated() { + final boolean hasUpdates = mAggregator.hasUpdates(); + assertFalse(hasUpdates); + final BlurRegion[] blurRegions = mAggregator.getBlurRegionsCopyForRT(); + assertEquals(1, blurRegions.length); + + mDrawable.mPositionUpdateListener.positionChanged(TEST_FRAME_NUMBER, 1, 2, 3, 4); + float[][] blurRegionsForSf = mAggregator.getBlurRegionsToDispatchToSf( + TEST_FRAME_NUMBER, blurRegions, hasUpdates); + assertNotNull(blurRegionsForSf); + assertEquals(1, blurRegionsForSf.length); + assertEquals((float) TEST_BLUR_RADIUS, blurRegionsForSf[0][0]); + assertEquals(1f, blurRegionsForSf[0][2]); + assertEquals(2f, blurRegionsForSf[0][3]); + assertEquals(3f, blurRegionsForSf[0][4]); + assertEquals(4f, blurRegionsForSf[0][5]); + } + + @Test + public void testPositionUpdateIsAppliedInNextFrameIfMissed() { + final boolean hasUpdates = mAggregator.hasUpdates(); + assertFalse(hasUpdates); + final BlurRegion[] blurRegions = mAggregator.getBlurRegionsCopyForRT(); + assertEquals(1, blurRegions.length); + + mDrawable.mPositionUpdateListener.positionChanged(TEST_FRAME_NUMBER, 1, 2, 3, 4); + float[][] blurRegionsForSf = mAggregator.getBlurRegionsToDispatchToSf( + TEST_FRAME_NUMBER + 1, blurRegions, hasUpdates); + assertNotNull(blurRegionsForSf); + assertEquals(1, blurRegionsForSf.length); + assertEquals((float) TEST_BLUR_RADIUS, blurRegionsForSf[0][0]); + assertEquals(1f, blurRegionsForSf[0][2]); + assertEquals(2f, blurRegionsForSf[0][3]); + assertEquals(3f, blurRegionsForSf[0][4]); + assertEquals(4f, blurRegionsForSf[0][5]); + } + + @Test + public void testMultipleDrawablesDispatchedToSfIfOneIsUpdated() { + final BackgroundBlurDrawable drawable2 = createTestBackgroundBlurDrawable(); + drawable2.setBlurRadius(50); + final boolean hasUpdates = mAggregator.hasUpdates(); + assertTrue(hasUpdates); + final BlurRegion[] blurRegions = mAggregator.getBlurRegionsCopyForRT(); + assertEquals(2, blurRegions.length); + + // Check that an update in one of the drawables triggers a dispatch of all blur regions + float[][] blurRegionsForSf = mAggregator.getBlurRegionsToDispatchToSf( + TEST_FRAME_NUMBER, blurRegions, hasUpdates); + assertNotNull(blurRegionsForSf); + assertEquals(2, blurRegionsForSf.length); + + // Check that the Aggregator deleted all position updates for frame TEST_FRAME_NUMBER + blurRegionsForSf = mAggregator.getBlurRegionsToDispatchToSf( + TEST_FRAME_NUMBER, blurRegions, /* hasUiUpdates= */ false); + assertNull(blurRegionsForSf); + + // Check that a position update triggers a dispatch of all blur regions + drawable2.mPositionUpdateListener.positionChanged(TEST_FRAME_NUMBER, 1, 2, 3, 4); + blurRegionsForSf = mAggregator.getBlurRegionsToDispatchToSf( + TEST_FRAME_NUMBER + 1, blurRegions, hasUpdates); + assertNotNull(blurRegionsForSf); + assertEquals(2, blurRegionsForSf.length); + } + + @Test + public void testUiThreadUpdatesDoNotChangeStateOnRenderThread() { + // Updates for frame N + mDrawable.setBlurRadius(50); + mDrawable.setCornerRadius(1, 2, 3, 4); + mDrawable.setAlpha(20); + + final BlurRegion[] blurRegions = mAggregator.getBlurRegionsCopyForRT(); + assertEquals(1, blurRegions.length); + assertEquals(50, blurRegions[0].blurRadius); + assertEquals(20 / 255f, blurRegions[0].alpha); + assertEquals(1f, blurRegions[0].cornerRadiusTL); + assertEquals(2f, blurRegions[0].cornerRadiusTR); + assertEquals(3f, blurRegions[0].cornerRadiusBL); + assertEquals(4f, blurRegions[0].cornerRadiusBR); + + // Updates for frame N+1 + mDrawable.setBlurRadius(60); + mDrawable.setCornerRadius(10, 20, 30, 40); + mDrawable.setAlpha(40); + + // Assert state for frame N is untouched + assertEquals(50, blurRegions[0].blurRadius); + assertEquals(20 / 255f, blurRegions[0].alpha); + assertEquals(1f, blurRegions[0].cornerRadiusTL); + assertEquals(2f, blurRegions[0].cornerRadiusTR); + assertEquals(3f, blurRegions[0].cornerRadiusBL); + assertEquals(4f, blurRegions[0].cornerRadiusBR); + } + + @Test + public void testPositionUpdatesForFutureFramesAreNotAppliedForCurrentFrame() { + final BlurRegion[] blurRegions = mAggregator.getBlurRegionsCopyForRT(); + + mDrawable.mPositionUpdateListener.positionChanged(TEST_FRAME_NUMBER, 1, 2, 3, 4); + mDrawable.mPositionUpdateListener.positionChanged(TEST_FRAME_NUMBER + 1, 5, 6, 7, 8); + + final float[][] blurRegionsForSf = mAggregator.getBlurRegionsToDispatchToSf( + TEST_FRAME_NUMBER, blurRegions, /* hasUiUpdates= */ false); + assertNotNull(blurRegionsForSf); + assertEquals(1, blurRegionsForSf.length); + // Assert state for first frame is not affected by update for second frame + assertEquals((float) TEST_BLUR_RADIUS, blurRegionsForSf[0][0]); + assertEquals(1f, blurRegionsForSf[0][2]); + assertEquals(2f, blurRegionsForSf[0][3]); + assertEquals(3f, blurRegionsForSf[0][4]); + assertEquals(4f, blurRegionsForSf[0][5]); + + final float[][] blurRegionsForSfForNextFrame = mAggregator.getBlurRegionsToDispatchToSf( + TEST_FRAME_NUMBER + 1, blurRegions, /* hasUiUpdates= */ false); + assertNotNull(blurRegionsForSfForNextFrame); + assertEquals(1, blurRegionsForSfForNextFrame.length); + // Assert second frame updates are applied normally + assertEquals((float) TEST_BLUR_RADIUS, blurRegionsForSfForNextFrame[0][0]); + assertEquals(5f, blurRegionsForSfForNextFrame[0][2]); + assertEquals(6f, blurRegionsForSfForNextFrame[0][3]); + assertEquals(7f, blurRegionsForSfForNextFrame[0][4]); + assertEquals(8f, blurRegionsForSfForNextFrame[0][5]); + } + +} diff --git a/core/tests/coretests/src/android/view/OWNERS b/core/tests/coretests/src/android/view/OWNERS index fa1aa5eab26c..80165f065995 100644 --- a/core/tests/coretests/src/android/view/OWNERS +++ b/core/tests/coretests/src/android/view/OWNERS @@ -9,6 +9,3 @@ per-file *Focus* = file:/services/core/java/com/android/server/wm/OWNERS per-file *Insets* = file:/services/core/java/com/android/server/wm/OWNERS per-file *View* = file:/services/core/java/com/android/server/wm/OWNERS per-file *Visibility* = file:/services/core/java/com/android/server/wm/OWNERS - -# Scroll Capture -per-file *ScrollCapture*.java = file:/packages/SystemUI/src/com/android/systemui/screenshot/OWNERS diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsCpuTimesTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsCpuTimesTest.java index 9cac7e794965..ff728d651067 100644 --- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsCpuTimesTest.java +++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsCpuTimesTest.java @@ -77,6 +77,7 @@ import java.util.Arrays; * bit FrameworksCoreTests:com.android.internal.os.BatteryStatsCpuTimesTest */ @SmallTest +@SkipPresubmit("b/180015146") @RunWith(AndroidJUnit4.class) public class BatteryStatsCpuTimesTest { @Mock diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsHistoryIteratorTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsHistoryIteratorTest.java new file mode 100644 index 000000000000..263daf0cd625 --- /dev/null +++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsHistoryIteratorTest.java @@ -0,0 +1,115 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.internal.os; + +import static com.google.common.truth.Truth.assertThat; + +import android.os.BatteryManager; +import android.os.BatteryStats; +import android.os.Process; + +import androidx.test.filters.SmallTest; +import androidx.test.runner.AndroidJUnit4; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(AndroidJUnit4.class) +@SmallTest +public class BatteryStatsHistoryIteratorTest { + private static final int APP_UID = Process.FIRST_APPLICATION_UID + 42; + + @Rule + public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule(); + + @Test + public void testIterator() { + MockBatteryStatsImpl batteryStats = mStatsRule.getBatteryStats(); + batteryStats.setRecordAllHistoryLocked(true); + batteryStats.forceRecordAllHistory(); + + mStatsRule.setTime(1000, 1000); + batteryStats.setNoAutoReset(true); + + batteryStats.setBatteryStateLocked(BatteryManager.BATTERY_STATUS_DISCHARGING, 100, + /* plugType */ 0, 90, 72, 3700, 3_600_000, 4_000_000, 0, 1_000_000, + 1_000_000, 1_000_000); + batteryStats.setBatteryStateLocked(BatteryManager.BATTERY_STATUS_DISCHARGING, 100, + /* plugType */ 0, 80, 72, 3700, 2_400_000, 4_000_000, 0, 2_000_000, + 2_000_000, 2_000_000); + + batteryStats.noteAlarmStartLocked("foo", null, APP_UID, 3_000_000, 2_000_000); + batteryStats.noteAlarmFinishLocked("foo", null, APP_UID, 3_001_000, 2_001_000); + + final BatteryStatsHistoryIterator iterator = + batteryStats.createBatteryStatsHistoryIterator(); + + BatteryStats.HistoryItem item = new BatteryStats.HistoryItem(); + + assertThat(iterator.next(item)).isTrue(); + assertHistoryItem(item, + BatteryStats.HistoryItem.CMD_RESET, BatteryStats.HistoryItem.EVENT_NONE, + null, 0, 3_600_000, 90, 1_000_000); + + assertThat(iterator.next(item)).isTrue(); + assertHistoryItem(item, + BatteryStats.HistoryItem.CMD_UPDATE, BatteryStats.HistoryItem.EVENT_NONE, + null, 0, 3_600_000, 90, 1_000_000); + + assertThat(iterator.next(item)).isTrue(); + assertHistoryItem(item, + BatteryStats.HistoryItem.CMD_UPDATE, BatteryStats.HistoryItem.EVENT_NONE, + null, 0, 2_400_000, 80, 2_000_000); + + assertThat(iterator.next(item)).isTrue(); + assertHistoryItem(item, + BatteryStats.HistoryItem.CMD_UPDATE, BatteryStats.HistoryItem.EVENT_NONE, + null, 0, 2_400_000, 80, 2_000_000); + + assertThat(iterator.next(item)).isTrue(); + assertHistoryItem(item, + BatteryStats.HistoryItem.CMD_UPDATE, + BatteryStats.HistoryItem.EVENT_ALARM | BatteryStats.HistoryItem.EVENT_FLAG_START, + "foo", APP_UID, 2_400_000, 80, 3_000_000); + + assertThat(iterator.next(item)).isTrue(); + assertHistoryItem(item, + BatteryStats.HistoryItem.CMD_UPDATE, + BatteryStats.HistoryItem.EVENT_ALARM | BatteryStats.HistoryItem.EVENT_FLAG_FINISH, + "foo", APP_UID, 2_400_000, 80, 3_001_000); + + assertThat(iterator.next(item)).isFalse(); + } + + private void assertHistoryItem(BatteryStats.HistoryItem item, int command, int eventCode, + String tag, int uid, int batteryChargeUah, int batteryLevel, + long elapsedTimeMs) { + assertThat(item.cmd).isEqualTo(command); + assertThat(item.eventCode).isEqualTo(eventCode); + if (tag == null) { + assertThat(item.eventTag).isNull(); + } else { + assertThat(item.eventTag.string).isEqualTo(tag); + assertThat(item.eventTag.uid).isEqualTo(uid); + } + assertThat(item.batteryChargeUah).isEqualTo(batteryChargeUah); + assertThat(item.batteryLevel).isEqualTo(batteryLevel); + + assertThat(item.time).isEqualTo(elapsedTimeMs); + } +} diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsImplTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsImplTest.java index 4b37dd226e69..24baa93337ba 100644 --- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsImplTest.java +++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsImplTest.java @@ -73,6 +73,7 @@ public class BatteryStatsImplTest { } @Test + @SkipPresubmit("b/180015146") public void testUpdateProcStateCpuTimes() { mBatteryStatsImpl.setOnBatteryInternal(true); mBatteryStatsImpl.updateTimeBasesLocked(false, Display.STATE_ON, 0, 0); @@ -230,6 +231,7 @@ public class BatteryStatsImplTest { } @Test + @SkipPresubmit("b/180015146") public void testCopyFromAllUidsCpuTimes() { mBatteryStatsImpl.setOnBatteryInternal(false); mBatteryStatsImpl.updateTimeBasesLocked(false, Display.STATE_ON, 0, 0); diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java index 6652c64c4344..931611ea7478 100644 --- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java +++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java @@ -295,6 +295,7 @@ public class BatteryStatsNoteTest extends TestCase { } @SmallTest + @SkipPresubmit("b/180015146") public void testAlarmStartAndFinishLocked() throws Exception { final MockClocks clocks = new MockClocks(); // holds realtime and uptime in ms MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks); @@ -332,6 +333,7 @@ public class BatteryStatsNoteTest extends TestCase { } @SmallTest + @SkipPresubmit("b/180015146") public void testAlarmStartAndFinishLocked_workSource() throws Exception { final MockClocks clocks = new MockClocks(); // holds realtime and uptime in ms MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks); diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsSamplingTimerTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsSamplingTimerTest.java index 3b27f1897bd2..dd814e651ede 100644 --- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsSamplingTimerTest.java +++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsSamplingTimerTest.java @@ -56,6 +56,7 @@ public class BatteryStatsSamplingTimerTest extends TestCase { } @SmallTest + @SkipPresubmit("b/180015146") public void testEndSampleAndContinueWhenTimeOrCountDecreases() throws Exception { final MockClocks clocks = new MockClocks(); final BatteryStatsImpl.TimeBase timeBase = Mockito.mock(BatteryStatsImpl.TimeBase.class); diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsTests.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsTests.java index 7b7cf65f89ed..74c37ada2054 100644 --- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsTests.java +++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsTests.java @@ -30,6 +30,7 @@ import org.junit.runners.Suite; BatteryStatsDualTimerTest.class, BatteryStatsDurationTimerTest.class, BatteryStatsHelperTest.class, + BatteryStatsHistoryIteratorTest.class, BatteryStatsHistoryTest.class, BatteryStatsImplTest.class, BatteryStatsNoteTest.class, @@ -77,5 +78,4 @@ import org.junit.runners.Suite; com.android.internal.power.MeasuredEnergyStatsTest.class }) public class BatteryStatsTests { -} - +}
\ No newline at end of file diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsUserLifecycleTests.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsUserLifecycleTests.java index e7a1bcae459a..e90bcb76e457 100644 --- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsUserLifecycleTests.java +++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsUserLifecycleTests.java @@ -78,6 +78,7 @@ public class BatteryStatsUserLifecycleTests { } @Test + @SkipPresubmit("b/180015146") public void testNoCpuDataForRemovedUser() throws Exception { mIam.startUserInBackground(mTestUserId); waitUntilTrue("No uids for started user " + mTestUserId, diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsProviderTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsProviderTest.java index c4b7796b49cf..0f591433a84e 100644 --- a/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsProviderTest.java +++ b/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsProviderTest.java @@ -20,8 +20,11 @@ import static com.google.common.truth.Truth.assertThat; import android.app.ActivityManager; import android.content.Context; +import android.os.BatteryManager; +import android.os.BatteryStats; import android.os.BatteryUsageStats; import android.os.BatteryUsageStatsQuery; +import android.os.Parcel; import android.os.Process; import android.os.UidBatteryConsumer; @@ -73,4 +76,86 @@ public class BatteryUsageStatsProviderTest { assertThat(uidBatteryConsumer.getTimeInStateMs(UidBatteryConsumer.STATE_BACKGROUND)) .isEqualTo(10 * MINUTE_IN_MS); } + + @Test + public void testWriteAndReadHistory() { + MockBatteryStatsImpl batteryStats = mStatsRule.getBatteryStats(); + batteryStats.setRecordAllHistoryLocked(true); + batteryStats.forceRecordAllHistory(); + + batteryStats.setNoAutoReset(true); + + batteryStats.setBatteryStateLocked(BatteryManager.BATTERY_STATUS_DISCHARGING, 100, + /* plugType */ 0, 90, 72, 3700, 3_600_000, 4_000_000, 0, 1_000_000, + 1_000_000, 1_000_000); + + batteryStats.noteAlarmStartLocked("foo", null, APP_UID, 3_000_000, 2_000_000); + batteryStats.noteAlarmFinishLocked("foo", null, APP_UID, 3_001_000, 2_001_000); + + Context context = InstrumentationRegistry.getContext(); + BatteryUsageStatsProvider provider = new BatteryUsageStatsProvider(context, batteryStats); + + final BatteryUsageStats batteryUsageStats = + provider.getBatteryUsageStats( + new BatteryUsageStatsQuery.Builder().includeBatteryHistory().build()); + + Parcel in = Parcel.obtain(); + batteryUsageStats.writeToParcel(in, 0); + final byte[] bytes = in.marshall(); + + Parcel out = Parcel.obtain(); + out.unmarshall(bytes, 0, bytes.length); + out.setDataPosition(0); + + BatteryUsageStats unparceled = BatteryUsageStats.CREATOR.createFromParcel(out); + + final BatteryStatsHistoryIterator iterator = + unparceled.iterateBatteryStatsHistory(); + BatteryStats.HistoryItem item = new BatteryStats.HistoryItem(); + + assertThat(iterator.next(item)).isTrue(); + assertHistoryItem(item, + BatteryStats.HistoryItem.CMD_RESET, BatteryStats.HistoryItem.EVENT_NONE, + null, 0, 3_600_000, 90, 1_000_000); + + assertThat(iterator.next(item)).isTrue(); + assertHistoryItem(item, + BatteryStats.HistoryItem.CMD_UPDATE, BatteryStats.HistoryItem.EVENT_NONE, + null, 0, 3_600_000, 90, 1_000_000); + + assertThat(iterator.next(item)).isTrue(); + assertHistoryItem(item, + BatteryStats.HistoryItem.CMD_UPDATE, BatteryStats.HistoryItem.EVENT_NONE, + null, 0, 3_600_000, 90, 2_000_000); + + assertThat(iterator.next(item)).isTrue(); + assertHistoryItem(item, + BatteryStats.HistoryItem.CMD_UPDATE, + BatteryStats.HistoryItem.EVENT_ALARM | BatteryStats.HistoryItem.EVENT_FLAG_START, + "foo", APP_UID, 3_600_000, 90, 3_000_000); + + assertThat(iterator.next(item)).isTrue(); + assertHistoryItem(item, + BatteryStats.HistoryItem.CMD_UPDATE, + BatteryStats.HistoryItem.EVENT_ALARM | BatteryStats.HistoryItem.EVENT_FLAG_FINISH, + "foo", APP_UID, 3_600_000, 90, 3_001_000); + + assertThat(iterator.next(item)).isFalse(); + } + + private void assertHistoryItem(BatteryStats.HistoryItem item, int command, int eventCode, + String tag, int uid, int batteryChargeUah, int batteryLevel, long elapsedTimeMs) { + assertThat(item.cmd).isEqualTo(command); + assertThat(item.eventCode).isEqualTo(eventCode); + if (tag == null) { + assertThat(item.eventTag).isNull(); + } else { + assertThat(item.eventTag.string).isEqualTo(tag); + assertThat(item.eventTag.uid).isEqualTo(uid); + } + assertThat(item.batteryChargeUah).isEqualTo(batteryChargeUah); + assertThat(item.batteryLevel).isEqualTo(batteryLevel); + + assertThat(item.time).isEqualTo(elapsedTimeMs); + } } diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsTest.java index 9ef628848beb..23ea508d19d3 100644 --- a/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsTest.java +++ b/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsTest.java @@ -35,6 +35,7 @@ import org.junit.runner.RunWith; import java.util.List; @SmallTest +@SkipPresubmit("b/180015146") @RunWith(AndroidJUnit4.class) public class BatteryUsageStatsTest { diff --git a/core/tests/coretests/src/com/android/internal/os/BluetoothPowerCalculatorTest.java b/core/tests/coretests/src/com/android/internal/os/BluetoothPowerCalculatorTest.java index e5594712db10..f6aa08bf0645 100644 --- a/core/tests/coretests/src/com/android/internal/os/BluetoothPowerCalculatorTest.java +++ b/core/tests/coretests/src/com/android/internal/os/BluetoothPowerCalculatorTest.java @@ -43,6 +43,7 @@ public class BluetoothPowerCalculatorTest { .setAveragePower(PowerProfile.POWER_BLUETOOTH_CONTROLLER_TX, 100.0); @Test + @SkipPresubmit("b/180015146") public void testTimerBasedModel() { setDurationsAndPower(mStatsRule.getUidStats(Process.BLUETOOTH_UID) .getOrCreateBluetoothControllerActivityLocked(), @@ -73,6 +74,7 @@ public class BluetoothPowerCalculatorTest { } @Test + @SkipPresubmit("b/180015146") public void testReportedPowerBasedModel() { setDurationsAndPower(mStatsRule.getUidStats(Process.BLUETOOTH_UID) .getOrCreateBluetoothControllerActivityLocked(), diff --git a/core/tests/coretests/src/com/android/internal/os/BstatsCpuTimesValidationTest.java b/core/tests/coretests/src/com/android/internal/os/BstatsCpuTimesValidationTest.java index a80f5a03ee4e..4fe7d70e86ff 100644 --- a/core/tests/coretests/src/com/android/internal/os/BstatsCpuTimesValidationTest.java +++ b/core/tests/coretests/src/com/android/internal/os/BstatsCpuTimesValidationTest.java @@ -382,6 +382,7 @@ public class BstatsCpuTimesValidationTest { } @Test + @SkipPresubmit("b/180015146 flakey") public void testCpuFreqTimes_stateFgService() throws Exception { if (!sCpuFreqTimesAvailable || !sPerProcStateTimesAvailable) { Log.w(TAG, "Skipping " + testName.getMethodName() @@ -514,6 +515,7 @@ public class BstatsCpuTimesValidationTest { } @Test + @SkipPresubmit("b/180015146") public void testCpuFreqTimes_trackingDisabled() throws Exception { if (!sCpuFreqTimesAvailable || !sPerProcStateTimesAvailable) { Log.w(TAG, "Skipping " + testName.getMethodName() diff --git a/core/tests/coretests/src/com/android/internal/os/CpuPowerCalculatorTest.java b/core/tests/coretests/src/com/android/internal/os/CpuPowerCalculatorTest.java index 9cf0d375ff51..e691beb09a70 100644 --- a/core/tests/coretests/src/com/android/internal/os/CpuPowerCalculatorTest.java +++ b/core/tests/coretests/src/com/android/internal/os/CpuPowerCalculatorTest.java @@ -92,6 +92,7 @@ public class CpuPowerCalculatorTest { } @Test + @SkipPresubmit("b/180015146") public void testTimerBasedModel() { when(mMockUserInfoProvider.exists(anyInt())).thenReturn(true); diff --git a/core/tests/coretests/src/com/android/internal/os/CustomMeasuredPowerCalculatorTest.java b/core/tests/coretests/src/com/android/internal/os/CustomMeasuredPowerCalculatorTest.java index a4ea8923794a..f298f5988fc3 100644 --- a/core/tests/coretests/src/com/android/internal/os/CustomMeasuredPowerCalculatorTest.java +++ b/core/tests/coretests/src/com/android/internal/os/CustomMeasuredPowerCalculatorTest.java @@ -42,6 +42,7 @@ public class CustomMeasuredPowerCalculatorTest { public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule(); @Test + @SkipPresubmit("b/180015146") public void testMeasuredEnergyCopiedIntoBatteryConsumers() { final BatteryStatsImpl batteryStats = mStatsRule.getBatteryStats(); SparseLongArray uidEnergies = new SparseLongArray(); diff --git a/core/tests/coretests/src/com/android/internal/os/KernelCpuUidUserSysTimeReaderTest.java b/core/tests/coretests/src/com/android/internal/os/KernelCpuUidUserSysTimeReaderTest.java index 7dca0cb92f9d..177f34875894 100644 --- a/core/tests/coretests/src/com/android/internal/os/KernelCpuUidUserSysTimeReaderTest.java +++ b/core/tests/coretests/src/com/android/internal/os/KernelCpuUidUserSysTimeReaderTest.java @@ -87,6 +87,7 @@ public class KernelCpuUidUserSysTimeReaderTest { } @Test + @SkipPresubmit("b/180015146") public void testThrottler() throws Exception { mReader = new KernelCpuUidUserSysTimeReader( new KernelCpuProcStringReader(mTestFile.getAbsolutePath()), true); diff --git a/core/tests/coretests/src/com/android/internal/os/SkipPresubmit.java b/core/tests/coretests/src/com/android/internal/os/SkipPresubmit.java new file mode 100644 index 000000000000..d03ed663cc89 --- /dev/null +++ b/core/tests/coretests/src/com/android/internal/os/SkipPresubmit.java @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.internal.os; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** Annotation to skip a test from TEST_MAPPING presubmit. */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE, ElementType.METHOD}) +public @interface SkipPresubmit { + /** The optional reason why the test is ignored. */ + String value() default ""; +} diff --git a/core/tests/coretests/src/com/android/internal/os/SystemServicePowerCalculatorTest.java b/core/tests/coretests/src/com/android/internal/os/SystemServicePowerCalculatorTest.java index dfbf28b286c6..b5282e9a625a 100644 --- a/core/tests/coretests/src/com/android/internal/os/SystemServicePowerCalculatorTest.java +++ b/core/tests/coretests/src/com/android/internal/os/SystemServicePowerCalculatorTest.java @@ -78,6 +78,7 @@ public class SystemServicePowerCalculatorTest { } @Test + @SkipPresubmit("b/180015146") public void testPowerProfileBasedModel() { when(mMockUserInfoProvider.exists(anyInt())).thenReturn(true); diff --git a/core/tests/coretests/src/com/android/internal/view/OWNERS b/core/tests/coretests/src/com/android/internal/view/OWNERS deleted file mode 100644 index 1dad10de5ac7..000000000000 --- a/core/tests/coretests/src/com/android/internal/view/OWNERS +++ /dev/null @@ -1,3 +0,0 @@ -# Scroll Capture -per-file *ScrollCapture*.java = file:/packages/SystemUI/src/com/android/systemui/screenshot/OWNERS -per-file *CaptureHelper*.java = file:/packages/SystemUI/src/com/android/systemui/screenshot/OWNERS diff --git a/data/etc/car/Android.bp b/data/etc/car/Android.bp index f6d76855ca68..2f41b9084f40 100644 --- a/data/etc/car/Android.bp +++ b/data/etc/car/Android.bp @@ -173,3 +173,10 @@ prebuilt_etc { src: "com.android.car.shell.xml", filename_from_src: true, } + +prebuilt_etc { + name: "allowed_privapp_com.android.car.activityresolver", + sub_dir: "permissions", + src: "com.android.car.activityresolver.xml", + filename_from_src: true, +} diff --git a/packages/SystemUI/res/layout/qs_tile_label_divider.xml b/data/etc/car/com.android.car.activityresolver.xml index 150a5b8bfef1..d48bc15b1678 100644 --- a/packages/SystemUI/res/layout/qs_tile_label_divider.xml +++ b/data/etc/car/com.android.car.activityresolver.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <!-- - ~ Copyright (C) 2020 The Android Open Source Project + ~ Copyright (C) 2021 The Android Open Source Project ~ ~ Licensed under the Apache License, Version 2.0 (the "License"); ~ you may not use this file except in compliance with the License. @@ -14,5 +14,8 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> - -<View />
\ No newline at end of file +<permissions> + <privapp-permissions package="com.android.car.activityresolver"> + <permission name="android.permission.MANAGE_USERS"/> + </privapp-permissions> +</permissions> diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java index f1f9a5fc92ea..e22257071dd2 100644 --- a/graphics/java/android/graphics/Paint.java +++ b/graphics/java/android/graphics/Paint.java @@ -153,6 +153,13 @@ public class Paint { * resource bitmaps often are) the filtering will already have been * done.</p> * + * <p>On devices running {@link Build.VERSION_CODES#O} and below, hardware + * accelerated drawing always uses bilinear sampling on scaled bitmaps, + * regardless of this flag. On devices running {@link Build.VERSION_CODES#Q} + * and above, this flag defaults to being set on a new {@code Paint}. It can + * be cleared with {@link #setFlags} or {@link #setFilterBitmap}.</p> + * + * @see #Paint() * @see #Paint(int) * @see #setFlags(int) */ @@ -558,6 +565,12 @@ public class Paint { /** * Create a new paint with default settings. + * + * <p>On devices running {@link Build.VERSION_CODES#O} and below, hardware + * accelerated drawing always acts as if {@link #FILTER_BITMAP_FLAG} is set. + * On devices running {@link Build.VERSION_CODES#Q} and above, + * {@code FILTER_BITMAP_FLAG} is set by this constructor, and it can be + * cleared with {@link #setFlags} or {@link #setFilterBitmap}.</p> */ public Paint() { this(0); @@ -567,6 +580,13 @@ public class Paint { * Create a new paint with the specified flags. Use setFlags() to change * these after the paint is created. * + * <p>On devices running {@link Build.VERSION_CODES#O} and below, hardware + * accelerated drawing always acts as if {@link #FILTER_BITMAP_FLAG} is set. + * On devices running {@link Build.VERSION_CODES#Q} and above, + * {@code FILTER_BITMAP_FLAG} is always set by this constructor, regardless + * of the value of {@code flags}. It can be cleared with {@link #setFlags} or + * {@link #setFilterBitmap}.</p> + * * @param flags initial flag bits, as if they were passed via setFlags(). */ public Paint(int flags) { @@ -991,6 +1011,7 @@ public class Paint { * device pixels. That is dependent on dithering and xfermodes. * * @see #setFilterBitmap(boolean) setFilterBitmap() + * @see #FILTER_BITMAP_FLAG */ public final boolean isFilterBitmap() { return (getFlags() & FILTER_BITMAP_FLAG) != 0; @@ -1004,6 +1025,7 @@ public class Paint { * * @param filter true to set the FILTER_BITMAP_FLAG bit in the paint's * flags, false to clear it. + * @see #FILTER_BITMAP_FLAG */ public void setFilterBitmap(boolean filter) { nSetFilterBitmap(mNativePaint, filter); diff --git a/keystore/java/android/security/AndroidKeyStoreMaintenance.java b/keystore/java/android/security/AndroidKeyStoreMaintenance.java index c81c8c54d88a..ed789f03f9ba 100644 --- a/keystore/java/android/security/AndroidKeyStoreMaintenance.java +++ b/keystore/java/android/security/AndroidKeyStoreMaintenance.java @@ -21,6 +21,7 @@ import android.annotation.Nullable; import android.os.ServiceManager; import android.os.ServiceSpecificException; import android.security.usermanager.IKeystoreUserManager; +import android.system.keystore2.Domain; import android.system.keystore2.ResponseCode; import android.util.Log; @@ -39,7 +40,7 @@ public class AndroidKeyStoreMaintenance { } /** - * Informs keystore2 about adding a user + * Informs Keystore 2.0 about adding a user * * @param userId - Android user id of the user being added * @return 0 if successful or a {@code ResponseCode} @@ -60,7 +61,7 @@ public class AndroidKeyStoreMaintenance { } /** - * Informs keystore2 about removing a usergit mer + * Informs Keystore 2.0 about removing a usergit mer * * @param userId - Android user id of the user being removed * @return 0 if successful or a {@code ResponseCode} @@ -81,7 +82,7 @@ public class AndroidKeyStoreMaintenance { } /** - * Informs keystore2 about changing user's password + * Informs Keystore 2.0 about changing user's password * * @param userId - Android user id of the user * @param password - a secret derived from the synthetic password provided by the @@ -102,4 +103,22 @@ public class AndroidKeyStoreMaintenance { return SYSTEM_ERROR; } } + + /** + * Informs Keystore 2.0 that an app was uninstalled and the corresponding namspace is to + * be cleared. + */ + public static int clearNamespace(@Domain int domain, long namespace) { + if (!android.security.keystore2.AndroidKeyStoreProvider.isInstalled()) return 0; + try { + getService().clearNamespace(domain, namespace); + return 0; + } catch (ServiceSpecificException e) { + Log.e(TAG, "clearNamespace failed", e); + return e.errorCode; + } catch (Exception e) { + Log.e(TAG, "Can not connect to keystore", e); + return SYSTEM_ERROR; + } + } } diff --git a/keystore/java/android/security/KeyStore.java b/keystore/java/android/security/KeyStore.java index 198df40c7d7b..93658e69eac8 100644 --- a/keystore/java/android/security/KeyStore.java +++ b/keystore/java/android/security/KeyStore.java @@ -43,6 +43,7 @@ import android.security.keystore.KeyPermanentlyInvalidatedException; import android.security.keystore.KeyProperties; import android.security.keystore.KeystoreResponse; import android.security.keystore.UserNotAuthenticatedException; +import android.system.keystore2.Domain; import android.util.Log; import com.android.internal.org.bouncycastle.asn1.ASN1InputStream; @@ -466,6 +467,9 @@ public class KeyStore { public boolean clearUid(int uid) { try { + if (android.security.keystore2.AndroidKeyStoreProvider.isInstalled()) { + return AndroidKeyStoreMaintenance.clearNamespace(Domain.APP, uid) == 0; + } return mBinder.clear_uid(uid) == NO_ERROR; } catch (RemoteException e) { Log.w(TAG, "Cannot connect to keystore", e); diff --git a/keystore/java/android/security/KeyStore2.java b/keystore/java/android/security/KeyStore2.java index 476e4d7b7b18..6ac3821d0f9c 100644 --- a/keystore/java/android/security/KeyStore2.java +++ b/keystore/java/android/security/KeyStore2.java @@ -24,6 +24,7 @@ import android.os.RemoteException; import android.os.ServiceManager; import android.os.ServiceSpecificException; import android.security.keymaster.KeymasterDefs; +import android.system.keystore2.Domain; import android.system.keystore2.IKeystoreService; import android.system.keystore2.KeyDescriptor; import android.system.keystore2.KeyEntryResponse; @@ -157,6 +158,50 @@ public class KeyStore2 { } /** + * Grant string prefix as used by the keystore boringssl engine. Must be kept in sync + * with system/security/keystore-engine. Note: The prefix here includes the 0x which + * std::stringstream used in keystore-engine needs to identify the number as hex represented. + * Here we include it in the prefix, because Long#parseUnsignedLong does not understand it + * and gets the radix as explicit argument. + * @hide + */ + private static final String KEYSTORE_ENGINE_GRANT_ALIAS_PREFIX = + "ks2_keystore-engine_grant_id:0x"; + + /** + * This function turns a grant identifier into a specific string that is understood by the + * keystore-engine in system/security/keystore-engine. Is only used by VPN and WI-FI components + * to allow certain system components like racoon or vendor components like WPA supplicant + * to use keystore keys with boring ssl. + * + * @param grantId the grant id as returned by {@link #grant} in the {@code nspace} filed of + * the resulting {@code KeyDescriptor}. + * @return The grant descriptor string. + * @hide + */ + public static String makeKeystoreEngineGrantString(long grantId) { + return String.format("%s%016X", KEYSTORE_ENGINE_GRANT_ALIAS_PREFIX, grantId); + } + + /** + * Convenience function to turn a keystore engine grant string as returned by + * {@link #makeKeystoreEngineGrantString(long)} back into a grant KeyDescriptor. + * + * @param grantString As string returned by {@link #makeKeystoreEngineGrantString(long)} + * @return The grant key descriptor. + * @hide + */ + public static KeyDescriptor keystoreEngineGrantString2KeyDescriptor(String grantString) { + KeyDescriptor key = new KeyDescriptor(); + key.domain = Domain.GRANT; + key.nspace = Long.parseUnsignedLong( + grantString.substring(KEYSTORE_ENGINE_GRANT_ALIAS_PREFIX.length()), 16); + key.alias = null; + key.blob = null; + return key; + } + + /** * Create a grant that allows the grantee identified by {@code granteeUid} to use * the key specified by {@code descriptor} withint the restrictions given by * {@code accessVectore}. diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java b/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java index 35059ac929c3..d36695b9b410 100644 --- a/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java +++ b/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java @@ -43,6 +43,7 @@ import java.security.interfaces.RSAPublicKey; import javax.crypto.Cipher; import javax.crypto.Mac; +import javax.crypto.SecretKey; /** * A provider focused on providing JCA interfaces for the Android KeyStore. @@ -299,13 +300,26 @@ public class AndroidKeyStoreProvider extends Provider { } } + /** @hide **/ + @NonNull + public static SecretKey loadAndroidKeyStoreSecretKeyFromKeystore( + @NonNull KeyStore2 keyStore, @NonNull KeyDescriptor descriptor) + throws UnrecoverableKeyException, KeyPermanentlyInvalidatedException { + + AndroidKeyStoreKey key = + loadAndroidKeyStoreKeyFromKeystore(keyStore, descriptor); + if (key instanceof SecretKey) { + return (SecretKey) key; + } else { + throw new UnrecoverableKeyException("No secret key found by the given alias."); + } + } @NonNull private static AndroidKeyStoreSecretKey makeAndroidKeyStoreSecretKeyFromKeyEntryResponse( @NonNull KeyDescriptor descriptor, @NonNull KeyEntryResponse response, int algorithm, int digest) throws UnrecoverableKeyException { - @KeyProperties.KeyAlgorithmEnum String keyAlgorithmString; try { keyAlgorithmString = KeyProperties.KeyAlgorithm.fromKeymasterSecretKeyAlgorithm( @@ -337,7 +351,6 @@ public class AndroidKeyStoreProvider extends Provider { public static AndroidKeyStoreKey loadAndroidKeyStoreKeyFromKeystore( @NonNull KeyStore2 keyStore, @NonNull String alias, int namespace) throws UnrecoverableKeyException, KeyPermanentlyInvalidatedException { - KeyDescriptor descriptor = new KeyDescriptor(); if (namespace == KeyProperties.NAMESPACE_APPLICATION) { descriptor.nspace = KeyProperties.NAMESPACE_APPLICATION; // ignored; diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipToHomeTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipCloseTransition.kt index 92928b16ee1a..3e331761f767 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipToHomeTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipCloseTransition.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020 The Android Open Source Project + * Copyright (C) 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,8 +19,6 @@ package com.android.wm.shell.flicker.pip import android.platform.test.annotations.Presubmit import android.view.Surface import androidx.test.filters.FlakyTest -import androidx.test.filters.RequiresDevice -import com.android.server.wm.flicker.FlickerParametersRunnerFactory import com.android.server.wm.flicker.FlickerTestParameter import com.android.server.wm.flicker.FlickerTestParameterFactory import com.android.server.wm.flicker.dsl.FlickerBuilder @@ -34,21 +32,10 @@ import com.android.server.wm.flicker.startRotation import com.android.server.wm.flicker.statusBarLayerIsAlwaysVisible import com.android.server.wm.flicker.statusBarLayerRotatesScales import com.android.server.wm.flicker.statusBarWindowIsAlwaysVisible -import org.junit.FixMethodOrder import org.junit.Test -import org.junit.runner.RunWith -import org.junit.runners.MethodSorters import org.junit.runners.Parameterized -/** - * Test Pip launch. - * To run this test: `atest WMShellFlickerTests:PipToHomeTest` - */ -@RequiresDevice -@RunWith(Parameterized::class) -@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) -@FixMethodOrder(MethodSorters.NAME_ASCENDING) -class PipToHomeTest(testSpec: FlickerTestParameter) : PipTransition(testSpec) { +abstract class PipCloseTransition(testSpec: FlickerTestParameter) : PipTransition(testSpec) { override val transition: FlickerBuilder.(Map<String, Any?>) -> Unit get() = buildTransition(eachRun = true) { configuration -> setup { @@ -61,30 +48,27 @@ class PipToHomeTest(testSpec: FlickerTestParameter) : PipTransition(testSpec) { this.setRotation(Surface.ROTATION_0) } } - transitions { - pipApp.closePipWindow(wmHelper) - } } @Presubmit @Test - fun navBarLayerIsAlwaysVisible() = testSpec.navBarLayerIsAlwaysVisible() + open fun navBarLayerIsAlwaysVisible() = testSpec.navBarLayerIsAlwaysVisible() @Presubmit @Test - fun statusBarLayerIsAlwaysVisible() = testSpec.statusBarLayerIsAlwaysVisible() + open fun statusBarLayerIsAlwaysVisible() = testSpec.statusBarLayerIsAlwaysVisible() @Presubmit @Test - fun navBarWindowIsAlwaysVisible() = testSpec.navBarWindowIsAlwaysVisible() + open fun navBarWindowIsAlwaysVisible() = testSpec.navBarWindowIsAlwaysVisible() @Presubmit @Test - fun statusBarWindowIsAlwaysVisible() = testSpec.statusBarWindowIsAlwaysVisible() + open fun statusBarWindowIsAlwaysVisible() = testSpec.statusBarWindowIsAlwaysVisible() @Presubmit @Test - fun pipWindowBecomesInvisible() { + open fun pipWindowBecomesInvisible() { testSpec.assertWm { this.showsAppWindow(PIP_WINDOW_TITLE) .then() @@ -94,7 +78,7 @@ class PipToHomeTest(testSpec: FlickerTestParameter) : PipTransition(testSpec) { @Presubmit @Test - fun pipLayerBecomesInvisible() { + open fun pipLayerBecomesInvisible() { testSpec.assertLayers { this.isVisible(PIP_WINDOW_TITLE) .then() @@ -104,22 +88,22 @@ class PipToHomeTest(testSpec: FlickerTestParameter) : PipTransition(testSpec) { @Presubmit @Test - fun statusBarLayerRotatesScales() = + open fun statusBarLayerRotatesScales() = testSpec.statusBarLayerRotatesScales(testSpec.config.startRotation, Surface.ROTATION_0) @Presubmit @Test - fun noUncoveredRegions() = + open fun noUncoveredRegions() = testSpec.noUncoveredRegions(testSpec.config.startRotation, Surface.ROTATION_0) @Presubmit @Test - fun navBarLayerRotatesAndScales() = + open fun navBarLayerRotatesAndScales() = testSpec.navBarLayerRotatesAndScales(testSpec.config.startRotation, Surface.ROTATION_0) @FlakyTest(bugId = 151179149) @Test - fun focusChanges() = testSpec.focusChanges(pipApp.launcherName, "NexusLauncherActivity") + open fun focusChanges() = testSpec.focusChanges(pipApp.launcherName, "NexusLauncherActivity") companion object { @Parameterized.Parameters(name = "{0}") diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipCloseWithDismissButtonTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipCloseWithDismissButtonTest.kt new file mode 100644 index 000000000000..0408421c72a5 --- /dev/null +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipCloseWithDismissButtonTest.kt @@ -0,0 +1,44 @@ +/* + * 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.wm.shell.flicker.pip + +import androidx.test.filters.RequiresDevice +import com.android.server.wm.flicker.FlickerParametersRunnerFactory +import com.android.server.wm.flicker.FlickerTestParameter +import com.android.server.wm.flicker.dsl.FlickerBuilder +import org.junit.FixMethodOrder +import org.junit.runner.RunWith +import org.junit.runners.MethodSorters +import org.junit.runners.Parameterized + +/** + * Test Pip launch. + * To run this test: `atest WMShellFlickerTests:PipCloseWithDismissButton` + */ +@RequiresDevice +@RunWith(Parameterized::class) +@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +class PipCloseWithDismissButtonTest(testSpec: FlickerTestParameter) : PipCloseTransition(testSpec) { + override val transition: FlickerBuilder.(Map<String, Any?>) -> Unit + get() = { + super.transition(this, it) + transitions { + pipApp.closePipWindow(wmHelper) + } + } +}
\ No newline at end of file diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipCloseWithSwipeTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipCloseWithSwipeTest.kt new file mode 100644 index 000000000000..afaf33a7c46f --- /dev/null +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipCloseWithSwipeTest.kt @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.wm.shell.flicker.pip + +import android.platform.test.annotations.Postsubmit +import android.view.Surface +import androidx.test.filters.RequiresDevice +import com.android.server.wm.flicker.FlickerParametersRunnerFactory +import com.android.server.wm.flicker.FlickerTestParameter +import com.android.server.wm.flicker.dsl.FlickerBuilder +import com.android.server.wm.flicker.startRotation +import com.android.server.wm.flicker.statusBarLayerRotatesScales +import org.junit.FixMethodOrder +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.MethodSorters +import org.junit.runners.Parameterized + +/** + * Test Pip launch. + * To run this test: `atest WMShellFlickerTests:PipCloseWithSwipe` + */ +@RequiresDevice +@RunWith(Parameterized::class) +@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +class PipCloseWithSwipeTest(testSpec: FlickerTestParameter) : PipCloseTransition(testSpec) { + override val transition: FlickerBuilder.(Map<String, Any?>) -> Unit + get() = { + super.transition(this, it) + transitions { + val pipRegion = wmHelper.getWindowRegion(pipApp.component).bounds + val pipCenterX = pipRegion.centerX() + val pipCenterY = pipRegion.centerY() + val displayCenterX = device.displayWidth / 2 + device.swipe(pipCenterX, pipCenterY, displayCenterX, device.displayHeight, 5) + } + } + + @Postsubmit + @Test + override fun navBarLayerIsAlwaysVisible() = super.navBarLayerIsAlwaysVisible() + + @Postsubmit + @Test + override fun statusBarLayerIsAlwaysVisible() = super.statusBarLayerIsAlwaysVisible() + + @Postsubmit + @Test + override fun navBarWindowIsAlwaysVisible() = super.navBarWindowIsAlwaysVisible() + + @Postsubmit + @Test + override fun statusBarWindowIsAlwaysVisible() = super.statusBarWindowIsAlwaysVisible() + + @Postsubmit + @Test + override fun pipWindowBecomesInvisible() = super.pipWindowBecomesInvisible() + + @Postsubmit + @Test + override fun pipLayerBecomesInvisible() = super.pipLayerBecomesInvisible() + + @Postsubmit + @Test + override fun statusBarLayerRotatesScales() = + testSpec.statusBarLayerRotatesScales(testSpec.config.startRotation, Surface.ROTATION_0) + + @Postsubmit + @Test + override fun noUncoveredRegions() = super.noUncoveredRegions() + + @Postsubmit + @Test + override fun navBarLayerRotatesAndScales() = super.navBarLayerRotatesAndScales() +}
\ No newline at end of file diff --git a/location/java/android/location/GnssAntennaInfo.java b/location/java/android/location/GnssAntennaInfo.java index f1eb8fccdd3c..6633d24ebc35 100644 --- a/location/java/android/location/GnssAntennaInfo.java +++ b/location/java/android/location/GnssAntennaInfo.java @@ -39,11 +39,7 @@ public final class GnssAntennaInfo implements Parcelable { /** * Used for receiving GNSS antenna info from the GNSS engine. - * - * @deprecated Prefer to use a broadcast receiver for - * {@link LocationManager#ACTION_GNSS_ANTENNA_INFOS_CHANGED}. */ - @Deprecated public interface Listener { /** * Invoked on a change to GNSS antenna info. diff --git a/location/java/android/location/IGnssAntennaInfoListener.aidl b/location/java/android/location/IGnssAntennaInfoListener.aidl new file mode 100644 index 000000000000..3cceea3e6d26 --- /dev/null +++ b/location/java/android/location/IGnssAntennaInfoListener.aidl @@ -0,0 +1,26 @@ +/* + * 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 android.location; + +import android.location.GnssAntennaInfo; + +/** + * {@hide} + */ +oneway interface IGnssAntennaInfoListener { + void onGnssAntennaInfoChanged(in List<GnssAntennaInfo> antennaInfos); +} diff --git a/location/java/android/location/ILocationManager.aidl b/location/java/android/location/ILocationManager.aidl index 38b48e97771a..6fa6536997c4 100644 --- a/location/java/android/location/ILocationManager.aidl +++ b/location/java/android/location/ILocationManager.aidl @@ -26,6 +26,7 @@ import android.location.GnssCapabilities; import android.location.GnssMeasurementCorrections; import android.location.GnssMeasurementRequest; import android.location.IGeocodeListener; +import android.location.IGnssAntennaInfoListener; import android.location.IGnssMeasurementsListener; import android.location.IGnssStatusListener; import android.location.IGnssNavigationMessageListener; @@ -92,6 +93,9 @@ interface ILocationManager void addGnssNavigationMessageListener(in IGnssNavigationMessageListener listener, String packageName, @nullable String attributionTag, String listenerId); void removeGnssNavigationMessageListener(in IGnssNavigationMessageListener listener); + void addGnssAntennaInfoListener(in IGnssAntennaInfoListener listener, String packageName, @nullable String attributionTag, String listenerId); + void removeGnssAntennaInfoListener(in IGnssAntennaInfoListener listener); + void addProviderRequestListener(in IProviderRequestListener listener); void removeProviderRequestListener(in IProviderRequestListener listener); diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java index 95bae5ae7aab..e73e915bf88b 100644 --- a/location/java/android/location/LocationManager.java +++ b/location/java/android/location/LocationManager.java @@ -43,10 +43,8 @@ import android.app.PropertyInvalidatedCache; import android.compat.Compatibility; import android.compat.annotation.ChangeId; import android.compat.annotation.EnabledAfter; -import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; -import android.content.IntentFilter; import android.content.pm.PackageManager; import android.location.provider.IProviderRequestListener; import android.location.provider.ProviderProperties; @@ -349,28 +347,6 @@ public class LocationManager { public static final String EXTRA_GNSS_CAPABILITIES = "android.location.extra.GNSS_CAPABILITIES"; /** - * Broadcast intent action when GNSS antenna infos change. Includes an intent extra, - * {@link #EXTRA_GNSS_ANTENNA_INFOS}, with an ArrayList of the new {@link GnssAntennaInfo}. This - * may be read via {@link android.content.Intent#getParcelableArrayListExtra(String)}. - * - * @see #EXTRA_GNSS_ANTENNA_INFOS - * @see #getGnssAntennaInfos() - */ - @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) - public static final String ACTION_GNSS_ANTENNA_INFOS_CHANGED = - "android.location.action.GNSS_ANTENNA_INFOS_CHANGED"; - - /** - * Intent extra included with {@link #ACTION_GNSS_ANTENNA_INFOS_CHANGED} broadcasts, containing - * the new ArrayList of {@link GnssAntennaInfo}. This may be read via - * {@link android.content.Intent#getParcelableArrayListExtra(String)}. - * - * @see #ACTION_GNSS_ANTENNA_INFOS_CHANGED - */ - public static final String EXTRA_GNSS_ANTENNA_INFOS = - "android.location.extra.GNSS_ANTENNA_INFOS"; - - /** * Broadcast intent action for Settings app to inject a footer at the bottom of location * settings. This is for use only by apps that are included in the system image. * @@ -1967,7 +1943,7 @@ public class LocationManager { * * @param provider the provider name * @param properties the provider properties - * @param locationTags the attribution tags for accessing location from the provider + * @param extraAttributionTags additional attribution tags associated with this provider * * @throws IllegalArgumentException if provider is null * @throws IllegalArgumentException if properties is null @@ -1976,13 +1952,14 @@ public class LocationManager { * allowed} for your app. */ public void addTestProvider(@NonNull String provider, @NonNull ProviderProperties properties, - @NonNull Set<String> locationTags) { + @NonNull Set<String> extraAttributionTags) { Preconditions.checkArgument(provider != null, "invalid null provider"); Preconditions.checkArgument(properties != null, "invalid null properties"); - Preconditions.checkArgument(locationTags != null, "invalid null location tags"); + Preconditions.checkArgument(extraAttributionTags != null, + "invalid null extra attribution tags"); try { - mService.addTestProvider(provider, properties, new ArrayList<>(locationTags), + mService.addTestProvider(provider, properties, new ArrayList<>(extraAttributionTags), mContext.getOpPackageName(), mContext.getFeatureId()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); @@ -2659,10 +2636,11 @@ public class LocationManager { } /** - * Registers a GNSS antenna info listener. GNSS antenna info updates will only be received while - * the {@link #GPS_PROVIDER} is enabled, and while the client app is in the foreground. + * Registers a GNSS antenna info listener that will receive all changes to antenna info. Use + * {@link #getGnssAntennaInfos()} to get current antenna info. * - * <p>Not all GNSS chipsets support antenna info updates, see {@link #getGnssCapabilities()}. + * <p>Not all GNSS chipsets support antenna info updates, see {@link #getGnssCapabilities()}. If + * unsupported, the listener will never be invoked. * * <p>Prior to Android S, this requires the {@link Manifest.permission#ACCESS_FINE_LOCATION} * permission. @@ -2673,10 +2651,7 @@ public class LocationManager { * * @throws IllegalArgumentException if executor is null * @throws IllegalArgumentException if listener is null - * - * @deprecated Prefer to use a receiver for {@link #ACTION_GNSS_ANTENNA_INFOS_CHANGED}. */ - @Deprecated public boolean registerAntennaInfoListener( @NonNull @CallbackExecutor Executor executor, @NonNull GnssAntennaInfo.Listener listener) { @@ -2686,13 +2661,10 @@ public class LocationManager { } /** - * Unregisters a GNSS Antenna Info listener. + * Unregisters a GNSS antenna info listener. * * @param listener a {@link GnssAntennaInfo.Listener} object to remove - * - * @deprecated Prefer to use a receiver for {@link #ACTION_GNSS_ANTENNA_INFOS_CHANGED}. */ - @Deprecated public void unregisterAntennaInfoListener(@NonNull GnssAntennaInfo.Listener listener) { GnssLazyLoader.sGnssAntennaInfoListeners.removeListener(listener); } @@ -3009,14 +2981,17 @@ public class LocationManager { } @Override - protected void registerTransport(GnssAntennaInfoTransport transport) { - transport.getContext().registerReceiver(transport, - new IntentFilter(ACTION_GNSS_ANTENNA_INFOS_CHANGED)); + protected void registerTransport(GnssAntennaInfoTransport transport) + throws RemoteException { + getService().addGnssAntennaInfoListener(transport, transport.getPackage(), + transport.getAttributionTag(), + AppOpsManager.toReceiverId(transport.getListener())); } @Override - protected void unregisterTransport(GnssAntennaInfoTransport transport) { - transport.getContext().unregisterReceiver(transport); + protected void unregisterTransport(GnssAntennaInfoTransport transport) + throws RemoteException { + getService().removeGnssAntennaInfoListener(transport); } } @@ -3376,11 +3351,12 @@ public class LocationManager { } } - private static class GnssAntennaInfoTransport extends BroadcastReceiver implements + private static class GnssAntennaInfoTransport extends IGnssAntennaInfoListener.Stub implements ListenerTransport<GnssAntennaInfo.Listener> { private final Executor mExecutor; - private final Context mContext; + private final String mPackageName; + private final String mAttributionTag; private volatile @Nullable GnssAntennaInfo.Listener mListener; @@ -3389,12 +3365,17 @@ public class LocationManager { Preconditions.checkArgument(executor != null, "invalid null executor"); Preconditions.checkArgument(listener != null, "invalid null listener"); mExecutor = executor; - mContext = context; + mPackageName = context.getPackageName(); + mAttributionTag = context.getAttributionTag(); mListener = listener; } - public Context getContext() { - return mContext; + public String getPackage() { + return mPackageName; + } + + public String getAttributionTag() { + return mAttributionTag; } @Override @@ -3408,12 +3389,8 @@ public class LocationManager { } @Override - public void onReceive(Context context, Intent intent) { - ArrayList<GnssAntennaInfo> infos = intent.getParcelableArrayListExtra( - EXTRA_GNSS_ANTENNA_INFOS); - if (infos != null) { - execute(mExecutor, callback -> callback.onGnssAntennaInfoReceived(infos)); - } + public void onGnssAntennaInfoChanged(List<GnssAntennaInfo> antennaInfos) { + execute(mExecutor, callback -> callback.onGnssAntennaInfoReceived(antennaInfos)); } } diff --git a/media/java/android/media/AudioAttributes.java b/media/java/android/media/AudioAttributes.java index bb1dbd436e0b..7e729d8c371f 100644 --- a/media/java/android/media/AudioAttributes.java +++ b/media/java/android/media/AudioAttributes.java @@ -1264,6 +1264,8 @@ public final class AudioAttributes implements Parcelable { * * @param usage one of the {@link AudioAttributes} usage constants * @return string representing the {@link AudioAttributes} usage constant passed as a parameter + * + * @hide */ @NonNull public static String usageToString(@AttributeSdkUsage int usage) { diff --git a/media/java/android/media/MediaCodecInfo.java b/media/java/android/media/MediaCodecInfo.java index 4d7ed1145990..06d0eb0b5423 100644 --- a/media/java/android/media/MediaCodecInfo.java +++ b/media/java/android/media/MediaCodecInfo.java @@ -19,6 +19,7 @@ package android.media; import static android.media.Utils.intersectSortedDistinctRanges; import static android.media.Utils.sortDistinctRanges; +import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SuppressLint; @@ -1133,6 +1134,7 @@ public final class MediaCodecInfo { * in the ranges returned by {@link #getInputChannelCountRanges} * */ + @IntRange(from = 1, to = 255) public int getMaxInputChannelCount() { int overall_max = 0; for (int i = mInputChannelRanges.length - 1; i >= 0; i--) { @@ -1151,6 +1153,7 @@ public final class MediaCodecInfo { * This returns the lowest channel count in the ranges returned by * {@link #getInputChannelCountRanges}. */ + @IntRange(from = 1, to = 255) public int getMinInputChannelCount() { int overall_min = MAX_INPUT_CHANNEL_COUNT; for (int i = mInputChannelRanges.length - 1; i >= 0; i--) { diff --git a/media/java/android/media/session/ISessionManager.aidl b/media/java/android/media/session/ISessionManager.aidl index dc476b873786..96bffee117ea 100644 --- a/media/java/android/media/session/ISessionManager.aidl +++ b/media/java/android/media/session/ISessionManager.aidl @@ -38,9 +38,7 @@ import android.view.KeyEvent; interface ISessionManager { ISession createSession(String packageName, in ISessionCallback sessionCb, String tag, in Bundle sessionInfo, int userId); - void notifySession2Created(in Session2Token sessionToken); List<MediaSession.Token> getSessions(in ComponentName compName, int userId); - ParceledListSlice getSession2Tokens(int userId); void dispatchMediaKeyEvent(String packageName, boolean asSystemService, in KeyEvent keyEvent, boolean needWakeLock); boolean dispatchMediaKeyEventToSessionAsSystemService(String packageName, diff --git a/media/java/android/media/session/MediaSessionManager.java b/media/java/android/media/session/MediaSessionManager.java index aa0f7fdd70d5..98a13cfa6f3f 100644 --- a/media/java/android/media/session/MediaSessionManager.java +++ b/media/java/android/media/session/MediaSessionManager.java @@ -25,9 +25,9 @@ import android.annotation.SystemApi; import android.annotation.SystemService; import android.content.ComponentName; import android.content.Context; -import android.content.pm.ParceledListSlice; import android.media.AudioManager; import android.media.IRemoteSessionCallback; +import android.media.MediaCommunicationManager; import android.media.MediaFrameworkPlatformInitializer; import android.media.MediaSession2; import android.media.Session2Token; @@ -84,6 +84,7 @@ public final class MediaSessionManager { public static final int RESULT_MEDIA_KEY_HANDLED = 1; private final ISessionManager mService; + private final MediaCommunicationManager mCommunicationManager; private final OnMediaKeyEventDispatchedListenerStub mOnMediaKeyEventDispatchedListenerStub = new OnMediaKeyEventDispatchedListenerStub(); private final OnMediaKeyEventSessionChangedListenerStub @@ -128,6 +129,8 @@ public final class MediaSessionManager { .getMediaServiceManager() .getMediaSessionServiceRegisterer() .get()); + mCommunicationManager = (MediaCommunicationManager) context + .getSystemService(Context.MEDIA_COMMUNICATION_SERVICE); } /** @@ -164,17 +167,11 @@ public final class MediaSessionManager { * {@link MediaSession2.Builder} instead. * * @param token newly created session2 token + * @deprecated Don't use this method. A new media session is notified automatically. */ + @Deprecated public void notifySession2Created(@NonNull Session2Token token) { - Objects.requireNonNull(token, "token shouldn't be null"); - if (token.getType() != Session2Token.TYPE_SESSION) { - throw new IllegalArgumentException("token's type should be TYPE_SESSION"); - } - try { - mService.notifySession2Created(token); - } catch (RemoteException e) { - e.rethrowFromSystemServer(); - } + // Does nothing } /** @@ -255,37 +252,7 @@ public final class MediaSessionManager { */ @NonNull public List<Session2Token> getSession2Tokens() { - return getSession2Tokens(UserHandle.myUserId()); - } - - /** - * Gets a list of {@link Session2Token} with type {@link Session2Token#TYPE_SESSION} for the - * given user. - * <p> - * The calling application needs to hold the - * {@link android.Manifest.permission#INTERACT_ACROSS_USERS_FULL} permission in order to - * retrieve session tokens for user ids that do not belong to current process. - * - * @param userHandle The user handle to fetch sessions for. - * @return A list of {@link Session2Token} - * @hide - */ - @NonNull - @SuppressLint("UserHandle") - public List<Session2Token> getSession2Tokens(@NonNull UserHandle userHandle) { - Objects.requireNonNull(userHandle, "userHandle shouldn't be null"); - return getSession2Tokens(userHandle.getIdentifier()); - - } - - private List<Session2Token> getSession2Tokens(int userId) { - try { - ParceledListSlice slice = mService.getSession2Tokens(userId); - return slice == null ? new ArrayList<>() : slice.getList(); - } catch (RemoteException e) { - Log.e(TAG, "Failed to get session tokens", e); - } - return new ArrayList<>(); + return mCommunicationManager.getSession2Tokens(); } /** @@ -534,8 +501,7 @@ public final class MediaSessionManager { } if (shouldRegisterCallback) { try { - mService.registerRemoteSessionCallback( - mRemoteSessionCallbackStub); + mService.registerRemoteSessionCallback(mRemoteSessionCallbackStub); } catch (RemoteException e) { Log.e(TAG, "Failed to register remote volume controller callback", e); } diff --git a/media/java/android/media/soundtrigger/OWNERS b/media/java/android/media/soundtrigger/OWNERS index 6a351d396836..e5d037003ac4 100644 --- a/media/java/android/media/soundtrigger/OWNERS +++ b/media/java/android/media/soundtrigger/OWNERS @@ -1 +1,2 @@ +ytai@google.com elaurent@google.com diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/AudioAttributesUnitTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/AudioAttributesUnitTest.java new file mode 100644 index 000000000000..3a4bec046da9 --- /dev/null +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/AudioAttributesUnitTest.java @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.mediaframeworktest.unit; + +import static org.junit.Assert.assertEquals; + +import android.media.AudioAttributes; + +import androidx.test.runner.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(AndroidJUnit4.class) +public class AudioAttributesUnitTest { + + @Test + public void testUsageToString_returnCorrectStrings() { + assertEquals("USAGE_UNKNOWN", AudioAttributes.usageToString(AudioAttributes.USAGE_UNKNOWN)); + assertEquals("USAGE_MEDIA", AudioAttributes.usageToString(AudioAttributes.USAGE_MEDIA)); + assertEquals("USAGE_VOICE_COMMUNICATION", + AudioAttributes.usageToString(AudioAttributes.USAGE_VOICE_COMMUNICATION)); + assertEquals("USAGE_VOICE_COMMUNICATION_SIGNALLING", + AudioAttributes.usageToString( + AudioAttributes.USAGE_VOICE_COMMUNICATION_SIGNALLING)); + assertEquals("USAGE_ALARM", AudioAttributes.usageToString(AudioAttributes.USAGE_ALARM)); + assertEquals("USAGE_NOTIFICATION", + AudioAttributes.usageToString(AudioAttributes.USAGE_NOTIFICATION)); + assertEquals("USAGE_NOTIFICATION_RINGTONE", + AudioAttributes.usageToString(AudioAttributes.USAGE_NOTIFICATION_RINGTONE)); + assertEquals("USAGE_NOTIFICATION_COMMUNICATION_REQUEST", + AudioAttributes.usageToString( + AudioAttributes.USAGE_NOTIFICATION_COMMUNICATION_REQUEST)); + assertEquals("USAGE_NOTIFICATION_COMMUNICATION_INSTANT", + AudioAttributes.usageToString( + AudioAttributes.USAGE_NOTIFICATION_COMMUNICATION_INSTANT)); + assertEquals("USAGE_NOTIFICATION_COMMUNICATION_DELAYED", + AudioAttributes.usageToString( + AudioAttributes.USAGE_NOTIFICATION_COMMUNICATION_DELAYED)); + assertEquals("USAGE_NOTIFICATION_EVENT", + AudioAttributes.usageToString(AudioAttributes.USAGE_NOTIFICATION_EVENT)); + assertEquals("USAGE_ASSISTANCE_ACCESSIBILITY", + AudioAttributes.usageToString(AudioAttributes.USAGE_ASSISTANCE_ACCESSIBILITY)); + assertEquals("USAGE_ASSISTANCE_NAVIGATION_GUIDANCE", + AudioAttributes.usageToString( + AudioAttributes.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE)); + assertEquals("USAGE_ASSISTANCE_SONIFICATION", + AudioAttributes.usageToString(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION)); + assertEquals("USAGE_GAME", AudioAttributes.usageToString(AudioAttributes.USAGE_GAME)); + assertEquals("USAGE_ASSISTANT", + AudioAttributes.usageToString(AudioAttributes.USAGE_ASSISTANT)); + assertEquals("USAGE_CALL_ASSISTANT", + AudioAttributes.usageToString(AudioAttributes.USAGE_CALL_ASSISTANT)); + assertEquals("USAGE_EMERGENCY", + AudioAttributes.usageToString(AudioAttributes.USAGE_EMERGENCY)); + assertEquals("USAGE_SAFETY", AudioAttributes.usageToString(AudioAttributes.USAGE_SAFETY)); + assertEquals("USAGE_VEHICLE_STATUS", + AudioAttributes.usageToString(AudioAttributes.USAGE_VEHICLE_STATUS)); + assertEquals("USAGE_ANNOUNCEMENT", + AudioAttributes.usageToString(AudioAttributes.USAGE_ANNOUNCEMENT)); + } + + @Test + public void testUsageToString_unknownUsage() { + assertEquals("unknown usage -1", AudioAttributes.usageToString(-1)); + } +} diff --git a/packages/Connectivity/framework/src/android/net/NetworkRequest.java b/packages/Connectivity/framework/src/android/net/NetworkRequest.java index 4e3085f4704d..b4a651c0607e 100644 --- a/packages/Connectivity/framework/src/android/net/NetworkRequest.java +++ b/packages/Connectivity/framework/src/android/net/NetworkRequest.java @@ -16,6 +16,22 @@ package android.net; +import static android.net.NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL; +import static android.net.NetworkCapabilities.NET_CAPABILITY_DUN; +import static android.net.NetworkCapabilities.NET_CAPABILITY_FOREGROUND; +import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET; +import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED; +import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED; +import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED; +import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING; +import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED; +import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED; +import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN; +import static android.net.NetworkCapabilities.NET_CAPABILITY_PARTIAL_CONNECTIVITY; +import static android.net.NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED; +import static android.net.NetworkCapabilities.NET_CAPABILITY_TRUSTED; +import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED; + import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresPermission; @@ -30,6 +46,8 @@ import android.os.Process; import android.text.TextUtils; import android.util.proto.ProtoOutputStream; +import java.util.Arrays; +import java.util.List; import java.util.Objects; import java.util.Set; @@ -154,8 +172,30 @@ public class NetworkRequest implements Parcelable { * needed in terms of {@link NetworkCapabilities} features */ public static class Builder { + /** + * Capabilities that are currently compatible with VCN networks. + */ + private static final List<Integer> VCN_SUPPORTED_CAPABILITIES = Arrays.asList( + NET_CAPABILITY_CAPTIVE_PORTAL, + NET_CAPABILITY_DUN, + NET_CAPABILITY_FOREGROUND, + NET_CAPABILITY_INTERNET, + NET_CAPABILITY_NOT_CONGESTED, + NET_CAPABILITY_NOT_METERED, + NET_CAPABILITY_NOT_RESTRICTED, + NET_CAPABILITY_NOT_ROAMING, + NET_CAPABILITY_NOT_SUSPENDED, + NET_CAPABILITY_NOT_VPN, + NET_CAPABILITY_PARTIAL_CONNECTIVITY, + NET_CAPABILITY_TEMPORARILY_NOT_METERED, + NET_CAPABILITY_TRUSTED, + NET_CAPABILITY_VALIDATED); + private final NetworkCapabilities mNetworkCapabilities; + // A boolean that represents the user modified NOT_VCN_MANAGED capability. + private boolean mModifiedNotVcnManaged = false; + /** * Default constructor for Builder. */ @@ -177,6 +217,7 @@ public class NetworkRequest implements Parcelable { // maybeMarkCapabilitiesRestricted() doesn't add back. final NetworkCapabilities nc = new NetworkCapabilities(mNetworkCapabilities); nc.maybeMarkCapabilitiesRestricted(); + deduceNotVcnManagedCapability(nc); return new NetworkRequest(nc, ConnectivityManager.TYPE_NONE, ConnectivityManager.REQUEST_ID_UNSET, Type.NONE); } @@ -193,6 +234,9 @@ public class NetworkRequest implements Parcelable { */ public Builder addCapability(@NetworkCapabilities.NetCapability int capability) { mNetworkCapabilities.addCapability(capability); + if (capability == NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED) { + mModifiedNotVcnManaged = true; + } return this; } @@ -204,6 +248,9 @@ public class NetworkRequest implements Parcelable { */ public Builder removeCapability(@NetworkCapabilities.NetCapability int capability) { mNetworkCapabilities.removeCapability(capability); + if (capability == NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED) { + mModifiedNotVcnManaged = true; + } return this; } @@ -261,6 +308,9 @@ public class NetworkRequest implements Parcelable { @NonNull public Builder clearCapabilities() { mNetworkCapabilities.clearAll(); + // If the caller explicitly clear all capabilities, the NOT_VCN_MANAGED capabilities + // should not be add back later. + mModifiedNotVcnManaged = true; return this; } @@ -380,6 +430,25 @@ public class NetworkRequest implements Parcelable { mNetworkCapabilities.setSignalStrength(signalStrength); return this; } + + /** + * Deduce the NET_CAPABILITY_NOT_VCN_MANAGED capability from other capabilities + * and user intention, which includes: + * 1. For the requests that don't have anything besides + * {@link #VCN_SUPPORTED_CAPABILITIES}, add the NET_CAPABILITY_NOT_VCN_MANAGED to + * allow the callers automatically utilize VCN networks if available. + * 2. For the requests that explicitly add or remove NET_CAPABILITY_NOT_VCN_MANAGED, + * do not alter them to allow user fire request that suits their need. + * + * @hide + */ + private void deduceNotVcnManagedCapability(final NetworkCapabilities nc) { + if (mModifiedNotVcnManaged) return; + for (final int cap : nc.getCapabilities()) { + if (!VCN_SUPPORTED_CAPABILITIES.contains(cap)) return; + } + nc.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED); + } } // implement the Parcelable interface diff --git a/packages/Connectivity/framework/src/android/net/NetworkUtils.java b/packages/Connectivity/framework/src/android/net/NetworkUtils.java index 9ccb04a44af4..b5e8a614b8ea 100644 --- a/packages/Connectivity/framework/src/android/net/NetworkUtils.java +++ b/packages/Connectivity/framework/src/android/net/NetworkUtils.java @@ -91,7 +91,8 @@ public class NetworkUtils { * this socket will go directly to the underlying network, so its traffic will not be * forwarded through the VPN. */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553, + publicAlternatives = "Use {@link android.net.VpnService#protect} instead.") public static native boolean protectFromVpn(FileDescriptor fd); /** diff --git a/packages/Connectivity/framework/src/android/net/VpnTransportInfo.java b/packages/Connectivity/framework/src/android/net/VpnTransportInfo.java index 0242ba08742c..340141b78aa5 100644 --- a/packages/Connectivity/framework/src/android/net/VpnTransportInfo.java +++ b/packages/Connectivity/framework/src/android/net/VpnTransportInfo.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 The Android Open Source Project + * Copyright (C) 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/packages/Connectivity/framework/src/android/net/util/MultinetworkPolicyTracker.java b/packages/Connectivity/framework/src/android/net/util/MultinetworkPolicyTracker.java index 85e3fa3048ed..43fffd733e91 100644 --- a/packages/Connectivity/framework/src/android/net/util/MultinetworkPolicyTracker.java +++ b/packages/Connectivity/framework/src/android/net/util/MultinetworkPolicyTracker.java @@ -40,6 +40,8 @@ import com.android.internal.annotations.VisibleForTesting; import java.util.Arrays; import java.util.List; +import java.util.concurrent.Executor; +import java.util.concurrent.RejectedExecutionException; /** * A class to encapsulate management of the "Smart Networking" capability of @@ -73,6 +75,32 @@ public class MultinetworkPolicyTracker { private volatile int mMeteredMultipathPreference; private int mActiveSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; + // Mainline module can't use internal HandlerExecutor, so add an identical executor here. + private static class HandlerExecutor implements Executor { + @NonNull + private final Handler mHandler; + + HandlerExecutor(@NonNull Handler handler) { + mHandler = handler; + } + @Override + public void execute(Runnable command) { + if (!mHandler.post(command)) { + throw new RejectedExecutionException(mHandler + " is shutting down"); + } + } + } + + @VisibleForTesting + protected class ActiveDataSubscriptionIdChangedListener extends PhoneStateListener + implements PhoneStateListener.ActiveDataSubscriptionIdChangedListener { + @Override + public void onActiveDataSubscriptionIdChanged(int subId) { + mActiveSubId = subId; + reevaluateInternal(); + } + } + public MultinetworkPolicyTracker(Context ctx, Handler handler) { this(ctx, handler, null); } @@ -93,14 +121,8 @@ public class MultinetworkPolicyTracker { } }; - ctx.getSystemService(TelephonyManager.class).listen( - new PhoneStateListener(handler.getLooper()) { - @Override - public void onActiveDataSubscriptionIdChanged(int subId) { - mActiveSubId = subId; - reevaluateInternal(); - } - }, PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE); + ctx.getSystemService(TelephonyManager.class).registerPhoneStateListener( + new HandlerExecutor(handler), new ActiveDataSubscriptionIdChangedListener()); updateAvoidBadWifi(); updateMeteredMultipathPreference(); diff --git a/packages/InputDevices/res/values-eu/strings.xml b/packages/InputDevices/res/values-eu/strings.xml index 0346d74ca7a7..513eba2ddc6d 100644 --- a/packages/InputDevices/res/values-eu/strings.xml +++ b/packages/InputDevices/res/values-eu/strings.xml @@ -42,7 +42,7 @@ <string name="keyboard_layout_greek" msgid="7289253560162386040">"Greziarra"</string> <string name="keyboard_layout_hebrew" msgid="7241473985890173812">"Hebrearra"</string> <string name="keyboard_layout_lithuanian" msgid="6943110873053106534">"Lituaniera"</string> - <string name="keyboard_layout_spanish_latin" msgid="5690539836069535697">"Espainiera (Latinoamerika)"</string> + <string name="keyboard_layout_spanish_latin" msgid="5690539836069535697">"Espainiarra (Latinoamerika)"</string> <string name="keyboard_layout_latvian" msgid="4405417142306250595">"Letoniera"</string> <string name="keyboard_layout_persian" msgid="3920643161015888527">"Persiarra"</string> <string name="keyboard_layout_azerbaijani" msgid="7315895417176467567">"Azerbaijandarra"</string> diff --git a/packages/LocalTransport/src/com/android/localtransport/LocalTransport.java b/packages/LocalTransport/src/com/android/localtransport/LocalTransport.java index c9d8a8198ca4..139c8e59a148 100644 --- a/packages/LocalTransport/src/com/android/localtransport/LocalTransport.java +++ b/packages/LocalTransport/src/com/android/localtransport/LocalTransport.java @@ -162,6 +162,9 @@ public class LocalTransport extends BackupTransport { if (mParameters.isFakeEncryptionFlag()) { flags |= BackupAgent.FLAG_FAKE_CLIENT_SIDE_ENCRYPTION_ENABLED; } + if (mParameters.isDeviceTransfer()) { + flags |= BackupAgent.FLAG_DEVICE_TO_DEVICE_TRANSFER; + } return flags; } diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml index 4b253c459b83..eafc6147fae8 100644 --- a/packages/SettingsLib/res/values-af/strings.xml +++ b/packages/SettingsLib/res/values-af/strings.xml @@ -404,6 +404,7 @@ <string name="transcode_user_control" msgid="6176368544817731314">"Ignoreer kodewisselingverstekke"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"Aktiveer kodewisseling"</string> <string name="transcode_default" msgid="3784803084573509491">"Aanvaar dat programme moderne formate steun"</string> + <string name="transcode_notification" msgid="5560515979793436168">"Wys kodewisselingkennisgewings"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"Lopende dienste"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"Sien en beheer dienste wat tans aktief is"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"WebView-implementering"</string> diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml index 4982f820ff37..547d0af6200d 100644 --- a/packages/SettingsLib/res/values-am/strings.xml +++ b/packages/SettingsLib/res/values-am/strings.xml @@ -404,6 +404,7 @@ <string name="transcode_user_control" msgid="6176368544817731314">"የትራንስኮዲንግ ነባሪዎችን ሻር"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"ትራንስኮዲንግን ያንቁ"</string> <string name="transcode_default" msgid="3784803084573509491">"መተግበሪያዎች ዘመናዊ ቅርጸቶችን እንደሚደግፉ አድርገው ይቁጠሩ"</string> + <string name="transcode_notification" msgid="5560515979793436168">"ትራንስኮዲንግ ማሳወቂያዎችን አሳይ"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"አሂድ አገልግሎቶች"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"በአሁኑጊዜ እየሄዱ ያሉ አገልግሎቶችን ተቆጣጠር እና እይ"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"የWebView ትግበራ"</string> diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml index 5eaefd02483b..c6a1d18f9c1e 100644 --- a/packages/SettingsLib/res/values-ar/strings.xml +++ b/packages/SettingsLib/res/values-ar/strings.xml @@ -404,6 +404,7 @@ <string name="transcode_user_control" msgid="6176368544817731314">"إلغاء الإعدادات التلقائية لتحويل الترميز"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"تفعيل تحويل الترميز"</string> <string name="transcode_default" msgid="3784803084573509491">"افتراض أن التطبيق يتوافق مع التنسيقات الحديثة"</string> + <string name="transcode_notification" msgid="5560515979793436168">"إظهار إشعارات تحويل الترميز"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"الخدمات قيد التشغيل"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"عرض الخدمات قيد التشغيل في الوقت الحالي والتحكم فيها"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"تطبيق WebView"</string> diff --git a/packages/SettingsLib/res/values-as/strings.xml b/packages/SettingsLib/res/values-as/strings.xml index 571f7d00ef89..e9deb4641e46 100644 --- a/packages/SettingsLib/res/values-as/strings.xml +++ b/packages/SettingsLib/res/values-as/strings.xml @@ -404,6 +404,7 @@ <string name="transcode_user_control" msgid="6176368544817731314">"ট্ৰেন্সক’ডিং ডিফ’ল্ট অ’ভাৰৰাইড কৰক"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"ট্ৰেন্সক’ডিং সক্ষম কৰক"</string> <string name="transcode_default" msgid="3784803084573509491">"এপে আধুনিক ফৰ্মেট সমৰ্থন কৰে বুলি ধৰি লওক"</string> + <string name="transcode_notification" msgid="5560515979793436168">"ট্ৰান্সক\'ডিঙৰ জাননী দেখুৱাওক"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"চলিত সেৱা"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"বৰ্তমান চলি থকা সেৱাসমূহ চাওক আৰু নিয়ন্ত্ৰণ কৰক"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"ৱেবভিউ প্ৰয়োগ"</string> diff --git a/packages/SettingsLib/res/values-az/strings.xml b/packages/SettingsLib/res/values-az/strings.xml index 36a13f50fe11..d04409cd5e56 100644 --- a/packages/SettingsLib/res/values-az/strings.xml +++ b/packages/SettingsLib/res/values-az/strings.xml @@ -404,6 +404,7 @@ <string name="transcode_user_control" msgid="6176368544817731314">"Yenidən kodlaşdırma defoltlarını əvəzləyin"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"Yenidən kodlaşdırmanı aktiv edin"</string> <string name="transcode_default" msgid="3784803084573509491">"Tətbiqlərin müasir formatları dəstəklədiyini qəbul edin"</string> + <string name="transcode_notification" msgid="5560515979793436168">"Kod dəyişmə bildirişlərini göstərin"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"İşləyən xidmətlər"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"Hazırda prosesdə olan xidmətləri görüntüləyin və onlara nəzarət edin"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"WebView icrası"</string> diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml index d7cc909fe15f..ecd70a285bd0 100644 --- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml +++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml @@ -404,6 +404,7 @@ <string name="transcode_user_control" msgid="6176368544817731314">"Zameni podrazumevana podešavanja transkodiranja"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"Omogući transkodiranje"</string> <string name="transcode_default" msgid="3784803084573509491">"Podrazumevaj da aplikacije podržavaju moderne formate"</string> + <string name="transcode_notification" msgid="5560515979793436168">"Prikazuj obaveštenja o transkodiranju"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"Pokrenute usluge"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"Prikaz i kontrola trenutno pokrenutih usluga"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"Primena WebView-a"</string> diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml index 01201b34f6a8..6a3b961d1c5c 100644 --- a/packages/SettingsLib/res/values-be/strings.xml +++ b/packages/SettingsLib/res/values-be/strings.xml @@ -404,6 +404,7 @@ <string name="transcode_user_control" msgid="6176368544817731314">"Перавызначыць стандартныя налады перакадзіравання"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"Уключыць перакадзіраванне"</string> <string name="transcode_default" msgid="3784803084573509491">"Лічыца, што праграмы падтрымліваюць сучасныя фарматы"</string> + <string name="transcode_notification" msgid="5560515979793436168">"Паказваць апавяшчэнні пра перакадзіраванне"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"Запушчаныя службы"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"Прагляд запушчаных службаў i кіраванне iмi"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"Рэалізацыя WebView"</string> diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml index 00f5e710b727..d2bf70565be9 100644 --- a/packages/SettingsLib/res/values-bg/strings.xml +++ b/packages/SettingsLib/res/values-bg/strings.xml @@ -404,6 +404,7 @@ <string name="transcode_user_control" msgid="6176368544817731314">"Отмяна на стандартните настройки за прекодирането"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"Активиране на прекодирането"</string> <string name="transcode_default" msgid="3784803084573509491">"Предполагане, че приложенията поддържат съвременни формати"</string> + <string name="transcode_notification" msgid="5560515979793436168">"Показване на известията за прекодиране"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"Изпълнявани услуги"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"Преглед и контрол върху изпълняващите се понастоящем услуги"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"Внедряване на WebView"</string> diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml index 43bb7581026c..3ccf0e426b77 100644 --- a/packages/SettingsLib/res/values-bn/strings.xml +++ b/packages/SettingsLib/res/values-bn/strings.xml @@ -404,6 +404,7 @@ <string name="transcode_user_control" msgid="6176368544817731314">"ট্রান্সকোডিং ডিফল্ট সেটিংস ওভাররাইড করুন"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"ট্রান্সকোডিং চালু করুন"</string> <string name="transcode_default" msgid="3784803084573509491">"অ্যাপ মর্ডার্ন ফর্ম্যাটে কাজ করবে বলে ধরে নিন"</string> + <string name="transcode_notification" msgid="5560515979793436168">"ট্রান্সকোডিং বিজ্ঞপ্তি দেখুন"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"এখন চলছে যে পরিষেবাগুলি"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"বর্তমান চলমান পরিষেবাগুলি দেখুন এবং নিয়ন্ত্রণ করুন"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"ওয়েবভিউ প্রয়োগ"</string> diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml index dacacfbb142d..f01eef340abc 100644 --- a/packages/SettingsLib/res/values-bs/strings.xml +++ b/packages/SettingsLib/res/values-bs/strings.xml @@ -404,6 +404,7 @@ <string name="transcode_user_control" msgid="6176368544817731314">"Zaobiđi zadane postavke transkodiranja"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"Omogući transkodiranje"</string> <string name="transcode_default" msgid="3784803084573509491">"Pretpostavi da aplikacije podržavaju moderne formate"</string> + <string name="transcode_notification" msgid="5560515979793436168">"Prikaži obavještenja o transkodiranju"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"Pokrenute usluge"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"Prikaz i kontrola trenutno pokrenutih usluga"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"Postavljanje WebViewa"</string> diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml index 17482ed18963..7069999fc8e7 100644 --- a/packages/SettingsLib/res/values-ca/strings.xml +++ b/packages/SettingsLib/res/values-ca/strings.xml @@ -404,6 +404,7 @@ <string name="transcode_user_control" msgid="6176368544817731314">"Substitueix els valors predeterminats de la transcodificació"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"Activa la transcodificació"</string> <string name="transcode_default" msgid="3784803084573509491">"Assumeix que les aplicacions són compatibles amb formats moderns"</string> + <string name="transcode_notification" msgid="5560515979793436168">"Mostra les notificacions de transcodificació"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"Serveis en execució"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"Visualitza i controla els serveis en execució"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"Implementació de WebView"</string> diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml index ddd5c523c8f9..c677feffc384 100644 --- a/packages/SettingsLib/res/values-cs/strings.xml +++ b/packages/SettingsLib/res/values-cs/strings.xml @@ -404,6 +404,7 @@ <string name="transcode_user_control" msgid="6176368544817731314">"Přepsat výchozí nastavení překódování"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"Povolit překódování"</string> <string name="transcode_default" msgid="3784803084573509491">"Předpokládat, že aplikace podporují moderní formáty"</string> + <string name="transcode_notification" msgid="5560515979793436168">"Zobrazit oznámení o překódování"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"Spuštěné služby"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"Umožňuje zobrazit a ovládat aktuálně spuštěné služby"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"Implementace WebView"</string> diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml index 421ed742bd23..84247a622740 100644 --- a/packages/SettingsLib/res/values-da/strings.xml +++ b/packages/SettingsLib/res/values-da/strings.xml @@ -404,6 +404,7 @@ <string name="transcode_user_control" msgid="6176368544817731314">"Tilsidesæt standardindstillingerne for omkodning"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"Aktivér omkodning"</string> <string name="transcode_default" msgid="3784803084573509491">"Gå ud fra, at apps understøtter moderne formater"</string> + <string name="transcode_notification" msgid="5560515979793436168">"Vis notifikationer for omkodning"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"Kørende tjenester"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"Vis og administrer kørende tjenester"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"WebView-implementering"</string> diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml index 7cb994cb06de..4cc79d32b797 100644 --- a/packages/SettingsLib/res/values-de/strings.xml +++ b/packages/SettingsLib/res/values-de/strings.xml @@ -404,6 +404,7 @@ <string name="transcode_user_control" msgid="6176368544817731314">"Standardeinstellungen für Transcodierung überschreiben"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"Transcodierung aktivieren"</string> <string name="transcode_default" msgid="3784803084573509491">"Voraussetzen, dass Apps moderne Formate unterstützen"</string> + <string name="transcode_notification" msgid="5560515979793436168">"Benachrichtigungen zur Transcodierung anzeigen"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"Aktive Dienste"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"Momentan ausgeführte Dienste anzeigen und steuern"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"WebView-Implementierung"</string> diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml index 7a73ccdf2c63..30705a1f6f62 100644 --- a/packages/SettingsLib/res/values-el/strings.xml +++ b/packages/SettingsLib/res/values-el/strings.xml @@ -404,6 +404,7 @@ <string name="transcode_user_control" msgid="6176368544817731314">"Παράκαμψη προεπιλογών διακωδικοποίησης"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"Ενεργοποίηση διακωδικοποίησης"</string> <string name="transcode_default" msgid="3784803084573509491">"Να θεωρείται ότι οι εφαρμογές χρησιμοποιούν σύγχρονες μορφές"</string> + <string name="transcode_notification" msgid="5560515979793436168">"Εμφάνιση ειδοποιήσεων διακωδικοποίησης"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"Υπηρεσίες που εκτελούνται"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"Προβολή και έλεγχος των εφαρμογών που εκτελούνται αυτή τη στιγμή"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"Υλοποίηση WebView"</string> diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml index 62419538309b..b3d80abfc0a2 100644 --- a/packages/SettingsLib/res/values-en-rAU/strings.xml +++ b/packages/SettingsLib/res/values-en-rAU/strings.xml @@ -404,6 +404,7 @@ <string name="transcode_user_control" msgid="6176368544817731314">"Override transcoding defaults"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"Enable transcoding"</string> <string name="transcode_default" msgid="3784803084573509491">"Assume apps support modern formats"</string> + <string name="transcode_notification" msgid="5560515979793436168">"Show transcoding notifications"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"Running services"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"View and control currently running services"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"WebView implementation"</string> diff --git a/packages/SettingsLib/res/values-en-rCA/strings.xml b/packages/SettingsLib/res/values-en-rCA/strings.xml index 198fee4b58af..ecf97ad07c85 100644 --- a/packages/SettingsLib/res/values-en-rCA/strings.xml +++ b/packages/SettingsLib/res/values-en-rCA/strings.xml @@ -404,6 +404,7 @@ <string name="transcode_user_control" msgid="6176368544817731314">"Override transcoding defaults"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"Enable transcoding"</string> <string name="transcode_default" msgid="3784803084573509491">"Assume apps support modern formats"</string> + <string name="transcode_notification" msgid="5560515979793436168">"Show transcoding notifications"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"Running services"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"View and control currently running services"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"WebView implementation"</string> diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml index 62419538309b..b3d80abfc0a2 100644 --- a/packages/SettingsLib/res/values-en-rGB/strings.xml +++ b/packages/SettingsLib/res/values-en-rGB/strings.xml @@ -404,6 +404,7 @@ <string name="transcode_user_control" msgid="6176368544817731314">"Override transcoding defaults"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"Enable transcoding"</string> <string name="transcode_default" msgid="3784803084573509491">"Assume apps support modern formats"</string> + <string name="transcode_notification" msgid="5560515979793436168">"Show transcoding notifications"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"Running services"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"View and control currently running services"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"WebView implementation"</string> diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml index 62419538309b..b3d80abfc0a2 100644 --- a/packages/SettingsLib/res/values-en-rIN/strings.xml +++ b/packages/SettingsLib/res/values-en-rIN/strings.xml @@ -404,6 +404,7 @@ <string name="transcode_user_control" msgid="6176368544817731314">"Override transcoding defaults"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"Enable transcoding"</string> <string name="transcode_default" msgid="3784803084573509491">"Assume apps support modern formats"</string> + <string name="transcode_notification" msgid="5560515979793436168">"Show transcoding notifications"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"Running services"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"View and control currently running services"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"WebView implementation"</string> diff --git a/packages/SettingsLib/res/values-en-rXC/strings.xml b/packages/SettingsLib/res/values-en-rXC/strings.xml index 27cd8b34889e..c3a3f3f484fb 100644 --- a/packages/SettingsLib/res/values-en-rXC/strings.xml +++ b/packages/SettingsLib/res/values-en-rXC/strings.xml @@ -404,6 +404,7 @@ <string name="transcode_user_control" msgid="6176368544817731314">"Override transcoding defaults"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"Enable transcoding"</string> <string name="transcode_default" msgid="3784803084573509491">"Assume apps support modern formats"</string> + <string name="transcode_notification" msgid="5560515979793436168">"Show transcoding notifications"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"Running services"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"View and control currently running services"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"WebView implementation"</string> diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml index 5e5b39a1bd0a..eb2a23b45e70 100644 --- a/packages/SettingsLib/res/values-es-rUS/strings.xml +++ b/packages/SettingsLib/res/values-es-rUS/strings.xml @@ -404,6 +404,7 @@ <string name="transcode_user_control" msgid="6176368544817731314">"Anular los valores predeterminados de transcodificación"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"Habilitar la transcodificación"</string> <string name="transcode_default" msgid="3784803084573509491">"Suponer que las apps admiten formatos modernos"</string> + <string name="transcode_notification" msgid="5560515979793436168">"Mostrar notificaciones de transcodificación"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"En ejecución"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"Ver y controlar servicios actuales en ejecución"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"Implementación de WebView"</string> diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml index 8d791771bf05..fe9984b701db 100644 --- a/packages/SettingsLib/res/values-es/strings.xml +++ b/packages/SettingsLib/res/values-es/strings.xml @@ -404,6 +404,7 @@ <string name="transcode_user_control" msgid="6176368544817731314">"Anular valores predeterminados de transcodificación"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"Habilitar transcodificación"</string> <string name="transcode_default" msgid="3784803084573509491">"Considerar que las aplicaciones admiten formatos modernos"</string> + <string name="transcode_notification" msgid="5560515979793436168">"Mostrar notificaciones de transcodificación"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"Servicios en ejecución"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"Ver y controlar los servicios en ejecución"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"Implementación de WebView"</string> diff --git a/packages/SettingsLib/res/values-et/strings.xml b/packages/SettingsLib/res/values-et/strings.xml index 18ee62371ef6..c70700ddc24c 100644 --- a/packages/SettingsLib/res/values-et/strings.xml +++ b/packages/SettingsLib/res/values-et/strings.xml @@ -404,6 +404,7 @@ <string name="transcode_user_control" msgid="6176368544817731314">"Alista transkodeerimise vaikeseaded"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"Luba transkodeerimine"</string> <string name="transcode_default" msgid="3784803084573509491">"Oleta, et rakendused toetavad kaasaegseid vorminguid"</string> + <string name="transcode_notification" msgid="5560515979793436168">"Kuva transkodeerimise märguanded"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"Käitatud teenused"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"Praegu käitatud teenuste vaatamine ja juhtimine"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"WebView\' rakendamine"</string> diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml index 71be593a055b..09c964aa9dd1 100644 --- a/packages/SettingsLib/res/values-eu/strings.xml +++ b/packages/SettingsLib/res/values-eu/strings.xml @@ -404,6 +404,7 @@ <string name="transcode_user_control" msgid="6176368544817731314">"Ez erabili transkodetzearen balio lehenetsiak"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"Gaitu transkodetzea"</string> <string name="transcode_default" msgid="3784803084573509491">"Arduratu aplikazioek formatu modernoak onartzeaz"</string> + <string name="transcode_notification" msgid="5560515979793436168">"Erakutsi transkodetze-jakinarazpenak"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"Abian diren zerbitzuak"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"Ikusi eta kontrolatu une honetan abian diren zerbitzuak"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"WebView inplementazioa"</string> diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml index 81a2cf888d1f..22cd6ae68de2 100644 --- a/packages/SettingsLib/res/values-fa/strings.xml +++ b/packages/SettingsLib/res/values-fa/strings.xml @@ -404,6 +404,7 @@ <string name="transcode_user_control" msgid="6176368544817731314">"ملغی کردن پیشفرضهای تراتبدیل"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"فعال کردن تراتبدیل"</string> <string name="transcode_default" msgid="3784803084573509491">"فرض شود برنامهها از قالبهای مدرن پشتیبانی میکنند"</string> + <string name="transcode_notification" msgid="5560515979793436168">"نمایش اعلانهای تراتبدیل"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"سرویسهای در حال اجرا"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"مشاهده و کنترل سرویسهای در حال اجرای فعلی"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"اجرای وبنما"</string> diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml index 0703c450a2ed..22dde690c3cf 100644 --- a/packages/SettingsLib/res/values-fi/strings.xml +++ b/packages/SettingsLib/res/values-fi/strings.xml @@ -404,6 +404,7 @@ <string name="transcode_user_control" msgid="6176368544817731314">"Ohita transkoodauksen oletukset"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"Salli transkoodaus"</string> <string name="transcode_default" msgid="3784803084573509491">"Oleta, että sovellukset tukevat nykyaikaisia formaatteja"</string> + <string name="transcode_notification" msgid="5560515979793436168">"Näytä transkoodausilmoituksia"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"Käynnissä olevat palvelut"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"Tarkastele ja hallitse käynnissä olevia palveluita."</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"WebView-käyttöönotto"</string> diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml index 5b8c93880446..d189f72aad65 100644 --- a/packages/SettingsLib/res/values-fr-rCA/strings.xml +++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml @@ -404,6 +404,7 @@ <string name="transcode_user_control" msgid="6176368544817731314">"Remplacer les valeurs par défaut de transcodage"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"Activer le transcodage"</string> <string name="transcode_default" msgid="3784803084573509491">"Présumer que les applications prennent en charge les formats modernes"</string> + <string name="transcode_notification" msgid="5560515979793436168">"Afficher les notifications de transcodage"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"Services en cours d\'exécution"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"Afficher et contrôler les services en cours d\'exécution"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"Mise en œuvre WebView"</string> diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml index b025357a4642..49d7faa63a3b 100644 --- a/packages/SettingsLib/res/values-fr/strings.xml +++ b/packages/SettingsLib/res/values-fr/strings.xml @@ -404,6 +404,7 @@ <string name="transcode_user_control" msgid="6176368544817731314">"Ignorer les paramètres de transcodage par défaut"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"Activer le transcodage"</string> <string name="transcode_default" msgid="3784803084573509491">"Supposer que les applications sont compatibles avec les formats modernes"</string> + <string name="transcode_notification" msgid="5560515979793436168">"Afficher les notifications de transcodage"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"Services en cours d\'exécution"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"Afficher et contrôler les services en cours d\'exécution"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"Mise en œuvre WebView"</string> diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml index d68595e98e04..0922c3dca3af 100644 --- a/packages/SettingsLib/res/values-gl/strings.xml +++ b/packages/SettingsLib/res/values-gl/strings.xml @@ -404,6 +404,7 @@ <string name="transcode_user_control" msgid="6176368544817731314">"Anular valores predeterminados de transcodificación"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"Activar transcodificación"</string> <string name="transcode_default" msgid="3784803084573509491">"Considerar que as aplicacións admiten formatos modernos"</string> + <string name="transcode_notification" msgid="5560515979793436168">"Mostrar notificacións de transcodificación"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"Servizos en uso"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"Comproba e controla os servizos actualmente en uso"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"Implementación de WebView"</string> diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml index e151ddb428d8..10c5cc87c6da 100644 --- a/packages/SettingsLib/res/values-gu/strings.xml +++ b/packages/SettingsLib/res/values-gu/strings.xml @@ -404,6 +404,7 @@ <string name="transcode_user_control" msgid="6176368544817731314">"ફૉર્મેટ બદલવાની પ્રક્રિયાના ડિફૉલ્ટ સેટિંગ ઓવરરાઇડ કરો"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"ફૉર્મેટ બદલવાની પ્રક્રિયા ચાલુ કરો"</string> <string name="transcode_default" msgid="3784803084573509491">"ધારો કે ઍપ આધુનિક ફૉર્મેટ પર કામ કરે છે"</string> + <string name="transcode_notification" msgid="5560515979793436168">"ફૉર્મેટ બદલવાની પ્રક્રિયાના નોટિફિકેશન બતાવો"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"ચાલુ સેવાઓ"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"હાલમાં ચાલતી સેવાઓ જુઓ અને નિયંત્રિત કરો"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"WebView અમલીકરણ"</string> diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml index beab7bdcc08e..ea25406b1541 100644 --- a/packages/SettingsLib/res/values-hi/strings.xml +++ b/packages/SettingsLib/res/values-hi/strings.xml @@ -404,6 +404,7 @@ <string name="transcode_user_control" msgid="6176368544817731314">"ट्रांसकोडिंग की डिफ़ॉल्ट सेटिंग बदलें"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"ट्रांसकोडिंग चालू करें"</string> <string name="transcode_default" msgid="3784803084573509491">"मानकर चलें कि ऐप्लिकेशन, नए फ़ॉर्मैट के साथ काम करेंगे"</string> + <string name="transcode_notification" msgid="5560515979793436168">"ट्रांसकोडिंग की सूचनाएं दिखाएं"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"चल रही सेवाएं"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"इस समय चल रही सेवाओं को देखें और नियंत्रित करें"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"वेबव्यू लागू करें"</string> diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml index 8989cc9c69db..27a7a6e7891a 100644 --- a/packages/SettingsLib/res/values-hr/strings.xml +++ b/packages/SettingsLib/res/values-hr/strings.xml @@ -404,6 +404,7 @@ <string name="transcode_user_control" msgid="6176368544817731314">"Nadjačaj zadane postavke konvertiranja"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"Omogući konvertiranje"</string> <string name="transcode_default" msgid="3784803084573509491">"Pretpostavi da aplikacije podržavaju moderne formate"</string> + <string name="transcode_notification" msgid="5560515979793436168">"Prikaži obavijesti o konvertiranju"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"Pokrenute usluge"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"Pregledajte i kontrolirajte pokrenute usluge"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"Implementacija WebViewa"</string> diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml index 7c5a1a004568..70a48b638506 100644 --- a/packages/SettingsLib/res/values-hu/strings.xml +++ b/packages/SettingsLib/res/values-hu/strings.xml @@ -404,6 +404,7 @@ <string name="transcode_user_control" msgid="6176368544817731314">"Az átkódolás alapértelmezett beállításainak felülbírálása"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"Átkódolás engedélyezése"</string> <string name="transcode_default" msgid="3784803084573509491">"Annak feltételezése, hogy az alkalmazások támogatják a modern formátumokat"</string> + <string name="transcode_notification" msgid="5560515979793436168">"Átkódolási értesítések megjelenítése"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"Futó szolgáltatások"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"A jelenleg futó szolgáltatások megtekintése és vezérlése"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"WebView-megvalósítás"</string> diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml index 6684d3507c77..c39e966d880a 100644 --- a/packages/SettingsLib/res/values-hy/strings.xml +++ b/packages/SettingsLib/res/values-hy/strings.xml @@ -404,6 +404,7 @@ <string name="transcode_user_control" msgid="6176368544817731314">"Չեղարկել վերակոդավորման կանխադրված կարգավորումները"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"Միացնել վերակոդավորումը"</string> <string name="transcode_default" msgid="3784803084573509491">"Ենթադրել, որ հավելվածներն աջակցում են ժամանակակից ձևաչափեր"</string> + <string name="transcode_notification" msgid="5560515979793436168">"Ցուցադրել անդրկոդավորման ծանուցումներ"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"Աշխատող ծառայություններ"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"Դիտել և վերահսկել ընթացիկ աշխատող ծառայությունները"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"WebView ծառայություն"</string> diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml index 075444cd04f8..037c1b3b3e76 100644 --- a/packages/SettingsLib/res/values-in/strings.xml +++ b/packages/SettingsLib/res/values-in/strings.xml @@ -404,6 +404,7 @@ <string name="transcode_user_control" msgid="6176368544817731314">"Ganti default transcoding"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"Aktifkan transcoding"</string> <string name="transcode_default" msgid="3784803084573509491">"Asumsikan aplikasi mendukung format modern"</string> + <string name="transcode_notification" msgid="5560515979793436168">"Tampilkan notifikasi transcoding"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"Layanan yang sedang berjalan"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"Melihat dan mengontrol layanan yang sedang berjalan"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"Penerapan WebView"</string> diff --git a/packages/SettingsLib/res/values-is/strings.xml b/packages/SettingsLib/res/values-is/strings.xml index b079f4d9b75e..3f8783053ba3 100644 --- a/packages/SettingsLib/res/values-is/strings.xml +++ b/packages/SettingsLib/res/values-is/strings.xml @@ -404,6 +404,7 @@ <string name="transcode_user_control" msgid="6176368544817731314">"Hnekkja sjálfgefinni umkóðun"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"Kveikja á umkóðun"</string> <string name="transcode_default" msgid="3784803084573509491">"Gera ráð fyrir að forrit styðji nútímasnið"</string> + <string name="transcode_notification" msgid="5560515979793436168">"Sýna umkóðunartilkynningar"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"Þjónustur í gangi"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"Skoða og stjórna þjónustum í gangi"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"Innleiðing WebView"</string> diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml index bf525c535583..80ab57b66548 100644 --- a/packages/SettingsLib/res/values-it/strings.xml +++ b/packages/SettingsLib/res/values-it/strings.xml @@ -404,6 +404,7 @@ <string name="transcode_user_control" msgid="6176368544817731314">"Sostituisci impostazioni predefinite transcodifica"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"Attiva transcodifica"</string> <string name="transcode_default" msgid="3784803084573509491">"Presupponi che le app supportino i formati moderni"</string> + <string name="transcode_notification" msgid="5560515979793436168">"Mostra notifiche relative alla transcodifica"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"Servizi in esecuzione"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"Visualizza e controlla i servizi attualmente in esecuzione"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"Implementazione di WebView"</string> diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml index 9055e77b08dd..4355f31e3ed1 100644 --- a/packages/SettingsLib/res/values-iw/strings.xml +++ b/packages/SettingsLib/res/values-iw/strings.xml @@ -404,6 +404,7 @@ <string name="transcode_user_control" msgid="6176368544817731314">"ביטול ברירות המחדל של המרת קידוד"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"הפעלת המרת קידוד"</string> <string name="transcode_default" msgid="3784803084573509491">"הנחת העבודה היא שאפליקציות תומכות בפורמטים מודרניים"</string> + <string name="transcode_notification" msgid="5560515979793436168">"הצגת התראות לגבי המרת קידוד"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"שירותים פועלים"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"הצגת השירותים הפועלים כעת ושליטה בהם"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"יישום WebView"</string> diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml index 7fa0df93e2ce..ea4a683dd283 100644 --- a/packages/SettingsLib/res/values-ja/strings.xml +++ b/packages/SettingsLib/res/values-ja/strings.xml @@ -404,6 +404,7 @@ <string name="transcode_user_control" msgid="6176368544817731314">"デフォルトのコード変換をオーバーライド"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"コード変換を有効にする"</string> <string name="transcode_default" msgid="3784803084573509491">"アプリによる最新形式のサポートを想定"</string> + <string name="transcode_notification" msgid="5560515979793436168">"コード変換に関する通知の表示"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"実行中のサービス"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"現在実行中のサービスを表示して制御する"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"WebView の実装"</string> diff --git a/packages/SettingsLib/res/values-ka/strings.xml b/packages/SettingsLib/res/values-ka/strings.xml index 7dd1eee09f83..5798a46e7c99 100644 --- a/packages/SettingsLib/res/values-ka/strings.xml +++ b/packages/SettingsLib/res/values-ka/strings.xml @@ -404,6 +404,7 @@ <string name="transcode_user_control" msgid="6176368544817731314">"ტრანსკოდირების ნაგულისხმევების უგულებელყოფა"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"ტრანსკოდირების ჩართვა"</string> <string name="transcode_default" msgid="3784803084573509491">"დაშვება, რომ აპებს აქვთ თანამედროვე ფორმატების მხარდაჭერა"</string> + <string name="transcode_notification" msgid="5560515979793436168">"ტრანსკოდირების შეტყობინებების ჩვენება"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"მიმდინარე სერვისები"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"ამჟამად მოქმედი სერვისების ნახვა და მართვა"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"WebView რეალიზაცია"</string> diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml index 59b1d63af04f..5ce4e3a8f1c8 100644 --- a/packages/SettingsLib/res/values-kk/strings.xml +++ b/packages/SettingsLib/res/values-kk/strings.xml @@ -404,6 +404,7 @@ <string name="transcode_user_control" msgid="6176368544817731314">"Қайта қодтаудың әдепкі параметрлерін қайта анықтау"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"Қайта кодтауды қосу"</string> <string name="transcode_default" msgid="3784803084573509491">"Қолданбалар қазіргі заманғы форматтарды қолдайды делік"</string> + <string name="transcode_notification" msgid="5560515979793436168">"Қайта кодтау хабарландыруларын көрсету"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"Қосылып тұрған қызметтер"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"Қазір істеп тұрған қызметтерді көру және басқару"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"WebView қызметі"</string> diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml index b01839d2280f..e6f2cb03439e 100644 --- a/packages/SettingsLib/res/values-km/strings.xml +++ b/packages/SettingsLib/res/values-km/strings.xml @@ -404,6 +404,7 @@ <string name="transcode_user_control" msgid="6176368544817731314">"លុបពីលើលំនាំដើមនៃការបំប្លែងកូដ"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"បើកការបំប្លែងកូដ"</string> <string name="transcode_default" msgid="3784803084573509491">"សន្មតថាកម្មវិធីអាចប្រើទម្រង់ទំនើបបាន"</string> + <string name="transcode_notification" msgid="5560515979793436168">"បង្ហាញការជូនដំណឹងអំពីការបំប្លែងកូដ"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"សេវាកម្មកំពុងដំណើរការ"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"មើល និងគ្រប់គ្រងសេវាកម្មកំពុងដំណើរការបច្ចុប្បន្ន"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"ការអនុវត្ត WebView"</string> diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml index 217c917f1d2b..561e6bed887d 100644 --- a/packages/SettingsLib/res/values-kn/strings.xml +++ b/packages/SettingsLib/res/values-kn/strings.xml @@ -404,6 +404,8 @@ <string name="transcode_user_control" msgid="6176368544817731314">"ಟ್ರಾನ್ಸ್ಕೋಡಿಂಗ್ ಡೀಫಾಲ್ಟ್ಗಳನ್ನು ಅತಿಕ್ರಮಿಸಿ"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"ಟ್ರಾನ್ಸ್ಕೋಡಿಂಗ್ ಅನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಿ"</string> <string name="transcode_default" msgid="3784803084573509491">"ಆ್ಯಪ್ಗಳು ಆಧುನಿಕ ಫಾರ್ಮ್ಯಾಟ್ಗಳನ್ನು ಬೆಂಬಲಿಸುತ್ತದೆ ಎಂದು ಊಹಿಸಿ"</string> + <!-- no translation found for transcode_notification (5560515979793436168) --> + <skip /> <string name="runningservices_settings_title" msgid="6460099290493086515">"ರನ್ ಆಗುತ್ತಿರುವ ಸೇವೆಗಳು"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"ಈಗ ರನ್ ಆಗುತ್ತಿರುವ ಸೇವೆಗಳನ್ನು ವೀಕ್ಷಿಸಿ ಮತ್ತು ನಿಯಂತ್ರಿಸಿ"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"WebView ಹೊಂದಿಸಿ"</string> diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml index 0b8c71d0d9cd..cd3b8b842c66 100644 --- a/packages/SettingsLib/res/values-ko/strings.xml +++ b/packages/SettingsLib/res/values-ko/strings.xml @@ -404,6 +404,7 @@ <string name="transcode_user_control" msgid="6176368544817731314">"트랜스코딩 기본값 재정의"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"트랜스코딩 사용"</string> <string name="transcode_default" msgid="3784803084573509491">"앱이 최신 형식을 지원하는 것으로 가정"</string> + <string name="transcode_notification" msgid="5560515979793436168">"트랜스코딩 알림 표시"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"실행 중인 서비스"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"현재 실행 중인 서비스 보기 및 제어"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"WebView 구현"</string> diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml index cad00a38e89d..1990353f80b8 100644 --- a/packages/SettingsLib/res/values-ky/strings.xml +++ b/packages/SettingsLib/res/values-ky/strings.xml @@ -404,6 +404,7 @@ <string name="transcode_user_control" msgid="6176368544817731314">"Демейки жүргүзүлгөн транскоддоону өзгөртүп коюу"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"Транскоддоо жүргүзүүнү иштетүү"</string> <string name="transcode_default" msgid="3784803084573509491">"Колдонмолордо заманбап форматтар колдоого алынат"</string> + <string name="transcode_notification" msgid="5560515979793436168">"Транскоддоо билдирмелерин көрсөтүү"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"Иштеп жаткан кызматтар"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"Учурда иштеп жаткан кызматтарды көрүп, көзөмөлдөп турасыз"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"WebView кызматы"</string> diff --git a/packages/SettingsLib/res/values-lo/strings.xml b/packages/SettingsLib/res/values-lo/strings.xml index 5bd297e310f5..4997ea1a82c6 100644 --- a/packages/SettingsLib/res/values-lo/strings.xml +++ b/packages/SettingsLib/res/values-lo/strings.xml @@ -404,6 +404,7 @@ <string name="transcode_user_control" msgid="6176368544817731314">"ຍົກເລີກຄ່າເລີ່ມຕົ້ນການປ່ຽນຮູບແບບລະຫັດ"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"ເປີດການນຳໃຊ້ການປ່ຽນຮູບແບບລະຫັດ"</string> <string name="transcode_default" msgid="3784803084573509491">"ສົມມຸດວ່າແອັບຮອງຮັບຮູບແບບສະໄໝໃໝ່"</string> + <string name="transcode_notification" msgid="5560515979793436168">"ສະແດງການແຈ້ງເຕືອນການປ່ຽນຮູບແບບລະຫັດ"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"ບໍລິການທີ່ເຮັດວຽກຢູ່"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"ເບິ່ງ ແລະຈັດການບໍລິການທີ່ກຳລັງເຮັດວຽກຢູ່ໃນປັດຈຸບັນ"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"ການຈັດຕັ້ງປະຕິບັດ WebView"</string> diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml index 8c7485f29af7..ec3cb0d94a51 100644 --- a/packages/SettingsLib/res/values-lt/strings.xml +++ b/packages/SettingsLib/res/values-lt/strings.xml @@ -404,6 +404,7 @@ <string name="transcode_user_control" msgid="6176368544817731314">"Perkodavimo numatytųjų nustatymų nepaisymas"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"Perkodavimo įgalinimas"</string> <string name="transcode_default" msgid="3784803084573509491">"Manoma, kad programos palaiko modernius formatus"</string> + <string name="transcode_notification" msgid="5560515979793436168">"Rodyti perkodavimo pranešimus"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"Vykdomos paslaugos"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"Žiūrėti ir valdyti dabar vykdomas paslaugas"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"„WebView“ diegimas"</string> diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml index d8020c7c1d05..ff9f0a1649f9 100644 --- a/packages/SettingsLib/res/values-lv/strings.xml +++ b/packages/SettingsLib/res/values-lv/strings.xml @@ -404,6 +404,7 @@ <string name="transcode_user_control" msgid="6176368544817731314">"Ignorēt pārkodēšanas noklusējuma iestatījumus"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"Iespējot pārkodēšanu"</string> <string name="transcode_default" msgid="3784803084573509491">"Pieņemt, ka lietotnēs tiek atbalstīti moderni formāti"</string> + <string name="transcode_notification" msgid="5560515979793436168">"Rādīt paziņojumus par pārkodēšanu"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"Aktīvie pakalpojumi"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"Pašreiz darbojošos pakalpojumu skatīšana un vadība"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"WebView ieviešana"</string> diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml index e4c8425495b7..507f65c641b2 100644 --- a/packages/SettingsLib/res/values-mk/strings.xml +++ b/packages/SettingsLib/res/values-mk/strings.xml @@ -404,6 +404,7 @@ <string name="transcode_user_control" msgid="6176368544817731314">"Отфрли стандардни вредности за транскодирање"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"Овозможи транскодирање"</string> <string name="transcode_default" msgid="3784803084573509491">"Претпостави дека апликациите поддржуваат модерни формати"</string> + <string name="transcode_notification" msgid="5560515979793436168">"Прикажувај известувања за транскодирање"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"Активни услуги"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"Погледнете и контролирајте услуги што се моментално активни"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"Воведување WebView"</string> diff --git a/packages/SettingsLib/res/values-ml/strings.xml b/packages/SettingsLib/res/values-ml/strings.xml index 28422c930683..8a09801502e1 100644 --- a/packages/SettingsLib/res/values-ml/strings.xml +++ b/packages/SettingsLib/res/values-ml/strings.xml @@ -404,6 +404,7 @@ <string name="transcode_user_control" msgid="6176368544817731314">"ട്രാൻസ്കോഡ് ചെയ്യൽ ഡിഫോൾട്ടുകൾ അസാധുവാക്കുക"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"ട്രാൻസ്കോഡ് ചെയ്യൽ പ്രവർത്തനക്ഷമമാക്കുക"</string> <string name="transcode_default" msgid="3784803084573509491">"ആപ്പുകൾ ആധുനിക ഫോർമാറ്റുകളെ പിന്തുണയ്ക്കുമെന്ന് കരുതുക"</string> + <string name="transcode_notification" msgid="5560515979793436168">"ട്രാൻസ്കോഡ് ചെയ്യൽ അറിയിപ്പുകൾ കാണിക്കുക"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"പ്രവർത്തിക്കുന്ന സേവനങ്ങൾ"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"നിലവിൽ പ്രവർത്തിക്കുന്ന സേവനങ്ങൾ കാണുക, നിയന്ത്രിക്കുക"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"WebView നടപ്പാക്കൽ"</string> diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml index 0d78ea9ac2e3..27ca8f59739d 100644 --- a/packages/SettingsLib/res/values-mn/strings.xml +++ b/packages/SettingsLib/res/values-mn/strings.xml @@ -404,6 +404,7 @@ <string name="transcode_user_control" msgid="6176368544817731314">"Хөрвүүлгийн өгөгдмөлийг дарах"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"Хөрвүүлгийг идэвхжүүлэх"</string> <string name="transcode_default" msgid="3784803084573509491">"Аппыг орчин үеийн форматыг дэмждэг гэж үздэг"</string> + <string name="transcode_notification" msgid="5560515979793436168">"Хөрвүүлгийн мэдэгдэл харуулах"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"Ажиллаж байгаа үйлчилгээнүүд"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"Одоо ажиллаж байгаа үйлчилгээнүүдийг харах болон хянах"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"WebView хэрэгжилт"</string> diff --git a/packages/SettingsLib/res/values-mr/strings.xml b/packages/SettingsLib/res/values-mr/strings.xml index d27f7051d1f1..b6c546072473 100644 --- a/packages/SettingsLib/res/values-mr/strings.xml +++ b/packages/SettingsLib/res/values-mr/strings.xml @@ -404,6 +404,8 @@ <string name="transcode_user_control" msgid="6176368544817731314">"ट्रान्सकोडिंग डीफॉल्ट ओव्हरराइड करा"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"ट्रान्सकोडिंग सुरू करा"</string> <string name="transcode_default" msgid="3784803084573509491">"असे गृहीत धरा की, ॲप्स आधुनिक फॉरमॅटना सपोर्ट करतात"</string> + <!-- no translation found for transcode_notification (5560515979793436168) --> + <skip /> <string name="runningservices_settings_title" msgid="6460099290493086515">"सुरू सेवा"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"सध्या सुरू असलेल्या सेवा पहा आणि नियंत्रित करा"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"वेबदृश्य अंमलबजावणी"</string> diff --git a/packages/SettingsLib/res/values-ms/strings.xml b/packages/SettingsLib/res/values-ms/strings.xml index c5a2c6276318..53a4398d1b90 100644 --- a/packages/SettingsLib/res/values-ms/strings.xml +++ b/packages/SettingsLib/res/values-ms/strings.xml @@ -404,6 +404,7 @@ <string name="transcode_user_control" msgid="6176368544817731314">"Batalkan transpengekodan lalai"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"Dayakan transpengekodan"</string> <string name="transcode_default" msgid="3784803084573509491">"Mengambil alih sokongan apl format moden"</string> + <string name="transcode_notification" msgid="5560515979793436168">"Tunjukkan pemberitahuan transpengekodan"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"Perkhidmatan dijalankan"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"Lihat dan kawal perkhidmatan yang sedang dijalankan"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"Pelaksanaan WebView"</string> diff --git a/packages/SettingsLib/res/values-my/strings.xml b/packages/SettingsLib/res/values-my/strings.xml index ed34f7d3dd9e..0fef5abf782b 100644 --- a/packages/SettingsLib/res/values-my/strings.xml +++ b/packages/SettingsLib/res/values-my/strings.xml @@ -307,7 +307,7 @@ <string name="adb_keys_warning_message" msgid="2968555274488101220">"သင် ယခင်က ခွင့်ပြုခဲ့သော ကွန်ပျူတာအားလုံးမှ ယူအက်စ်ဘီ အမှားစစ်ခွင့်ကို ရုတ်သိမ်းမည်လား ?"</string> <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_title" msgid="6031809675604442636">"USB ဖြင့် အက်ပ်များစိစစ်ရန်"</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> @@ -404,6 +404,7 @@ <string name="transcode_user_control" msgid="6176368544817731314">"အမျိုးအစားပြောင်းခြင်း၏ မူရင်းဆက်တင်များကို အစားထိုးရန်"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"အမျိုးအစားပြောင်းခြင်းကို ဖွင့်ရန်"</string> <string name="transcode_default" msgid="3784803084573509491">"ဤအက်ပ်များက ဖော်မက်အသစ်များကို ပံ့ပိုးသည်"</string> + <string name="transcode_notification" msgid="5560515979793436168">"အမျိုးအစားပြောင်းခြင်း အကြောင်းကြားချက်များကို ပြရန်"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"အလုပ်လုပ်နေသောဝန်ဆောင်မှုများ"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"လက်ရှိ ဝန်ဆောင်မှုများကို ကြည့်ရှု ထိန်းသိမ်းသည်"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"WebView အကောင်အထည်ဖော်မှု"</string> diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml index 5366e7e13843..0ca8d51645e8 100644 --- a/packages/SettingsLib/res/values-nb/strings.xml +++ b/packages/SettingsLib/res/values-nb/strings.xml @@ -404,6 +404,7 @@ <string name="transcode_user_control" msgid="6176368544817731314">"Overstyr omkodingsstandarder"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"Slå på omkoding"</string> <string name="transcode_default" msgid="3784803084573509491">"Anta at apper støtter moderne formater"</string> + <string name="transcode_notification" msgid="5560515979793436168">"Vis omkodingsvarsler"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"Aktive tjenester"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"Se og kontrollér tjenester som kjører"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"WebView-implementering"</string> diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml index cde7b8033509..75b4537f6a8f 100644 --- a/packages/SettingsLib/res/values-ne/strings.xml +++ b/packages/SettingsLib/res/values-ne/strings.xml @@ -404,6 +404,8 @@ <string name="transcode_user_control" msgid="6176368544817731314">"ट्रान्सकोडिङसम्बन्धी पूर्वनिर्धारित सेटिङ परिवर्तन गर्नुहोस्"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"ट्रान्सकोडिङ अन गर्नुहोस्"</string> <string name="transcode_default" msgid="3784803084573509491">"एपहरूमा आधुनिक फर्म्याट प्रयोग गर्न मिल्छ भनी मान्नुहोस्"</string> + <!-- no translation found for transcode_notification (5560515979793436168) --> + <skip /> <string name="runningservices_settings_title" msgid="6460099290493086515">"चलिरहेका सेवाहरू"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"हाल चालु भइरहेका सेवाहरू हेर्नुहोस् र नियन्त्रण गर्नुहोस्"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"WebView कार्यान्वयन"</string> diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml index bb1402a93227..71d6acc6a22b 100644 --- a/packages/SettingsLib/res/values-nl/strings.xml +++ b/packages/SettingsLib/res/values-nl/strings.xml @@ -404,6 +404,7 @@ <string name="transcode_user_control" msgid="6176368544817731314">"Standaardwaarden voor transcodering overschrijven"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"Transcodering inschakelen"</string> <string name="transcode_default" msgid="3784803084573509491">"Aannemen dat apps moderne indelingen ondersteunen"</string> + <string name="transcode_notification" msgid="5560515979793436168">"Transcoderingsmeldingen laten zien"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"Actieve services"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"Services die momenteel actief zijn, weergeven en beheren"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"WebView-implementatie"</string> diff --git a/packages/SettingsLib/res/values-or/strings.xml b/packages/SettingsLib/res/values-or/strings.xml index 90fc8bce9339..1d6e34f7af23 100644 --- a/packages/SettingsLib/res/values-or/strings.xml +++ b/packages/SettingsLib/res/values-or/strings.xml @@ -404,6 +404,7 @@ <string name="transcode_user_control" msgid="6176368544817731314">"ଟ୍ରାନ୍ସକୋଡିଂ ଡିଫଲ୍ଟଗୁଡ଼ିକୁ ଓଭରରାଇଡ୍ କରନ୍ତୁ"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"ଟ୍ରାନ୍ସକୋଡିଂକୁ ସକ୍ଷମ କରନ୍ତୁ"</string> <string name="transcode_default" msgid="3784803084573509491">"ଧରିନିଅନ୍ତୁ ଆପଗୁଡ଼ିକ ଆଧୁନିକ ଫର୍ମାଟଗୁଡ଼ିକୁ ସମର୍ଥନ କରେ"</string> + <string name="transcode_notification" msgid="5560515979793436168">"ଟ୍ରାନ୍ସକୋଡିଂ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକୁ ଦେଖାନ୍ତୁ"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"ଚାଲୁଥିବା ସେବାଗୁଡ଼ିକ"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"ଏବେ ଚାଲୁଥିବା ସେବାଗୁଡ଼ିକୁ ଦେଖନ୍ତୁ ଓ ନିୟନ୍ତ୍ରଣ କରନ୍ତୁ"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"ୱେବ୍ଭ୍ୟୁ ପ୍ରୟୋଗ"</string> diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml index 4c20e196b1bb..9d91aae0a982 100644 --- a/packages/SettingsLib/res/values-pa/strings.xml +++ b/packages/SettingsLib/res/values-pa/strings.xml @@ -404,6 +404,8 @@ <string name="transcode_user_control" msgid="6176368544817731314">"ਟ੍ਰਾਂਸਕੋਡਿੰਗ ਦੀਆਂ ਪੂਰਵ-ਨਿਰਧਾਰਤ ਸੈਟਿੰਗਾਂ ਨੂੰ ਓਵਰਰਾਈਡ ਕਰੋ"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"ਟ੍ਰਾਂਸਕੋਡਿੰਗ ਚਾਲੂ ਕਰੋ"</string> <string name="transcode_default" msgid="3784803084573509491">"ਮੰਨ ਲਓ ਕਿ ਐਪਾਂ ਆਧੁਨਿਕ ਫਾਰਮੈਟਾਂ ਦਾ ਸਮਰਥਨ ਕਰਦੀਆਂ ਹਨ"</string> + <!-- no translation found for transcode_notification (5560515979793436168) --> + <skip /> <string name="runningservices_settings_title" msgid="6460099290493086515">"ਚੱਲ ਰਹੀਆਂ ਸੇਵਾਵਾਂ"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"ਇਸ ਵੇਲੇ ਚੱਲ ਰਹੀਆਂ ਸੇਵਾਵਾਂ ਦੇਖੋ ਅਤੇ ਇਹਨਾਂ ਨੂੰ ਕੰਟਰੋਲ ਕਰੋ"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"WebView ਅਮਲ"</string> diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml index 6d037d8e0aaf..f48b05f01ddc 100644 --- a/packages/SettingsLib/res/values-pl/strings.xml +++ b/packages/SettingsLib/res/values-pl/strings.xml @@ -404,6 +404,7 @@ <string name="transcode_user_control" msgid="6176368544817731314">"Zastąp ustawienia domyślne transkodowania"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"Włącz transkodowanie"</string> <string name="transcode_default" msgid="3784803084573509491">"Zakładaj, że aplikacje obsługują nowoczesne formaty"</string> + <string name="transcode_notification" msgid="5560515979793436168">"Pokaż powiadomienia transkodowania"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"Uruchomione usługi"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"Wyświetl obecnie uruchomione usługi i nimi zarządzaj"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"Implementacja WebView"</string> diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml index 3feed99762ef..b9c919129623 100644 --- a/packages/SettingsLib/res/values-pt-rBR/strings.xml +++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml @@ -404,6 +404,7 @@ <string name="transcode_user_control" msgid="6176368544817731314">"Substituir os padrões de transcodificação"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"Ativar transcodificação"</string> <string name="transcode_default" msgid="3784803084573509491">"Considerar que os apps são compatíveis com formatos modernos"</string> + <string name="transcode_notification" msgid="5560515979793436168">"Mostrar notificações de transcodificação"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"Serviços em execução"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"Visualizar e controlar os serviços em execução no momento"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"Implementação do WebView"</string> diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml index a886aa9d4cb4..57e38c078375 100644 --- a/packages/SettingsLib/res/values-pt-rPT/strings.xml +++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml @@ -404,6 +404,7 @@ <string name="transcode_user_control" msgid="6176368544817731314">"Substituir as predefinições da transcodificação"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"Ativar a transcodificação"</string> <string name="transcode_default" msgid="3784803084573509491">"Assumir que as apps suportam formatos modernos"</string> + <string name="transcode_notification" msgid="5560515979793436168">"Mostrar notificações de transcodificação"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"Serviços em execução"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"Ver e controlar os serviços actualmente em execução"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"Implementação WebView"</string> diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml index 3feed99762ef..b9c919129623 100644 --- a/packages/SettingsLib/res/values-pt/strings.xml +++ b/packages/SettingsLib/res/values-pt/strings.xml @@ -404,6 +404,7 @@ <string name="transcode_user_control" msgid="6176368544817731314">"Substituir os padrões de transcodificação"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"Ativar transcodificação"</string> <string name="transcode_default" msgid="3784803084573509491">"Considerar que os apps são compatíveis com formatos modernos"</string> + <string name="transcode_notification" msgid="5560515979793436168">"Mostrar notificações de transcodificação"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"Serviços em execução"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"Visualizar e controlar os serviços em execução no momento"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"Implementação do WebView"</string> diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml index 7fbe6225bc9c..c2da73c5679c 100644 --- a/packages/SettingsLib/res/values-ro/strings.xml +++ b/packages/SettingsLib/res/values-ro/strings.xml @@ -404,6 +404,7 @@ <string name="transcode_user_control" msgid="6176368544817731314">"Modificați setările prestabilite de transcodare"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"Activați transcodarea"</string> <string name="transcode_default" msgid="3784803084573509491">"Presupuneți că aplicațiile acceptă formatele moderne"</string> + <string name="transcode_notification" msgid="5560515979793436168">"Vedeți notificările privind transcodarea"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"Servicii în curs de funcționare"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"Vedeți și controlați serviciile care funcționează în prezent"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"Implementare WebView"</string> diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml index 1669df6136f0..efcce7556910 100644 --- a/packages/SettingsLib/res/values-ru/strings.xml +++ b/packages/SettingsLib/res/values-ru/strings.xml @@ -404,6 +404,7 @@ <string name="transcode_user_control" msgid="6176368544817731314">"Переопределять настройки транскодирования по умолчанию"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"Включить перекодирование"</string> <string name="transcode_default" msgid="3784803084573509491">"Считать, что приложения поддерживают современные форматы кодирования"</string> + <string name="transcode_notification" msgid="5560515979793436168">"Показывать уведомления о перекодировании"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"Работающие службы"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"Просмотр и управление работающими службами"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"Сервис WebView"</string> diff --git a/packages/SettingsLib/res/values-si/strings.xml b/packages/SettingsLib/res/values-si/strings.xml index 1fdd968c9b7e..590e0e4eded1 100644 --- a/packages/SettingsLib/res/values-si/strings.xml +++ b/packages/SettingsLib/res/values-si/strings.xml @@ -404,6 +404,7 @@ <string name="transcode_user_control" msgid="6176368544817731314">"ට්රාන්ස්කෝඩින් පෙරනිමි ප්රතික්ෂේප කරන්න"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"ට්රාන්ස්කෝඩින් සබල කරන්න"</string> <string name="transcode_default" msgid="3784803084573509491">"යෙදුම් නවීන ආකෘති සඳහා සහාය දක්වයි යැයි උපකල්පනය කරමු"</string> + <string name="transcode_notification" msgid="5560515979793436168">"ට්රාන්ස්කෝඩින් දැනුම්දීම් පෙන්වන්න"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"ධාවනය වන සේවා"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"දැනට ධාවනය වන සේවා බලන්න සහ පාලනය කරන්න"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"WebView ක්රියාත්මක කිරීම"</string> diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml index 03b454ea6a14..c817ed0e200c 100644 --- a/packages/SettingsLib/res/values-sk/strings.xml +++ b/packages/SettingsLib/res/values-sk/strings.xml @@ -404,6 +404,7 @@ <string name="transcode_user_control" msgid="6176368544817731314">"Prepísať predvolené nastavenia prekódovania"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"Povoliť prekódovanie"</string> <string name="transcode_default" msgid="3784803084573509491">"Prepdokladať, že aplikácie podporujú moderné formáty"</string> + <string name="transcode_notification" msgid="5560515979793436168">"Zobraziť upozornenia prekódovania"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"Spustené služby"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"Zobrazovať a riadiť aktuálne spustené služby"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"Implementácia WebView"</string> diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml index 73b48187747c..464b235e90da 100644 --- a/packages/SettingsLib/res/values-sl/strings.xml +++ b/packages/SettingsLib/res/values-sl/strings.xml @@ -404,6 +404,7 @@ <string name="transcode_user_control" msgid="6176368544817731314">"Preglasi privzete nastavitve prekodiranja"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"Omogoči prekodiranje"</string> <string name="transcode_default" msgid="3784803084573509491">"Aplikacije naj bi podpirale sodobne oblike zapisov"</string> + <string name="transcode_notification" msgid="5560515979793436168">"Prikaz obvestil o prekodiranju"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"Zagnane storitve"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"Preglejte in nadzorujte storitve, ki so trenutno zagnane"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"Izvedba spletnega pogleda"</string> diff --git a/packages/SettingsLib/res/values-sq/strings.xml b/packages/SettingsLib/res/values-sq/strings.xml index a07bb2bc1cfd..a2a63e165a96 100644 --- a/packages/SettingsLib/res/values-sq/strings.xml +++ b/packages/SettingsLib/res/values-sq/strings.xml @@ -404,6 +404,7 @@ <string name="transcode_user_control" msgid="6176368544817731314">"Anulo parazgjedhjet e transkodimit"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"Aktivizo transkodimin"</string> <string name="transcode_default" msgid="3784803084573509491">"Supozo se aplikacionet i mbështetin formatet moderne"</string> + <string name="transcode_notification" msgid="5560515979793436168">"Shfaq njoftimet e transkodimit"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"Shërbimet në ekzekutim"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"Shiko dhe kontrollo shërbimet që po ekzekutohen aktualisht"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"Zbatimi i WebView"</string> diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml index 0faaf83e65c9..2119303410e0 100644 --- a/packages/SettingsLib/res/values-sr/strings.xml +++ b/packages/SettingsLib/res/values-sr/strings.xml @@ -404,6 +404,7 @@ <string name="transcode_user_control" msgid="6176368544817731314">"Замени подразумевана подешавања транскодирања"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"Омогући транскодирање"</string> <string name="transcode_default" msgid="3784803084573509491">"Подразумевај да апликације подржавају модерне формате"</string> + <string name="transcode_notification" msgid="5560515979793436168">"Приказуј обавештења о транскодирању"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"Покренуте услуге"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"Приказ и контрола тренутно покренутих услуга"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"Примена WebView-а"</string> diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml index 87606d0f7ed5..c7a21692fea6 100644 --- a/packages/SettingsLib/res/values-sv/strings.xml +++ b/packages/SettingsLib/res/values-sv/strings.xml @@ -404,6 +404,7 @@ <string name="transcode_user_control" msgid="6176368544817731314">"Åsidosätta standardinställningar för omkodning"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"Aktivera omkodning"</string> <string name="transcode_default" msgid="3784803084573509491">"Anta att appar har stöd för moderna format"</string> + <string name="transcode_notification" msgid="5560515979793436168">"Visa aviseringar för omkodning"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"Aktiva tjänster"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"Visa och styr aktiva tjänster"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"WebView-implementering"</string> diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml index d479b0b174b8..60014f437c4b 100644 --- a/packages/SettingsLib/res/values-sw/strings.xml +++ b/packages/SettingsLib/res/values-sw/strings.xml @@ -404,6 +404,7 @@ <string name="transcode_user_control" msgid="6176368544817731314">"Batilisha chaguomsingi za kubadilisha miundo ya faili"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"Ruhusu ubadilishaji wa miundo ya faili"</string> <string name="transcode_default" msgid="3784803084573509491">"Chukulia kuwa programu zinatumia miundo ya kisasa"</string> + <string name="transcode_notification" msgid="5560515979793436168">"Onyesha arifa za kubadilisha muundo wa faili"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"Huduma zinazoendeshwa"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"Onyesha na udhibiti huduma zinazoendeshwa kwa sasa"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"Utekelezaji wa WebView"</string> diff --git a/packages/SettingsLib/res/values-ta/strings.xml b/packages/SettingsLib/res/values-ta/strings.xml index 247889bb4e83..82cce1275b10 100644 --- a/packages/SettingsLib/res/values-ta/strings.xml +++ b/packages/SettingsLib/res/values-ta/strings.xml @@ -404,6 +404,7 @@ <string name="transcode_user_control" msgid="6176368544817731314">"இயல்புநிலை குறிமாற்றங்களை மீறிச் செயல்படு"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"குறிமாற்றத்தை இயக்கு"</string> <string name="transcode_default" msgid="3784803084573509491">"ஆப்ஸ் மாடர்ன் வடிவங்களை ஆதரிக்கும்படி அமை"</string> + <string name="transcode_notification" msgid="5560515979793436168">"குறிமாற்ற அறிவிப்புகளைக் காட்டு"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"இயங்கும் சேவைகள்"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"தற்போது இயக்கத்தில் இருக்கும் சேவைகளைப் பார்த்து கட்டுப்படுத்து"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"WebView செயல்படுத்தல்"</string> diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml index b5d584f23d7e..3b04eb402585 100644 --- a/packages/SettingsLib/res/values-te/strings.xml +++ b/packages/SettingsLib/res/values-te/strings.xml @@ -404,6 +404,7 @@ <string name="transcode_user_control" msgid="6176368544817731314">"ట్రాన్స్కోడింగ్ ఆటోమేటిక్ సెట్టింగ్లను ఓవర్రైడ్ చేయండి"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"ట్రాన్స్కోడింగ్ను ఎనేబుల్ చేయండి"</string> <string name="transcode_default" msgid="3784803084573509491">"యాప్లు ఆధునిక ఫార్మాట్లకు సపోర్ట్ చేస్తాయని అనుకోండి"</string> + <string name="transcode_notification" msgid="5560515979793436168">"ట్రాన్స్కోడింగ్ నోటిఫికేషన్లను చూపండి"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"అమలులో ఉన్న సేవలు"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"ప్రస్తుతం అమలులో ఉన్న సేవలను వీక్షించండి మరియు నియంత్రించండి"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"వెబ్ వీక్షణ అమలు"</string> diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml index dc1514f2777b..a9703213813e 100644 --- a/packages/SettingsLib/res/values-th/strings.xml +++ b/packages/SettingsLib/res/values-th/strings.xml @@ -404,6 +404,7 @@ <string name="transcode_user_control" msgid="6176368544817731314">"ลบล้างค่าเริ่มต้นของการแปลง"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"เปิดใช้การแปลง"</string> <string name="transcode_default" msgid="3784803084573509491">"ถือว่าแอปรองรับรูปแบบสมัยใหม่"</string> + <string name="transcode_notification" msgid="5560515979793436168">"แสดงการแจ้งเตือนการแปลง"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"บริการที่ทำงานอยู่"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"ดูและควบคุมบริการที่ทำงานอยู่"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"การใช้งาน WebView"</string> diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml index 7c4ceec08dd1..bedd00511118 100644 --- a/packages/SettingsLib/res/values-tl/strings.xml +++ b/packages/SettingsLib/res/values-tl/strings.xml @@ -404,6 +404,7 @@ <string name="transcode_user_control" msgid="6176368544817731314">"I-override ang mga default ng pagta-transcode"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"I-enable ang pagta-transcode"</string> <string name="transcode_default" msgid="3784803084573509491">"Ipagpalagay na sinusuportahan ng mga app ang mga modernong format"</string> + <string name="transcode_notification" msgid="5560515979793436168">"Ipakita ang mga notification sa pag-transcode"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"Mga tumatakbong serbisyo"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"Tingnan at kontrolin ang mga kasalukuyang tumatakbong serbisyo"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"Pagpapatupad sa WebView"</string> diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml index 2b5dff15d101..2b2b44e0f9dc 100644 --- a/packages/SettingsLib/res/values-tr/strings.xml +++ b/packages/SettingsLib/res/values-tr/strings.xml @@ -404,6 +404,7 @@ <string name="transcode_user_control" msgid="6176368544817731314">"Kod dönüştürme varsayılanlarını geçersiz kıl"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"Kod dönüştürmeyi etkinleştir"</string> <string name="transcode_default" msgid="3784803084573509491">"Uygulamaların modern biçimleri desteklediğini varsay"</string> + <string name="transcode_notification" msgid="5560515979793436168">"Kod dönüştürme bildirimlerini göster"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"Çalışan hizmetler"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"Şu anda çalışan hizmetleri görüntüle ve denetle"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"Web Görünümü kullanımı"</string> diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml index 6fff40dab7f2..9c5e2aa858aa 100644 --- a/packages/SettingsLib/res/values-uk/strings.xml +++ b/packages/SettingsLib/res/values-uk/strings.xml @@ -404,6 +404,7 @@ <string name="transcode_user_control" msgid="6176368544817731314">"Замінити стандартні налаштування перекодування"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"Увімкнути перекодування"</string> <string name="transcode_default" msgid="3784803084573509491">"Вважати, що додатки підтримують сучасні формати"</string> + <string name="transcode_notification" msgid="5560515979793436168">"Показувати сповіщення про перекодування"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"Запущені сервіси"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"Переглянути й налаштувати запущені сервіси"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"Застосування WebView"</string> diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml index 055d9b86e3e0..ee06623240de 100644 --- a/packages/SettingsLib/res/values-ur/strings.xml +++ b/packages/SettingsLib/res/values-ur/strings.xml @@ -404,6 +404,7 @@ <string name="transcode_user_control" msgid="6176368544817731314">"ٹرانسکوڈنگ ڈیفالٹس کو اوور رائیڈ کریں"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"ٹرانسکوڈنگ فعال کریں"</string> <string name="transcode_default" msgid="3784803084573509491">"فرض کریں کہ ایپس جدید فارمیٹس کو سپورٹ کرتی ہیں"</string> + <string name="transcode_notification" msgid="5560515979793436168">"ٹرانسکوڈنگ اطلاعات دکھائیں"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"چل رہی سروسز"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"فی الحال چل رہی سروسز دیکھیں اور انہیں کنٹرول کریں"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"WebView کا نفاذ"</string> diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml index d897ba697580..29c0f91c4e60 100644 --- a/packages/SettingsLib/res/values-uz/strings.xml +++ b/packages/SettingsLib/res/values-uz/strings.xml @@ -404,6 +404,7 @@ <string name="transcode_user_control" msgid="6176368544817731314">"Transkripsiya parametrlarini almashtirish"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"Transkripsiyasini yoqish"</string> <string name="transcode_default" msgid="3784803084573509491">"Ilovalarda zamonaviy kodlash formatlari ishlaydi deb hisoblash"</string> + <string name="transcode_notification" msgid="5560515979793436168">"Transkripsiya bildirishnomalarini chiqarish"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"Ishlab turgan ilovalar"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"Ishlab turgan ilovalarni ko‘rish va boshqarish"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"WebView ta’minotchisi"</string> diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml index c6b7915b927d..39beecd0a87a 100644 --- a/packages/SettingsLib/res/values-vi/strings.xml +++ b/packages/SettingsLib/res/values-vi/strings.xml @@ -404,6 +404,7 @@ <string name="transcode_user_control" msgid="6176368544817731314">"Ghi đè tùy chọn chuyển mã mặc định"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"Bật tính năng chuyển mã"</string> <string name="transcode_default" msgid="3784803084573509491">"Giả định rằng các ứng dụng hỗ trợ định dạng hiện đại"</string> + <string name="transcode_notification" msgid="5560515979793436168">"Hiển thị thông báo chuyển mã"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"Các dịch vụ đang chạy"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"Xem và kiểm soát các dịch vụ đang chạy"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"Triển khai WebView"</string> diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml index 05b27d14c4f9..010a4dc9ea6c 100644 --- a/packages/SettingsLib/res/values-zh-rCN/strings.xml +++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml @@ -404,6 +404,7 @@ <string name="transcode_user_control" msgid="6176368544817731314">"覆盖转码默认设置"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"启用转码"</string> <string name="transcode_default" msgid="3784803084573509491">"假设应用支持现代格式"</string> + <string name="transcode_notification" msgid="5560515979793436168">"显示转码通知"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"正在运行的服务"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"查看和控制当前正在运行的服务"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"WebView 实现"</string> diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml index 13398d74588c..1e06a91859e2 100644 --- a/packages/SettingsLib/res/values-zh-rHK/strings.xml +++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml @@ -404,6 +404,7 @@ <string name="transcode_user_control" msgid="6176368544817731314">"覆寫轉碼預設設定"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"啟用轉碼功能"</string> <string name="transcode_default" msgid="3784803084573509491">"假設應用程式支援新型格式"</string> + <string name="transcode_notification" msgid="5560515979793436168">"顯示轉碼通知"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"執行中的服務"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"查看並控制目前正在執行中的服務"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"WebView 設置"</string> diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml index fead5e50f7e4..2c077e7991be 100644 --- a/packages/SettingsLib/res/values-zh-rTW/strings.xml +++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml @@ -404,6 +404,7 @@ <string name="transcode_user_control" msgid="6176368544817731314">"覆寫轉碼預設設定"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"啟用轉碼"</string> <string name="transcode_default" msgid="3784803084573509491">"假設應用程式支援新格式"</string> + <string name="transcode_notification" msgid="5560515979793436168">"顯示轉碼通知"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"正在運作的服務"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"查看並管理目前正在執行的服務"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"WebView 實作"</string> @@ -434,9 +435,9 @@ <skip /> <string name="power_discharge_by_enhanced" msgid="563438403581662942">"根據你的使用情形,目前電量為 <xliff:g id="LEVEL">%2$s</xliff:g>,預估可持續使用到<xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_enhanced" msgid="3268796172652988877">"根據你的使用情形,預估可持續使用到<xliff:g id="TIME">%1$s</xliff:g>"</string> - <string name="power_discharge_by" msgid="4113180890060388350">"目前電量 <xliff:g id="LEVEL">%2$s</xliff:g>,預估還能持續使用到<xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="power_discharge_by" msgid="4113180890060388350">"目前電量 <xliff:g id="LEVEL">%2$s</xliff:g>,預估可用到<xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only" msgid="92545648425937000">"預估電力大約可使用到<xliff:g id="TIME">%1$s</xliff:g>"</string> - <string name="power_discharge_by_only_short" msgid="5883041507426914446">"還能持續使用到<xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="power_discharge_by_only_short" msgid="5883041507426914446">"可用到<xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"電池電力可能於<xliff:g id="TIME">%1$s</xliff:g> 前耗盡"</string> <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"電池可用時間不到 <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> <string name="power_remaining_less_than_duration" msgid="318215464914990578">"電池可用時間不到 <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml index 79b8946f1e98..87cf75b0beaf 100644 --- a/packages/SettingsLib/res/values-zu/strings.xml +++ b/packages/SettingsLib/res/values-zu/strings.xml @@ -404,6 +404,7 @@ <string name="transcode_user_control" msgid="6176368544817731314">"Khipha okuzenzakalelayo kokudlulisela ikhodi"</string> <string name="transcode_enable_all" msgid="2411165920039166710">"Nika amandla ukudlulisela ikhodi"</string> <string name="transcode_default" msgid="3784803084573509491">"Kuthathe njengokungathi izinhlelo zokusebenza zisekela amafomethi esimanje"</string> + <string name="transcode_notification" msgid="5560515979793436168">"Bonisa izaziso zokudlulisela ikhodi"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"Amasevisi asebenzayo"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"Buka futhi ulawule amasevisi asebenzayo okwamanje"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"Ukufakwa ke-WebView"</string> diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTileView.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTileView.java index bcd28a6ab124..53f7e44bc25a 100644 --- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTileView.java +++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTileView.java @@ -50,6 +50,4 @@ public abstract class QSTileView extends LinearLayout { public abstract void onStateChanged(State state); public abstract int getDetailY(); - - public void setShowLabels(boolean show) {} } diff --git a/packages/SystemUI/res-product/values-az/strings.xml b/packages/SystemUI/res-product/values-az/strings.xml index ee86ae23d48f..c0668dbcea07 100644 --- a/packages/SystemUI/res-product/values-az/strings.xml +++ b/packages/SystemUI/res-product/values-az/strings.xml @@ -38,8 +38,8 @@ <string name="kg_failed_attempts_almost_at_erase_profile" product="default" msgid="3280816298678433681">"Telefonun kilidini açmaq üçün <xliff:g id="NUMBER_0">%1$d</xliff:g> dəfə yanlış cəhd etmisiniz. Daha <xliff:g id="NUMBER_1">%2$d</xliff:g> uğursuz cəhddən sonra iş profili silinəcək və bütün profil datası ləğv ediləcək."</string> <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="4417100487251371559">"Planşetin kilidini açmaq üçün <xliff:g id="NUMBER">%d</xliff:g> dəfə yanlış cəhd etmisiniz. İş profili silinəcək və bütün data ləğv ediləcək."</string> <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Telefonun kilidini açmaq üçün <xliff:g id="NUMBER">%d</xliff:g> dəfə yanlış cəhd etmisiniz. İş profili silinəcək və bütün data ləğv ediləcək."</string> - <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Kilid açma modelini <xliff:g id="NUMBER_0">%1$d</xliff:g> dəfə yanlış çəkmisiniz. Daha <xliff:g id="NUMBER_1">%2$d</xliff:g> uğursuz cəhddən sonra planşet kilidini e-poçt hesabınızla açmaq tələb olunacaq.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> saniyə sonra yenidən cəhd edin."</string> - <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Kilid açma modelini artıq <xliff:g id="NUMBER_0">%1$d</xliff:g> dəfə yanlış çəkmisiniz. Daha <xliff:g id="NUMBER_1">%2$d</xliff:g> uğursuz cəhddən sonra telefon kilidini e-poçt hesabınızla açmaq tələb olunacaq.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> saniyə sonra yenidən cəhd edin."</string> + <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Kilid açma modelini <xliff:g id="NUMBER_0">%1$d</xliff:g> dəfə yanlış çəkmisiniz. Daha <xliff:g id="NUMBER_1">%2$d</xliff:g> uğursuz cəhddən sonra planşet kilidini e-poçt hesabınızla açmaq tələb olunacaq.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> saniyə sonra cəhd edin."</string> + <string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Kilid açma modelini artıq <xliff:g id="NUMBER_0">%1$d</xliff:g> dəfə yanlış çəkmisiniz. Daha <xliff:g id="NUMBER_1">%2$d</xliff:g> uğursuz cəhddən sonra telefon kilidini e-poçt hesabınızla açmaq tələb olunacaq.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> saniyə sonra cəhd edin."</string> <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Daha çox seçim üçün telefonu kiliddən çıxarın"</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Daha çox seçim üçün planşeti kiliddən çıxarın"</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Daha çox seçim üçün cihazı kiliddən çıxarın"</string> diff --git a/packages/SystemUI/res/drawable/control_no_favorites_background.xml b/packages/SystemUI/res/drawable/control_no_favorites_background.xml index d895dd0c85c7..2165b12e5697 100644 --- a/packages/SystemUI/res/drawable/control_no_favorites_background.xml +++ b/packages/SystemUI/res/drawable/control_no_favorites_background.xml @@ -26,12 +26,4 @@ <corners android:radius="@dimen/control_corner_radius" /> </shape> </item> - <item> - <shape> - <stroke - android:width="1dp" - android:color="#4DFFFFFF" /> - <corners android:radius="@dimen/control_corner_radius"/> - </shape> - </item> </ripple> diff --git a/packages/SystemUI/res/drawable/controls_dialog_bg.xml b/packages/SystemUI/res/drawable/controls_dialog_bg.xml index cb4686dd04a7..1ccb176b8689 100644 --- a/packages/SystemUI/res/drawable/controls_dialog_bg.xml +++ b/packages/SystemUI/res/drawable/controls_dialog_bg.xml @@ -16,6 +16,6 @@ --> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> - <solid android:color="?android:attr/colorBackgroundFloating" /> + <solid android:color="?android:attr/colorBackground" /> <corners android:radius="@dimen/notification_corner_radius" /> </shape> diff --git a/packages/SystemUI/res/drawable/horizontal_ellipsis.xml b/packages/SystemUI/res/drawable/horizontal_ellipsis.xml new file mode 100644 index 000000000000..1800857a826c --- /dev/null +++ b/packages/SystemUI/res/drawable/horizontal_ellipsis.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2021 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0" + android:tint="?android:attr/colorBackgroundFloating" > + + <path + android:pathData="M6 10c-1.1 0-2 0.9-2 2s0.9 2 2 2 2-0.9 2-2-0.9-2-2-2zm12 0c-1.1 0-2 0.9-2 2s0.9 2 2 2 2-0.9 2-2-0.9-2-2-2zm-6 0c-1.1 0-2 0.9-2 2s0.9 2 2 2 2-0.9 2-2-0.9-2-2-2z" + android:fillColor="@android:color/white" /> +</vector>
\ No newline at end of file diff --git a/packages/SystemUI/res/drawable/volume_drawer_bg.xml b/packages/SystemUI/res/drawable/volume_drawer_bg.xml new file mode 100644 index 000000000000..f0e22926d07a --- /dev/null +++ b/packages/SystemUI/res/drawable/volume_drawer_bg.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2021 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> +<shape xmlns:android="http://schemas.android.com/apk/res/android" + android:paddingMode="stack" > + <size android:width="@dimen/volume_ringer_drawer_item_size" /> + <solid android:color="?android:attr/colorBackgroundFloating" /> + <corners android:radius="@dimen/volume_ringer_drawer_item_size_half" /> +</shape>
\ No newline at end of file diff --git a/packages/SystemUI/res/drawable/volume_drawer_selection_bg.xml b/packages/SystemUI/res/drawable/volume_drawer_selection_bg.xml new file mode 100644 index 000000000000..5e7cb12d1c5f --- /dev/null +++ b/packages/SystemUI/res/drawable/volume_drawer_selection_bg.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2021 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> +<shape xmlns:android="http://schemas.android.com/apk/res/android" + android:paddingMode="stack" > + <size + android:height="@dimen/volume_ringer_drawer_item_size" + android:width="@dimen/volume_ringer_drawer_item_size" /> + <solid android:color="?android:attr/colorAccent" /> + <corners android:radius="@dimen/volume_ringer_drawer_item_size_half" /> +</shape>
\ No newline at end of file diff --git a/packages/SystemUI/res/drawable/volume_row_seekbar.xml b/packages/SystemUI/res/drawable/volume_row_seekbar.xml new file mode 100644 index 000000000000..b0e0ed5079e6 --- /dev/null +++ b/packages/SystemUI/res/drawable/volume_row_seekbar.xml @@ -0,0 +1,56 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2021 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> + +<!-- SeekBar drawable for volume rows. This contains a background layer (with a solid round rect, + and a bottom-aligned icon) and a progress layer (with an accent-colored round rect and icon) + that moves up and down with the progress value. --> +<layer-list xmlns:android="http://schemas.android.com/apk/res/android" + android:paddingMode="stack" > + <item android:id="@android:id/background" + android:gravity="center_vertical|fill_horizontal"> + <layer-list> + <item android:id="@+id/volume_seekbar_background_solid"> + <shape> + <size android:height="@dimen/volume_dialog_panel_width" /> + <solid android:color="?android:attr/colorBackgroundFloating" /> + <corners android:radius="@dimen/volume_dialog_panel_width_half" /> + </shape> + </item> + <item + android:id="@+id/volume_seekbar_background_icon" + android:gravity="center_vertical|left" + android:height="@dimen/rounded_slider_icon_size" + android:width="@dimen/rounded_slider_icon_size" + android:left="@dimen/rounded_slider_icon_inset"> + <rotate + android:fromDegrees="-270" + android:toDegrees="-270"> + <!-- A placeholder drawable is required here - it'll be replaced in code. --> + <com.android.systemui.util.AlphaTintDrawableWrapper + android:drawable="@drawable/ic_volume_media" + android:tint="?android:attr/colorAccent" /> + </rotate> + </item> + </layer-list> + </item> + <item android:id="@android:id/progress" + android:gravity="center_vertical|fill_horizontal"> + <com.android.systemui.util.RoundedCornerProgressDrawable + android:drawable="@drawable/volume_row_seekbar_progress" + /> + </item> +</layer-list>
\ No newline at end of file diff --git a/packages/SystemUI/res/drawable/volume_row_seekbar_progress.xml b/packages/SystemUI/res/drawable/volume_row_seekbar_progress.xml new file mode 100644 index 000000000000..ef202360b1ce --- /dev/null +++ b/packages/SystemUI/res/drawable/volume_row_seekbar_progress.xml @@ -0,0 +1,44 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2021 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> + +<!-- Progress drawable for volume row SeekBars. This is the accent-colored round rect that moves up + and down as the progress value changes. --> +<layer-list xmlns:android="http://schemas.android.com/apk/res/android" + android:autoMirrored="true"> + <item android:id="@+id/volume_seekbar_progress_solid"> + <shape> + <size android:height="@dimen/volume_dialog_panel_width" /> + <solid android:color="?android:attr/colorAccent" /> + <corners android:radius="@dimen/volume_dialog_panel_width_half"/> + </shape> + </item> + <item + android:id="@+id/volume_seekbar_progress_icon" + android:gravity="center_vertical|right" + android:height="@dimen/rounded_slider_icon_size" + android:width="@dimen/rounded_slider_icon_size" + android:right="@dimen/rounded_slider_icon_inset"> + <rotate + android:fromDegrees="-270" + android:toDegrees="-270"> + <!-- A placeholder drawable is required here - it'll be replaced in code. --> + <com.android.systemui.util.AlphaTintDrawableWrapper + android:drawable="@drawable/ic_volume_media" + android:tint="?android:attr/colorBackgroundFloating" /> + </rotate> + </item> +</layer-list>
\ No newline at end of file diff --git a/packages/SystemUI/res/layout-land/volume_dialog.xml b/packages/SystemUI/res/layout-land/volume_dialog.xml index c420117073c5..237dc02e5d8c 100644 --- a/packages/SystemUI/res/layout-land/volume_dialog.xml +++ b/packages/SystemUI/res/layout-land/volume_dialog.xml @@ -32,105 +32,124 @@ android:gravity="right" android:layout_gravity="right" android:background="@android:color/transparent" - android:paddingRight="@dimen/volume_dialog_panel_transparent_padding_right" - android:paddingTop="@dimen/volume_dialog_panel_transparent_padding" - android:paddingBottom="@dimen/volume_dialog_panel_transparent_padding" + android:paddingRight="@dimen/volume_dialog_stream_padding" android:paddingLeft="@dimen/volume_dialog_panel_transparent_padding" android:clipToPadding="false"> - <FrameLayout - android:id="@+id/ringer" - android:layout_width="@dimen/volume_dialog_ringer_size" - android:layout_height="@dimen/volume_dialog_ringer_size" - android:layout_marginBottom="@dimen/volume_dialog_spacer" - android:gravity="right" - android:layout_gravity="right" - android:translationZ="@dimen/volume_dialog_elevation" - android:clipToPadding="false" - android:background="@drawable/rounded_bg_full"> - <com.android.keyguard.AlphaOptimizedImageButton - android:id="@+id/ringer_icon" - style="@style/VolumeButtons" - android:background="@drawable/rounded_ripple" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:scaleType="fitCenter" - android:padding="@dimen/volume_dialog_ringer_icon_padding" - android:tint="@color/accent_tint_color_selector" - android:layout_gravity="center" - android:soundEffectsEnabled="false" /> - - <include layout="@layout/volume_dnd_icon" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_marginRight="@dimen/volume_dialog_stream_padding" - android:layout_marginTop="6dp"/> - </FrameLayout> - + <!-- + Container for a) the ringer drawer and the caption button next to b) the volume rows. + --> <LinearLayout - android:id="@+id/main" android:layout_width="wrap_content" - android:minWidth="@dimen/volume_dialog_panel_width" android:layout_height="wrap_content" - android:layout_marginTop="68dp" - android:gravity="right" - android:layout_gravity="right" - android:orientation="vertical" - android:translationZ="@dimen/volume_dialog_elevation" + android:orientation="horizontal" android:clipChildren="false" - android:clipToPadding="false" - android:background="@drawable/rounded_bg_full" > - <LinearLayout - android:id="@+id/volume_dialog_rows" + android:clipToPadding="false"> + + <!-- The ringer drawer and the caption button. --> + <FrameLayout android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:minWidth="@dimen/volume_dialog_panel_width" - android:gravity="center" - android:orientation="horizontal" + android:layout_height="match_parent" android:paddingRight="@dimen/volume_dialog_stream_padding" - android:paddingLeft="@dimen/volume_dialog_stream_padding"> - <!-- volume rows added and removed here! :-) --> - </LinearLayout> + android:clipChildren="false" + android:clipToPadding="false" + android:orientation="vertical"> + + <include layout="@layout/volume_ringer_drawer" + android:layout_gravity="top|right"/> + + <FrameLayout + android:id="@+id/odi_captions" + android:layout_width="@dimen/volume_dialog_caption_size" + android:layout_height="@dimen/volume_dialog_caption_size" + android:gravity="center" + android:layout_gravity="bottom|right" + android:layout_marginBottom="@dimen/volume_dialog_tap_target_size" + android:clipToPadding="false"> + + <com.android.systemui.volume.CaptionsToggleImageButton + android:id="@+id/odi_captions_icon" + android:src="@drawable/ic_volume_odi_captions_disabled" + style="@style/VolumeButtons" + android:background="@drawable/rounded_ripple" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:tint="@color/caption_tint_color_selector" + android:layout_gravity="center" + android:soundEffectsEnabled="false" + sysui:optedOut="false"/> + + </FrameLayout> + + </FrameLayout> + <FrameLayout - android:id="@+id/settings_container" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:background="@drawable/rounded_bg_bottom_background"> + android:visibility="gone" + android:id="@+id/ringer" + android:layout_width="@dimen/volume_dialog_ringer_size" + android:layout_height="@dimen/volume_dialog_ringer_size" + android:layout_marginBottom="@dimen/volume_dialog_spacer" + android:gravity="right" + android:layout_gravity="right" + android:translationZ="@dimen/volume_dialog_elevation" + android:clipToPadding="false" + android:background="@drawable/rounded_bg_full"> <com.android.keyguard.AlphaOptimizedImageButton - android:id="@+id/settings" - android:src="@drawable/ic_tune_black_16dp" - android:layout_width="@dimen/volume_dialog_tap_target_size" - android:layout_height="@dimen/volume_dialog_tap_target_size" + android:id="@+id/ringer_icon" + style="@style/VolumeButtons" + android:background="@drawable/rounded_ripple" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:scaleType="fitCenter" + android:padding="@dimen/volume_dialog_ringer_icon_padding" + android:tint="@color/accent_tint_color_selector" android:layout_gravity="center" - android:contentDescription="@string/accessibility_volume_settings" - android:background="@drawable/ripple_drawable_20dp" - android:tint="?android:attr/textColorSecondary" android:soundEffectsEnabled="false" /> + + <include layout="@layout/volume_dnd_icon" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginRight="@dimen/volume_dialog_stream_padding" + android:layout_marginTop="6dp"/> </FrameLayout> - </LinearLayout> - <FrameLayout - android:id="@+id/odi_captions" - android:layout_width="@dimen/volume_dialog_caption_size" - android:layout_height="@dimen/volume_dialog_caption_size" - android:layout_marginRight="68dp" - android:gravity="right" - android:layout_gravity="right" - android:clipToPadding="false" - android:translationZ="@dimen/volume_dialog_elevation" - android:background="@drawable/rounded_bg_full"> - <com.android.systemui.volume.CaptionsToggleImageButton - android:id="@+id/odi_captions_icon" - android:src="@drawable/ic_volume_odi_captions_disabled" - style="@style/VolumeButtons" - android:background="@drawable/rounded_ripple" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:tint="@color/caption_tint_color_selector" - android:layout_gravity="center" - android:soundEffectsEnabled="false" - sysui:optedOut="false"/> - </FrameLayout> + <LinearLayout + android:id="@+id/main" + android:layout_width="wrap_content" + android:minWidth="@dimen/volume_dialog_panel_width" + android:layout_height="wrap_content" + android:gravity="right" + android:layout_gravity="right" + android:orientation="vertical" + android:clipChildren="false" + android:clipToPadding="false"> + <LinearLayout + android:id="@+id/volume_dialog_rows" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:minWidth="@dimen/volume_dialog_panel_width" + android:gravity="center" + android:orientation="horizontal"> + <!-- volume rows added and removed here! :-) --> + </LinearLayout> + <FrameLayout + android:id="@+id/settings_container" + android:layout_width="match_parent" + android:layout_height="wrap_content"> + <com.android.keyguard.AlphaOptimizedImageButton + android:id="@+id/settings" + android:src="@drawable/horizontal_ellipsis" + android:layout_width="@dimen/volume_dialog_tap_target_size" + android:layout_height="@dimen/volume_dialog_tap_target_size" + android:layout_gravity="center" + android:contentDescription="@string/accessibility_volume_settings" + android:background="@drawable/ripple_drawable_20dp" + android:tint="?android:attr/colorBackgroundFloating" + android:soundEffectsEnabled="false" /> + </FrameLayout> + </LinearLayout> + + </LinearLayout> <ViewStub android:id="@+id/odi_captions_tooltip_stub" diff --git a/packages/SystemUI/res/layout/qs_footer_impl.xml b/packages/SystemUI/res/layout/qs_footer_impl.xml index 0822947e8b16..93dd1a12f147 100644 --- a/packages/SystemUI/res/layout/qs_footer_impl.xml +++ b/packages/SystemUI/res/layout/qs_footer_impl.xml @@ -81,6 +81,22 @@ android:layout_height="match_parent" android:layout_weight="@integer/qs_footer_actions_weight" android:gravity="center_vertical|end" > + + <com.android.systemui.statusbar.AlphaOptimizedImageView + android:id="@+id/pm_lite" + android:layout_width="@dimen/qs_footer_action_button_size" + android:layout_height="@dimen/qs_footer_action_button_size" + android:background="?android:attr/selectableItemBackgroundBorderless" + android:clickable="true" + android:clipToPadding="false" + android:contentDescription="@string/accessibility_quick_settings_edit" + android:focusable="true" + android:padding="@dimen/qs_footer_icon_padding" + android:src="@*android:drawable/ic_lock_power_off" + android:tint="?android:attr/colorForeground" + android:visibility="gone" + /> + <com.android.systemui.statusbar.phone.MultiUserSwitch android:id="@+id/multi_user_switch" android:layout_width="@dimen/qs_footer_action_button_size" diff --git a/packages/SystemUI/res/layout/qs_paged_page_side_labels.xml b/packages/SystemUI/res/layout/qs_paged_page_side_labels.xml index ee54f1da8897..c83077371bb0 100644 --- a/packages/SystemUI/res/layout/qs_paged_page_side_labels.xml +++ b/packages/SystemUI/res/layout/qs_paged_page_side_labels.xml @@ -14,4 +14,10 @@ See the License for the specific language governing permissions and limitations under the License. --> -<include layout="@layout/qs_paged_page" /> +<com.android.systemui.qs.SideLabelTileLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/tile_page" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:clipChildren="false" + android:clipToPadding="false" /> diff --git a/packages/SystemUI/res/layout/volume_dialog.xml b/packages/SystemUI/res/layout/volume_dialog.xml index 1810c196c83d..6aac5a34821b 100644 --- a/packages/SystemUI/res/layout/volume_dialog.xml +++ b/packages/SystemUI/res/layout/volume_dialog.xml @@ -21,6 +21,8 @@ android:layout_height="wrap_content" android:gravity="right" android:layout_gravity="right" + android:paddingRight="@dimen/volume_dialog_stream_padding" + android:clipToPadding="false" android:background="@android:color/transparent" android:theme="@style/volume_dialog_theme"> @@ -34,13 +36,15 @@ android:layout_gravity="right" android:background="@android:color/transparent" android:paddingRight="@dimen/volume_dialog_panel_transparent_padding_right" - android:paddingTop="@dimen/volume_dialog_panel_transparent_padding" - android:paddingBottom="@dimen/volume_dialog_panel_transparent_padding" android:paddingLeft="@dimen/volume_dialog_panel_transparent_padding" android:orientation="vertical" - android:clipToPadding="false"> + android:clipToPadding="false" + android:clipChildren="false"> + + <include layout="@layout/volume_ringer_drawer" /> <FrameLayout + android:visibility="gone" android:id="@+id/ringer" android:layout_width="@dimen/volume_dialog_ringer_size" android:layout_height="@dimen/volume_dialog_ringer_size" @@ -77,10 +81,8 @@ android:gravity="right" android:layout_gravity="right" android:orientation="vertical" - android:translationZ="@dimen/volume_dialog_elevation" android:clipChildren="false" - android:clipToPadding="false" - android:background="@drawable/rounded_bg_full" > + android:clipToPadding="false" > <LinearLayout android:id="@+id/volume_dialog_rows" android:layout_width="wrap_content" @@ -88,24 +90,22 @@ android:minWidth="@dimen/volume_dialog_panel_width" android:gravity="center" android:orientation="horizontal" - android:paddingRight="@dimen/volume_dialog_stream_padding" - android:paddingLeft="@dimen/volume_dialog_stream_padding"> + android:layout_marginTop="@dimen/volume_row_slider_padding_start"> <!-- volume rows added and removed here! :-) --> </LinearLayout> <FrameLayout android:id="@+id/settings_container" android:layout_width="match_parent" - android:layout_height="wrap_content" - android:background="@drawable/rounded_bg_bottom_background"> + android:layout_height="wrap_content"> <com.android.keyguard.AlphaOptimizedImageButton android:id="@+id/settings" - android:src="@drawable/ic_tune_black_16dp" + android:src="@drawable/horizontal_ellipsis" android:layout_width="@dimen/volume_dialog_tap_target_size" android:layout_height="@dimen/volume_dialog_tap_target_size" android:layout_gravity="center" android:contentDescription="@string/accessibility_volume_settings" android:background="@drawable/ripple_drawable_20dp" - android:tint="?android:attr/textColorPrimary" + android:tint="?android:attr/colorBackgroundFloating" android:soundEffectsEnabled="false" /> </FrameLayout> </LinearLayout> @@ -118,7 +118,6 @@ android:gravity="right" android:layout_gravity="right" android:clipToPadding="false" - android:translationZ="@dimen/volume_dialog_elevation" android:background="@drawable/rounded_bg_full"> <com.android.systemui.volume.CaptionsToggleImageButton android:id="@+id/odi_captions_icon" @@ -127,7 +126,7 @@ android:background="@drawable/rounded_ripple" android:layout_width="match_parent" android:layout_height="match_parent" - android:tint="?android:attr/textColorPrimary" + android:tint="?android:attr/colorAccent" android:layout_gravity="center" android:soundEffectsEnabled="false" sysui:optedOut="false"/> diff --git a/packages/SystemUI/res/layout/volume_dialog_row.xml b/packages/SystemUI/res/layout/volume_dialog_row.xml index b9efc5be70c1..fda59b50104a 100644 --- a/packages/SystemUI/res/layout/volume_dialog_row.xml +++ b/packages/SystemUI/res/layout/volume_dialog_row.xml @@ -20,11 +20,12 @@ android:layout_width="@dimen/volume_dialog_panel_width" android:clipChildren="false" android:clipToPadding="false" + android:translationZ="@dimen/volume_dialog_elevation" android:theme="@style/volume_dialog_theme"> <LinearLayout android:layout_height="wrap_content" - android:layout_width="match_parent" + android:layout_width="@dimen/volume_dialog_panel_width" android:gravity="center" android:layout_gravity="center" android:orientation="vertical" > @@ -41,21 +42,23 @@ <FrameLayout android:id="@+id/volume_row_slider_frame" android:layout_width="match_parent" - android:layout_marginTop="@dimen/volume_dialog_slider_margin_top" - android:layout_marginBottom="@dimen/volume_dialog_slider_margin_bottom" - android:layoutDirection="rtl" - android:layout_height="@dimen/volume_dialog_slider_height"> + android:layout_height="@dimen/volume_row_slider_height"> + <include layout="@layout/volume_dnd_icon"/> <SeekBar android:id="@+id/volume_row_slider" + android:paddingLeft="0dp" + android:paddingRight="0dp" + android:paddingStart="0dp" + android:paddingEnd="0dp" android:clickable="true" - android:layout_width="@dimen/volume_dialog_slider_height" + android:layout_width="@dimen/volume_row_slider_height" android:layout_height="match_parent" - android:layoutDirection="rtl" android:layout_gravity="center" - android:rotation="90" /> + android:rotation="270" /> </FrameLayout> <com.android.keyguard.AlphaOptimizedImageButton + android:visibility="gone" android:id="@+id/volume_row_icon" style="@style/VolumeButtons" android:layout_width="@dimen/volume_dialog_tap_target_size" @@ -66,6 +69,4 @@ android:soundEffectsEnabled="false" /> </LinearLayout> - <include layout="@layout/volume_dnd_icon"/> - </FrameLayout> diff --git a/packages/SystemUI/res/layout/volume_ringer_drawer.xml b/packages/SystemUI/res/layout/volume_ringer_drawer.xml new file mode 100644 index 000000000000..d6e1782382fa --- /dev/null +++ b/packages/SystemUI/res/layout/volume_ringer_drawer.xml @@ -0,0 +1,126 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2021 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<!-- Contains the active ringer icon and a hidden drawer containing all three ringer options. --> +<FrameLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:gravity="center" + android:clipToPadding="false" + android:clipChildren="false"> + + <!-- Drawer view, invisible by default. --> + <FrameLayout + android:id="@+id/volume_drawer_container" + android:alpha="0.0" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:background="@drawable/volume_drawer_bg" + android:orientation="vertical"> + + <!-- View that is animated to a tapped ringer selection, so it appears selected. --> + <FrameLayout + android:id="@+id/volume_drawer_selection_background" + android:alpha="0.0" + android:layout_width="@dimen/volume_ringer_drawer_item_size" + android:layout_height="@dimen/volume_ringer_drawer_item_size" + android:layout_gravity="bottom|right" + android:background="@drawable/volume_drawer_selection_bg" /> + + <LinearLayout + android:id="@+id/volume_drawer_options" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical"> + + <FrameLayout + android:id="@+id/volume_drawer_vibrate" + android:layout_width="@dimen/volume_ringer_drawer_item_size" + android:layout_height="@dimen/volume_ringer_drawer_item_size" + android:description="@string/volume_ringer_hint_vibrate" + android:gravity="center"> + + <ImageView + android:id="@+id/volume_drawer_vibrate_icon" + android:layout_width="@dimen/volume_ringer_drawer_icon_size" + android:layout_height="@dimen/volume_ringer_drawer_icon_size" + android:layout_gravity="center" + android:tint="?android:attr/colorAccent" + android:src="@drawable/ic_volume_ringer_vibrate" /> + + </FrameLayout> + + <FrameLayout + android:id="@+id/volume_drawer_mute" + android:layout_width="@dimen/volume_ringer_drawer_item_size" + android:layout_height="@dimen/volume_ringer_drawer_item_size" + android:description="@string/volume_ringer_hint_mute" + android:gravity="center"> + + <ImageView + android:id="@+id/volume_drawer_mute_icon" + android:layout_width="@dimen/volume_ringer_drawer_icon_size" + android:layout_height="@dimen/volume_ringer_drawer_icon_size" + android:layout_gravity="center" + android:tint="?android:attr/colorAccent" + android:src="@drawable/ic_volume_ringer_mute" /> + + </FrameLayout> + + <FrameLayout + android:id="@+id/volume_drawer_normal" + android:layout_width="@dimen/volume_ringer_drawer_item_size" + android:layout_height="@dimen/volume_ringer_drawer_item_size" + android:description="@string/volume_ringer_hint_unmute" + android:gravity="center"> + + <ImageView + android:id="@+id/volume_drawer_normal_icon" + android:layout_width="@dimen/volume_ringer_drawer_icon_size" + android:layout_height="@dimen/volume_ringer_drawer_icon_size" + android:layout_gravity="center" + android:tint="?android:attr/colorAccent" + android:src="@drawable/ic_volume_ringer" /> + + </FrameLayout> + + </LinearLayout> + + </FrameLayout> + + <!-- The current ringer selection. When the drawer is opened, this animates to the corresponding + position in the drawer. When the drawer is closed, it animates back. --> + <FrameLayout + android:id="@+id/volume_new_ringer_active_icon_container" + android:layout_width="@dimen/volume_ringer_drawer_item_size" + android:layout_height="@dimen/volume_ringer_drawer_item_size" + android:layout_gravity="bottom|right" + android:description="@string/volume_ringer_change" + android:background="@drawable/volume_drawer_selection_bg"> + + <ImageView + android:id="@+id/volume_new_ringer_active_icon" + android:layout_width="@dimen/volume_ringer_drawer_icon_size" + android:layout_height="@dimen/volume_ringer_drawer_icon_size" + android:layout_gravity="center" + android:tint="?android:attr/colorBackgroundFloating" + android:src="@drawable/ic_volume_media" /> + + </FrameLayout> + +</FrameLayout>
\ No newline at end of file diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml index 68c7467b7bf2..c3a62b05db20 100644 --- a/packages/SystemUI/res/values-af/strings.xml +++ b/packages/SystemUI/res/values-af/strings.xml @@ -412,7 +412,8 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Tot sonsopkoms"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Aan om <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Tot <xliff:g id="TIME">%s</xliff:g>"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Verminder helderheid"</string> + <!-- no translation found for quick_settings_reduce_bright_colors_label (7537352080559075175) --> + <skip /> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC is gedeaktiveer"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC is geaktiveer"</string> @@ -446,6 +447,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Ontsluit om NFC te gebruik"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Hierdie toestel behoort aan jou organisasie"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"Hierdie toestel behoort aan <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"Swiep vanaf ikoon vir foon"</string> <string name="voice_hint" msgid="7476017460191291417">"Swiep vanaf ikoon vir stembystand"</string> <string name="camera_hint" msgid="4519495795000658637">"Swiep vanaf ikoon vir kamera"</string> @@ -625,6 +628,8 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Tik om te demp. Toeganklikheidsdienste kan dalk gedemp wees."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Tik om op vibreer te stel."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Tik om te demp."</string> + <!-- no translation found for volume_ringer_change (3574969197796055532) --> + <skip /> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"demp"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"ontdemp"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibreer"</string> @@ -1038,6 +1043,7 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"Voeg by"</string> <string name="controls_dialog_message" msgid="342066938390663844">"Voorgestel deur <xliff:g id="APP">%s</xliff:g>"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"Kontroles opgedateer"</string> + <string name="controls_tile_locked" msgid="731547768182831938">"Toestel is gesluit"</string> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN bevat letters of simbole"</string> <string name="controls_pin_verify" msgid="3452778292918877662">"Verifieer <xliff:g id="DEVICE">%s</xliff:g>"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"Verkeerde PIN"</string> diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml index 7618af8cfda4..0c0487dd8c10 100644 --- a/packages/SystemUI/res/values-am/strings.xml +++ b/packages/SystemUI/res/values-am/strings.xml @@ -412,7 +412,8 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"ጸሐይ እስክትወጣ ድረስ"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"<xliff:g id="TIME">%s</xliff:g> ላይ ይበራል"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"እስከ <xliff:g id="TIME">%s</xliff:g> ድረስ"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"ብሩህነትን ይቀንሱ"</string> + <!-- no translation found for quick_settings_reduce_bright_colors_label (7537352080559075175) --> + <skip /> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"ኤንኤፍሲ"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"ኤንኤፍሲ ተሰናክሏል"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"ኤንኤፍሲ ነቅቷል"</string> @@ -446,6 +447,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFCን ለመጠቀም ይክፈቱ"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"ይህ መሣሪያ የድርጅትዎ ነው"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"ይህ መሳሪያ ንብረትነቱ የ<xliff:g id="ORGANIZATION_NAME">%s</xliff:g> ነው"</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"ለስልክ ከአዶ ላይ ጠረግ ያድርጉ"</string> <string name="voice_hint" msgid="7476017460191291417">"ለድምጽ ረዳት ከአዶ ጠረግ ያድርጉ"</string> <string name="camera_hint" msgid="4519495795000658637">"ለካሜራ ከአዶ ላይ ጠረግ ያድርጉ"</string> @@ -625,6 +628,8 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s። ድምጸ-ከል ለማድረግ መታ ያድርጉ። የተደራሽነት አገልግሎቶች ድምጸ-ከል ሊደረግባቸው ይችላል።"</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s። ወደ ንዝረት ለማቀናበር መታ ያድርጉ።"</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s። ድምጸ-ከል ለማድረግ መታ ያድርጉ።"</string> + <!-- no translation found for volume_ringer_change (3574969197796055532) --> + <skip /> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"ድምጸ-ከል አድርግ"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"ድምጸ-ከልን አንሳ"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"ንዘር"</string> @@ -1038,6 +1043,7 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"አክል"</string> <string name="controls_dialog_message" msgid="342066938390663844">"በ<xliff:g id="APP">%s</xliff:g> የተጠቆመ"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"መቆጣጠሪያዎች ተዘምነዋል"</string> + <string name="controls_tile_locked" msgid="731547768182831938">"መሣሪያ ተቆልፏል"</string> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"ፒን ፊደሎችን ወይም ምልክቶችን ይይዛል"</string> <string name="controls_pin_verify" msgid="3452778292918877662">"<xliff:g id="DEVICE">%s</xliff:g> አረጋግጥ"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"የተሳሳተ ፒን"</string> diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml index 67622c7eed7b..ae8df906c974 100644 --- a/packages/SystemUI/res/values-ar/strings.xml +++ b/packages/SystemUI/res/values-ar/strings.xml @@ -420,7 +420,8 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"حتى شروق الشمس"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"تفعيل الوضع في <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"حتى <xliff:g id="TIME">%s</xliff:g>"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"تقليل السطوع"</string> + <!-- no translation found for quick_settings_reduce_bright_colors_label (7537352080559075175) --> + <skip /> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"تم إيقاف الاتصال القريب المدى"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"تم تفعيل الاتصال القريب المدى"</string> @@ -454,6 +455,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"افتح قفل الشاشة لاستخدام تقنية NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"هذا الجهاز يخص مؤسستك."</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"هذا الجهاز يخص <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>."</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"يمكنك التمرير سريعًا من الرمز لتشغيل الهاتف"</string> <string name="voice_hint" msgid="7476017460191291417">"يمكنك التمرير سريعًا من الرمز لتشغيل المساعد الصوتي"</string> <string name="camera_hint" msgid="4519495795000658637">"يمكنك التمرير سريعًا من الرمز لتشغيل الكاميرا"</string> @@ -637,6 +640,8 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. انقر للتجاهل. قد يتم تجاهل خدمات \"سهولة الاستخدام\"."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. انقر للتعيين على الاهتزاز."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. انقر لكتم الصوت."</string> + <!-- no translation found for volume_ringer_change (3574969197796055532) --> + <skip /> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"كتم الصوت"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"إعادة الصوت"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"اهتزاز"</string> @@ -1062,6 +1067,7 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"إضافة"</string> <string name="controls_dialog_message" msgid="342066938390663844">"اقتراح من <xliff:g id="APP">%s</xliff:g>"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"تم تعديل عناصر التحكّم."</string> + <string name="controls_tile_locked" msgid="731547768182831938">"الجهاز مُقفل."</string> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"يشتمل رقم التعريف الشخصي على أحرف أو رموز."</string> <string name="controls_pin_verify" msgid="3452778292918877662">"إثبات ملكية <xliff:g id="DEVICE">%s</xliff:g>"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"رقم تعريف شخصي خاطئ"</string> diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml index b1b28ad130bd..1f925708b2b7 100644 --- a/packages/SystemUI/res/values-as/strings.xml +++ b/packages/SystemUI/res/values-as/strings.xml @@ -412,7 +412,8 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"সূৰ্যোদয়লৈকে"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"<xliff:g id="TIME">%s</xliff:g>ত অন কৰক"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"<xliff:g id="TIME">%s</xliff:g> পৰ্যন্ত"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"উজ্জ্বলতা কমাওক"</string> + <!-- no translation found for quick_settings_reduce_bright_colors_label (7537352080559075175) --> + <skip /> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC নিষ্ক্ৰিয় হৈ আছে"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC সক্ষম হৈ আছে"</string> @@ -446,6 +447,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC ব্যৱহাৰ কৰিবলৈ আনলক কৰক"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"এই ডিভাইচটো আপোনাৰ প্ৰতিষ্ঠানৰ"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"এই ডিভাইচটো <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>ৰ"</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"ফ\'নৰ বাবে আইকনৰপৰা ছোৱাইপ কৰক"</string> <string name="voice_hint" msgid="7476017460191291417">"কণ্ঠধ্বনিৰে সহায়ৰ বাবে আইকনৰ পৰা ছোৱাইপ কৰক"</string> <string name="camera_hint" msgid="4519495795000658637">"কেমেৰা খুলিবলৈ আইকনৰপৰা ছোৱাইপ কৰক"</string> @@ -625,6 +628,8 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s। মিউট কৰিবলৈ টিপক। দিব্য়াংগসকলৰ বাবে থকা সেৱা মিউট হৈ থাকিব পাৰে।"</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s। কম্পন অৱস্থাত ছেট কৰিবলৈ টিপক।"</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s। মিউট কৰিবলৈ টিপক।"</string> + <!-- no translation found for volume_ringer_change (3574969197796055532) --> + <skip /> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"মিউট কৰক"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"আনমিউট কৰক"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"কম্পন কৰক"</string> @@ -1038,6 +1043,7 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"যোগ দিয়ক"</string> <string name="controls_dialog_message" msgid="342066938390663844">"<xliff:g id="APP">%s</xliff:g>এ পৰামৰ্শ হিচাপে আগবঢ়োৱা"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"নিয়ন্ত্ৰণসমূহ আপডে\'ট কৰা হৈছে"</string> + <string name="controls_tile_locked" msgid="731547768182831938">"ডিভাইচ লক হৈ আছে"</string> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"পিনত বৰ্ণ অথবা প্ৰতীকসমূহ থাকে"</string> <string name="controls_pin_verify" msgid="3452778292918877662">"<xliff:g id="DEVICE">%s</xliff:g> সত্যাপন কৰক"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"ভুল পিন"</string> diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml index fed444b9083f..e813a901c608 100644 --- a/packages/SystemUI/res/values-az/strings.xml +++ b/packages/SystemUI/res/values-az/strings.xml @@ -412,7 +412,8 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Şəfəq vaxtına qədər"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Bu vaxt aktiv olur: <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Bu vaxtadək: <xliff:g id="TIME">%s</xliff:g>"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Parlaqlığı Azaldın"</string> + <!-- no translation found for quick_settings_reduce_bright_colors_label (7537352080559075175) --> + <skip /> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC deaktiv edilib"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC aktiv edilib"</string> @@ -446,6 +447,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC istifadə etmək üçün kiliddən çıxarın"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Bu cihaz təşkilatınıza məxsusdur"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"Bu cihaz <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> təşkilatına məxsusdur"</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"Telefon üçün ikonadan sürüşdürün"</string> <string name="voice_hint" msgid="7476017460191291417">"Səs yardımçısı üçün ikonadan sürüşdürün"</string> <string name="camera_hint" msgid="4519495795000658637">"Kamera üçün ikonadan sürüşdürün"</string> @@ -625,6 +628,8 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Səssiz etmək üçün tıklayın. Əlçatımlılıq xidmətləri səssiz edilmiş ola bilər."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Vibrasiyanı ayarlamaq üçün klikləyin."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Səssiz etmək üçün klikləyin."</string> + <!-- no translation found for volume_ringer_change (3574969197796055532) --> + <skip /> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"susdurun"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"səssiz rejimdən çıxarın"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibrasiya"</string> @@ -1038,6 +1043,7 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"Əlavə edin"</string> <string name="controls_dialog_message" msgid="342066938390663844">"<xliff:g id="APP">%s</xliff:g> tərəfindən təklif edilib"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"Nizamlayıcılar güncəlləndi"</string> + <string name="controls_tile_locked" msgid="731547768182831938">"Cihaz kilidlənib"</string> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN hərflər və ya simvollar ehtiva edir"</string> <string name="controls_pin_verify" msgid="3452778292918877662">"<xliff:g id="DEVICE">%s</xliff:g> cihazını doğrulayın"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"Yanlış PIN"</string> diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml index ded8fa591f0b..27d4b182b3f7 100644 --- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml +++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml @@ -414,7 +414,8 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Do izlaska sunca"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Uključuje se u <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Do <xliff:g id="TIME">%s</xliff:g>"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Smanji osvetljenost"</string> + <!-- no translation found for quick_settings_reduce_bright_colors_label (7537352080559075175) --> + <skip /> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC je onemogućen"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC je omogućen"</string> @@ -448,6 +449,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Otključajte da biste koristili NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Ovaj uređaj pripada organizaciji"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"Ovaj uređaj pripada organizaciji <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"Prevucite od ikone za telefon"</string> <string name="voice_hint" msgid="7476017460191291417">"Prevucite od ikone za glasovnu pomoć"</string> <string name="camera_hint" msgid="4519495795000658637">"Prevucite od ikone za kameru"</string> @@ -628,6 +631,8 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Dodirnite da biste isključili zvuk. Zvuk usluga pristupačnosti će možda biti isključen."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Dodirnite da biste podesili na vibraciju."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Dodirnite da biste isključili zvuk."</string> + <!-- no translation found for volume_ringer_change (3574969197796055532) --> + <skip /> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"isključite zvuk"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"uključite zvuk"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibracija"</string> @@ -1044,6 +1049,7 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"Dodaj"</string> <string name="controls_dialog_message" msgid="342066938390663844">"Predlaže <xliff:g id="APP">%s</xliff:g>"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"Kontrole su ažurirane"</string> + <string name="controls_tile_locked" msgid="731547768182831938">"Uređaj je zaključan"</string> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN sadrži slova ili simbole"</string> <string name="controls_pin_verify" msgid="3452778292918877662">"Verifikujte: <xliff:g id="DEVICE">%s</xliff:g>"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"Pogrešan PIN"</string> diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml index 18756f8c8083..ab1cc69ee35c 100644 --- a/packages/SystemUI/res/values-be/strings.xml +++ b/packages/SystemUI/res/values-be/strings.xml @@ -416,7 +416,8 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Да ўсходу сонца"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Уключана ў <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Да <xliff:g id="TIME">%s</xliff:g>"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Паменшыць яркасць"</string> + <!-- no translation found for quick_settings_reduce_bright_colors_label (7537352080559075175) --> + <skip /> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC адключаны"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC уключаны"</string> @@ -450,6 +451,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Разблакіруйце, каб выкарыстоўваць NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Гэта прылада належыць вашай арганізацыі"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"Гэта прылада належыць арганізацыі \"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>\""</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"Тэлефон: правядзіце пальцам ад значка"</string> <string name="voice_hint" msgid="7476017460191291417">"Галасавая дапамога: правядзіце пальцам ад значка"</string> <string name="camera_hint" msgid="4519495795000658637">"Камера: правядзіце пальцам ад значка"</string> @@ -631,6 +634,8 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Дакраніцеся, каб адключыць гук. Можа быць адключаны гук службаў спецыяльных магчымасцей."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Дакраніцеся, каб уключыць вібрацыю."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Дакраніцеся, каб адключыць гук"</string> + <!-- no translation found for volume_ringer_change (3574969197796055532) --> + <skip /> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"выключыць гук"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"уключыць гук"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"вібрыраваць"</string> @@ -1050,6 +1055,7 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"Дадаць"</string> <string name="controls_dialog_message" msgid="342066938390663844">"Прапанавана праграмай \"<xliff:g id="APP">%s</xliff:g>\""</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"Элементы кіравання абноўлены"</string> + <string name="controls_tile_locked" msgid="731547768182831938">"Прылада блакіравана"</string> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN-код складаецца з літар або знакаў"</string> <string name="controls_pin_verify" msgid="3452778292918877662">"Спраўдзіце прыладу \"<xliff:g id="DEVICE">%s</xliff:g>\""</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"Няправільны PIN-код"</string> diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml index e1efd3bd3c50..6716e15ca6cd 100644 --- a/packages/SystemUI/res/values-bg/strings.xml +++ b/packages/SystemUI/res/values-bg/strings.xml @@ -412,7 +412,8 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"До изгрев"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Ще се включи в <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"До <xliff:g id="TIME">%s</xliff:g>"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Намаляване на яркостта"</string> + <!-- no translation found for quick_settings_reduce_bright_colors_label (7537352080559075175) --> + <skip /> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"КБП е деактивирана"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"КБП е активирана"</string> @@ -446,6 +447,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Отключете, за да използвате NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Това устройство принадлежи на организацията ви"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"Това устройство принадлежи на <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"Плъзнете с пръст от иконата, за да използвате телефона"</string> <string name="voice_hint" msgid="7476017460191291417">"Прекарайте пръст от иконата, за да получите гласова помощ"</string> <string name="camera_hint" msgid="4519495795000658637">"Плъзнете с пръст от иконата, за да включите камерата"</string> @@ -625,6 +628,8 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Докоснете, за да заглушите звука. Възможно е звукът на услугите за достъпност да бъде заглушен."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Докоснете, за да зададете вибриране."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Докоснете, за да заглушите звука."</string> + <!-- no translation found for volume_ringer_change (3574969197796055532) --> + <skip /> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"спиране"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"пускане"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"вибриране"</string> @@ -1038,6 +1043,7 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"Добавяне"</string> <string name="controls_dialog_message" msgid="342066938390663844">"Предложено от <xliff:g id="APP">%s</xliff:g>"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"Контролите са актуализирани"</string> + <string name="controls_tile_locked" msgid="731547768182831938">"У-вото е заключено"</string> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"ПИН кодът съдържа букви или символи"</string> <string name="controls_pin_verify" msgid="3452778292918877662">"Потвърждаване на <xliff:g id="DEVICE">%s</xliff:g>"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"Грешен ПИН код"</string> diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml index 12f53454c94e..ee639d6e639c 100644 --- a/packages/SystemUI/res/values-bn/strings.xml +++ b/packages/SystemUI/res/values-bn/strings.xml @@ -93,10 +93,8 @@ <string name="screenshot_scroll_description" msgid="7855773867093272175">"স্ক্রিনশট স্ক্রল করুন"</string> <string name="screenshot_dismiss_description" msgid="4702341245899508786">"স্ক্রিনশট বাতিল করুন"</string> <string name="screenshot_preview_description" msgid="7606510140714080474">"স্ক্রিনশটের প্রিভিউ"</string> - <!-- no translation found for screenshot_top_boundary (1500569103321300856) --> - <skip /> - <!-- no translation found for screenshot_bottom_boundary (5657242629526407311) --> - <skip /> + <string name="screenshot_top_boundary" msgid="1500569103321300856">"স্ক্রিনশটের একদম উপরের দিকে"</string> + <string name="screenshot_bottom_boundary" msgid="5657242629526407311">"স্ক্রিনশটের একদম নিচের দিকে"</string> <string name="screenrecord_name" msgid="2596401223859996572">"স্ক্রিন রেকর্ডার"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"স্ক্রিন রেকর্ডিং প্রসেস হচ্ছে"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"স্ক্রিন রেকর্ডিং সেশন চলার বিজ্ঞপ্তি"</string> @@ -414,7 +412,8 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"সূর্যোদয় পর্যন্ত"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"<xliff:g id="TIME">%s</xliff:g>-এ চালু হবে"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"<xliff:g id="TIME">%s</xliff:g> পর্যন্ত"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"উজ্জ্বলতা কমান"</string> + <!-- no translation found for quick_settings_reduce_bright_colors_label (7537352080559075175) --> + <skip /> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC অক্ষম করা আছে"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC সক্ষম করা আছে"</string> @@ -448,6 +447,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC ব্যবহার করতে আনলক করুন"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"এই ডিভাইসটি আপনার প্রতিষ্ঠানের"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"এই ডিভাইসটি <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>-এর"</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"ফোনের জন্য আইকন থেকে সোয়াইপ করুন"</string> <string name="voice_hint" msgid="7476017460191291417">"ভয়েস সহায়তার জন্য আইকন থেকে সোয়াইপ করুন"</string> <string name="camera_hint" msgid="4519495795000658637">"ক্যামেরার জন্য আইকন থেকে সোয়াইপ করুন"</string> @@ -546,8 +547,7 @@ <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"আপনার প্রতিষ্ঠান আপনার অফিস প্রোফাইলে একটি সার্টিফিকেট কর্তৃপক্ষ ইনস্টল করেছে। আপনার নিরাপদ নেটওয়ার্ক ট্রাফিকে নজর রাখা হতে পারে বা তাতে পরিবর্তন করা হতে পারে।"</string> <string name="monitoring_description_ca_certificate" msgid="448923057059097497">"এই ডিভাইসে একটি সার্টিফিকেট কর্তৃপক্ষ ইনস্টল করা আছে। আপনার নিরাপদ নেটওয়ার্ক ট্রাফিকে নজর রাখা হতে পারে বা তাতে পরিবর্তন করা হতে পারে।"</string> <string name="monitoring_description_management_network_logging" msgid="216983105036994771">"আপনার প্রশাসক নেটওয়ার্ক লগিং চালু করেছেন, যা আপনার ডিভাইসের ট্রাফিকের উপরে নজর রাখে।"</string> - <!-- no translation found for monitoring_description_managed_profile_network_logging (6932303843097006037) --> - <skip /> + <string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"আপনার অ্যাডমিন নেটওয়ার্ক লগ করা চালু করেছেন যা আপনার অফিস প্রোফাইলে ট্রাফিক মনিটর করে তবে ব্যক্তিগত প্রোফাইলে করে না।"</string> <string name="monitoring_description_named_vpn" msgid="5749932930634037027">"আপনি <xliff:g id="VPN_APP">%1$s</xliff:g> এ সংযুক্ত রয়েছেন, যা আপনার ইমেল, অ্যাপ, এবং ওয়েবসাইট সহ আপনার নেটওয়ার্ক অ্যাক্টিভিটির উপর নজর রাখতে পারে।"</string> <string name="monitoring_description_two_named_vpns" msgid="3516830755681229463">"আপনি <xliff:g id="VPN_APP_0">%1$s</xliff:g> এবং <xliff:g id="VPN_APP_1">%2$s</xliff:g> এর সাথে সংযুক্ত রয়েছেন, যেগুলি আপনার ইমেল, অ্যাপ, এবং ওয়েবসাইট সহ আপনার নেটওয়ার্ক অ্যাক্টিভিটির উপর নজর রাখতে পারে।"</string> <string name="monitoring_description_managed_profile_named_vpn" msgid="368812367182387320">"আপনার কর্মস্থলের প্রোফাইল <xliff:g id="VPN_APP">%1$s</xliff:g> এর সাথে সংযুক্ত রয়েছে, যেটি ইমেল, অ্যাপ, এবং ওয়েবসাইট সহ আপনার নেটওয়ার্ক কার্যকলাপে নজর রাখতে পারে।"</string> @@ -628,6 +628,8 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s। মিউট করতে আলতো চাপুন। অ্যাক্সেসযোগ্যতার পরিষেবাগুলিকে মিউট করা হতে পারে।"</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s। ভাইব্রেট করতে ট্যাপ করুন।"</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s। মিউট করতে ট্যাপ করুন।"</string> + <!-- no translation found for volume_ringer_change (3574969197796055532) --> + <skip /> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"মিউট করুন"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"আনমিউট করুন"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"ভাইব্রেট করান"</string> @@ -1041,6 +1043,7 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"যোগ করুন"</string> <string name="controls_dialog_message" msgid="342066938390663844">"<xliff:g id="APP">%s</xliff:g> সাজেস্ট করেছে"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"কন্ট্রোল আপডেট করা হয়েছে"</string> + <string name="controls_tile_locked" msgid="731547768182831938">"ডিভাইস লক করা আছে"</string> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"পিন-এ অক্ষর বা চিহ্ন রয়েছে"</string> <string name="controls_pin_verify" msgid="3452778292918877662">"<xliff:g id="DEVICE">%s</xliff:g> যাচাই করুন"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"ভুল পিন"</string> diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml index 746323386b1c..01a55d3d06ba 100644 --- a/packages/SystemUI/res/values-bs/strings.xml +++ b/packages/SystemUI/res/values-bs/strings.xml @@ -414,7 +414,8 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Do svitanja"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Uključuje se u <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Do <xliff:g id="TIME">%s</xliff:g>"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Smanji osvjetljenje"</string> + <!-- no translation found for quick_settings_reduce_bright_colors_label (7537352080559075175) --> + <skip /> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC je onemogućen"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC je omogućen"</string> @@ -448,6 +449,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Otključajte da koristite NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Ovaj uređaj pripada vašoj organizaciji"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"Ovaj uređaj pripada organizaciji <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"Prevucite preko ikone da otvorite telefon"</string> <string name="voice_hint" msgid="7476017460191291417">"Prevucite preko ikone za glasovnu pomoć"</string> <string name="camera_hint" msgid="4519495795000658637">"Prevucite od ikone da otvorite kameru"</string> @@ -628,6 +631,8 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Dodirnite da isključite zvuk. Zvukovi usluga pristupačnosti mogu biti isključeni."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Dodirnite da postavite vibraciju."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Dodirnite da isključite zvuk."</string> + <!-- no translation found for volume_ringer_change (3574969197796055532) --> + <skip /> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"isključite zvuk"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"uključite zvuk"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibriranje"</string> @@ -1044,6 +1049,7 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"Dodaj"</string> <string name="controls_dialog_message" msgid="342066938390663844">"Predlaže <xliff:g id="APP">%s</xliff:g>"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"Kontrole su ažurirane"</string> + <string name="controls_tile_locked" msgid="731547768182831938">"Uređaj je zaključan"</string> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN sadrži slova ili simbole"</string> <string name="controls_pin_verify" msgid="3452778292918877662">"Potvrdite uređaj <xliff:g id="DEVICE">%s</xliff:g>"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"Pogrešan PIN"</string> diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml index 524bb6258774..5d8ccbc1f52c 100644 --- a/packages/SystemUI/res/values-ca/strings.xml +++ b/packages/SystemUI/res/values-ca/strings.xml @@ -412,7 +412,8 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Fins a l\'alba"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Activat a les <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Fins a les <xliff:g id="TIME">%s</xliff:g>"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Reducció de la brillantor"</string> + <!-- no translation found for quick_settings_reduce_bright_colors_label (7537352080559075175) --> + <skip /> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"L\'NFC està desactivada"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"L\'NFC està activada"</string> @@ -446,6 +447,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Desbloqueja per utilitzar l\'NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Aquest dispositiu pertany a la teva organització"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"Aquest dispositiu pertany a <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"Llisca des de la icona per obrir el telèfon"</string> <string name="voice_hint" msgid="7476017460191291417">"Llisca des de la icona per obrir l\'assistent de veu"</string> <string name="camera_hint" msgid="4519495795000658637">"Llisca des de la icona per obrir la càmera"</string> @@ -625,6 +628,8 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Toca per silenciar el so. Pot ser que els serveis d\'accessibilitat se silenciïn."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Toca per activar la vibració."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Toca per silenciar."</string> + <!-- no translation found for volume_ringer_change (3574969197796055532) --> + <skip /> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"silenciar"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"deixar de silenciar"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibrar"</string> @@ -1038,6 +1043,7 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"Afegeix"</string> <string name="controls_dialog_message" msgid="342066938390663844">"Suggerit per <xliff:g id="APP">%s</xliff:g>"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"S\'han actualitzat els controls"</string> + <string name="controls_tile_locked" msgid="731547768182831938">"Dispositiu bloquejat"</string> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"El PIN conté lletres o símbols"</string> <string name="controls_pin_verify" msgid="3452778292918877662">"Verifica <xliff:g id="DEVICE">%s</xliff:g>"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"PIN incorrecte"</string> diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml index 47a673dd4c42..024b836bbe53 100644 --- a/packages/SystemUI/res/values-cs/strings.xml +++ b/packages/SystemUI/res/values-cs/strings.xml @@ -416,7 +416,8 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Do svítání"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Zapnout v <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Do <xliff:g id="TIME">%s</xliff:g>"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Snížit jas"</string> + <!-- no translation found for quick_settings_reduce_bright_colors_label (7537352080559075175) --> + <skip /> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC je vypnuto"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC je zapnuto"</string> @@ -450,6 +451,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC vyžaduje odemknutou obrazovku"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Toto zařízení patří vaší organizaci"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"Toto zařízení patří organizaci <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"Telefon otevřete přejetím prstem od ikony"</string> <string name="voice_hint" msgid="7476017460191291417">"Hlasovou asistenci otevřete přejetím prstem od ikony"</string> <string name="camera_hint" msgid="4519495795000658637">"Fotoaparát otevřete přejetím prstem od ikony"</string> @@ -631,6 +634,8 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Klepnutím vypnete zvuk. Služby přístupnosti mohou být ztlumeny."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Klepnutím nastavíte vibrace."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Klepnutím vypnete zvuk."</string> + <!-- no translation found for volume_ringer_change (3574969197796055532) --> + <skip /> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"vypnout zvuk"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"zapnout zvuk"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibrovat"</string> @@ -1050,6 +1055,7 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"Přidat"</string> <string name="controls_dialog_message" msgid="342066938390663844">"Návrh z aplikace <xliff:g id="APP">%s</xliff:g>"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"Ovládací prvky aktualizovány"</string> + <string name="controls_tile_locked" msgid="731547768182831938">"Zařízení uzamčeno"</string> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"Kód PIN obsahuje písmena nebo symboly"</string> <string name="controls_pin_verify" msgid="3452778292918877662">"Ověření zařízení <xliff:g id="DEVICE">%s</xliff:g>"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"Chybný PIN"</string> diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml index e12b91c13ec7..b1a7a5afd938 100644 --- a/packages/SystemUI/res/values-da/strings.xml +++ b/packages/SystemUI/res/values-da/strings.xml @@ -412,7 +412,8 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Indtil solopgang"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Tænd kl. <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Indtil kl. <xliff:g id="TIME">%s</xliff:g>"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Reducer lysstyrken"</string> + <!-- no translation found for quick_settings_reduce_bright_colors_label (7537352080559075175) --> + <skip /> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC er deaktiveret"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC er aktiveret"</string> @@ -446,6 +447,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Lås op for at bruge NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Denne enhed tilhører din organisation"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"Denne enhed tilhører <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"Stryg fra telefonikonet"</string> <string name="voice_hint" msgid="7476017460191291417">"Stryg fra mikrofonikonet"</string> <string name="camera_hint" msgid="4519495795000658637">"Stryg fra kameraikonet"</string> @@ -625,6 +628,8 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Tryk for at slå lyden fra. Lyden i tilgængelighedstjenester kan blive slået fra."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Tryk for at aktivere vibration."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Tryk for at slå lyden fra."</string> + <!-- no translation found for volume_ringer_change (3574969197796055532) --> + <skip /> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"slå lyden fra"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"slå lyden til"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibrer"</string> @@ -1038,6 +1043,7 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"Tilføj"</string> <string name="controls_dialog_message" msgid="342066938390663844">"Foreslået af <xliff:g id="APP">%s</xliff:g>"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"Betjeningselementerne er opdateret"</string> + <string name="controls_tile_locked" msgid="731547768182831938">"Enheden er låst"</string> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"Pinkoden indeholder bogstaver eller symboler"</string> <string name="controls_pin_verify" msgid="3452778292918877662">"Bekræft <xliff:g id="DEVICE">%s</xliff:g>"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"Forkert pinkode"</string> diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml index 6a69ed204b0c..88dd62da811c 100644 --- a/packages/SystemUI/res/values-de/strings.xml +++ b/packages/SystemUI/res/values-de/strings.xml @@ -93,10 +93,8 @@ <string name="screenshot_scroll_description" msgid="7855773867093272175">"Screenshot scrollen"</string> <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Screenshot schließen"</string> <string name="screenshot_preview_description" msgid="7606510140714080474">"Screenshotvorschau"</string> - <!-- no translation found for screenshot_top_boundary (1500569103321300856) --> - <skip /> - <!-- no translation found for screenshot_bottom_boundary (5657242629526407311) --> - <skip /> + <string name="screenshot_top_boundary" msgid="1500569103321300856">"Oberer Rand"</string> + <string name="screenshot_bottom_boundary" msgid="5657242629526407311">"Unterer Rand"</string> <string name="screenrecord_name" msgid="2596401223859996572">"Bildschirmaufzeichnung"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Bildschirmaufzeichnung…"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"Fortlaufende Benachrichtigung für eine Bildschirmaufzeichnung"</string> @@ -414,7 +412,8 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Bis Sonnenaufgang"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"An um <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Bis <xliff:g id="TIME">%s</xliff:g>"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Helligkeit verringern"</string> + <!-- no translation found for quick_settings_reduce_bright_colors_label (7537352080559075175) --> + <skip /> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC ist deaktiviert"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC ist aktiviert"</string> @@ -448,6 +447,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Zur Verwendung von NFC entsperren"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Dieses Gerät gehört deiner Organisation"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"Dieses Gerät gehört <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"Zum Öffnen des Telefons vom Symbol wegwischen"</string> <string name="voice_hint" msgid="7476017460191291417">"Zum Öffnen des Sprachassistenten vom Symbol wegwischen"</string> <string name="camera_hint" msgid="4519495795000658637">"Zum Öffnen der Kamera vom Symbol wegwischen"</string> @@ -546,8 +547,7 @@ <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Deine Organisation hat ein Zertifikat einer Zertifizierungsstelle in deinem Arbeitsprofil installiert. Eventuell wird dein sicherer Netzwerkverkehr überwacht oder bearbeitet."</string> <string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Auf dem Gerät ist das Zertifikat einer Zertifizierungsstelle installiert. Eventuell wird dein sicherer Netzwerkverkehr überwacht oder bearbeitet."</string> <string name="monitoring_description_management_network_logging" msgid="216983105036994771">"Dein Administrator hat die Netzwerkprotokollierung aktiviert. Damit wird der Netzwerkverkehr auf deinem Gerät überwacht."</string> - <!-- no translation found for monitoring_description_managed_profile_network_logging (6932303843097006037) --> - <skip /> + <string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"Dein Administrator hat die Netzwerkprotokollierung aktiviert. Damit werden die Zugriffe in deinem Arbeitsprofil erfasst, jedoch nicht in deinem privaten Profil."</string> <string name="monitoring_description_named_vpn" msgid="5749932930634037027">"Du bist mit <xliff:g id="VPN_APP">%1$s</xliff:g> verbunden. Die App kann deine Netzwerkaktivitäten (E-Mails, Apps und Websites) erfassen."</string> <string name="monitoring_description_two_named_vpns" msgid="3516830755681229463">"Du bist mit <xliff:g id="VPN_APP_0">%1$s</xliff:g> und <xliff:g id="VPN_APP_1">%2$s</xliff:g> verbunden. Die Apps können deine Netzwerkaktivitäten (E-Mails, Apps und Websites) erfassen."</string> <string name="monitoring_description_managed_profile_named_vpn" msgid="368812367182387320">"Dein Arbeitsprofil ist mit <xliff:g id="VPN_APP">%1$s</xliff:g> verbunden, die deine Netzwerkaktivitäten wie E-Mails, Apps und Websites überwachen kann."</string> @@ -628,6 +628,8 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Zum Stummschalten tippen. Bedienungshilfen werden unter Umständen stummgeschaltet."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Zum Aktivieren der Vibration tippen."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Zum Stummschalten tippen."</string> + <!-- no translation found for volume_ringer_change (3574969197796055532) --> + <skip /> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"stummschalten"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"Stummschaltung aufheben"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibrieren"</string> @@ -1041,6 +1043,7 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"Hinzufügen"</string> <string name="controls_dialog_message" msgid="342066938390663844">"Vorgeschlagen von <xliff:g id="APP">%s</xliff:g>"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"Gerätekarten aktualisiert"</string> + <string name="controls_tile_locked" msgid="731547768182831938">"Gerät gesperrt"</string> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"Die PIN enthält Buchstaben oder Symbole"</string> <string name="controls_pin_verify" msgid="3452778292918877662">"<xliff:g id="DEVICE">%s</xliff:g> bestätigen"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"Falsche PIN"</string> diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml index 5bed0e5b9ad3..21330256d079 100644 --- a/packages/SystemUI/res/values-el/strings.xml +++ b/packages/SystemUI/res/values-el/strings.xml @@ -412,7 +412,8 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Μέχρι την ανατολή"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Ενεργοποίηση στις <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Έως <xliff:g id="TIME">%s</xliff:g>"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Μείωση φωτεινότητας"</string> + <!-- no translation found for quick_settings_reduce_bright_colors_label (7537352080559075175) --> + <skip /> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"Το NFC είναι απενεργοποιημένο"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"Το NFC είναι ενεργοποιημένο"</string> @@ -446,6 +447,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Ξεκλείδωμα για χρήση του NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Αυτή η συσκευή ανήκει στον οργανισμό σας."</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"Αυτή η συσκευή ανήκει στον οργανισμό <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"Σύρετε προς τα έξω για τηλέφωνο"</string> <string name="voice_hint" msgid="7476017460191291417">"Σύρετε προς τα έξω για voice assist"</string> <string name="camera_hint" msgid="4519495795000658637">"Σύρετε προς τα έξω για κάμερα"</string> @@ -625,6 +628,8 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Πατήστε για σίγαση. Οι υπηρεσίες προσβασιμότητας ενδέχεται να τεθούν σε σίγαση."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Πατήστε για να ενεργοποιήσετε τη δόνηση."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Πατήστε για σίγαση."</string> + <!-- no translation found for volume_ringer_change (3574969197796055532) --> + <skip /> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"σίγαση"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"κατάργηση σίγασης"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"δόνηση"</string> @@ -1038,6 +1043,7 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"Προσθήκη"</string> <string name="controls_dialog_message" msgid="342066938390663844">"Προτείνεται από <xliff:g id="APP">%s</xliff:g>"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"Ενημέρωση στοιχείων ελέγχου"</string> + <string name="controls_tile_locked" msgid="731547768182831938">"Η συσκευή κλειδώθηκε"</string> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"Το PIN περιέχει γράμματα ή σύμβολα"</string> <string name="controls_pin_verify" msgid="3452778292918877662">"Επαλήθευση <xliff:g id="DEVICE">%s</xliff:g>"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"Λάθος PIN"</string> diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml index 137070fa0437..0a0f8f7aab1e 100644 --- a/packages/SystemUI/res/values-en-rAU/strings.xml +++ b/packages/SystemUI/res/values-en-rAU/strings.xml @@ -412,7 +412,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Until sunrise"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"On at <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Until <xliff:g id="TIME">%s</xliff:g>"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Reduce Brightness"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"Reduce brightness"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC is disabled"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC is enabled"</string> @@ -446,6 +446,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Unlock to use NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"This device belongs to your organisation"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"This device belongs to <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"Swipe from icon for phone"</string> <string name="voice_hint" msgid="7476017460191291417">"Swipe from icon for voice assist"</string> <string name="camera_hint" msgid="4519495795000658637">"Swipe from icon for camera"</string> @@ -625,6 +627,7 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Tap to mute. Accessibility services may be muted."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Tap to set to vibrate."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Tap to mute."</string> + <string name="volume_ringer_change" msgid="3574969197796055532">"Tap to change ringer mode"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"mute"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"unmute"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibrate"</string> @@ -1038,6 +1041,7 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"Add"</string> <string name="controls_dialog_message" msgid="342066938390663844">"Suggested by <xliff:g id="APP">%s</xliff:g>"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"Controls updated"</string> + <string name="controls_tile_locked" msgid="731547768182831938">"Device locked"</string> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN contains letters or symbols"</string> <string name="controls_pin_verify" msgid="3452778292918877662">"Verify <xliff:g id="DEVICE">%s</xliff:g>"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"Wrong PIN"</string> diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml index 5df29337493a..403fdeec6641 100644 --- a/packages/SystemUI/res/values-en-rCA/strings.xml +++ b/packages/SystemUI/res/values-en-rCA/strings.xml @@ -412,7 +412,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Until sunrise"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"On at <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Until <xliff:g id="TIME">%s</xliff:g>"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Reduce Brightness"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"Reduce brightness"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC is disabled"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC is enabled"</string> @@ -446,6 +446,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Unlock to use NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"This device belongs to your organisation"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"This device belongs to <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"Swipe from icon for phone"</string> <string name="voice_hint" msgid="7476017460191291417">"Swipe from icon for voice assist"</string> <string name="camera_hint" msgid="4519495795000658637">"Swipe from icon for camera"</string> @@ -625,6 +627,7 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Tap to mute. Accessibility services may be muted."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Tap to set to vibrate."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Tap to mute."</string> + <string name="volume_ringer_change" msgid="3574969197796055532">"Tap to change ringer mode"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"mute"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"unmute"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibrate"</string> @@ -1038,6 +1041,7 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"Add"</string> <string name="controls_dialog_message" msgid="342066938390663844">"Suggested by <xliff:g id="APP">%s</xliff:g>"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"Controls updated"</string> + <string name="controls_tile_locked" msgid="731547768182831938">"Device locked"</string> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN contains letters or symbols"</string> <string name="controls_pin_verify" msgid="3452778292918877662">"Verify <xliff:g id="DEVICE">%s</xliff:g>"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"Wrong PIN"</string> diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml index 137070fa0437..0a0f8f7aab1e 100644 --- a/packages/SystemUI/res/values-en-rGB/strings.xml +++ b/packages/SystemUI/res/values-en-rGB/strings.xml @@ -412,7 +412,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Until sunrise"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"On at <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Until <xliff:g id="TIME">%s</xliff:g>"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Reduce Brightness"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"Reduce brightness"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC is disabled"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC is enabled"</string> @@ -446,6 +446,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Unlock to use NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"This device belongs to your organisation"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"This device belongs to <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"Swipe from icon for phone"</string> <string name="voice_hint" msgid="7476017460191291417">"Swipe from icon for voice assist"</string> <string name="camera_hint" msgid="4519495795000658637">"Swipe from icon for camera"</string> @@ -625,6 +627,7 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Tap to mute. Accessibility services may be muted."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Tap to set to vibrate."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Tap to mute."</string> + <string name="volume_ringer_change" msgid="3574969197796055532">"Tap to change ringer mode"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"mute"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"unmute"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibrate"</string> @@ -1038,6 +1041,7 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"Add"</string> <string name="controls_dialog_message" msgid="342066938390663844">"Suggested by <xliff:g id="APP">%s</xliff:g>"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"Controls updated"</string> + <string name="controls_tile_locked" msgid="731547768182831938">"Device locked"</string> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN contains letters or symbols"</string> <string name="controls_pin_verify" msgid="3452778292918877662">"Verify <xliff:g id="DEVICE">%s</xliff:g>"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"Wrong PIN"</string> diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml index 137070fa0437..0a0f8f7aab1e 100644 --- a/packages/SystemUI/res/values-en-rIN/strings.xml +++ b/packages/SystemUI/res/values-en-rIN/strings.xml @@ -412,7 +412,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Until sunrise"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"On at <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Until <xliff:g id="TIME">%s</xliff:g>"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Reduce Brightness"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"Reduce brightness"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC is disabled"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC is enabled"</string> @@ -446,6 +446,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Unlock to use NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"This device belongs to your organisation"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"This device belongs to <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"Swipe from icon for phone"</string> <string name="voice_hint" msgid="7476017460191291417">"Swipe from icon for voice assist"</string> <string name="camera_hint" msgid="4519495795000658637">"Swipe from icon for camera"</string> @@ -625,6 +627,7 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Tap to mute. Accessibility services may be muted."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Tap to set to vibrate."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Tap to mute."</string> + <string name="volume_ringer_change" msgid="3574969197796055532">"Tap to change ringer mode"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"mute"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"unmute"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibrate"</string> @@ -1038,6 +1041,7 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"Add"</string> <string name="controls_dialog_message" msgid="342066938390663844">"Suggested by <xliff:g id="APP">%s</xliff:g>"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"Controls updated"</string> + <string name="controls_tile_locked" msgid="731547768182831938">"Device locked"</string> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN contains letters or symbols"</string> <string name="controls_pin_verify" msgid="3452778292918877662">"Verify <xliff:g id="DEVICE">%s</xliff:g>"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"Wrong PIN"</string> diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml index 46c09f668383..a665fb12b662 100644 --- a/packages/SystemUI/res/values-en-rXC/strings.xml +++ b/packages/SystemUI/res/values-en-rXC/strings.xml @@ -412,7 +412,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Until sunrise"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"On at <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Until <xliff:g id="TIME">%s</xliff:g>"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Reduce Brightness"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"Reduce brightness"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC is disabled"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC is enabled"</string> @@ -446,6 +446,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Unlock to use NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"This device belongs to your organization"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"This device belongs to <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"Swipe from icon for phone"</string> <string name="voice_hint" msgid="7476017460191291417">"Swipe from icon for voice assist"</string> <string name="camera_hint" msgid="4519495795000658637">"Swipe from icon for camera"</string> @@ -625,6 +627,7 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Tap to mute. Accessibility services may be muted."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Tap to set to vibrate."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Tap to mute."</string> + <string name="volume_ringer_change" msgid="3574969197796055532">"Tap to change ringer mode"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"mute"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"unmute"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibrate"</string> @@ -1038,6 +1041,7 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"Add"</string> <string name="controls_dialog_message" msgid="342066938390663844">"Suggested by <xliff:g id="APP">%s</xliff:g>"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"Controls updated"</string> + <string name="controls_tile_locked" msgid="731547768182831938">"Device locked"</string> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN contains letters or symbols"</string> <string name="controls_pin_verify" msgid="3452778292918877662">"Verify <xliff:g id="DEVICE">%s</xliff:g>"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"Wrong PIN"</string> diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml index e1ad516254c7..c97194f1fe08 100644 --- a/packages/SystemUI/res/values-es-rUS/strings.xml +++ b/packages/SystemUI/res/values-es-rUS/strings.xml @@ -412,7 +412,8 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Hasta el amanecer"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"A la(s) <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Hasta la(s) <xliff:g id="TIME">%s</xliff:g>"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Reducir el brillo"</string> + <!-- no translation found for quick_settings_reduce_bright_colors_label (7537352080559075175) --> + <skip /> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"La tecnología NFC está inhabilitada"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"La tecnología NFC está habilitada"</string> @@ -446,6 +447,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Desbloquea el dispositivo para usar NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Este dispositivo pertenece a tu organización"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"Este dispositivo pertenece a <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"Desliza el dedo para desbloquear el teléfono."</string> <string name="voice_hint" msgid="7476017460191291417">"Desliza el dedo desde el ícono para abrir asistente de voz."</string> <string name="camera_hint" msgid="4519495795000658637">"Desliza el dedo para acceder a la cámara."</string> @@ -625,6 +628,8 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Presiona para silenciar. Es posible que los servicios de accesibilidad estén silenciados."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Presiona para establecer el modo vibración."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Presiona para silenciar."</string> + <!-- no translation found for volume_ringer_change (3574969197796055532) --> + <skip /> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"silenciar"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"dejar de silenciar"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibrar"</string> @@ -1038,6 +1043,7 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"Agregar"</string> <string name="controls_dialog_message" msgid="342066938390663844">"Sugerido por <xliff:g id="APP">%s</xliff:g>"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"Controles actualizados"</string> + <string name="controls_tile_locked" msgid="731547768182831938">"Dispos. bloqueado"</string> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"El PIN contiene letras o símbolos"</string> <string name="controls_pin_verify" msgid="3452778292918877662">"Verificar <xliff:g id="DEVICE">%s</xliff:g>"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"PIN incorrecto"</string> diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml index c4b8b24b8e06..4c5ef0b090fc 100644 --- a/packages/SystemUI/res/values-es/strings.xml +++ b/packages/SystemUI/res/values-es/strings.xml @@ -412,7 +412,8 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Hasta el amanecer"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"A las <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Hasta las <xliff:g id="TIME">%s</xliff:g>"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Reducir brillo"</string> + <!-- no translation found for quick_settings_reduce_bright_colors_label (7537352080559075175) --> + <skip /> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"El NFC está desactivado"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"El NFC está activado"</string> @@ -446,6 +447,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Desbloquea para usar el NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Este dispositivo pertenece a tu organización"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"Este dispositivo pertenece a <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"Desliza desde el icono para abrir el teléfono"</string> <string name="voice_hint" msgid="7476017460191291417">"Desliza desde el icono para abrir asistente de voz"</string> <string name="camera_hint" msgid="4519495795000658637">"Desliza desde el icono para abrir la cámara"</string> @@ -625,6 +628,8 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Toca para silenciar. Los servicios de accesibilidad pueden silenciarse."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Toca para activar la vibración."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Toca para silenciar."</string> + <!-- no translation found for volume_ringer_change (3574969197796055532) --> + <skip /> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"silenciar"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"dejar de silenciar"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibrar"</string> @@ -1038,6 +1043,7 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"Añadir"</string> <string name="controls_dialog_message" msgid="342066938390663844">"Sugerido por <xliff:g id="APP">%s</xliff:g>"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"Controles actualizados"</string> + <string name="controls_tile_locked" msgid="731547768182831938">"Dispositivo bloqueado"</string> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"El PIN contiene letras o símbolos"</string> <string name="controls_pin_verify" msgid="3452778292918877662">"Verifica <xliff:g id="DEVICE">%s</xliff:g>"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"PIN incorrecto"</string> diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml index 5402b6185a76..65c5930d29d3 100644 --- a/packages/SystemUI/res/values-et/strings.xml +++ b/packages/SystemUI/res/values-et/strings.xml @@ -412,7 +412,8 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Kuni päikesetõusuni"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Sisse kell <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Kuni <xliff:g id="TIME">%s</xliff:g>"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Ereduse vähendamine"</string> + <!-- no translation found for quick_settings_reduce_bright_colors_label (7537352080559075175) --> + <skip /> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC on keelatud"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC on lubatud"</string> @@ -446,6 +447,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC kasutamiseks avage."</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"See seade kuulub teie organisatsioonile"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"Selle seadme omanik on <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"Telefoni kasutamiseks pühkige ikoonilt eemale"</string> <string name="voice_hint" msgid="7476017460191291417">"Häälabi kasutamiseks pühkige ikoonilt eemale"</string> <string name="camera_hint" msgid="4519495795000658637">"Kaamera kasutamiseks pühkige ikoonilt eemale"</string> @@ -625,6 +628,8 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Puudutage vaigistamiseks. Juurdepääsetavuse teenused võidakse vaigistada."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Puudutage vibreerimise määramiseks."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Puudutage vaigistamiseks."</string> + <!-- no translation found for volume_ringer_change (3574969197796055532) --> + <skip /> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"vaigistamine"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"vaigistuse tühistamine"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibreerimine"</string> @@ -1038,6 +1043,7 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"Lisa"</string> <string name="controls_dialog_message" msgid="342066938390663844">"Soovitas <xliff:g id="APP">%s</xliff:g>"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"Juhtelemente värskendati"</string> + <string name="controls_tile_locked" msgid="731547768182831938">"Seade on lukustatud"</string> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN-kood sisaldab tähti või sümboleid"</string> <string name="controls_pin_verify" msgid="3452778292918877662">"Kinnitage <xliff:g id="DEVICE">%s</xliff:g>"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"Vale PIN-kood"</string> diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml index 510e7f93402d..9cebde110938 100644 --- a/packages/SystemUI/res/values-eu/strings.xml +++ b/packages/SystemUI/res/values-eu/strings.xml @@ -412,7 +412,8 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Egunsentira arte"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Aktibatze-ordua: <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Desaktibatze-ordua: <xliff:g id="TIME">%s</xliff:g>"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Murriztu distira"</string> + <!-- no translation found for quick_settings_reduce_bright_colors_label (7537352080559075175) --> + <skip /> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"Desgaituta dago NFC"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"Gaituta dago NFC"</string> @@ -443,9 +444,11 @@ <string name="notification_tap_again" msgid="4477318164947497249">"Irekitzeko, ukitu berriro"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"Pasatu hatza gora irekitzeko"</string> <string name="keyguard_retry" msgid="886802522584053523">"Berriro saiatzeko, pasatu hatza gora"</string> - <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Desblokeatu NFC erabiltzeko"</string> + <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Desblokea ezazu NFC erabiltzeko"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Gailu hau zure erakundearena da"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"Gailu hau <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> erakundearena da"</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"Pasatu hatza ikonotik, telefonoa irekitzeko"</string> <string name="voice_hint" msgid="7476017460191291417">"Pasatu hatza ikonotik, ahots-laguntza irekitzeko"</string> <string name="camera_hint" msgid="4519495795000658637">"Pasatu hatza ikonotik, kamera irekitzeko"</string> @@ -461,8 +464,8 @@ <string name="keyguard_indication_charging_time_fast" msgid="7895986003578341126">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Bizkor kargatzen (<xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> guztiz kargatu arte)"</string> <string name="keyguard_indication_charging_time_slowly" msgid="245442950133408398">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Mantso kargatzen (<xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> guztiz kargatu arte)"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Aldatu erabiltzailea"</string> - <string name="accessibility_multi_user_switch_switcher_with_current" msgid="5759855008166759399">"Aldatu erabiltzailez. <xliff:g id="CURRENT_USER_NAME">%s</xliff:g> da saioa hasita duena."</string> - <string name="accessibility_multi_user_switch_inactive" msgid="383168614528618402">"Uneko erabiltzailea: <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string> + <string name="accessibility_multi_user_switch_switcher_with_current" msgid="5759855008166759399">"Aldatu erabiltzailea. <xliff:g id="CURRENT_USER_NAME">%s</xliff:g> da saioa hasita daukana."</string> + <string name="accessibility_multi_user_switch_inactive" msgid="383168614528618402">"Erabiltzailea: <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string> <string name="accessibility_multi_user_switch_quick_contact" msgid="4504508915324898576">"Erakutsi profila"</string> <string name="user_add_user" msgid="4336657383006913022">"Gehitu erabiltzailea"</string> <string name="user_new_user_name" msgid="2019166282704195789">"Erabiltzaile berria"</string> @@ -478,7 +481,7 @@ <string name="guest_notification_text" msgid="4202692942089571351">"Aplikazioak eta datuak ezabatzeko, kendu gonbidatua"</string> <string name="guest_notification_remove_action" msgid="4153019027696868099">"KENDU GONBIDATUA"</string> <string name="user_logout_notification_title" msgid="3644848998053832589">"Amaitu erabiltzailearen saioa"</string> - <string name="user_logout_notification_text" msgid="7441286737342997991">"Amaitu uneko erabiltzailearen saioa"</string> + <string name="user_logout_notification_text" msgid="7441286737342997991">"Amaitu erabiltzailearen saioa"</string> <string name="user_logout_notification_action" msgid="7974458760719361881">"AMAITU ERABILTZAILEAREN SAIOA"</string> <string name="user_add_user_title" msgid="4172327541504825032">"Beste erabiltzaile bat gehitu?"</string> <string name="user_add_user_message_short" msgid="2599370307878014791">"Erabiltzaile bat gehitzen duzunean, horrek bere eremua konfiguratu beharko du.\n\nEdozein erabiltzailek egunera ditzake beste erabiltzaile guztien aplikazioak."</string> @@ -544,7 +547,7 @@ <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Erakundeak ziurtagiri-emaile bat instalatu dizu laneko profilean. Baliteke sareko trafiko segurua gainbegiratzea edo aldatzea."</string> <string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Ziurtagiri-emaile bat dago instalatuta gailuan. Baliteke sareko trafiko segurua gainbegiratzea edo aldatzea."</string> <string name="monitoring_description_management_network_logging" msgid="216983105036994771">"Administratzaileak sare-erregistroak aktibatu ditu; horrela, zure gailuko trafikoa gainbegira dezake."</string> - <string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"Administratzaileak sare-erregistroak aktibatu ditu; horrela, zure laneko profileko trafikoa gainbegira dezake, baina ez zure profil pertsonalekoa."</string> + <string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"Administratzaileak sarearen erregistroak aktibatu ditu; horrela, zure laneko profileko trafikoa gainbegira dezake, baina ez zure profil pertsonalekoa."</string> <string name="monitoring_description_named_vpn" msgid="5749932930634037027">"<xliff:g id="VPN_APP">%1$s</xliff:g> aplikaziora konektatuta zaude eta hark sareko jarduerak gainbegira ditzake, mezu elektronikoak, aplikazioak eta webguneak barne."</string> <string name="monitoring_description_two_named_vpns" msgid="3516830755681229463">"<xliff:g id="VPN_APP_0">%1$s</xliff:g> eta <xliff:g id="VPN_APP_1">%2$s</xliff:g> aplikazioetara konektatuta zaude, eta haiek sareko jarduerak gainbegira ditzakete, mezu elektronikoak, aplikazioak eta webguneak barne."</string> <string name="monitoring_description_managed_profile_named_vpn" msgid="368812367182387320">"<xliff:g id="VPN_APP">%1$s</xliff:g> aplikaziora dago konektatuta laneko profila, eta aplikazio horrek sareko jarduerak gainbegira ditzake, mezu elektronikoak, aplikazioak eta webguneak barne."</string> @@ -625,6 +628,8 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Sakatu audioa desaktibatzeko. Baliteke erabilerraztasun-eginbideen audioa desaktibatzea."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Sakatu hau dardara ezartzeko."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Sakatu hau audioa desaktibatzeko."</string> + <!-- no translation found for volume_ringer_change (3574969197796055532) --> + <skip /> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"desaktibatu audioa"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"aktibatu audioa"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"dardara"</string> @@ -954,7 +959,7 @@ <string name="running_foreground_services_msg" msgid="3009459259222695385">"Sakatu bateria eta datuen erabilerari buruzko xehetasunak ikusteko"</string> <string name="mobile_data_disable_title" msgid="5366476131671617790">"Datu-konexioa desaktibatu nahi duzu?"</string> <string name="mobile_data_disable_message" msgid="8604966027899770415">"<xliff:g id="CARRIER">%s</xliff:g> erabilita ezingo dituzu erabili datuak edo Internet. Wifi-sare baten bidez soilik konektatu ahal izango zara Internetera."</string> - <string name="mobile_data_disable_message_default_carrier" msgid="6496033312431658238">"Uneko operadorea"</string> + <string name="mobile_data_disable_message_default_carrier" msgid="6496033312431658238">"Zure operadorea"</string> <string name="touch_filtered_warning" msgid="8119511393338714836">"Aplikazio bat baimen-eskaera oztopatzen ari denez, ezarpenek ezin dute egiaztatu erantzuna."</string> <string name="slice_permission_title" msgid="3262615140094151017">"<xliff:g id="APP_2">%2$s</xliff:g> aplikazioaren zatiak erakusteko baimena eman nahi diozu <xliff:g id="APP_0">%1$s</xliff:g> aplikazioari?"</string> <string name="slice_permission_text_1" msgid="6675965177075443714">"- <xliff:g id="APP">%1$s</xliff:g> aplikazioaren informazioa irakur dezake."</string> @@ -1038,6 +1043,7 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"Gehitu"</string> <string name="controls_dialog_message" msgid="342066938390663844">"<xliff:g id="APP">%s</xliff:g> aplikazioak iradoki du"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"Eguneratu dira kontrolatzeko aukerak"</string> + <string name="controls_tile_locked" msgid="731547768182831938">"Gailua blokeatuta"</string> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN kodeak hizkiak edo ikurrak ditu"</string> <string name="controls_pin_verify" msgid="3452778292918877662">"Egiaztatu <xliff:g id="DEVICE">%s</xliff:g>"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"PIN okerra"</string> @@ -1049,8 +1055,8 @@ <string name="controls_structure_tooltip" msgid="4355922222944447867">"Pasatu hatza aukera gehiago ikusteko"</string> <string name="controls_seeding_in_progress" msgid="3033855341410264148">"Gomendioak kargatzen"</string> <string name="controls_media_title" msgid="1746947284862928133">"Multimedia-edukia"</string> - <string name="controls_media_close_session" msgid="3957093425905475065">"Ezkutatu uneko saioa."</string> - <string name="controls_media_active_session" msgid="1984383994625845642">"Ezin da ezkutatu uneko saioa."</string> + <string name="controls_media_close_session" msgid="3957093425905475065">"Ezkutatu saioa."</string> + <string name="controls_media_active_session" msgid="1984383994625845642">"Ezin da ezkutatu saioa."</string> <string name="controls_media_dismiss_button" msgid="9081375542265132213">"Baztertu"</string> <string name="controls_media_resume" msgid="1933520684481586053">"Berrekin"</string> <string name="controls_media_settings_button" msgid="5815790345117172504">"Ezarpenak"</string> diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml index 72d7b50ac850..04b14f1c482b 100644 --- a/packages/SystemUI/res/values-fa/strings.xml +++ b/packages/SystemUI/res/values-fa/strings.xml @@ -412,7 +412,8 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"تا طلوع آفتاب"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"ساعت <xliff:g id="TIME">%s</xliff:g> روشن میشود"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"تا<xliff:g id="TIME">%s</xliff:g>"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"کاهش روشنایی"</string> + <!-- no translation found for quick_settings_reduce_bright_colors_label (7537352080559075175) --> + <skip /> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"ارتباط میدان نزدیک (NFC)"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"«ارتباط میدان نزدیک» (NFC) غیرفعال است"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"«ارتباط میدان نزدیک» (NFC) فعال است"</string> @@ -446,6 +447,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"برای استفاده از NFC، قفل را باز کنید"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"این دستگاه به سازمان شما تعلق دارد"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"این دستگاه به <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> تعلق دارد"</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"انگشتتان را از نماد تلفن تند بکشید"</string> <string name="voice_hint" msgid="7476017460191291417">"برای «دستیار صوتی»، تند بکشید"</string> <string name="camera_hint" msgid="4519495795000658637">"انگشتتان را از نماد دوربین تند بکشید"</string> @@ -625,6 +628,8 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. برای صامت کردن ضربه بزنید. ممکن است سرویسهای دسترسپذیری صامت شود."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. برای تنظیم روی لرزش، ضربه بزنید."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. برای صامت کردن ضربه بزنید."</string> + <!-- no translation found for volume_ringer_change (3574969197796055532) --> + <skip /> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"صامت کردن"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"باصدا کردن"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"لرزش"</string> @@ -1038,6 +1043,7 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"افزودن"</string> <string name="controls_dialog_message" msgid="342066938390663844">"پیشنهاد <xliff:g id="APP">%s</xliff:g>"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"کنترلها بهروزرسانی شد"</string> + <string name="controls_tile_locked" msgid="731547768182831938">"دستگاه قفل است"</string> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"پین شامل حروف یا نماد است"</string> <string name="controls_pin_verify" msgid="3452778292918877662">"تأیید <xliff:g id="DEVICE">%s</xliff:g>"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"پین اشتباه است"</string> diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml index 457d765f641d..d08bfb5daabb 100644 --- a/packages/SystemUI/res/values-fi/strings.xml +++ b/packages/SystemUI/res/values-fi/strings.xml @@ -125,7 +125,7 @@ <string name="use_ptp_button_title" msgid="7676427598943446826">"Käytä kamerana (PTP)"</string> <string name="installer_cd_button_title" msgid="5499998592841984743">"Asenna Android File Transfer -sovellus Macille"</string> <string name="accessibility_back" msgid="6530104400086152611">"Takaisin"</string> - <string name="accessibility_home" msgid="5430449841237966217">"Aloituspainike"</string> + <string name="accessibility_home" msgid="5430449841237966217">"Aloitus"</string> <string name="accessibility_menu" msgid="2701163794470513040">"Valikko"</string> <string name="accessibility_accessibility_button" msgid="4089042473497107709">"Esteettömyys"</string> <string name="accessibility_rotate_button" msgid="1238584767612362586">"Näytön kääntäminen"</string> @@ -412,7 +412,8 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Auringonnousuun"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Päälle klo <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"<xliff:g id="TIME">%s</xliff:g> asti"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Vähennä kirkkautta"</string> + <!-- no translation found for quick_settings_reduce_bright_colors_label (7537352080559075175) --> + <skip /> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC on poistettu käytöstä"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC on käytössä"</string> @@ -446,6 +447,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Avaa lukitus, jotta voit käyttää NFC:tä"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Organisaatiosi omistaa tämän laitteen"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g> omistaa tämän laitteen"</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"Avaa puhelu pyyhkäisemällä."</string> <string name="voice_hint" msgid="7476017460191291417">"Avaa ääniapuri pyyhkäisemällä kuvakkeesta."</string> <string name="camera_hint" msgid="4519495795000658637">"Avaa kamera pyyhkäisemällä."</string> @@ -625,6 +628,8 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Mykistä koskettamalla. Myös esteettömyyspalvelut saattavat mykistyä."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Siirry värinätilaan napauttamalla."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Mykistä napauttamalla."</string> + <!-- no translation found for volume_ringer_change (3574969197796055532) --> + <skip /> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"mykistä"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"poista mykistys"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"värinä"</string> @@ -1038,6 +1043,7 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"Lisää"</string> <string name="controls_dialog_message" msgid="342066938390663844">"Ehdottaja: <xliff:g id="APP">%s</xliff:g>"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"Säätimet päivitetty"</string> + <string name="controls_tile_locked" msgid="731547768182831938">"Laite lukittu"</string> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN-koodi sisältää kirjaimia tai symboleja"</string> <string name="controls_pin_verify" msgid="3452778292918877662">"Vahvista <xliff:g id="DEVICE">%s</xliff:g>"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"Väärä PIN-koodi"</string> diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml index 3c4a91085fb3..3d1ab93cb238 100644 --- a/packages/SystemUI/res/values-fr-rCA/strings.xml +++ b/packages/SystemUI/res/values-fr-rCA/strings.xml @@ -412,7 +412,8 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Jusqu\'à l\'aube"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Actif à <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Jusqu\'à <xliff:g id="TIME">%s</xliff:g>"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Réduire la luminosité"</string> + <!-- no translation found for quick_settings_reduce_bright_colors_label (7537352080559075175) --> + <skip /> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC désactivée"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC activée"</string> @@ -446,6 +447,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Déverrouillez l\'écran pour utiliser la NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Cet appareil appartient à votre organisation"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"Cet appareil appartient à <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"Balayez à partir de l\'icône pour accéder au téléphone"</string> <string name="voice_hint" msgid="7476017460191291417">"Balayez à partir de l\'icône pour accéder à l\'assist. vocale"</string> <string name="camera_hint" msgid="4519495795000658637">"Balayez à partir de l\'icône pour accéder à l\'appareil photo"</string> @@ -625,6 +628,8 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Touchez pour couper le son. Il est possible de couper le son des services d\'accessibilité."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Touchez pour activer les vibrations."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Touchez pour couper le son."</string> + <!-- no translation found for volume_ringer_change (3574969197796055532) --> + <skip /> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"désactiver le son"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"réactiver le son"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibration"</string> @@ -1038,6 +1043,7 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"Ajouter"</string> <string name="controls_dialog_message" msgid="342066938390663844">"Suggestion de <xliff:g id="APP">%s</xliff:g>"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"Commandes mises à jour"</string> + <string name="controls_tile_locked" msgid="731547768182831938">"Appareil verrouillé"</string> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"Le NIP contient des lettres ou des symboles"</string> <string name="controls_pin_verify" msgid="3452778292918877662">"Vérifier <xliff:g id="DEVICE">%s</xliff:g>"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"NIP incorrect"</string> diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml index 629cbbabbba3..c6d0674f97a1 100644 --- a/packages/SystemUI/res/values-fr/strings.xml +++ b/packages/SystemUI/res/values-fr/strings.xml @@ -238,7 +238,7 @@ <skip /> <string name="accessibility_notification_dismissed" msgid="4411652015138892952">"Notification masquée"</string> <string name="accessibility_desc_notification_shade" msgid="5355229129428759989">"Volet des notifications"</string> - <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Paramètres rapides"</string> + <string name="accessibility_desc_quick_settings" msgid="4374766941484719179">"Réglages rapides"</string> <string name="accessibility_desc_lock_screen" msgid="5983125095181194887">"Écran de verrouillage"</string> <string name="accessibility_desc_settings" msgid="6728577365389151969">"Paramètres"</string> <string name="accessibility_desc_recent_apps" msgid="1748675199348914194">"Aperçu"</string> @@ -412,7 +412,8 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Jusqu\'à l\'aube"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"À partir de <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Jusqu\'à <xliff:g id="TIME">%s</xliff:g>"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Réduire la luminosité"</string> + <!-- no translation found for quick_settings_reduce_bright_colors_label (7537352080559075175) --> + <skip /> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC désactivée"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"La technologie NFC est activée"</string> @@ -446,6 +447,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Déverrouillez l\'écran pour pouvoir utiliser NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Cet appareil appartient à votre organisation"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"Cet appareil appartient à <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"Balayer pour téléphoner"</string> <string name="voice_hint" msgid="7476017460191291417">"Balayer l\'écran depuis l\'icône pour l\'assistance vocale"</string> <string name="camera_hint" msgid="4519495795000658637">"Balayer pour prendre une photo"</string> @@ -625,6 +628,8 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Appuyez pour ignorer. Vous pouvez ignorer les services d\'accessibilité."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Appuyez pour mettre en mode vibreur."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Appuyez pour ignorer."</string> + <!-- no translation found for volume_ringer_change (3574969197796055532) --> + <skip /> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"couper le son"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"réactiver le son"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"activer le vibreur"</string> @@ -640,7 +645,7 @@ <string name="system_ui_tuner" msgid="1471348823289954729">"System UI Tuner"</string> <string name="show_battery_percentage" msgid="6235377891802910455">"Afficher le pourcentage intégré de la batterie"</string> <string name="show_battery_percentage_summary" msgid="9053024758304102915">"Affichez le pourcentage correspondant au niveau de la batterie dans l\'icône de la barre d\'état lorsque l\'appareil n\'est pas en charge."</string> - <string name="quick_settings" msgid="6211774484997470203">"Configuration rapide"</string> + <string name="quick_settings" msgid="6211774484997470203">"Réglages rapides"</string> <string name="status_bar" msgid="4357390266055077437">"Barre d\'état"</string> <string name="overview" msgid="3522318590458536816">"Aperçu"</string> <string name="demo_mode" msgid="263484519766901593">"Mode de démonstration de l\'interface du système"</string> @@ -650,13 +655,13 @@ <string name="status_bar_alarm" msgid="87160847643623352">"Alarme"</string> <string name="status_bar_work" msgid="5238641949837091056">"Profil professionnel"</string> <string name="status_bar_airplane" msgid="4848702508684541009">"Mode Avion"</string> - <string name="add_tile" msgid="6239678623873086686">"Ajouter une tuile"</string> - <string name="broadcast_tile" msgid="5224010633596487481">"Tuile de diffusion"</string> + <string name="add_tile" msgid="6239678623873086686">"Ajouter un bloc"</string> + <string name="broadcast_tile" msgid="5224010633596487481">"Bloc de diffusion"</string> <string name="zen_alarm_warning_indef" msgid="5252866591716504287">"Vous n\'entendrez pas votre prochaine alarme <xliff:g id="WHEN">%1$s</xliff:g>, sauf si vous désactivez cette option avant."</string> <string name="zen_alarm_warning" msgid="7844303238486849503">"Vous n\'entendrez pas votre prochaine alarme <xliff:g id="WHEN">%1$s</xliff:g>."</string> <string name="alarm_template" msgid="2234991538018805736">"à <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="alarm_template_far" msgid="3561752195856839456">"le <xliff:g id="WHEN">%1$s</xliff:g>"</string> - <string name="accessibility_quick_settings_detail" msgid="544463655956179791">"Configuration rapide – <xliff:g id="TITLE">%s</xliff:g>"</string> + <string name="accessibility_quick_settings_detail" msgid="544463655956179791">"Réglages rapides – <xliff:g id="TITLE">%s</xliff:g>"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"Point d\'accès"</string> <string name="accessibility_managed_profile" msgid="4703836746209377356">"Profil professionnel"</string> <string name="tuner_warning_title" msgid="7721976098452135267">"Divertissant pour certains, mais pas pour tous"</string> @@ -669,8 +674,8 @@ <string name="activity_not_found" msgid="8711661533828200293">"L\'application n\'est pas installée sur votre appareil."</string> <string name="clock_seconds" msgid="8709189470828542071">"Afficher les secondes sur l\'horloge"</string> <string name="clock_seconds_desc" msgid="2415312788902144817">"Afficher les secondes dans la barre d\'état. Cela risque de réduire l\'autonomie de la batterie."</string> - <string name="qs_rearrange" msgid="484816665478662911">"Réorganiser la fenêtre de configuration rapide"</string> - <string name="show_brightness" msgid="6700267491672470007">"Afficher la luminosité dans fenêtre de configuration rapide"</string> + <string name="qs_rearrange" msgid="484816665478662911">"Réorganiser les Réglages rapides"</string> + <string name="show_brightness" msgid="6700267491672470007">"Afficher la luminosité dans les Réglages rapides"</string> <string name="experimental" msgid="3549865454812314826">"Paramètres expérimentaux"</string> <string name="enable_bluetooth_title" msgid="866883307336662596">"Activer le Bluetooth ?"</string> <string name="enable_bluetooth_message" msgid="6740938333772779717">"Pour connecter un clavier à votre tablette, vous devez avoir activé le Bluetooth."</string> @@ -878,20 +883,20 @@ </string-array> <string name="tuner_low_priority" msgid="8412666814123009820">"Afficher les icônes de notification à faible priorité"</string> <string name="other" msgid="429768510980739978">"Autre"</string> - <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"supprimer la carte"</string> - <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"ajouter la carte à la fin"</string> - <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Déplacer la carte"</string> - <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"Ajouter une carte"</string> + <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"supprimer le bloc"</string> + <string name="accessibility_qs_edit_tile_add_action" msgid="5051211910345301833">"ajouter le bloc à la fin"</string> + <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Déplacer le bloc"</string> + <string name="accessibility_qs_edit_tile_start_add" msgid="7560798153975555772">"Ajouter un bloc"</string> <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Déplacer vers <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Ajouter à la position <xliff:g id="POSITION">%1$d</xliff:g>"</string> <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Position <xliff:g id="POSITION">%1$d</xliff:g>"</string> - <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Carte ajoutée"</string> - <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Carte supprimée"</string> - <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Éditeur de configuration rapide."</string> + <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Bloc ajouté"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Bloc supprimé"</string> + <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Éditeur Réglages rapides"</string> <string name="accessibility_desc_notification_icon" msgid="7331265967584178674">"Notification <xliff:g id="ID_1">%1$s</xliff:g> : <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="accessibility_quick_settings_settings" msgid="7098489591715844713">"Ouvrir les paramètres."</string> - <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Ouvrir la fenêtre de configuration rapide."</string> - <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Fermer la fenêtre de configuration rapide."</string> + <string name="accessibility_quick_settings_expand" msgid="2609275052412521467">"Ouvrir les Réglages rapides."</string> + <string name="accessibility_quick_settings_collapse" msgid="4674876336725041982">"Fermer les Réglages rapides."</string> <string name="accessibility_quick_settings_alarm_set" msgid="7237918261045099853">"Alarme définie."</string> <string name="accessibility_quick_settings_user" msgid="505821942882668619">"Connecté en tant que <xliff:g id="ID_1">%s</xliff:g>"</string> <string name="data_connection_no_internet" msgid="691058178914184544">"Aucun accès à Internet"</string> @@ -1038,6 +1043,7 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"Ajouter"</string> <string name="controls_dialog_message" msgid="342066938390663844">"Suggérée par <xliff:g id="APP">%s</xliff:g>"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"Commandes mises à jour"</string> + <string name="controls_tile_locked" msgid="731547768182831938">"Appareil verrouillé"</string> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"Le code contient des lettres ou des symboles"</string> <string name="controls_pin_verify" msgid="3452778292918877662">"Valider <xliff:g id="DEVICE">%s</xliff:g>"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"Code incorrect"</string> diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml index 9383fb6328ce..08841a2ef866 100644 --- a/packages/SystemUI/res/values-gl/strings.xml +++ b/packages/SystemUI/res/values-gl/strings.xml @@ -412,7 +412,8 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Ata o amencer"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Activarase ás: <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Utilizarase ata as: <xliff:g id="TIME">%s</xliff:g>"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Reducir brillo"</string> + <!-- no translation found for quick_settings_reduce_bright_colors_label (7537352080559075175) --> + <skip /> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"A opción NFC está desactivada"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"A opción NFC está activada"</string> @@ -446,6 +447,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Desbloquea o dispositivo para utilizar a NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Este dispositivo pertence á túa organización"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"Este dispositivo pertence a <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"Pasa o dedo desde a icona para acceder ao teléfono"</string> <string name="voice_hint" msgid="7476017460191291417">"Pasa o dedo desde a icona para acceder ao asistente de voz"</string> <string name="camera_hint" msgid="4519495795000658637">"Pasa o dedo desde a icona para acceder á cámara"</string> @@ -625,6 +628,8 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Toca para silenciar. Pódense silenciar os servizos de accesibilidade."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Toca para establecer a vibración."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Toca para silenciar."</string> + <!-- no translation found for volume_ringer_change (3574969197796055532) --> + <skip /> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"silenciar"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"activar o son"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibrar"</string> @@ -1038,6 +1043,7 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"Engadir"</string> <string name="controls_dialog_message" msgid="342066938390663844">"Control suxerido por <xliff:g id="APP">%s</xliff:g>"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"Actualizáronse os controis"</string> + <string name="controls_tile_locked" msgid="731547768182831938">"Disposit. bloqueado"</string> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"O PIN contén letras ou símbolos"</string> <string name="controls_pin_verify" msgid="3452778292918877662">"Verificar <xliff:g id="DEVICE">%s</xliff:g>"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"O PIN é incorrecto"</string> diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml index be62a2943491..867bc2f6d38b 100644 --- a/packages/SystemUI/res/values-gu/strings.xml +++ b/packages/SystemUI/res/values-gu/strings.xml @@ -93,10 +93,8 @@ <string name="screenshot_scroll_description" msgid="7855773867093272175">"સ્ક્રીનશૉટ પર સ્ક્રોલ કરો"</string> <string name="screenshot_dismiss_description" msgid="4702341245899508786">"સ્ક્રીનશૉટ છોડી દો"</string> <string name="screenshot_preview_description" msgid="7606510140714080474">"સ્ક્રીનશૉટનો પ્રીવ્યૂ"</string> - <!-- no translation found for screenshot_top_boundary (1500569103321300856) --> - <skip /> - <!-- no translation found for screenshot_bottom_boundary (5657242629526407311) --> - <skip /> + <string name="screenshot_top_boundary" msgid="1500569103321300856">"સ્ક્રીનશૉટની સૌથી ઉપરની બાજુની સીમા"</string> + <string name="screenshot_bottom_boundary" msgid="5657242629526407311">"સ્ક્રીનશૉટની સૌથી નીચેની બાજુની સીમા"</string> <string name="screenrecord_name" msgid="2596401223859996572">"સ્ક્રીન રેકૉર્ડર"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"સ્ક્રીન રેકૉર્ડિંગ ચાલુ છે"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"સ્ક્રીન રેકોર્ડિંગ સત્ર માટે ચાલુ નોટિફિકેશન"</string> @@ -414,7 +412,8 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"સૂર્યોદય સુધી"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"<xliff:g id="TIME">%s</xliff:g> વાગ્યે ચાલુ"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"<xliff:g id="TIME">%s</xliff:g> વાગ્યા સુધી"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"બ્રાઇટનેસ ઘટાડો"</string> + <!-- no translation found for quick_settings_reduce_bright_colors_label (7537352080559075175) --> + <skip /> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC અક્ષમ કરેલ છે"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC સક્ષમ કરેલ છે"</string> @@ -448,6 +447,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFCનો ઉપયોગ કરવા માટે અનલૉક કરો"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"આ ડિવાઇસ તમારી સંસ્થાની માલિકીનું છે"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"આ ડિવાઇસ <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>ની માલિકીનું છે"</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"ફોન માટે આયકનમાંથી સ્વાઇપ કરો"</string> <string name="voice_hint" msgid="7476017460191291417">"વૉઇસ સહાય માટે આયકનમાંથી સ્વાઇપ કરો"</string> <string name="camera_hint" msgid="4519495795000658637">"કૅમેરા માટે આયકનમાંથી સ્વાઇપ કરો"</string> @@ -546,8 +547,7 @@ <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"તમારી સંસ્થાએ તમારી કાર્ય પ્રોફાઇલમાં પ્રમાણપત્ર સત્તાધિકારી ઇન્સ્ટૉલ કર્યું છે. તમારા સુરક્ષિત નેટવર્ક ટ્રાફિકનું નિયમન થઈ શકે છે અથવા તેમાં ફેરફાર કરવામાં આવી શકે છે."</string> <string name="monitoring_description_ca_certificate" msgid="448923057059097497">"આ ઉપકરણ પર પ્રમાણપત્ર સત્તાધિકારી ઇન્સ્ટૉલ કરેલ છે. તમારા સુરક્ષિત નેટવર્ક ટ્રાફિકનું નિયમન થઈ શકે છે અથવા તેમાં ફેરફાર કરવામાં આવી શકે છે."</string> <string name="monitoring_description_management_network_logging" msgid="216983105036994771">"તમારા વ્યવસ્થાપકે નેટવર્ક લૉગિંગ ચાલુ કર્યું છે, જે તમારા ઉપકરણ પર નેટવર્ક ટ્રાફિકનું નિયમન કરે છે."</string> - <!-- no translation found for monitoring_description_managed_profile_network_logging (6932303843097006037) --> - <skip /> + <string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"તમારા વ્યવસ્થાપકે નેટવર્ક લૉગ ઇન ચાલુ કર્યુ છે, જે તમારી વ્યક્તિગત પ્રોફાઇલમાં નહીં, પરંતુ ઑફિસની પ્રોફાઇલમાં ટ્રાફિકનું નિરીક્ષણ કરે છે."</string> <string name="monitoring_description_named_vpn" msgid="5749932930634037027">"તમે <xliff:g id="VPN_APP">%1$s</xliff:g> સાથે કનેક્ટ થયાં છો, જે ઇમેઇલ, ઍપ્લિકેશનો અને વેબસાઇટ સહિત તમારી નેટવર્ક પ્રવૃત્તિનું નિરીક્ષણ કરી શકે છે."</string> <string name="monitoring_description_two_named_vpns" msgid="3516830755681229463">"તમે <xliff:g id="VPN_APP_0">%1$s</xliff:g> અને <xliff:g id="VPN_APP_1">%2$s</xliff:g> સાથે કનેક્ટ થયાં છો, જે ઇમેઇલ, ઍપ્લિકેશનો અને વેબસાઇટ સહિત તમારી નેટવર્ક પ્રવૃત્તિનું નિરીક્ષણ કરી શકે છે."</string> <string name="monitoring_description_managed_profile_named_vpn" msgid="368812367182387320">"તમારી કાર્યાલયની પ્રોફાઇલ <xliff:g id="VPN_APP">%1$s</xliff:g> સાથે કનેક્ટ કરેલ છે, જે ઇમેઇલ, ઍપ્લિકેશનો અને વેબસાઇટો સહિતની તમારી નેટવર્ક પ્રવૃત્તિનું નિયમન કરી શકે છે."</string> @@ -628,6 +628,8 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. મ્યૂટ કરવા માટે ટૅપ કરો. ઍક્સેસિબિલિટી સેવાઓ મ્યૂટ કરવામાં આવી શકે છે."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. કંપન પર સેટ કરવા માટે ટૅપ કરો."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. મ્યૂટ કરવા માટે ટૅપ કરો."</string> + <!-- no translation found for volume_ringer_change (3574969197796055532) --> + <skip /> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"મ્યૂટ કરો"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"અનમ્યૂટ કરો"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"વાઇબ્રેટ"</string> @@ -1041,6 +1043,7 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"ઉમેરો"</string> <string name="controls_dialog_message" msgid="342066938390663844">"<xliff:g id="APP">%s</xliff:g> દ્વારા સૂચન કરેલા"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"નિયંત્રણ અપડેટ કર્યા"</string> + <string name="controls_tile_locked" msgid="731547768182831938">"ડિવાઇસ લૉક કરેલું છે"</string> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"પિનમાં અક્ષરો અથવા પ્રતીકોનો સમાવેશ થાય છે"</string> <string name="controls_pin_verify" msgid="3452778292918877662">"<xliff:g id="DEVICE">%s</xliff:g>ને ચકાસો"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"ખોટો પિન"</string> diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml index b487689c86c6..a357ad2b09bc 100644 --- a/packages/SystemUI/res/values-hi/strings.xml +++ b/packages/SystemUI/res/values-hi/strings.xml @@ -93,8 +93,8 @@ <string name="screenshot_scroll_description" msgid="7855773867093272175">"स्क्रीनशॉट को स्क्रोल करें"</string> <string name="screenshot_dismiss_description" msgid="4702341245899508786">"स्क्रीनशॉट को खारिज करें"</string> <string name="screenshot_preview_description" msgid="7606510140714080474">"स्क्रीनशॉट की झलक"</string> - <string name="screenshot_top_boundary" msgid="1500569103321300856">"स्क्रीनशाॉट की ऊपर की सीमा"</string> - <string name="screenshot_bottom_boundary" msgid="5657242629526407311">"स्क्रीनशॉट की नीचे की सीमा"</string> + <string name="screenshot_top_boundary" msgid="1500569103321300856">"स्क्रीनशॉट को ऊपर से काटने की सीमा"</string> + <string name="screenshot_bottom_boundary" msgid="5657242629526407311">"स्क्रीनशॉट को नीचे से काटने की सीमा"</string> <string name="screenrecord_name" msgid="2596401223859996572">"स्क्रीन रिकॉर्डर"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"स्क्रीन रिकॉर्डिंग को प्रोसेस किया जा रहा है"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"स्क्रीन रिकॉर्ड सेशन के लिए जारी सूचना"</string> @@ -414,7 +414,8 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"सुबह तक चालू रहेगी"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"<xliff:g id="TIME">%s</xliff:g> पर चालू हाेगी"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"<xliff:g id="TIME">%s</xliff:g> तक चालू रहेगी"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"स्क्रीन की चमक कम करें"</string> + <!-- no translation found for quick_settings_reduce_bright_colors_label (7537352080559075175) --> + <skip /> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"एनएफ़सी"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC बंद है"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC चालू है"</string> @@ -448,6 +449,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"एनएफ़सी इस्तेमाल करने के लिए स्क्रीन को अनलॉक करें"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"इस डिवाइस का मालिकाना हक आपके संगठन के पास है"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"इस डिवाइस का मालिकाना हक <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> के पास है"</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"फ़ोन के लिए आइकॉन से स्वाइप करें"</string> <string name="voice_hint" msgid="7476017460191291417">"\'आवाज़ से डिवाइस का इस्तेमाल\' आइकॉन से स्वाइप करें"</string> <string name="camera_hint" msgid="4519495795000658637">"कैमरे के लिए आइकॉन से स्वाइप करें"</string> @@ -546,7 +549,7 @@ <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"आपके संगठन ने आपकी वर्क प्रोफ़ाइल में एक प्रमाणपत्र अनुमति इंस्टॉल की है. आपके सुरक्षित नेटवर्क ट्रैफ़िक की निगरानी या उसमें बदलाव किया जा सकता है."</string> <string name="monitoring_description_ca_certificate" msgid="448923057059097497">"इस डिवाइस पर एक प्रमाणपत्र अनुमति इंस्टॉल की है. आपके सुरक्षित नेटवर्क ट्रैफ़िक की निगरानी या उसमें बदलाव किया जा सकता है."</string> <string name="monitoring_description_management_network_logging" msgid="216983105036994771">"आपके व्यवस्थापक ने नेटवर्क लॉगिंग चालू किया है, जो आपके डिवाइस पर ट्रैफ़िक की निगरानी करता है."</string> - <string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"आपके एडमिन ने नेटवर्क लॉगिंग की सुविधा चालू कर दी है, जिससे आपकी वर्क प्रोफ़ाइल पर आने वाले ट्रैफ़िक की निगरानी की जाती है. हालांकि, इससे आपकी निजी प्रोफ़ाइल की निगरानी नहीं की जाती."</string> + <string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"आपके एडमिन ने नेटवर्क लॉगिंग की सुविधा चालू कर दी है. इससे आपकी वर्क प्रोफ़ाइल पर आने वाले ट्रैफ़िक की निगरानी की जाती है. हालांकि, इससे आपकी निजी प्रोफ़ाइल की निगरानी नहीं की जाती."</string> <string name="monitoring_description_named_vpn" msgid="5749932930634037027">"आप <xliff:g id="VPN_APP">%1$s</xliff:g> से कनेक्ट हैं, जो ईमेल, ऐप्लिकेशन और वेबसाइटों सहित आपकी नेटवर्क गतिविधि की निगरानी कर सकते हैं."</string> <string name="monitoring_description_two_named_vpns" msgid="3516830755681229463">"आप <xliff:g id="VPN_APP_0">%1$s</xliff:g> और <xliff:g id="VPN_APP_1">%2$s</xliff:g> से कनेक्ट हैं, जो ईमेल, ऐप्लिकेशन और वेबसाइटों सहित आपकी नेटवर्क गतिविधि की निगरानी कर सकते हैं."</string> <string name="monitoring_description_managed_profile_named_vpn" msgid="368812367182387320">"आपकी वर्क प्रोफ़ाइल <xliff:g id="VPN_APP">%1$s</xliff:g> से कनेक्ट है, जो ईमेल, ऐप्लिकेशन और वेबसाइटों सहित आपकी नेटवर्क गतिविधि की निगरानी कर सकता है."</string> @@ -627,6 +630,8 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. म्यूट करने के लिए टैप करें. सुलभता सेवाएं म्यूट हो सकती हैं."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. कंपन (वाइब्रेशन) पर सेट करने के लिए छूएं."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. म्यूट करने के लिए टैप करें."</string> + <!-- no translation found for volume_ringer_change (3574969197796055532) --> + <skip /> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"म्यूट करें"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"अनम्यूट करें"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"वाइब्रेशन की सुविधा चालू करें"</string> @@ -1040,6 +1045,7 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"जोड़ें"</string> <string name="controls_dialog_message" msgid="342066938390663844">"<xliff:g id="APP">%s</xliff:g> से मिला सुझाव"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"कंट्रोल अपडेट किए गए"</string> + <string name="controls_tile_locked" msgid="731547768182831938">"डिवाइस लॉक है"</string> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"पिन में अक्षर या चिह्न शामिल होते हैं"</string> <string name="controls_pin_verify" msgid="3452778292918877662">"<xliff:g id="DEVICE">%s</xliff:g> की पुष्टि करें"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"गलत पिन"</string> diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml index 8f3d7c03be75..d8064ab2fb64 100644 --- a/packages/SystemUI/res/values-hr/strings.xml +++ b/packages/SystemUI/res/values-hr/strings.xml @@ -414,7 +414,8 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Do izlaska sunca"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Uključuje se u <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Do <xliff:g id="TIME">%s</xliff:g>"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Smanjenje svjetline"</string> + <!-- no translation found for quick_settings_reduce_bright_colors_label (7537352080559075175) --> + <skip /> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC je onemogućen"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC je omogućen"</string> @@ -448,6 +449,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Otključajte da biste upotrijebili NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Ovaj uređaj pripada vašoj organizaciji"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"Ovaj uređaj pripada organizaciji <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"Prijeđite prstom od ikone za telefon"</string> <string name="voice_hint" msgid="7476017460191291417">"Prijeđite prstom od ikone za glasovnu pomoć"</string> <string name="camera_hint" msgid="4519495795000658637">"Prijeđite prstom od ikone za fotoaparat"</string> @@ -628,6 +631,8 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Dodirnite da biste isključili zvuk. Usluge pristupačnosti možda neće imati zvuk."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Dodirnite da biste postavili na vibraciju."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Dodirnite da biste isključili zvuk."</string> + <!-- no translation found for volume_ringer_change (3574969197796055532) --> + <skip /> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"isključivanje zvuka"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"uključivanje zvuka"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibriranje"</string> @@ -1044,6 +1049,7 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"Dodaj"</string> <string name="controls_dialog_message" msgid="342066938390663844">"Preporuka s kanala <xliff:g id="APP">%s</xliff:g>"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"Kontrole su ažurirane"</string> + <string name="controls_tile_locked" msgid="731547768182831938">"Uređaj je zaključan"</string> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN sadrži slova ili simbole"</string> <string name="controls_pin_verify" msgid="3452778292918877662">"Potvrdite uređaj <xliff:g id="DEVICE">%s</xliff:g>"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"Pogrešan PIN"</string> diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml index 4fda6679e2d9..a736f88ffd6d 100644 --- a/packages/SystemUI/res/values-hu/strings.xml +++ b/packages/SystemUI/res/values-hu/strings.xml @@ -412,7 +412,8 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Napfelkeltéig"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Be: <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Eddig: <xliff:g id="TIME">%s</xliff:g>"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Fényerő csökkentése"</string> + <!-- no translation found for quick_settings_reduce_bright_colors_label (7537352080559075175) --> + <skip /> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"Az NFC ki van kapcsolva"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"Az NFC be van kapcsolva"</string> @@ -446,6 +447,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Az NFC használatához oldja fel a képernyőzárat"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Ez az eszköz az Ön szervezetének tulajdonában van"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"Ez az eszköz a(z) <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> tulajdonában van"</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"A telefonhoz csúsztasson az ikonról"</string> <string name="voice_hint" msgid="7476017460191291417">"A hangsegéd eléréséhez csúsztassa ujját az ikonról"</string> <string name="camera_hint" msgid="4519495795000658637">"A fényképezőhöz csúsztasson az ikonról"</string> @@ -625,6 +628,8 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Koppintson a némításhoz. Előfordulhat, hogy a kisegítő lehetőségek szolgáltatásai le vannak némítva."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Koppintson a rezgés beállításához."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Koppintson a némításhoz."</string> + <!-- no translation found for volume_ringer_change (3574969197796055532) --> + <skip /> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"némítás"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"némítás feloldása"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"rezgés"</string> @@ -1038,6 +1043,7 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"Hozzáadás"</string> <string name="controls_dialog_message" msgid="342066938390663844">"<xliff:g id="APP">%s</xliff:g> javasolta"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"Vezérlők frissítve"</string> + <string name="controls_tile_locked" msgid="731547768182831938">"Az eszköz zárolva van"</string> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"A PIN-kód betűket vagy szimbólumokat tartalmaz"</string> <string name="controls_pin_verify" msgid="3452778292918877662">"<xliff:g id="DEVICE">%s</xliff:g> ellenőrzése"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"Helytelen PIN-kód"</string> diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml index f0c1f21b505e..40ddf54cec04 100644 --- a/packages/SystemUI/res/values-hy/strings.xml +++ b/packages/SystemUI/res/values-hy/strings.xml @@ -412,7 +412,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Մինչև լուսաբաց"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Կմիանա՝ <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Մինչև <xliff:g id="TIME">%s</xliff:g>"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Նվազեցնել պայծառությունը"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"Պայծառության նվազեցում"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC-ն անջատված է"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC-ն միացված է"</string> @@ -446,6 +446,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Ապակողպեք՝ NFC-ն օգտագործելու համար"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Այս սարքը պատկանում է ձեր կազմակերպությանը"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"Այս սարքը պատկանում է «<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>» կազմակերպությանը"</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"Սահահարվածեք հեռախոսի պատկերակից"</string> <string name="voice_hint" msgid="7476017460191291417">"Սահահարվածեք ձայնային հուշման պատկերակից"</string> <string name="camera_hint" msgid="4519495795000658637">"Սահահարվածեք խցիկի պատկերակից"</string> @@ -625,6 +627,7 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s: Հպեք՝ ձայնն անջատելու համար: Մատչելիության ծառայությունների ձայնը կարող է անջատվել:"</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s։ Հպեք՝ թրթռոցը միացնելու համար։"</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s։ Հպեք՝ ձայնը անջատելու համար։"</string> + <string name="volume_ringer_change" msgid="3574969197796055532">"Հպեք՝ զանգակի ռեժիմը փոխելու համար"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"անջատել ձայնը"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"միացնել ձայնը"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"միացնել թրթռոցը"</string> @@ -1038,6 +1041,7 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"Ավելացնել"</string> <string name="controls_dialog_message" msgid="342066938390663844">"Առաջարկվել է <xliff:g id="APP">%s</xliff:g> հավելվածի կողմից"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"Կառավարման տարրերը թարմացվեցին"</string> + <string name="controls_tile_locked" msgid="731547768182831938">"Սարքը կողպված է"</string> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN կոդը տառեր և նշաններ է պարունակում"</string> <string name="controls_pin_verify" msgid="3452778292918877662">"Ստուգել <xliff:g id="DEVICE">%s</xliff:g> սարքը"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"PIN կոդը սխալ է"</string> diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml index 71ff39c12c8d..e20dd51276e7 100644 --- a/packages/SystemUI/res/values-in/strings.xml +++ b/packages/SystemUI/res/values-in/strings.xml @@ -412,7 +412,8 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Sampai pagi"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Aktif pada <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Sampai <xliff:g id="TIME">%s</xliff:g>"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Kurangi Kecerahan"</string> + <!-- no translation found for quick_settings_reduce_bright_colors_label (7537352080559075175) --> + <skip /> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC dinonaktifkan"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC diaktifkan"</string> @@ -446,6 +447,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Buka kunci untuk menggunakan NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Perangkat ini milik organisasi Anda"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"Perangkat ini milik <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"Geser dari ikon untuk telepon"</string> <string name="voice_hint" msgid="7476017460191291417">"Geser dari ikon untuk bantuan suara"</string> <string name="camera_hint" msgid="4519495795000658637">"Geser dari ikon untuk kamera"</string> @@ -625,6 +628,8 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Ketuk untuk membisukan. Layanan aksesibilitas mungkin dibisukan."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Ketuk untuk menyetel agar bergetar."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Ketuk untuk menonaktifkan."</string> + <!-- no translation found for volume_ringer_change (3574969197796055532) --> + <skip /> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"Tanpa suara"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"aktifkan"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"getar"</string> @@ -1038,6 +1043,7 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"Tambahkan"</string> <string name="controls_dialog_message" msgid="342066938390663844">"Disarankan oleh <xliff:g id="APP">%s</xliff:g>"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"Kontrol diperbarui"</string> + <string name="controls_tile_locked" msgid="731547768182831938">"Perangkat terkunci"</string> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN berisi huruf atau simbol"</string> <string name="controls_pin_verify" msgid="3452778292918877662">"Verifikasi <xliff:g id="DEVICE">%s</xliff:g>"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"PIN salah"</string> diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml index 482338ad3090..0c994209f544 100644 --- a/packages/SystemUI/res/values-is/strings.xml +++ b/packages/SystemUI/res/values-is/strings.xml @@ -412,7 +412,8 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Til sólarupprásar"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Virkt kl. <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Til <xliff:g id="TIME">%s</xliff:g>"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Draga úr birtu"</string> + <!-- no translation found for quick_settings_reduce_bright_colors_label (7537352080559075175) --> + <skip /> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"Slökkt á NFC"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"Kveikt á NFC"</string> @@ -446,6 +447,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Taktu úr lás til að nota NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Þetta tæki tilheyrir fyrirtækinu þínu"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"Þetta tæki tilheyrir <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"Strjúktu frá tákninu fyrir síma"</string> <string name="voice_hint" msgid="7476017460191291417">"Strjúktu frá tákninu fyrir raddaðstoð"</string> <string name="camera_hint" msgid="4519495795000658637">"Strjúktu frá tákninu fyrir myndavél"</string> @@ -625,6 +628,8 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Ýttu til að þagga. Hugsanlega verður slökkt á hljóði aðgengisþjónustu."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Ýttu til að stilla á titring."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Ýttu til að þagga."</string> + <!-- no translation found for volume_ringer_change (3574969197796055532) --> + <skip /> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"þagga"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"hætta að þagga"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"titringur"</string> @@ -1038,6 +1043,7 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"Bæta við"</string> <string name="controls_dialog_message" msgid="342066938390663844">"Tillaga frá <xliff:g id="APP">%s</xliff:g>"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"Stýringar uppfærðar"</string> + <string name="controls_tile_locked" msgid="731547768182831938">"Tækið er læst"</string> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN inniheldur bókstafi eða tákn"</string> <string name="controls_pin_verify" msgid="3452778292918877662">"Staðfesta <xliff:g id="DEVICE">%s</xliff:g>"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"Rangt PIN-númer"</string> diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml index 0896d0c5f9de..527a6956d5e3 100644 --- a/packages/SystemUI/res/values-it/strings.xml +++ b/packages/SystemUI/res/values-it/strings.xml @@ -412,7 +412,8 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Fino all\'alba"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Attivazione alle <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Fino alle <xliff:g id="TIME">%s</xliff:g>"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Riduci la luminosità"</string> + <!-- no translation found for quick_settings_reduce_bright_colors_label (7537352080559075175) --> + <skip /> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC non attiva"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC attiva"</string> @@ -446,6 +447,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Sblocca per usare NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Questo dispositivo appartiene alla tua organizzazione"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"Questo dispositivo appartiene a <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"Scorri per accedere al telefono"</string> <string name="voice_hint" msgid="7476017460191291417">"Scorri dall\'icona per accedere a Voice Assist"</string> <string name="camera_hint" msgid="4519495795000658637">"Scorri dall\'icona per accedere alla fotocamera"</string> @@ -625,6 +628,8 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Tocca per disattivare l\'audio. L\'audio dei servizi di accessibilità può essere disattivato."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Tocca per attivare la vibrazione."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Tocca per disattivare l\'audio."</string> + <!-- no translation found for volume_ringer_change (3574969197796055532) --> + <skip /> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"disattiva l\'audio"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"riattiva l\'audio"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibrazione"</string> @@ -1038,6 +1043,7 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"Aggiungi"</string> <string name="controls_dialog_message" msgid="342066938390663844">"Suggerito da <xliff:g id="APP">%s</xliff:g>"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"Controlli aggiornati"</string> + <string name="controls_tile_locked" msgid="731547768182831938">"Dispositivo bloccato"</string> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"Il PIN contiene lettere o simboli"</string> <string name="controls_pin_verify" msgid="3452778292918877662">"Verifica <xliff:g id="DEVICE">%s</xliff:g>"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"PIN errato"</string> diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml index e304dbe66c7a..9fc8b23c8e6e 100644 --- a/packages/SystemUI/res/values-iw/strings.xml +++ b/packages/SystemUI/res/values-iw/strings.xml @@ -93,10 +93,8 @@ <string name="screenshot_scroll_description" msgid="7855773867093272175">"צילום מסך נגלל"</string> <string name="screenshot_dismiss_description" msgid="4702341245899508786">"סגירת צילום מסך"</string> <string name="screenshot_preview_description" msgid="7606510140714080474">"תצוגה מקדימה של צילום מסך"</string> - <!-- no translation found for screenshot_top_boundary (1500569103321300856) --> - <skip /> - <!-- no translation found for screenshot_bottom_boundary (5657242629526407311) --> - <skip /> + <string name="screenshot_top_boundary" msgid="1500569103321300856">"הקצה העליון"</string> + <string name="screenshot_bottom_boundary" msgid="5657242629526407311">"הקצה התחתון"</string> <string name="screenrecord_name" msgid="2596401223859996572">"מקליט המסך"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"מתבצע עיבוד של הקלטת מסך"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"התראה מתמשכת לסשן הקלטת מסך"</string> @@ -418,7 +416,8 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"עד הזריחה"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"יתחיל בשעה <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"עד <xliff:g id="TIME">%s</xliff:g>"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"הפחתה של עוצמת הבהירות"</string> + <!-- no translation found for quick_settings_reduce_bright_colors_label (7537352080559075175) --> + <skip /> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC מושבת"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC מופעל"</string> @@ -452,6 +451,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"יש לבטל את הנעילה כדי להשתמש ב-NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"המכשיר הזה שייך לארגון שלך"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"המכשיר הזה שייך לארגון <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"החלק מהסמל כדי להפעיל את הטלפון"</string> <string name="voice_hint" msgid="7476017460191291417">"החלק מהסמל כדי להפעיל את המסייע הקולי"</string> <string name="camera_hint" msgid="4519495795000658637">"החלק מהסמל כדי להפעיל את המצלמה"</string> @@ -552,8 +553,7 @@ <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"הארגון שלך התקין רשות אישורים בפרופיל העבודה. ניתן לעקוב אחר התנועה ברשת המאובטחת או לשנות אותה."</string> <string name="monitoring_description_ca_certificate" msgid="448923057059097497">"במכשיר זה מותקנת רשות אישורים. ניתן לעקוב אחר התנועה ברשת המאובטחת או לשנות אותה."</string> <string name="monitoring_description_management_network_logging" msgid="216983105036994771">"מנהל המערכת הפעיל את התכונה \'רישום התנועה ברשת\', שמנטרת את תנועת הנתונים במכשיר."</string> - <!-- no translation found for monitoring_description_managed_profile_network_logging (6932303843097006037) --> - <skip /> + <string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"מנהל המערכת הפעיל את תכונת רישום התנועה ברשת, שמנטרת את תנועת הנתונים בפרופיל העבודה, אבל לא בפרופיל האישי."</string> <string name="monitoring_description_named_vpn" msgid="5749932930634037027">"אתה מחובר לאפליקציה <xliff:g id="VPN_APP">%1$s</xliff:g>, שיכולה לעקוב אחר הפעילות שלך ברשת, כולל הודעות אימייל, אפליקציות ואתרים."</string> <string name="monitoring_description_two_named_vpns" msgid="3516830755681229463">"אתה מחובר לאפליקציות <xliff:g id="VPN_APP_0">%1$s</xliff:g> ו-<xliff:g id="VPN_APP_1">%2$s</xliff:g>, שיכולות לעקוב אחר הפעילות שלך ברשת, כולל הודעות אימייל, אפליקציות ואתרים."</string> <string name="monitoring_description_managed_profile_named_vpn" msgid="368812367182387320">"פרופיל העבודה שלך מחובר לאפליקציה <xliff:g id="VPN_APP">%1$s</xliff:g>, שיכולה לעקוב אחר הפעילות שלך ברשת, כולל הודעות אימייל, אפליקציות ואתרים."</string> @@ -634,6 +634,8 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. הקש כדי להשתיק. ייתכן ששירותי הנגישות מושתקים."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. הקש כדי להעביר למצב רטט."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. הקש כדי להשתיק."</string> + <!-- no translation found for volume_ringer_change (3574969197796055532) --> + <skip /> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"השתקה"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"ביטול ההשתקה"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"רטט"</string> @@ -1053,6 +1055,7 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"הוספה"</string> <string name="controls_dialog_message" msgid="342066938390663844">"הוצע על-ידי <xliff:g id="APP">%s</xliff:g>"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"הפקדים עודכנו"</string> + <string name="controls_tile_locked" msgid="731547768182831938">"המכשיר נעול"</string> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"קוד האימות מכיל אותיות או סמלים"</string> <string name="controls_pin_verify" msgid="3452778292918877662">"אימות <xliff:g id="DEVICE">%s</xliff:g>"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"קוד גישה שגוי"</string> diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml index 05b1f7679e59..1b18b5ce4607 100644 --- a/packages/SystemUI/res/values-ja/strings.xml +++ b/packages/SystemUI/res/values-ja/strings.xml @@ -412,7 +412,8 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"日の出まで"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"<xliff:g id="TIME">%s</xliff:g>にオン"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"<xliff:g id="TIME">%s</xliff:g>まで"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"明るさを下げる"</string> + <!-- no translation found for quick_settings_reduce_bright_colors_label (7537352080559075175) --> + <skip /> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC は無効です"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC は有効です"</string> @@ -446,6 +447,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC を使用するには、ロックを解除してください"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"これは組織が所有するデバイスです"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"これは <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> が所有するデバイスです"</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"右にスワイプして通話"</string> <string name="voice_hint" msgid="7476017460191291417">"アイコンからスワイプして音声アシストを起動"</string> <string name="camera_hint" msgid="4519495795000658637">"左にスワイプしてカメラを起動"</string> @@ -625,6 +628,8 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s。タップしてミュートします。ユーザー補助機能サービスがミュートされる場合があります。"</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s。タップしてバイブレーションに設定します。"</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s。タップしてミュートします。"</string> + <!-- no translation found for volume_ringer_change (3574969197796055532) --> + <skip /> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"ミュート"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"ミュートを解除"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"バイブレーション"</string> @@ -1038,6 +1043,7 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"追加"</string> <string name="controls_dialog_message" msgid="342066938390663844">"<xliff:g id="APP">%s</xliff:g> によるおすすめ"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"コントロールを更新しました"</string> + <string name="controls_tile_locked" msgid="731547768182831938">"デバイス: ロック状態"</string> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN に英字や記号を含める"</string> <string name="controls_pin_verify" msgid="3452778292918877662">"<xliff:g id="DEVICE">%s</xliff:g>の確認"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"PIN が間違っています"</string> diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml index 5404e67a927b..e2b9fac8f208 100644 --- a/packages/SystemUI/res/values-ka/strings.xml +++ b/packages/SystemUI/res/values-ka/strings.xml @@ -412,7 +412,8 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"მზის ამოსვლამდე"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"ჩაირთოს <xliff:g id="TIME">%s</xliff:g>-ზე"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"<xliff:g id="TIME">%s</xliff:g>-მდე"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"სიკაშკაშის შემცირება"</string> + <!-- no translation found for quick_settings_reduce_bright_colors_label (7537352080559075175) --> + <skip /> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC გათიშულია"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC ჩართულია"</string> @@ -446,6 +447,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"განბლოკეთ NFC-ის გამოსაყენებლად"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"ამ მოწყობილობას ფლობს თქვენი ორგანიზაცია"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"ამ მოწყობილობას ფლობს <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"ტელეფონისთვის გადაფურცლეთ ხატულადან"</string> <string name="voice_hint" msgid="7476017460191291417">"ხმოვანი დახმარებისთვის გადაფურცლეთ ხატულადან"</string> <string name="camera_hint" msgid="4519495795000658637">"კამერისთვის გადაფურცლეთ ხატულადან"</string> @@ -625,6 +628,8 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. შეეხეთ დასადუმებლად. შეიძლება დადუმდეს მარტივი წვდომის სერვისებიც."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. შეეხეთ ვიბრაციაზე დასაყენებლად."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. შეეხეთ დასადუმებლად."</string> + <!-- no translation found for volume_ringer_change (3574969197796055532) --> + <skip /> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"დადუმება"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"დადუმების მოხსნა"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"ვიბრაცია"</string> @@ -1038,6 +1043,7 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"დამატება"</string> <string name="controls_dialog_message" msgid="342066938390663844">"შემოთავაზებულია <xliff:g id="APP">%s</xliff:g>-ის მიერ"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"მართვის საშუალებები განახლდა"</string> + <string name="controls_tile_locked" msgid="731547768182831938">"მოწყობილ. ჩაკეტილია"</string> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN-კოდი შეიცავს ასოებს ან სიმბოლოებს"</string> <string name="controls_pin_verify" msgid="3452778292918877662">"დაადასტურეთ <xliff:g id="DEVICE">%s</xliff:g>"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"PIN-კოდი არასწორია"</string> diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml index 21c62018bef1..1fbb8a51372b 100644 --- a/packages/SystemUI/res/values-kk/strings.xml +++ b/packages/SystemUI/res/values-kk/strings.xml @@ -412,7 +412,8 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Күн шыққанға дейін"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Қосылу уақыты: <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"<xliff:g id="TIME">%s</xliff:g> дейін"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Жарықтығын азайту"</string> + <!-- no translation found for quick_settings_reduce_bright_colors_label (7537352080559075175) --> + <skip /> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC өшірулі"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC қосулы"</string> @@ -446,6 +447,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC пайдалану үшін құлыпты ашыңыз."</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Бұл құрылғы ұйымыңызға тиесілі."</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"Бұл құрылғы <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> ұйымына тиесілі."</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"Телефонды ашу үшін белгішеден әрі қарай сырғытыңыз"</string> <string name="voice_hint" msgid="7476017460191291417">"Дауыс көмекшісін ашу үшін белгішеден әрі қарай сырғытыңыз"</string> <string name="camera_hint" msgid="4519495795000658637">"Камераны ашу үшін белгішеден әрі қарай сырғытыңыз"</string> @@ -625,6 +628,8 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Дыбысын өшіру үшін түртіңіз. Арнайы мүмкіндік қызметтерінің дыбысы өшуі мүмкін."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Діріл режимін орнату үшін түртіңіз."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Дыбысын өшіру үшін түртіңіз."</string> + <!-- no translation found for volume_ringer_change (3574969197796055532) --> + <skip /> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"дыбысын өшіру"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"дыбысын қосу"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"дірілдету"</string> @@ -1038,6 +1043,7 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"Енгізу"</string> <string name="controls_dialog_message" msgid="342066938390663844">"<xliff:g id="APP">%s</xliff:g> ұсынған"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"Басқару элементтері жаңартылды"</string> + <string name="controls_tile_locked" msgid="731547768182831938">"Құрылғы құлыпталды."</string> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN коды әріптерден не таңбалардан құралады."</string> <string name="controls_pin_verify" msgid="3452778292918877662">"<xliff:g id="DEVICE">%s</xliff:g> растау"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"PIN коды қате"</string> diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml index 567bfa87c316..e6f96688a15d 100644 --- a/packages/SystemUI/res/values-km/strings.xml +++ b/packages/SystemUI/res/values-km/strings.xml @@ -412,7 +412,8 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"រហូតដល់ពេលថ្ងៃរះ"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"បើកនៅម៉ោង <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"រហូតដល់ម៉ោង <xliff:g id="TIME">%s</xliff:g>"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"បន្ថយពន្លឺ"</string> + <!-- no translation found for quick_settings_reduce_bright_colors_label (7537352080559075175) --> + <skip /> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"បានបិទ NFC"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"បានបើក NFC"</string> @@ -446,6 +447,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"ដោះសោ ដើម្បីប្រើ NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"ឧបករណ៍នេះគឺជាកម្មសិទ្ធិរបស់ស្ថាប័នអ្នក"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"ឧបករណ៍នេះគឺជាកម្មសិទ្ធិរបស់ <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"អូសចេញពីរូបតំណាងដើម្បីប្រើទូរស័ព្ទ"</string> <string name="voice_hint" msgid="7476017460191291417">"អូសចេញពីរូបតំណាងដើម្បីប្រើជំនួយសំឡេង"</string> <string name="camera_hint" msgid="4519495795000658637">"អូសចេញពីរូបតំណាងដើម្បីប្រើកាមេរ៉ា"</string> @@ -625,6 +628,8 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s។ ប៉ះដើម្បីបិទសំឡេង។ សេវាកម្មលទ្ធភាពប្រើប្រាស់អាចនឹងត្រូវបានបិទសំឡេង។"</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s ។ ចុចដើម្បីកំណត់ឲ្យញ័រ។"</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s ។ ចុចដើម្បីបិទសំឡេង។"</string> + <!-- no translation found for volume_ringer_change (3574969197796055532) --> + <skip /> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"បិទសំឡេង"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"បើកសំឡេង"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"ញ័រ"</string> @@ -1038,6 +1043,7 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"បញ្ចូល"</string> <string name="controls_dialog_message" msgid="342066938390663844">"បានណែនាំដោយ <xliff:g id="APP">%s</xliff:g>"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"បានធ្វើបច្ចុប្បន្នភាពការគ្រប់គ្រង"</string> + <string name="controls_tile_locked" msgid="731547768182831938">"បានចាក់សោឧបករណ៍"</string> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"កូដ PIN មានអក្សរ ឬនិមិត្តសញ្ញា"</string> <string name="controls_pin_verify" msgid="3452778292918877662">"ផ្ទៀងផ្ទាត់ <xliff:g id="DEVICE">%s</xliff:g>"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"កូដ PIN មិនត្រឹមត្រូវ"</string> diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml index e0ea3c223819..15abcaa7d326 100644 --- a/packages/SystemUI/res/values-kn/strings.xml +++ b/packages/SystemUI/res/values-kn/strings.xml @@ -412,7 +412,8 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"ಸೂರ್ಯೋದಯದವರೆಗೆ"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"<xliff:g id="TIME">%s</xliff:g> ಸಮಯದಲ್ಲಿ"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"<xliff:g id="TIME">%s</xliff:g> ವರೆಗೂ"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"ಪ್ರಖರತೆಯನ್ನು ಕಡಿಮೆ ಮಾಡಿ"</string> + <!-- no translation found for quick_settings_reduce_bright_colors_label (7537352080559075175) --> + <skip /> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC ನಿಷ್ಕ್ರಿಯಗೊಂಡಿದೆ"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC ಸಕ್ರಿಯಗೊಂಡಿದೆ"</string> @@ -446,6 +447,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC ಬಳಸಲು ಅನ್ಲಾಕ್ ಮಾಡಿ"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"ಈ ಸಾಧನವು ನಿಮ್ಮ ಸಂಸ್ಥೆಗೆ ಸೇರಿದೆ"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"ಈ ಸಾಧನವು <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> ಗೆ ಸೇರಿದೆ"</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"ಫೋನ್ಗಾಗಿ ಐಕಾನ್ನಿಂದ ಸ್ವೈಪ್ ಮಾಡಿ"</string> <string name="voice_hint" msgid="7476017460191291417">"ಧ್ವನಿ ಸಹಾಯಕ್ಕಾಗಿ ಐಕಾನ್ನಿಂದ ಸ್ವೈಪ್ ಮಾಡಿ"</string> <string name="camera_hint" msgid="4519495795000658637">"ಕ್ಯಾಮರಾಗಾಗಿ ಐಕಾನ್ನಿಂದ ಸ್ವೈಪ್ ಮಾಡಿ"</string> @@ -625,6 +628,8 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. ಮ್ಯೂಟ್ ಮಾಡಲು ಟ್ಯಾಪ್ ಮಾಡಿ. ಪ್ರವೇಶಿಸುವಿಕೆ ಸೇವೆಗಳನ್ನು ಮ್ಯೂಟ್ ಮಾಡಬಹುದು."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. ವೈಬ್ರೇಟ್ ಮಾಡಲು ಹೊಂದಿಸುವುದಕ್ಕಾಗಿ ಟ್ಯಾಪ್ ಮಾಡಿ."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. ಮ್ಯೂಟ್ ಮಾಡಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string> + <!-- no translation found for volume_ringer_change (3574969197796055532) --> + <skip /> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"ಮ್ಯೂಟ್ ಮಾಡಿ"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"ಅನ್ಮ್ಯೂಟ್ ಮಾಡಿ"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"ವೈಬ್ರೇಟ್"</string> @@ -1038,6 +1043,8 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"ಸೇರಿಸಿ"</string> <string name="controls_dialog_message" msgid="342066938390663844">"<xliff:g id="APP">%s</xliff:g> ಆ್ಯಪ್ ಸೂಚಿಸಿದೆ"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"ನಿಯಂತ್ರಣಗಳನ್ನು ನವೀಕರಿಸಲಾಗಿದೆ"</string> + <!-- no translation found for controls_tile_locked (731547768182831938) --> + <skip /> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"ಪಿನ್ ಅಕ್ಷರಗಳು ಅಥವಾ ಸಂಕೇತಗಳನ್ನು ಒಳಗೊಂಡಿದೆ"</string> <string name="controls_pin_verify" msgid="3452778292918877662">"<xliff:g id="DEVICE">%s</xliff:g> ಅನ್ನು ಪರಿಶೀಲಿಸಿ"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"ತಪ್ಪಾದ ಪಿನ್"</string> diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml index 64e4a69d1db3..78c2958f017c 100644 --- a/packages/SystemUI/res/values-ko/strings.xml +++ b/packages/SystemUI/res/values-ko/strings.xml @@ -412,7 +412,8 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"일출까지"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"<xliff:g id="TIME">%s</xliff:g>에 켜짐"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"<xliff:g id="TIME">%s</xliff:g>까지"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"밝기 낮추기"</string> + <!-- no translation found for quick_settings_reduce_bright_colors_label (7537352080559075175) --> + <skip /> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC 사용 중지됨"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC 사용 설정됨"</string> @@ -446,6 +447,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"잠금 해제하여 NFC 사용"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"내 조직에 속한 기기입니다."</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>에 속한 기기입니다."</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"전화 기능을 사용하려면 아이콘에서 스와이프하세요."</string> <string name="voice_hint" msgid="7476017460191291417">"음성 지원을 사용하려면 아이콘에서 스와이프하세요."</string> <string name="camera_hint" msgid="4519495795000658637">"카메라를 사용하려면 아이콘에서 스와이프하세요."</string> @@ -625,6 +628,8 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. 탭하여 음소거로 설정하세요. 접근성 서비스가 음소거될 수 있습니다."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. 탭하여 진동으로 설정하세요."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. 탭하여 음소거로 설정하세요."</string> + <!-- no translation found for volume_ringer_change (3574969197796055532) --> + <skip /> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"음소거"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"음소거 해제"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"진동"</string> @@ -1038,6 +1043,7 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"추가"</string> <string name="controls_dialog_message" msgid="342066938390663844">"<xliff:g id="APP">%s</xliff:g>에서 제안"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"컨트롤 업데이트됨"</string> + <string name="controls_tile_locked" msgid="731547768182831938">"기기 잠김"</string> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN에 문자나 기호가 포함됨"</string> <string name="controls_pin_verify" msgid="3452778292918877662">"<xliff:g id="DEVICE">%s</xliff:g> 확인"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"잘못된 PIN"</string> diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml index ecbcd55ad962..7a4d7d2caf57 100644 --- a/packages/SystemUI/res/values-ky/strings.xml +++ b/packages/SystemUI/res/values-ky/strings.xml @@ -94,7 +94,7 @@ <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Скриншотту четке кагуу"</string> <string name="screenshot_preview_description" msgid="7606510140714080474">"Скриншотту алдын ала көрүү"</string> <string name="screenshot_top_boundary" msgid="1500569103321300856">"Жогорку чеги"</string> - <string name="screenshot_bottom_boundary" msgid="5657242629526407311">"Баскычтын чеги"</string> + <string name="screenshot_bottom_boundary" msgid="5657242629526407311">"Төмөнкү чеги"</string> <string name="screenrecord_name" msgid="2596401223859996572">"экрандан видео жаздырып алуу"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Экрандан жаздырылып алынган видео иштетилүүдө"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"Экранды жаздыруу сеансы боюнча учурдагы билдирме"</string> @@ -414,7 +414,8 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Күн чыкканга чейин"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Саат <xliff:g id="TIME">%s</xliff:g> күйөт"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"<xliff:g id="TIME">%s</xliff:g> чейин"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Экрандын жарыктыгын төмөндөтүү"</string> + <!-- no translation found for quick_settings_reduce_bright_colors_label (7537352080559075175) --> + <skip /> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC өчүрүлгөн"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC иштетилген"</string> @@ -448,6 +449,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC колдонуу үчүн түзмөктүн кулпусун ачыңыз"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Бул түзмөк уюмуңузга таандык"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"Бул түзмөк төмөнкүгө таандык: <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"Сүрөтчөнү сүрүп телефонго өтүңүз"</string> <string name="voice_hint" msgid="7476017460191291417">"Сүрөтчөнү сүрүп үн жардамчысына өтүңүз"</string> <string name="camera_hint" msgid="4519495795000658637">"Сүрөтчөнү сүрүп камерага өтүңүз"</string> @@ -627,6 +630,8 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Үнүн өчүрүү үчүн таптап коюңуз. Атайын мүмкүнчүлүктөр кызматынын үнүн өчүрүп койсо болот."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Дирилдөөгө коюу үчүн басыңыз."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Үнүн өчүрүү үчүн басыңыз."</string> + <!-- no translation found for volume_ringer_change (3574969197796055532) --> + <skip /> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"үнсүз"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"үнүн чыгаруу"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"дирилдөө"</string> @@ -1040,6 +1045,7 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"Кошуу"</string> <string name="controls_dialog_message" msgid="342066938390663844">"<xliff:g id="APP">%s</xliff:g> сунуштайт"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"Башкаруу элементтери жаңырды"</string> + <string name="controls_tile_locked" msgid="731547768182831938">"Түзмөк кулпуланды"</string> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN код тамгалардан же символдордон турат"</string> <string name="controls_pin_verify" msgid="3452778292918877662">"<xliff:g id="DEVICE">%s</xliff:g> түзмөгүн ырастаңыз"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"PIN код туура эмес"</string> diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml index 98a75c28ca8a..7070fa19802c 100644 --- a/packages/SystemUI/res/values-lo/strings.xml +++ b/packages/SystemUI/res/values-lo/strings.xml @@ -412,7 +412,8 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"ຈົນກວ່າຕາເວັນຂຶ້ນ"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"ເປີດເວລາ <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"ຈົນຮອດ <xliff:g id="TIME">%s</xliff:g>"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"ຫຼຸດຄວາມສະຫວ່າງ"</string> + <!-- no translation found for quick_settings_reduce_bright_colors_label (7537352080559075175) --> + <skip /> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC is disabled"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC is enabled"</string> @@ -446,6 +447,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"ປົດລັອກເພື່ອໃຊ້ NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"ອຸປະກອນນີ້ເປັນຂອງອົງການທ່ານ"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"ອຸປະກອນນີ້ເປັນຂອງ <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"ປັດຈາກໄອຄອນສຳລັບໂທລະສັບ"</string> <string name="voice_hint" msgid="7476017460191291417">"ປັດຈາກໄອຄອນສຳລັບການຊ່ວຍທາງສຽງ"</string> <string name="camera_hint" msgid="4519495795000658637">"ປັດຈາກໄອຄອນສຳລັບກ້ອງຖ່າຍຮູບ"</string> @@ -625,6 +628,8 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. ແຕະເພື່ອປິດສຽງ. ບໍລິການຊ່ວຍເຂົ້າເຖິງອາດຖືກປິດສຽງໄວ້."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. ແຕະເພື່ອຕັ້ງເປັນສັ່ນເຕືອນ."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. ແຕະເພື່ອປິດສຽງ."</string> + <!-- no translation found for volume_ringer_change (3574969197796055532) --> + <skip /> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"ປິດສຽງ"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"ເຊົາປິດສຽງ"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"ສັ່ນເຕືອນ"</string> @@ -1038,6 +1043,7 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"ເພີ່ມ"</string> <string name="controls_dialog_message" msgid="342066938390663844">"ແນະນຳໂດຍ <xliff:g id="APP">%s</xliff:g>"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"ອັບເດດການຄວບຄຸມແລ້ວ"</string> + <string name="controls_tile_locked" msgid="731547768182831938">"ອຸປະກອນຖືກລັອກໄວ້"</string> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN ປະກອບມີຕົວອັກສອນ ຫຼື ສັນຍາລັກ"</string> <string name="controls_pin_verify" msgid="3452778292918877662">"ຢັ້ງຢືນ <xliff:g id="DEVICE">%s</xliff:g>"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"PIN ບໍ່ຖືກຕ້ອງ"</string> diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml index f4a2a0d6cc75..ff69e056793b 100644 --- a/packages/SystemUI/res/values-lt/strings.xml +++ b/packages/SystemUI/res/values-lt/strings.xml @@ -416,7 +416,8 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Iki saulėtekio"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"<xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Iki <xliff:g id="TIME">%s</xliff:g>"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Šviesumo mažinimas"</string> + <!-- no translation found for quick_settings_reduce_bright_colors_label (7537352080559075175) --> + <skip /> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"ALR"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"ALR išjungtas"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"ALR įjungtas"</string> @@ -450,6 +451,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Norėdami naudoti NFC, atrakinkite"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Šis įrenginys priklauso jūsų organizacijai"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"Šis įrenginys priklauso „<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>“"</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"Perbraukite iš telefono piktogramos"</string> <string name="voice_hint" msgid="7476017460191291417">"Perbraukite iš „Voice Assist“ piktogramos"</string> <string name="camera_hint" msgid="4519495795000658637">"Perbraukite iš fotoaparato piktogramos"</string> @@ -631,6 +634,8 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Palieskite, kad nutildytumėte. Gali būti nutildytos pritaikymo neįgaliesiems paslaugos."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Palieskite, kad nustatytumėte vibravimą."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Palieskite, kad nutildytumėte."</string> + <!-- no translation found for volume_ringer_change (3574969197796055532) --> + <skip /> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"nutildyti"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"įjungti garsą"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibruoti"</string> @@ -1050,6 +1055,7 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"Pridėti"</string> <string name="controls_dialog_message" msgid="342066938390663844">"Siūlo „<xliff:g id="APP">%s</xliff:g>“"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"Valdikliai atnaujinti"</string> + <string name="controls_tile_locked" msgid="731547768182831938">"Įrenginys užrakintas"</string> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN kodą sudaro raidės arba simboliai"</string> <string name="controls_pin_verify" msgid="3452778292918877662">"<xliff:g id="DEVICE">%s</xliff:g> patvirtinimas"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"Netinkamas PIN kodas"</string> diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml index caca22cc5aba..18816ad0c913 100644 --- a/packages/SystemUI/res/values-lv/strings.xml +++ b/packages/SystemUI/res/values-lv/strings.xml @@ -414,7 +414,8 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Līdz saullēktam"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Plkst. <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Līdz plkst. <xliff:g id="TIME">%s</xliff:g>"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Spilgtuma samazināšana"</string> + <!-- no translation found for quick_settings_reduce_bright_colors_label (7537352080559075175) --> + <skip /> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC ir atspējoti"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC ir iespējoti"</string> @@ -448,6 +449,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Atbloķējiet ierīci, lai izmantotu NFC."</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Šī ierīce pieder jūsu organizācijai."</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"Šī ierīce pieder organizācijai <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>."</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"Lai lietotu tālruni, velciet no ikonas"</string> <string name="voice_hint" msgid="7476017460191291417">"Lai lietotu balss palīgu, velciet no ikonas"</string> <string name="camera_hint" msgid="4519495795000658637">"Lai lietotu kameru, velciet no ikonas"</string> @@ -628,6 +631,8 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Pieskarieties, lai izslēgtu skaņu. Var tikt izslēgti pieejamības pakalpojumu signāli."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Pieskarieties, lai iestatītu vibrozvanu."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Pieskarieties, lai izslēgtu skaņu."</string> + <!-- no translation found for volume_ringer_change (3574969197796055532) --> + <skip /> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"izslēgt skaņu"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"ieslēgt skaņu"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibrēt"</string> @@ -1044,6 +1049,7 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"Pievienot"</string> <string name="controls_dialog_message" msgid="342066938390663844">"Ieteica: <xliff:g id="APP">%s</xliff:g>"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"Vadīklas atjauninātas"</string> + <string name="controls_tile_locked" msgid="731547768182831938">"Ierīce ir bloķēta"</string> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN ietver burtus vai simbolus."</string> <string name="controls_pin_verify" msgid="3452778292918877662">"Verifikācija: <xliff:g id="DEVICE">%s</xliff:g>"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"Nepareizs PIN"</string> diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml index b3b4a4531d9e..59fc2d4849c2 100644 --- a/packages/SystemUI/res/values-mk/strings.xml +++ b/packages/SystemUI/res/values-mk/strings.xml @@ -412,7 +412,8 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"До изгрејсонце"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Се вклучува во <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"До <xliff:g id="TIME">%s</xliff:g>"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Намали ја осветленоста"</string> + <!-- no translation found for quick_settings_reduce_bright_colors_label (7537352080559075175) --> + <skip /> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC е оневозможено"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC е овозможено"</string> @@ -446,6 +447,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Отклучете за да користите NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Уредов е во сопственост на организацијата"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"Уредов е во сопственост на <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"Повлечете од иконата за телефонот"</string> <string name="voice_hint" msgid="7476017460191291417">"Повлечете од иконата за гласовна помош"</string> <string name="camera_hint" msgid="4519495795000658637">"Повлечете од иконата за камерата"</string> @@ -505,7 +508,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> @@ -625,6 +628,8 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Допрете за да исклучите звук. Можеби ќе се исклучи звукот на услугите за достапност."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Допрете за да се постави на вибрации."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Допрете за да се исклучи звукот."</string> + <!-- no translation found for volume_ringer_change (3574969197796055532) --> + <skip /> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"исклучен звук"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"вклучен звук"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"вибрации"</string> @@ -1038,6 +1043,7 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"Додај"</string> <string name="controls_dialog_message" msgid="342066938390663844">"Предложено од <xliff:g id="APP">%s</xliff:g>"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"Контролите се ажурирани"</string> + <string name="controls_tile_locked" msgid="731547768182831938">"Уредот е заклучен"</string> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN-кодот содржи букви или симболи"</string> <string name="controls_pin_verify" msgid="3452778292918877662">"Потврдете го <xliff:g id="DEVICE">%s</xliff:g>"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"Погрешен PIN"</string> diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml index 420de5bbcb79..44883d6dd797 100644 --- a/packages/SystemUI/res/values-ml/strings.xml +++ b/packages/SystemUI/res/values-ml/strings.xml @@ -93,10 +93,8 @@ <string name="screenshot_scroll_description" msgid="7855773867093272175">"സ്ക്രീൻഷോട്ട് സ്ക്രോൾ ചെയ്യുക"</string> <string name="screenshot_dismiss_description" msgid="4702341245899508786">"സ്ക്രീൻഷോട്ട് ഡിസ്മിസ് ചെയ്യുക"</string> <string name="screenshot_preview_description" msgid="7606510140714080474">"സ്ക്രീൻഷോട്ട് പ്രിവ്യു"</string> - <!-- no translation found for screenshot_top_boundary (1500569103321300856) --> - <skip /> - <!-- no translation found for screenshot_bottom_boundary (5657242629526407311) --> - <skip /> + <string name="screenshot_top_boundary" msgid="1500569103321300856">"മുകളിലുള്ള അതിർത്തി"</string> + <string name="screenshot_bottom_boundary" msgid="5657242629526407311">"ചുവടെയുള്ള അതിർത്തി"</string> <string name="screenrecord_name" msgid="2596401223859996572">"സ്ക്രീൻ റെക്കോർഡർ"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"സ്ക്രീൻ റെക്കോർഡിംഗ് പ്രോസസുചെയ്യുന്നു"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"ഒരു സ്ക്രീൻ റെക്കോർഡിംഗ് സെഷനായി നിലവിലുള്ള അറിയിപ്പ്"</string> @@ -414,7 +412,8 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"സൂര്യോദയം വരെ"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"<xliff:g id="TIME">%s</xliff:g>-ന്"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"<xliff:g id="TIME">%s</xliff:g> വരെ"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"തെളിച്ചം കുറയ്ക്കുക"</string> + <!-- no translation found for quick_settings_reduce_bright_colors_label (7537352080559075175) --> + <skip /> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC പ്രവർത്തനരഹിതമാക്കി"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC പ്രവർത്തനക്ഷമമാക്കി"</string> @@ -448,6 +447,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC ഉപയോഗിക്കാൻ അൺലോക്ക് ചെയ്യുക"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"ഈ ഉപകരണം നിങ്ങളുടെ സ്ഥാപനത്തിന്റേതാണ്"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"ഈ ഉപകരണം <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> എന്ന സ്ഥാപനത്തിന്റേതാണ്"</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"ഫോൺ ഐക്കണിൽ നിന്ന് സ്വൈപ്പുചെയ്യുക"</string> <string name="voice_hint" msgid="7476017460191291417">"വോയ്സ് അസിസ്റ്റിനായുള്ള ഐക്കണിൽ നിന്ന് സ്വൈപ്പുചെയ്യുക"</string> <string name="camera_hint" msgid="4519495795000658637">"ക്യാമറ ഐക്കണിൽ നിന്ന് സ്വൈപ്പുചെയ്യുക"</string> @@ -546,8 +547,7 @@ <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"നിങ്ങളുടെ ഔദ്യോഗിക പ്രൊഫൈലിൽ നിങ്ങളുടെ സ്ഥാപനമൊരു സർട്ടിഫിക്കറ്റ് അതോറിറ്റി ഇൻസ്റ്റാൾ ചെയ്തിരിക്കുന്നു. നിങ്ങളുടെ സുരക്ഷിത നെറ്റ്വർക്ക് ട്രാഫിക്ക് നിരീക്ഷിക്കപ്പെടുകയോ പരിഷ്കരിക്കപ്പെടുയോ ചെയ്തേക്കാം."</string> <string name="monitoring_description_ca_certificate" msgid="448923057059097497">"നിങ്ങളുടെ ഉപകരണത്തിൽ ഒരു സർട്ടിഫിക്കറ്റ് അതോറിറ്റി ഇൻസ്റ്റാൾ ചെയ്തിരിക്കുന്നു. നിങ്ങളുടെ സുരക്ഷിത നെറ്റ്വർക്ക് ട്രാഫിക്ക് നിരീക്ഷിക്കപ്പെടുകയോ പരിഷ്കരിക്കപ്പെടുയോ ചെയ്തേക്കാം."</string> <string name="monitoring_description_management_network_logging" msgid="216983105036994771">"നിങ്ങളുടെ അഡ്മിൻ, നെറ്റ്വർക്ക് ലോഗിംഗ് ഓണാക്കിയിട്ടുണ്ട്, ഇതിന് നിങ്ങളുടെ ഉപകരണത്തിലെ ട്രാഫിക്ക് നിരീക്ഷിക്കാൻ കഴിയും."</string> - <!-- no translation found for monitoring_description_managed_profile_network_logging (6932303843097006037) --> - <skip /> + <string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"നിങ്ങളുടെ അഡ്മിൻ നെറ്റ്വർക്ക് ലോഗിംഗ് ഓണാക്കി, ഇത് നിങ്ങളുടെ ഔദ്യോഗിക പ്രൊഫൈലിലെ ട്രാഫിക് നിരീക്ഷിക്കുന്നു എന്നാൽ വ്യക്തിപരമായ പ്രൊഫൈലിലെ ട്രാഫിക് നിരീക്ഷിക്കുന്നില്ല."</string> <string name="monitoring_description_named_vpn" msgid="5749932930634037027">"നിങ്ങൾ <xliff:g id="VPN_APP">%1$s</xliff:g> എന്ന ആപ്പിലേക്ക് കണക്റ്റുചെയ്തിരിക്കുന്നു, ഇമെയിലുകൾ, ആപ്പുകൾ, വെബ്സൈറ്റുകൾ എന്നിവ ഉൾപ്പെടെ നിങ്ങളുടെ നെറ്റ്വർക്ക് ആക്റ്റിവിറ്റി നിരീക്ഷിക്കാൻ ഈ ആപ്പിന് കഴിയും."</string> <string name="monitoring_description_two_named_vpns" msgid="3516830755681229463">"നിങ്ങൾ <xliff:g id="VPN_APP_0">%1$s</xliff:g>, <xliff:g id="VPN_APP_1">%2$s</xliff:g> എന്നീ ആപ്പുകളിലേക്ക് കണക്റ്റുചെയ്തിരിക്കുന്നു, ഇമെയിലുകൾ, ആപ്പുകൾ, വെബ്സൈറ്റുകൾ എന്നിവ ഉൾപ്പെടെ നിങ്ങളുടെ നെറ്റ്വർക്ക് ആക്റ്റിവിറ്റി നിരീക്ഷിക്കാൻ ഈ ആപ്പിന് കഴിയും."</string> <string name="monitoring_description_managed_profile_named_vpn" msgid="368812367182387320">"<xliff:g id="VPN_APP">%1$s</xliff:g> ആപ്പിലേക്ക് നിങ്ങളുടെ ഔദ്യോഗിക പ്രൊഫൈൽ കണക്റ്റുചെയ്തിരിക്കുന്നു, ഇമെയിലുകൾ, ആപ്സ്, വെബ്സൈറ്റുകൾ എന്നിവ ഉൾപ്പെടെ നിങ്ങളുടെ നെറ്റ്വർക്ക് ആക്റ്റിവിറ്റി നിരീക്ഷിക്കാൻ ഈ ആപ്പിന് കഴിയും."</string> @@ -628,6 +628,8 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. മ്യൂട്ടുചെയ്യുന്നതിന് ടാപ്പുചെയ്യുക. ഉപയോഗസഹായി സേവനങ്ങൾ മ്യൂട്ടുചെയ്യപ്പെട്ടേക്കാം."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s വൈബ്രേറ്റിലേക്ക് സജ്ജമാക്കുന്നതിന് ടാപ്പുചെയ്യുക."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s മ്യൂട്ടുചെയ്യുന്നതിന് ടാപ്പുചെയ്യുക."</string> + <!-- no translation found for volume_ringer_change (3574969197796055532) --> + <skip /> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"മ്യൂട്ട് ചെയ്യുക"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"അൺമ്യൂട്ട് ചെയ്യുക"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"വൈബ്രേറ്റ് ചെയ്യുക"</string> @@ -1041,6 +1043,7 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"ചേർക്കുക"</string> <string name="controls_dialog_message" msgid="342066938390663844">"<xliff:g id="APP">%s</xliff:g> നിർദ്ദേശിച്ചത്"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"നിയന്ത്രണങ്ങൾ അപ്ഡേറ്റ് ചെയ്തു"</string> + <string name="controls_tile_locked" msgid="731547768182831938">"ഉപകരണം ലോക്ക് ചെയ്തു"</string> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"പിന്നിൽ അക്ഷരങ്ങളോ ചിഹ്നങ്ങളോ അടങ്ങിയിരിക്കുന്നു"</string> <string name="controls_pin_verify" msgid="3452778292918877662">"<xliff:g id="DEVICE">%s</xliff:g> പരിശോധിച്ചുറപ്പിക്കുക"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"പിൻ തെറ്റാണ്"</string> diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml index 63547d59b931..efb27110abe6 100644 --- a/packages/SystemUI/res/values-mn/strings.xml +++ b/packages/SystemUI/res/values-mn/strings.xml @@ -412,7 +412,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Нар мандах хүртэл"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"<xliff:g id="TIME">%s</xliff:g>-д"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"<xliff:g id="TIME">%s</xliff:g> хүртэл"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Гэрэлтүүлгийг багасгах"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"Гэрэлтүүлгийг багасгах"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC-г цуцалсан"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC-г идэвхжүүлсэн"</string> @@ -446,6 +446,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC-г ашиглахын тулд түгжээг тайлна уу"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Энэ төхөөрөмж танай байгууллагад харьяалагддаг"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"Энэ төхөөрөмж <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>-д харьяалагддаг"</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"Утсыг гаргахын тулд дүрс тэмдгээс шудрах"</string> <string name="voice_hint" msgid="7476017460191291417">"Дуут туслахыг нээхийн тулд дүрс тэмдгээс шудрах"</string> <string name="camera_hint" msgid="4519495795000658637">"Камер нээхийн тулд дүрс тэмдгийг шудрах"</string> @@ -625,6 +627,7 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Дууг нь хаахын тулд товшино уу. Хүртээмжийн үйлчилгээний дууг хаасан."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Чичиргээнд тохируулахын тулд товшино уу."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Дууг хаахын тулд товшино уу."</string> + <string name="volume_ringer_change" msgid="3574969197796055532">"Хонхны горимыг өөрчлөхийн тулд товшино уу"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"дууг хаах"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"дууг нээх"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"чичрэх"</string> @@ -1038,6 +1041,7 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"Нэмэх"</string> <string name="controls_dialog_message" msgid="342066938390663844">"<xliff:g id="APP">%s</xliff:g>-н санал болгосон"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"Хяналтуудыг шинэчиллээ"</string> + <string name="controls_tile_locked" msgid="731547768182831938">"Төхөөрөмжийг түгжсэн"</string> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"ПИН нь үсэг эсвэл дүрс тэмдэгт агуулдаг"</string> <string name="controls_pin_verify" msgid="3452778292918877662">"<xliff:g id="DEVICE">%s</xliff:g>-г бататгах"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"ПИН код буруу байна"</string> diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml index de0e7becde88..fcff3dfea74e 100644 --- a/packages/SystemUI/res/values-mr/strings.xml +++ b/packages/SystemUI/res/values-mr/strings.xml @@ -93,10 +93,8 @@ <string name="screenshot_scroll_description" msgid="7855773867093272175">"स्क्रीनशॉटवर स्क्रोल करा"</string> <string name="screenshot_dismiss_description" msgid="4702341245899508786">"स्क्रीनशॉट डिसमिस करा"</string> <string name="screenshot_preview_description" msgid="7606510140714080474">"स्क्रीनशॉटचे पूर्वावलोकन"</string> - <!-- no translation found for screenshot_top_boundary (1500569103321300856) --> - <skip /> - <!-- no translation found for screenshot_bottom_boundary (5657242629526407311) --> - <skip /> + <string name="screenshot_top_boundary" msgid="1500569103321300856">"सर्वात वरची सीमा"</string> + <string name="screenshot_bottom_boundary" msgid="5657242629526407311">"तळाची सीमा"</string> <string name="screenrecord_name" msgid="2596401223859996572">"स्क्रीन रेकॉर्डर"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"स्क्रीन रेकॉर्डिंग प्रोसेस सुरू"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"स्क्रीन रेकॉर्ड सत्रासाठी सुरू असलेली सूचना"</string> @@ -414,7 +412,8 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"सूर्योदयापर्यंत"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"<xliff:g id="TIME">%s</xliff:g> वाजता सुरू होते"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"<xliff:g id="TIME">%s</xliff:g> पर्यंत"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"ब्राइटनेस कमी करा"</string> + <!-- no translation found for quick_settings_reduce_bright_colors_label (7537352080559075175) --> + <skip /> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC अक्षम केले आहे"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC सक्षम केले आहे"</string> @@ -448,6 +447,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC वापरण्यासाठी स्क्रीन अनलॉक करा"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"हे डिव्हाइस तुमच्या संस्थेचे आहे"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"हे डिव्हाइस <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> चे आहे"</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"फोनसाठी चिन्हावरून स्वाइप करा"</string> <string name="voice_hint" msgid="7476017460191291417">"व्हॉइस सहाय्यासाठी चिन्हावरून स्वाइप करा"</string> <string name="camera_hint" msgid="4519495795000658637">"कॅमेर्यासाठी चिन्हावरून स्वाइप करा"</string> @@ -546,8 +547,7 @@ <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"आपल्या संस्थेने आपल्या कार्य प्रोफाइलवर प्रमाणपत्र अधिकार इंस्टॉल केला आहे. आपल्या सुरक्षित नेटवर्क रहदारीचे परीक्षण केले जाऊ शकते किंवा ती सुधारली जाऊ शकते."</string> <string name="monitoring_description_ca_certificate" msgid="448923057059097497">"या डिव्हाइसवर प्रमाणपत्र अधिकार इंस्टॉल केला आहे. आपल्या सुरक्षित नेटवर्क रहदारीचे परीक्षण केले जाऊ शकते किंवा ती सुधारली जाऊ शकते."</string> <string name="monitoring_description_management_network_logging" msgid="216983105036994771">"आपल्या प्रशासकाने नेटवर्क लॉगिंग सुरू केले आहे, जे आपल्या डिव्हाइसवरील रहदारीचे परीक्षण करते."</string> - <!-- no translation found for monitoring_description_managed_profile_network_logging (6932303843097006037) --> - <skip /> + <string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"तुमच्या ॲडमिनने नेटवर्क लॉग इन सुरू केले आहे, जे तुमच्या कार्य प्रोफाइलमधील रहदारीचे निरीक्षण करत असले तरी तुमच्या वैयक्तिक प्रोफाइलमधील रहदारीचे निरीक्षण करत नाही."</string> <string name="monitoring_description_named_vpn" msgid="5749932930634037027">"तुम्ही <xliff:g id="VPN_APP">%1$s</xliff:g> शी कनेक्ट केले आहे, जे ईमेल, अॅप्स आणि वेबसाइटसहित आपल्या नेटवर्क क्रिया मॉनिटर करू शकते."</string> <string name="monitoring_description_two_named_vpns" msgid="3516830755681229463">"तुम्ही <xliff:g id="VPN_APP_0">%1$s</xliff:g> आणि <xliff:g id="VPN_APP_1">%2$s</xliff:g> शी कनेक्ट केले आहे, जे ईमेल, अॅप्स आणि वेबसाइटसहित आपल्या नेटवर्क क्रिया मॉनिटर करू शकते."</string> <string name="monitoring_description_managed_profile_named_vpn" msgid="368812367182387320">"तुमचे कार्य प्रोफाइल <xliff:g id="VPN_APP">%1$s</xliff:g> शी कनेक्ट केले आहे, जे ईमेल, अॅप्स आणि वेबसाइटसह आपल्या नेटवर्क क्रियाकलापाचे परीक्षण करू शकते."</string> @@ -628,6 +628,8 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. म्यूट करण्यासाठी टॅप करा. प्रवेशक्षमता सेवा म्यूट केल्या जाऊ शकतात."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. व्हायब्रेट सेट करण्यासाठी टॅप करा."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. म्यूट करण्यासाठी टॅप करा."</string> + <!-- no translation found for volume_ringer_change (3574969197796055532) --> + <skip /> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"म्यूट करा"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"म्यूट काढून टाका"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"व्हायब्रेट करा"</string> @@ -1041,6 +1043,8 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"जोडा"</string> <string name="controls_dialog_message" msgid="342066938390663844">"<xliff:g id="APP">%s</xliff:g> ने सुचवले आहे"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"नियंत्रणे अपडेट केली आहेत"</string> + <!-- no translation found for controls_tile_locked (731547768182831938) --> + <skip /> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"पिनमध्ये अक्षरे किंवा चिन्हे आहेत"</string> <string name="controls_pin_verify" msgid="3452778292918877662">"<xliff:g id="DEVICE">%s</xliff:g> ची पडताळणी करा"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"चुकीचा पिन"</string> diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml index 319dbde2be5f..e723ec6f9035 100644 --- a/packages/SystemUI/res/values-ms/strings.xml +++ b/packages/SystemUI/res/values-ms/strings.xml @@ -412,7 +412,8 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Hingga matahari trbt"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Dihidupkan pada <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Hingga <xliff:g id="TIME">%s</xliff:g>"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Kurangkan Kecerahan"</string> + <!-- no translation found for quick_settings_reduce_bright_colors_label (7537352080559075175) --> + <skip /> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC dilumpuhkan"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC didayakan"</string> @@ -446,6 +447,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Buka kunci untuk menggunakan NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Peranti ini milik organisasi anda"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"Peranti ini milik <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"Leret dari ikon untuk telefon"</string> <string name="voice_hint" msgid="7476017460191291417">"Leret dari ikon untuk bantuan suara"</string> <string name="camera_hint" msgid="4519495795000658637">"Leret dari ikon untuk kamera"</string> @@ -625,6 +628,8 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Ketik untuk meredam. Perkhidmatan kebolehaksesan mungkin diredamkan."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Ketik untuk menetapkan pada getar."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Ketik untuk meredam."</string> + <!-- no translation found for volume_ringer_change (3574969197796055532) --> + <skip /> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"redam"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"nyahredam"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"getar"</string> @@ -1038,6 +1043,7 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"Tambah"</string> <string name="controls_dialog_message" msgid="342066938390663844">"Dicadangkan oleh <xliff:g id="APP">%s</xliff:g>"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"Kawalan dikemas kini"</string> + <string name="controls_tile_locked" msgid="731547768182831938">"Peranti dikunci"</string> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN mengandungi huruf atau simbol"</string> <string name="controls_pin_verify" msgid="3452778292918877662">"Sahkan <xliff:g id="DEVICE">%s</xliff:g>"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"PIN salah"</string> diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml index 15ddf599d788..c57a94c8a7cc 100644 --- a/packages/SystemUI/res/values-my/strings.xml +++ b/packages/SystemUI/res/values-my/strings.xml @@ -412,7 +412,8 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"နေထွက်ချိန် အထိ"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"<xliff:g id="TIME">%s</xliff:g> တွင် ဖွင့်မည်"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"<xliff:g id="TIME">%s</xliff:g> အထိ"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"တောက်ပမှုကို လျှော့ရန်"</string> + <!-- no translation found for quick_settings_reduce_bright_colors_label (7537352080559075175) --> + <skip /> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC ကို ပိတ်ထားသည်"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC ကို ဖွင့်ထားသည်"</string> @@ -446,6 +447,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC ကို အသုံးပြုရန် လော့ခ်ဖွင့်ပါ"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"ဤစက်ကို သင့်အဖွဲ့အစည်းက ပိုင်ဆိုင်သည်"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"ဤစက်ကို <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> က ပိုင်ဆိုင်သည်"</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"ဖုန်းအတွက် သင်္ကေတပုံအား ပွတ်ဆွဲပါ"</string> <string name="voice_hint" msgid="7476017460191291417">"အသံအကူအညီအတွက် သင်္ကေတပုံအား ပွတ်ဆွဲပါ"</string> <string name="camera_hint" msgid="4519495795000658637">"ကင်မရာအတွက် သင်္ကေတပုံအား ပွတ်ဆွဲပါ"</string> @@ -625,6 +628,8 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s။ အသံပိတ်ရန် တို့ပါ။ အများသုံးစွဲနိုင်မှု ဝန်ဆောင်မှုများကို အသံပိတ်ထားနိုင်ပါသည်။"</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s။ တုန်ခါခြင်းသို့ သတ်မှတ်ရန်တို့ပါ။"</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s။ အသံတိတ်ရန် တို့ပါ။"</string> + <!-- no translation found for volume_ringer_change (3574969197796055532) --> + <skip /> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"အသံတိတ်ရန်"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"အသံဖွင့်ရန်"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"တုန်ခါမှု"</string> @@ -1038,6 +1043,7 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"ထည့်ရန်"</string> <string name="controls_dialog_message" msgid="342066938390663844">"<xliff:g id="APP">%s</xliff:g> က အကြံပြုထားသည်"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"ထိန်းချုပ်မှု အပ်ဒိတ်လုပ်ပြီးပြီ"</string> + <string name="controls_tile_locked" msgid="731547768182831938">"စက်ကိုလော့ခ်ချထားသည်"</string> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"ပင်နံပါတ်တွင် စာလုံး သို့မဟုတ် သင်္ကေတများပါဝင်သည်"</string> <string name="controls_pin_verify" msgid="3452778292918877662">"<xliff:g id="DEVICE">%s</xliff:g> ကို အတည်ပြုခြင်း"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"ပင်နံပါတ် မှားနေသည်"</string> diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml index 1c2fa8a68b11..997147dd15f0 100644 --- a/packages/SystemUI/res/values-nb/strings.xml +++ b/packages/SystemUI/res/values-nb/strings.xml @@ -412,7 +412,8 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Til soloppgang"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Slås på klokken <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Til <xliff:g id="TIME">%s</xliff:g>"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Reduser lysstyrken"</string> + <!-- no translation found for quick_settings_reduce_bright_colors_label (7537352080559075175) --> + <skip /> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC er slått av"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC er slått på"</string> @@ -446,6 +447,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Lås opp for å bruke NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Denne enheten tilhører organisasjonen din"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"Denne enheten tilhører <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"Sveip ikonet for å åpne telefon"</string> <string name="voice_hint" msgid="7476017460191291417">"Sveip fra ikonet for å åpne talehjelp"</string> <string name="camera_hint" msgid="4519495795000658637">"Sveip ikonet for å åpne kamera"</string> @@ -625,6 +628,8 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Trykk for å slå av lyden. Lyden kan bli slått av for tilgjengelighetstjenestene."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Trykk for å angi vibrasjon."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Trykk for å slå av lyden."</string> + <!-- no translation found for volume_ringer_change (3574969197796055532) --> + <skip /> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"kutt lyden"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"slå på lyden"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibrer"</string> @@ -1038,6 +1043,7 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"Legg til"</string> <string name="controls_dialog_message" msgid="342066938390663844">"Foreslått av <xliff:g id="APP">%s</xliff:g>"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"Kontrollene er oppdatert"</string> + <string name="controls_tile_locked" msgid="731547768182831938">"Enheten er låst"</string> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN-koden inneholder bokstaver eller symboler"</string> <string name="controls_pin_verify" msgid="3452778292918877662">"Bekreft <xliff:g id="DEVICE">%s</xliff:g>"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"Feil PIN-kode"</string> diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml index 3ab0136f4d77..e03ee5bfb240 100644 --- a/packages/SystemUI/res/values-ne/strings.xml +++ b/packages/SystemUI/res/values-ne/strings.xml @@ -93,10 +93,8 @@ <string name="screenshot_scroll_description" msgid="7855773867093272175">"स्क्रिनसट स्क्रोल गर्नुहोस्"</string> <string name="screenshot_dismiss_description" msgid="4702341245899508786">"स्क्रिनसट हटाउनुहोस्"</string> <string name="screenshot_preview_description" msgid="7606510140714080474">"स्क्रिनसटको पूर्वावलोकन"</string> - <!-- no translation found for screenshot_top_boundary (1500569103321300856) --> - <skip /> - <!-- no translation found for screenshot_bottom_boundary (5657242629526407311) --> - <skip /> + <string name="screenshot_top_boundary" msgid="1500569103321300856">"सिरानको सीमा"</string> + <string name="screenshot_bottom_boundary" msgid="5657242629526407311">"फेदको सीमा"</string> <string name="screenrecord_name" msgid="2596401223859996572">"स्क्रिन रेकर्डर"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"स्क्रिन रेकर्डिङको प्रक्रिया अघि बढाइँदै"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"कुनै स्क्रिन रेकर्ड गर्ने सत्रका लागि चलिरहेको सूचना"</string> @@ -414,7 +412,8 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"सूर्योदयसम्म"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"<xliff:g id="TIME">%s</xliff:g> मा सक्रिय"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"<xliff:g id="TIME">%s</xliff:g> सम्म"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"स्क्रिनको चमक घटाउनुहोस्"</string> + <!-- no translation found for quick_settings_reduce_bright_colors_label (7537352080559075175) --> + <skip /> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC लाई असक्षम पारिएको छ"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC लाई सक्षम पारिएको छ"</string> @@ -448,6 +447,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC प्रयोग गर्न स्क्रिन अनलक गर्नुहोस्"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"यो यन्त्र तपाईंको सङ्गठनको स्वामित्वमा छ"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"यो यन्त्र <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> को स्वामित्वमा छ"</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"फोनको लागि आइकनबाट स्वाइप गर्नुहोस्"</string> <string name="voice_hint" msgid="7476017460191291417">"आवाज सहायताका लागि आइकनबाट स्वाइप गर्नुहोस्"</string> <string name="camera_hint" msgid="4519495795000658637">"क्यामेराको लागि आइकनबाट स्वाइप गर्नुहोस्"</string> @@ -546,8 +547,7 @@ <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"तपाईंको संगठनले तपाईंको कार्य प्रोफाइलमा एउटा प्रमाणपत्र सम्बन्धी अख्तियार सुविधा स्थापना गरेको छ। तपाईंको सुरक्षित नेटवर्क ट्राफिकको अनुगमन वा परिमार्जन हुनसक्छ।"</string> <string name="monitoring_description_ca_certificate" msgid="448923057059097497">"यस यन्त्रमा एउटा प्रमाणपत्र सम्बन्धी अख्तियार सुविधा स्थापना गरिएको छ। तपाईंको सुरक्षित नेटवर्कको ट्राफिकको अनुगमन वा परिमार्जन हुनसक्छ।"</string> <string name="monitoring_description_management_network_logging" msgid="216983105036994771">"तपाईंका प्रशासकले तपाईंको यन्त्रमा ट्राफिकको अनुगमन गर्ने नेटवर्क लग गर्ने प्रक्रियालाई सक्रिय गर्नुभएको छ।"</string> - <!-- no translation found for monitoring_description_managed_profile_network_logging (6932303843097006037) --> - <skip /> + <string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"तपाईंका एड्मिनले \'नेटवर्क लगिङ\' सुविधा अन गर्नुभएको छ। यो सुविधाले तपाईंको कार्य प्रोफाइलको ट्राफिक अनुगमन गर्छ तर व्यक्तिगत प्रोफाइलको ट्राफिक भने अनुगमन गर्दैन।"</string> <string name="monitoring_description_named_vpn" msgid="5749932930634037027">"तपाईं इमेल, एप र वेबसाइटहरू लगायत तपाईंको नेटवर्कको गतिविधिको अनुगमन गर्नसक्ने <xliff:g id="VPN_APP">%1$s</xliff:g> मा जडान हुनुहुन्छ।"</string> <string name="monitoring_description_two_named_vpns" msgid="3516830755681229463">"तपाईं इमेल, एप र वेबसाइटहरू लगायत तपाईंको नेटवर्कको गतिविधिको अनुगमन गर्नसक्ने <xliff:g id="VPN_APP_0">%1$s</xliff:g> र <xliff:g id="VPN_APP_1">%2$s</xliff:g> मा जडान हुनुहुन्छ।"</string> <string name="monitoring_description_managed_profile_named_vpn" msgid="368812367182387320">"तपाईंको कार्य प्रोफाइल तपाईंका इमेल, एप र वेबसाइटहरू लगायत तपाईंको नेटवर्कको गतिविधिको अनुगमन गर्नसक्ने <xliff:g id="VPN_APP">%1$s</xliff:g> मा जडान छ।"</string> @@ -628,6 +628,8 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s। म्यूट गर्नाका लागि ट्याप गर्नुहोस्। पहुँच सम्बन्धी सेवाहरू म्यूट हुन सक्छन्।"</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s। कम्पन मोडमा सेट गर्न ट्याप गर्नुहोस्।"</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s। म्यूट गर्न ट्याप गर्नुहोस्।"</string> + <!-- no translation found for volume_ringer_change (3574969197796055532) --> + <skip /> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"म्युट गर्नुहोस्"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"अनम्युट गर्नुहोस्"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"कम्पन गर्नुहोस्"</string> @@ -1041,6 +1043,8 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"थप्नुहोस्"</string> <string name="controls_dialog_message" msgid="342066938390663844">"<xliff:g id="APP">%s</xliff:g> ले सिफारिस गरेको"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"नियन्त्रण सुविधाहरू अद्यावधिक गरिए"</string> + <!-- no translation found for controls_tile_locked (731547768182831938) --> + <skip /> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN मा अक्षर वा चिन्हहरू समाविष्ट हुन्छन्"</string> <string name="controls_pin_verify" msgid="3452778292918877662">"<xliff:g id="DEVICE">%s</xliff:g> पुष्टि गर्नुहोस्"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"PIN मिलेन"</string> diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml index dcadbf58330f..8ffc3f415442 100644 --- a/packages/SystemUI/res/values-nl/strings.xml +++ b/packages/SystemUI/res/values-nl/strings.xml @@ -412,7 +412,8 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Tot zonsopgang"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Aan om <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Tot <xliff:g id="TIME">%s</xliff:g>"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Helderheid verlagen"</string> + <!-- no translation found for quick_settings_reduce_bright_colors_label (7537352080559075175) --> + <skip /> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC is uitgeschakeld"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC is ingeschakeld"</string> @@ -446,6 +447,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Ontgrendel het apparaat om NFC te gebruiken"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Dit apparaat is eigendom van je organisatie"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"Dit apparaat is eigendom van <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"Swipen voor telefoon"</string> <string name="voice_hint" msgid="7476017460191291417">"Swipen vanaf icoon voor spraakassistent"</string> <string name="camera_hint" msgid="4519495795000658637">"Vegen voor camera"</string> @@ -625,6 +628,8 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Tik om te dempen. Het geluid van toegankelijkheidsservices kan hierdoor uitgaan."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Tik om in te stellen op trillen."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Tik om geluid uit te zetten."</string> + <!-- no translation found for volume_ringer_change (3574969197796055532) --> + <skip /> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"geluid uit"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"geluid aanzetten"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"trillen"</string> @@ -1038,6 +1043,7 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"Toevoegen"</string> <string name="controls_dialog_message" msgid="342066938390663844">"Voorgesteld door <xliff:g id="APP">%s</xliff:g>"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"Bedieningselementen geüpdated"</string> + <string name="controls_tile_locked" msgid="731547768182831938">"Apparaat vergrendeld"</string> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"Pincode bevat letters of symbolen"</string> <string name="controls_pin_verify" msgid="3452778292918877662">"<xliff:g id="DEVICE">%s</xliff:g> verifiëren"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"Onjuiste pincode"</string> diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml index 955c08a35922..f03c31d313a6 100644 --- a/packages/SystemUI/res/values-or/strings.xml +++ b/packages/SystemUI/res/values-or/strings.xml @@ -412,7 +412,8 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"ସକାଳ ପର୍ଯ୍ୟନ୍ତ"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"<xliff:g id="TIME">%s</xliff:g>ରେ ଚାଲୁ ହେବ"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"<xliff:g id="TIME">%s</xliff:g> ପର୍ଯ୍ୟନ୍ତ"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"ଉଜ୍ଜ୍ୱଳତା କମାନ୍ତୁ"</string> + <!-- no translation found for quick_settings_reduce_bright_colors_label (7537352080559075175) --> + <skip /> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC ଅକ୍ଷମ କରାଯାଇଛି"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC ସକ୍ଷମ କରାଯାଇଛି"</string> @@ -446,6 +447,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC ବ୍ୟବହାର କରିବାକୁ ଅନଲକ୍ କରନ୍ତୁ"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"ଏହି ଡିଭାଇସଟି ଆପଣଙ୍କ ସଂସ୍ଥାର ଅଟେ"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"ଏହି ଡିଭାଇସଟି <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>ର ଅଟେ"</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"ଫୋନ୍ ପାଇଁ ଆଇକନରୁ ସ୍ୱାଇପ୍ କରନ୍ତୁ"</string> <string name="voice_hint" msgid="7476017460191291417">"ଭଏସ୍ ସହାୟକ ପାଇଁ ଆଇକନରୁ ସ୍ୱାଇପ୍ କରନ୍ତୁ"</string> <string name="camera_hint" msgid="4519495795000658637">"କ୍ୟାମେରା ପାଇଁ ଆଇକନରୁ ସ୍ୱାଇପ୍ କରନ୍ତୁ"</string> @@ -625,6 +628,8 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s। ମ୍ୟୁଟ୍ କରିବାକୁ ଟାପ୍ କରନ୍ତୁ। ଆକ୍ସେସିବିଲିଟୀ ସର୍ଭିସ୍ ମ୍ୟୁଟ୍ କରାଯାଇପାରେ।"</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s। ଭାଇବ୍ରେଟରେ ସେଟ୍ କରିବାକୁ ଟାପ୍ କରନ୍ତୁ।"</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s। ମ୍ୟୁଟ୍ କରିବାକୁ ଟାପ୍ କରନ୍ତୁ।"</string> + <!-- no translation found for volume_ringer_change (3574969197796055532) --> + <skip /> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"ମ୍ୟୁଟ୍"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"ଅନ୍-ମ୍ୟୁଟ୍ କରନ୍ତୁ"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"ଭାଇବ୍ରେଟ୍"</string> @@ -1038,6 +1043,7 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"ଯୋଗ କରନ୍ତୁ"</string> <string name="controls_dialog_message" msgid="342066938390663844">"<xliff:g id="APP">%s</xliff:g> ଦ୍ଵାରା ପ୍ରସ୍ତାବିତ"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"ନିୟନ୍ତ୍ରଣଗୁଡ଼ିକ ଅପଡେଟ୍ କରାଯାଇଛି"</string> + <string name="controls_tile_locked" msgid="731547768182831938">"ଡିଭାଇସ୍ ଲକ୍ ହୋଇଯାଇଛି"</string> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PINରେ ଅକ୍ଷର କିମ୍ୱା ପ୍ରତୀକଗୁଡ଼ିକ ଥାଏ"</string> <string name="controls_pin_verify" msgid="3452778292918877662">"<xliff:g id="DEVICE">%s</xliff:g> ଯାଞ୍ଚ କରନ୍ତୁ"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"ଭୁଲ PIN"</string> diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml index 47f56bd7a09d..459b1631a373 100644 --- a/packages/SystemUI/res/values-pa/strings.xml +++ b/packages/SystemUI/res/values-pa/strings.xml @@ -93,10 +93,8 @@ <string name="screenshot_scroll_description" msgid="7855773867093272175">"ਸਕ੍ਰੀਨਸ਼ਾਟ ਨੂੰ ਸਕ੍ਰੋਲ ਕਰੋ"</string> <string name="screenshot_dismiss_description" msgid="4702341245899508786">"ਸਕ੍ਰੀਨਸ਼ਾਟ ਖਾਰਜ ਕਰੋ"</string> <string name="screenshot_preview_description" msgid="7606510140714080474">"ਸਕ੍ਰੀਨਸ਼ਾਟ ਪੂਰਵ-ਝਲਕ"</string> - <!-- no translation found for screenshot_top_boundary (1500569103321300856) --> - <skip /> - <!-- no translation found for screenshot_bottom_boundary (5657242629526407311) --> - <skip /> + <string name="screenshot_top_boundary" msgid="1500569103321300856">"ਉੱਪਰ ਦੀ ਸੀਮਾ"</string> + <string name="screenshot_bottom_boundary" msgid="5657242629526407311">"ਹੇਠਾਂ ਦੀ ਸੀਮਾ"</string> <string name="screenrecord_name" msgid="2596401223859996572">"ਸਕ੍ਰੀਨ ਰਿਕਾਰਡਰ"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"ਸਕ੍ਰੀਨ ਰਿਕਾਰਡਿੰਗ ਜਾਰੀ ਹੈ"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"ਕਿਸੇ ਸਕ੍ਰੀਨ ਰਿਕਾਰਡ ਸੈਸ਼ਨ ਲਈ ਚੱਲ ਰਹੀ ਸੂਚਨਾ"</string> @@ -414,7 +412,8 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"ਸੂਰਜ ਚੜ੍ਹਨ ਤੱਕ"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"<xliff:g id="TIME">%s</xliff:g> ਵਜੇ ਚਾਲੂ"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"<xliff:g id="TIME">%s</xliff:g> ਵਜੇ ਤੱਕ"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"ਚਮਕ ਘਟਾਓ"</string> + <!-- no translation found for quick_settings_reduce_bright_colors_label (7537352080559075175) --> + <skip /> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC ਨੂੰ ਅਯੋਗ ਬਣਾਇਆ ਗਿਆ ਹੈ"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC ਨੂੰ ਯੋਗ ਬਣਾਇਆ ਗਿਆ ਹੈ"</string> @@ -448,6 +447,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC ਵਰਤਣ ਲਈ ਅਣਲਾਕ ਕਰੋ"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"ਇਹ ਡੀਵਾਈਸ ਤੁਹਾਡੀ ਸੰਸਥਾ ਨਾਲ ਸੰਬੰਧਿਤ ਹੈ"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"ਇਹ ਡੀਵਾਈਸ <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> ਨਾਲ ਸੰਬੰਧਿਤ ਹੈ"</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"ਫ਼ੋਨ ਲਈ ਪ੍ਰਤੀਕ ਤੋਂ ਸਵਾਈਪ ਕਰੋ"</string> <string name="voice_hint" msgid="7476017460191291417">"ਅਵਾਜ਼ੀ ਸਹਾਇਕ ਲਈ ਪ੍ਰਤੀਕ ਤੋਂ ਸਵਾਈਪ ਕਰੋ"</string> <string name="camera_hint" msgid="4519495795000658637">"ਕੈਮਰੇ ਲਈ ਪ੍ਰਤੀਕ ਤੋਂ ਸਵਾਈਪ ਕਰੋ"</string> @@ -546,8 +547,7 @@ <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"ਤੁਹਾਡੀ ਸੰਸਥਾ ਵੱਲੋਂ ਤੁਹਾਡੇ ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਵਿੱਚ ਇੱਕ ਪ੍ਰਮਾਣ-ਪੱਤਰ ਅਥਾਰਟੀ ਸਥਾਪਤ ਕੀਤੀ ਗਈ ਹੈ। ਤੁਹਾਡੇ ਸੁਰੱਖਿਅਤ ਨੈੱਟਵਰਕ ਟਰੈਫਿਕ ਦੀ ਨਿਗਰਾਨੀ ਕੀਤੀ ਜਾ ਸਕਦੀ ਹੈ ਜਾਂ ਉਸਨੂੰ ਸੋਧਿਆ ਜਾ ਸਕਦਾ ਹੈ।"</string> <string name="monitoring_description_ca_certificate" msgid="448923057059097497">"ਇੱਕ ਪ੍ਰਮਾਣ-ਪੱਤਰ ਅਥਾਰਟੀ ਇਸ ਡੀਵਾਈਸ \'ਤੇ ਸਥਾਪਤ ਕੀਤੀ ਜਾਂਦੀ ਹੈ। ਤੁਹਾਡੇ ਸੁਰੱਖਿਅਤ ਨੈੱਟਵਰਕ ਟਰੈਫਿਕ ਦੀ ਨਿਗਰਾਨੀ ਕੀਤੀ ਜਾ ਸਕਦੀ ਹੈ ਜਾਂ ਉਸਨੂੰ ਸੋਧਿਆ ਜਾ ਸਕਦਾ ਹੈ।"</string> <string name="monitoring_description_management_network_logging" msgid="216983105036994771">"ਤੁਹਾਡੇ ਪ੍ਰਸ਼ਾਸਕ ਨੇ ਨੈੱਟਵਰਕ ਲੌਗਿੰਗ ਨੂੰ ਚਾਲੂ ਕੀਤਾ ਹੋਇਆ ਹੈ, ਜੋ ਤੁਹਾਡੇ ਡੀਵਾਈਸ \'ਤੇ ਟਰੈਫਿਕ ਦੀ ਨਿਗਰਾਨੀ ਕਰਦਾ ਹੈ।"</string> - <!-- no translation found for monitoring_description_managed_profile_network_logging (6932303843097006037) --> - <skip /> + <string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"ਤੁਹਾਡੇ ਪ੍ਰਸ਼ਾਸਕ ਨੇ ਨੈੱਟਵਰਕ ਲੌਗ-ਇਨ ਨੂੰ ਚਾਲੂ ਕੀਤਾ ਹੋਇਆ ਹੈ, ਜੋ ਤੁਹਾਡੇ ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਵਿੱਚ ਟਰੈਫ਼ਿਕ ਦੀ ਨਿਗਰਾਨੀ ਕਰਦਾ ਹੈ ਪਰ ਤੁਹਾਡੀ ਨਿੱਜੀ ਪ੍ਰੋਫਾਈਲ ਵਿੱਚ ਨਹੀਂ।"</string> <string name="monitoring_description_named_vpn" msgid="5749932930634037027">"ਤੁਸੀਂ <xliff:g id="VPN_APP">%1$s</xliff:g> ਨਾਲ ਕਨੈਕਟ ਹੋ, ਜੋ ਈਮੇਲਾਂ, ਐਪਾਂ, ਅਤੇ ਵੈੱਬਸਾਈਟਾਂ ਸਮੇਤ ਤੁਹਾਡੀ ਨੈੱਟਵਰਕ ਸਰਗਰਮੀ ਦੀ ਨਿਗਰਾਨੀ ਕਰ ਸਕਦੀ ਹੈ।"</string> <string name="monitoring_description_two_named_vpns" msgid="3516830755681229463">"ਤੁਸੀਂ <xliff:g id="VPN_APP_0">%1$s</xliff:g> ਅਤੇ <xliff:g id="VPN_APP_1">%2$s</xliff:g> ਨਾਲ ਕਨੈਕਟ ਹੋ, ਜੋ ਈਮੇਲਾਂ, ਐਪਾਂ, ਅਤੇ ਵੈੱਬਸਾਈਟਾਂ ਸਮੇਤ ਤੁਹਾਡੀ ਨੈੱਟਵਰਕ ਸਰਗਰਮੀ ਦੀ ਨਿਗਰਾਨੀ ਕਰ ਸਕਦੀਆਂ ਹਨ।"</string> <string name="monitoring_description_managed_profile_named_vpn" msgid="368812367182387320">"ਤੁਹਾਡੀ ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ <xliff:g id="VPN_APP">%1$s</xliff:g> ਨਾਲ ਕਨੈਕਟ ਹੈ, ਜੋ ਈਮੇਲਾਂ, ਐਪਾਂ ਅਤੇ ਵੈੱਬਸਾਈਟਾਂ ਸਮੇਤ ਤੁਹਾਡੀ ਨੈੱਟਵਰਕ ਸਰਗਰਮੀ ਦੀ ਨਿਗਰਾਨੀ ਕਰ ਸਕਦੀ ਹੈ।"</string> @@ -628,6 +628,8 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s। ਮਿਊਟ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ। ਪਹੁੰਚਯੋਗਤਾ ਸੇਵਾਵਾਂ ਮਿਊਟ ਹੋ ਸਕਦੀਆਂ ਹਨ।"</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s। ਥਰਥਰਾਹਟ \'ਤੇ ਸੈੱਟ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ।"</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s। ਮਿਊਟ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ।"</string> + <!-- no translation found for volume_ringer_change (3574969197796055532) --> + <skip /> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"ਮਿਊਟ ਕਰੋ"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"ਅਣਮਿਊਟ ਕਰੋ"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"ਥਰਥਰਾਹਟ"</string> @@ -1041,6 +1043,8 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"ਸ਼ਾਮਲ ਕਰੋ"</string> <string name="controls_dialog_message" msgid="342066938390663844">"<xliff:g id="APP">%s</xliff:g> ਵੱਲੋਂ ਸੁਝਾਇਆ ਗਿਆ"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"ਕੰਟਰੋਲ ਅੱਪਡੇਟ ਕੀਤੇ ਗਏ"</string> + <!-- no translation found for controls_tile_locked (731547768182831938) --> + <skip /> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"ਪਿੰਨ ਵਿੱਚ ਅੱਖਰ ਜਾਂ ਚਿੰਨ੍ਹ ਸ਼ਾਮਲ ਹਨ"</string> <string name="controls_pin_verify" msgid="3452778292918877662">"<xliff:g id="DEVICE">%s</xliff:g> ਦੀ ਪੁਸ਼ਟੀ ਕਰੋ"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"ਗਲਤ ਪਿੰਨ"</string> diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml index 59c9f52c4dc2..e16b5ec73d15 100644 --- a/packages/SystemUI/res/values-pl/strings.xml +++ b/packages/SystemUI/res/values-pl/strings.xml @@ -93,10 +93,8 @@ <string name="screenshot_scroll_description" msgid="7855773867093272175">"Przewiń zrzut ekranu"</string> <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Zamknij zrzut ekranu"</string> <string name="screenshot_preview_description" msgid="7606510140714080474">"Podgląd zrzutu ekranu"</string> - <!-- no translation found for screenshot_top_boundary (1500569103321300856) --> - <skip /> - <!-- no translation found for screenshot_bottom_boundary (5657242629526407311) --> - <skip /> + <string name="screenshot_top_boundary" msgid="1500569103321300856">"Górna granica"</string> + <string name="screenshot_bottom_boundary" msgid="5657242629526407311">"Dolna granica"</string> <string name="screenrecord_name" msgid="2596401223859996572">"Nagrywanie ekranu"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Przetwarzam nagrywanie ekranu"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"Stałe powiadomienie o sesji rejestrowania zawartości ekranu"</string> @@ -418,7 +416,8 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Do wschodu słońca"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Włącz o <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Do <xliff:g id="TIME">%s</xliff:g>"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Zmniejsz jasność"</string> + <!-- no translation found for quick_settings_reduce_bright_colors_label (7537352080559075175) --> + <skip /> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"Komunikacja NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"Komunikacja NFC jest wyłączona"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"Komunikacja NFC jest włączona"</string> @@ -452,6 +451,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Odblokuj, by użyć komunikacji NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"To urządzenie należy do Twojej organizacji"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"Właściciel tego urządzenia: <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"Aby włączyć telefon, przesuń palcem od ikony"</string> <string name="voice_hint" msgid="7476017460191291417">"Aby uzyskać pomoc głosową, przesuń palcem od ikony"</string> <string name="camera_hint" msgid="4519495795000658637">"Przesuń palcem od ikony, by włączyć aparat"</string> @@ -552,8 +553,7 @@ <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Twoja organizacja zainstalowała urząd certyfikacji w Twoim profilu służbowym. Zabezpieczony ruch w sieci może być monitorowany i zmieniany."</string> <string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Urząd certyfikacji zainstalowany na tym urządzeniu. Twój zabezpieczony ruch w sieci może być monitorowany i zmieniany."</string> <string name="monitoring_description_management_network_logging" msgid="216983105036994771">"Administrator włączył rejestrowanie sieciowe, które pozwala monitorować ruch na Twoim urządzeniu."</string> - <!-- no translation found for monitoring_description_managed_profile_network_logging (6932303843097006037) --> - <skip /> + <string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"Administrator włączył rejestrowanie sieciowe, które pozwala monitorować ruch na Twoim profilu służbowym, ale nie na profilu osobistym."</string> <string name="monitoring_description_named_vpn" msgid="5749932930634037027">"Łączysz się z aplikacją <xliff:g id="VPN_APP">%1$s</xliff:g>, która może monitorować Twoją aktywność w sieci, w tym e-maile, aplikacje i strony internetowe."</string> <string name="monitoring_description_two_named_vpns" msgid="3516830755681229463">"Łączysz się z aplikacjami <xliff:g id="VPN_APP_0">%1$s</xliff:g> i <xliff:g id="VPN_APP_1">%2$s</xliff:g>, które mogą monitorować Twoją aktywność w sieci, w tym e-maile, aplikacje i strony internetowe."</string> <string name="monitoring_description_managed_profile_named_vpn" msgid="368812367182387320">"Twój profil służbowy jest połączony z aplikacją <xliff:g id="VPN_APP">%1$s</xliff:g>, która może monitorować Twoją aktywność w sieci, w tym e-maile, aplikacje i strony internetowe."</string> @@ -634,6 +634,8 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Kliknij, by wyciszyć. Ułatwienia dostępu mogą być wyciszone."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Kliknij, by włączyć wibracje."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Kliknij, by wyciszyć."</string> + <!-- no translation found for volume_ringer_change (3574969197796055532) --> + <skip /> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"wycisz"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"wyłącz wyciszenie"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"włącz wibracje"</string> @@ -1053,6 +1055,7 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"Dodaj"</string> <string name="controls_dialog_message" msgid="342066938390663844">"Sugestia: <xliff:g id="APP">%s</xliff:g>"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"Zaktualizowano elementy sterujące"</string> + <string name="controls_tile_locked" msgid="731547768182831938">"Urządzenie zablokowane"</string> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"Kod PIN zawiera litery lub symbole"</string> <string name="controls_pin_verify" msgid="3452778292918877662">"Sprawdź urządzenie <xliff:g id="DEVICE">%s</xliff:g>"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"Nieprawidłowy kod PIN"</string> diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml index fca802d4d49f..efe0f064c350 100644 --- a/packages/SystemUI/res/values-pt-rBR/strings.xml +++ b/packages/SystemUI/res/values-pt-rBR/strings.xml @@ -412,7 +412,8 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Até o nascer do sol"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Ativar: <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Até: <xliff:g id="TIME">%s</xliff:g>"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Reduzir brilho"</string> + <!-- no translation found for quick_settings_reduce_bright_colors_label (7537352080559075175) --> + <skip /> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"A NFC está desativada"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"A NFC está ativada"</string> @@ -446,6 +447,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Desbloqueie para usar a NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Este dispositivo pertence à sua organização"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"Este dispositivo pertence à organização <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"Deslize a partir do ícone do telefone"</string> <string name="voice_hint" msgid="7476017460191291417">"Deslize a partir do ícone de assistência de voz"</string> <string name="camera_hint" msgid="4519495795000658637">"Deslize a partir do ícone da câmera"</string> @@ -625,6 +628,8 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Toque para silenciar. É possível que os serviços de acessibilidade sejam silenciados."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Toque para configurar para vibrar."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Toque para silenciar."</string> + <!-- no translation found for volume_ringer_change (3574969197796055532) --> + <skip /> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"desativar o som"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"ativar o som"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibrar"</string> @@ -791,7 +796,7 @@ <string name="keyboard_key_media_stop" msgid="1509943745250377699">"Parar"</string> <string name="keyboard_key_media_next" msgid="8502476691227914952">"Avançar"</string> <string name="keyboard_key_media_previous" msgid="5637875709190955351">"Anterior"</string> - <string name="keyboard_key_media_rewind" msgid="3450387734224327577">"Retroceder"</string> + <string name="keyboard_key_media_rewind" msgid="3450387734224327577">"Voltar"</string> <string name="keyboard_key_media_fast_forward" msgid="3572444327046911822">"Avançar rapidamente"</string> <string name="keyboard_key_page_up" msgid="173914303254199845">"Page Up"</string> <string name="keyboard_key_page_down" msgid="9035902490071829731">"Page Down"</string> @@ -1038,6 +1043,7 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"Adicionar"</string> <string name="controls_dialog_message" msgid="342066938390663844">"Sugerido por <xliff:g id="APP">%s</xliff:g>"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"Controles atualizados"</string> + <string name="controls_tile_locked" msgid="731547768182831938">"Dispositivo bloq."</string> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"O PIN contém letras ou símbolos"</string> <string name="controls_pin_verify" msgid="3452778292918877662">"Verificar <xliff:g id="DEVICE">%s</xliff:g>"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"PIN incorreto"</string> diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml index 9b4d45b615fc..3a82febd79b7 100644 --- a/packages/SystemUI/res/values-pt-rPT/strings.xml +++ b/packages/SystemUI/res/values-pt-rPT/strings.xml @@ -412,7 +412,8 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Até ao amanhecer"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Ativado à(s) <xliff:g id="TIME">%s</xliff:g>."</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Até à(s) <xliff:g id="TIME">%s</xliff:g>."</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Reduzir o brilho"</string> + <!-- no translation found for quick_settings_reduce_bright_colors_label (7537352080559075175) --> + <skip /> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"O NFC está desativado"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"O NFC está ativado"</string> @@ -446,6 +447,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Desbloquear para utilizar o NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Este dispositivo pertence à sua entidade."</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"Este dispositivo pertence à entidade <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>."</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"Deslize rapid. a partir do ícone para aceder ao telemóvel"</string> <string name="voice_hint" msgid="7476017460191291417">"Deslize rapid. a partir do ícone para aceder ao assist. voz"</string> <string name="camera_hint" msgid="4519495795000658637">"Deslize rapidamente a partir do ícone para aceder à câmara"</string> @@ -625,6 +628,8 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Toque para desativar o som. Os serviços de acessibilidade podem ser silenciados."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Toque para ativar a vibração."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Toque para desativar o som."</string> + <!-- no translation found for volume_ringer_change (3574969197796055532) --> + <skip /> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"desativar som"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"reativar som"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibrar"</string> @@ -1038,6 +1043,7 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"Adicionar"</string> <string name="controls_dialog_message" msgid="342066938390663844">"Sugerido por <xliff:g id="APP">%s</xliff:g>"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"Controlos atualizados"</string> + <string name="controls_tile_locked" msgid="731547768182831938">"Dispositivo bloq."</string> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"O PIN contém letras ou símbolos."</string> <string name="controls_pin_verify" msgid="3452778292918877662">"Validar <xliff:g id="DEVICE">%s</xliff:g>"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"PIN incorreto"</string> diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml index fca802d4d49f..efe0f064c350 100644 --- a/packages/SystemUI/res/values-pt/strings.xml +++ b/packages/SystemUI/res/values-pt/strings.xml @@ -412,7 +412,8 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Até o nascer do sol"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Ativar: <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Até: <xliff:g id="TIME">%s</xliff:g>"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Reduzir brilho"</string> + <!-- no translation found for quick_settings_reduce_bright_colors_label (7537352080559075175) --> + <skip /> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"A NFC está desativada"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"A NFC está ativada"</string> @@ -446,6 +447,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Desbloqueie para usar a NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Este dispositivo pertence à sua organização"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"Este dispositivo pertence à organização <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"Deslize a partir do ícone do telefone"</string> <string name="voice_hint" msgid="7476017460191291417">"Deslize a partir do ícone de assistência de voz"</string> <string name="camera_hint" msgid="4519495795000658637">"Deslize a partir do ícone da câmera"</string> @@ -625,6 +628,8 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Toque para silenciar. É possível que os serviços de acessibilidade sejam silenciados."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Toque para configurar para vibrar."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Toque para silenciar."</string> + <!-- no translation found for volume_ringer_change (3574969197796055532) --> + <skip /> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"desativar o som"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"ativar o som"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibrar"</string> @@ -791,7 +796,7 @@ <string name="keyboard_key_media_stop" msgid="1509943745250377699">"Parar"</string> <string name="keyboard_key_media_next" msgid="8502476691227914952">"Avançar"</string> <string name="keyboard_key_media_previous" msgid="5637875709190955351">"Anterior"</string> - <string name="keyboard_key_media_rewind" msgid="3450387734224327577">"Retroceder"</string> + <string name="keyboard_key_media_rewind" msgid="3450387734224327577">"Voltar"</string> <string name="keyboard_key_media_fast_forward" msgid="3572444327046911822">"Avançar rapidamente"</string> <string name="keyboard_key_page_up" msgid="173914303254199845">"Page Up"</string> <string name="keyboard_key_page_down" msgid="9035902490071829731">"Page Down"</string> @@ -1038,6 +1043,7 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"Adicionar"</string> <string name="controls_dialog_message" msgid="342066938390663844">"Sugerido por <xliff:g id="APP">%s</xliff:g>"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"Controles atualizados"</string> + <string name="controls_tile_locked" msgid="731547768182831938">"Dispositivo bloq."</string> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"O PIN contém letras ou símbolos"</string> <string name="controls_pin_verify" msgid="3452778292918877662">"Verificar <xliff:g id="DEVICE">%s</xliff:g>"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"PIN incorreto"</string> diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml index 3a069210bf5b..18093b4e5422 100644 --- a/packages/SystemUI/res/values-ro/strings.xml +++ b/packages/SystemUI/res/values-ro/strings.xml @@ -414,7 +414,8 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Până la răsărit"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Activată la <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Până la <xliff:g id="TIME">%s</xliff:g>"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Reduceți luminozitatea"</string> + <!-- no translation found for quick_settings_reduce_bright_colors_label (7537352080559075175) --> + <skip /> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"Serviciul NFC este dezactivat"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"Serviciul NFC este activat"</string> @@ -448,6 +449,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Deblocați pentru a folosi NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Dispozitivul aparține organizației dvs."</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"Acest dispozitiv aparține organizației <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"Glisați dinspre telefon"</string> <string name="voice_hint" msgid="7476017460191291417">"Glisați dinspre pictogramă pentru asistentul vocal"</string> <string name="camera_hint" msgid="4519495795000658637">"Glisați pentru a fotografia"</string> @@ -628,6 +631,8 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Atingeți pentru a dezactiva sunetul. Sunetul se poate dezactiva pentru serviciile de accesibilitate."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Atingeți pentru a seta pe vibrații."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Atingeți pentru a dezactiva sunetul."</string> + <!-- no translation found for volume_ringer_change (3574969197796055532) --> + <skip /> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"dezactivați sunetul"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"activați sunetul"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibrații"</string> @@ -1044,6 +1049,7 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"Adăugați"</string> <string name="controls_dialog_message" msgid="342066938390663844">"Sugerat de <xliff:g id="APP">%s</xliff:g>"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"S-au actualizat comenzile"</string> + <string name="controls_tile_locked" msgid="731547768182831938">"Dispozitiv blocat"</string> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"Codul PIN conține litere sau simboluri"</string> <string name="controls_pin_verify" msgid="3452778292918877662">"Verificați <xliff:g id="DEVICE">%s</xliff:g>"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"Cod PIN greșit"</string> diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml index a81401a60de9..a9f7c02c4bde 100644 --- a/packages/SystemUI/res/values-ru/strings.xml +++ b/packages/SystemUI/res/values-ru/strings.xml @@ -416,7 +416,8 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"До рассвета"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Включить в <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"До <xliff:g id="TIME">%s</xliff:g>"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Уменьшение яркости"</string> + <!-- no translation found for quick_settings_reduce_bright_colors_label (7537352080559075175) --> + <skip /> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"Модуль NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"Модуль NFC отключен"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"Модуль NFC включен"</string> @@ -450,6 +451,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Чтобы использовать NFC, разблокируйте устройство."</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Это устройство принадлежит вашей организации"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"Этим устройством владеет организация \"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>\""</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"Телефон: проведите от значка"</string> <string name="voice_hint" msgid="7476017460191291417">"Аудиоподсказки: проведите от значка"</string> <string name="camera_hint" msgid="4519495795000658637">"Камера: проведите от значка"</string> @@ -631,6 +634,8 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Нажмите, чтобы выключить звук. Специальные возможности могут прекратить работу."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Нажмите, чтобы включить вибрацию."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Нажмите, чтобы выключить звук."</string> + <!-- no translation found for volume_ringer_change (3574969197796055532) --> + <skip /> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"отключить звук"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"включить звук"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"включить вибрацию"</string> @@ -1050,6 +1055,7 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"Добавить"</string> <string name="controls_dialog_message" msgid="342066938390663844">"Предложено приложением \"<xliff:g id="APP">%s</xliff:g>\""</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"Элементы управления обновлены."</string> + <string name="controls_tile_locked" msgid="731547768182831938">"Устройство заблокировано"</string> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN-код содержит буквы или символы"</string> <string name="controls_pin_verify" msgid="3452778292918877662">"Подтвердите устройство \"<xliff:g id="DEVICE">%s</xliff:g>\""</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"Неверный PIN-код"</string> diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml index f62eae05e1c0..5134e04d72d0 100644 --- a/packages/SystemUI/res/values-si/strings.xml +++ b/packages/SystemUI/res/values-si/strings.xml @@ -412,7 +412,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"හිරු නගින තෙක්"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"<xliff:g id="TIME">%s</xliff:g>ට ක්රියාත්මකයි"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"<xliff:g id="TIME">%s</xliff:g> තෙක්"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"දීප්තිය අඩු කරන්න"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"දීප්තිය අඩු කරන්න"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC අබලයි"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC සබලයි"</string> @@ -446,6 +446,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC භාවිත කිරීමට අගුලු හරින්න"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"මෙම උපාංගය ඔබේ සංවිධානයට අයිතිය"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"මෙම උපාංගය <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> සංවිධානයට අයිතිය"</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"දුරකථනය සඳහා නිරූපකය වෙතින් ස්වයිප් කරන්න"</string> <string name="voice_hint" msgid="7476017460191291417">"හඬ සහාය සඳහා නිරූපකය වෙතින් ස්වයිප් කරන්න"</string> <string name="camera_hint" msgid="4519495795000658637">"කැමරාව සඳහා නිරූපකය වෙතින් ස්වයිප් කරන්න"</string> @@ -625,6 +627,7 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. නිහඬ කිරීමට තට්ටු කරන්න. ප්රවේශ්යතා සේවා නිහඬ කළ හැකිය."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. කම්පනය කිරීමට සකස් කිරීමට තට්ටු කරන්න."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. නිහඬ කිරීමට තට්ටු කරන්න."</string> + <string name="volume_ringer_change" msgid="3574969197796055532">"නාදකය වෙනස් කිරීමට තට්ටු කරන්න"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"නිහඬ කරන්න"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"නිශ්ශබ්දතාවය ඉවත් කරන්න"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"කම්පනය"</string> @@ -1038,6 +1041,7 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"එක් කරන්න"</string> <string name="controls_dialog_message" msgid="342066938390663844">"යෝජනා කළේ <xliff:g id="APP">%s</xliff:g>"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"පාලන යාවත්කාලීනයි"</string> + <string name="controls_tile_locked" msgid="731547768182831938">"උපාංගය අගුලු දමා ඇත"</string> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN හි අකුරු හෝ සංකේත අඩංගු වේ"</string> <string name="controls_pin_verify" msgid="3452778292918877662">"<xliff:g id="DEVICE">%s</xliff:g> සත්යාපනය කරන්න"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"වැරදි PIN එකකි"</string> diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml index 927b2ac97a20..d514b66e30ad 100644 --- a/packages/SystemUI/res/values-sk/strings.xml +++ b/packages/SystemUI/res/values-sk/strings.xml @@ -416,7 +416,8 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Do východu slnka"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Zapne sa o <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Do <xliff:g id="TIME">%s</xliff:g>"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Znížiť jas"</string> + <!-- no translation found for quick_settings_reduce_bright_colors_label (7537352080559075175) --> + <skip /> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC je deaktivované"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC je aktivované"</string> @@ -450,6 +451,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Ak chcete použiť NFC, odomknite"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Toto zariadenie patrí vašej organizácii"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"Toto zariadení patrí organizácii <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"Telefón otvoríte prejdením prstom od ikony"</string> <string name="voice_hint" msgid="7476017460191291417">"Hlasového asistenta otvoríte prejdením prstom od ikony"</string> <string name="camera_hint" msgid="4519495795000658637">"Fotoaparát otvoríte prejdením prstom od ikony"</string> @@ -631,6 +634,8 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Klepnutím vypnite zvuk. Služby dostupnosti je možné stlmiť."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Klepnutím nastavíte vibrovanie."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Klepnutím vypnete zvuk."</string> + <!-- no translation found for volume_ringer_change (3574969197796055532) --> + <skip /> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"vypnite zvuk"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"zapnite zvuk"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"zapnite vibrovanie"</string> @@ -1050,6 +1055,7 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"Pridať"</string> <string name="controls_dialog_message" msgid="342066938390663844">"Navrhuje <xliff:g id="APP">%s</xliff:g>"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"Ovládanie bolo aktualizované"</string> + <string name="controls_tile_locked" msgid="731547768182831938">"Uzamknuté zariadenie"</string> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN obsahuje písmená či symboly"</string> <string name="controls_pin_verify" msgid="3452778292918877662">"<xliff:g id="DEVICE">%s</xliff:g>, overenie"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"Nesprávny PIN"</string> diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml index 881ba91d013e..b7b2dd0e4784 100644 --- a/packages/SystemUI/res/values-sl/strings.xml +++ b/packages/SystemUI/res/values-sl/strings.xml @@ -416,7 +416,8 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Do sončnega vzhoda"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Vklop ob <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Do <xliff:g id="TIME">%s</xliff:g>"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Zmanjšanje svetlosti"</string> + <!-- no translation found for quick_settings_reduce_bright_colors_label (7537352080559075175) --> + <skip /> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"Tehnologija NFC je onemogočena"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"Tehnologija NFC je omogočena"</string> @@ -450,6 +451,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Odklenite napravo, če želite uporabljati NFC."</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Ta naprava pripada vaši organizaciji"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"Ta naprava pripada organizaciji <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"Povlecite z ikone za telefon"</string> <string name="voice_hint" msgid="7476017460191291417">"Povlecite z ikone za glasovnega pomočnika"</string> <string name="camera_hint" msgid="4519495795000658637">"Povlecite z ikone za fotoaparat"</string> @@ -631,6 +634,8 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Dotaknite se, če želite izklopiti zvok. V storitvah za ljudi s posebnimi potrebami bo morda izklopljen zvok."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Dotaknite se, če želite nastaviti vibriranje."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Dotaknite se, če želite izklopiti zvok."</string> + <!-- no translation found for volume_ringer_change (3574969197796055532) --> + <skip /> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"izklop zvoka"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"vklop zvoka"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibriranje"</string> @@ -1050,6 +1055,7 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"Dodaj"</string> <string name="controls_dialog_message" msgid="342066938390663844">"Predlagala aplikacija <xliff:g id="APP">%s</xliff:g>"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"Kontrolniki so posodobljeni"</string> + <string name="controls_tile_locked" msgid="731547768182831938">"Naprava je zaklenjena"</string> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"Koda PIN vsebuje črke ali simbole"</string> <string name="controls_pin_verify" msgid="3452778292918877662">"Preverjanje naprave <xliff:g id="DEVICE">%s</xliff:g>"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"Napačna koda PIN"</string> diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml index 29d16617571d..9f4c1e183e79 100644 --- a/packages/SystemUI/res/values-sq/strings.xml +++ b/packages/SystemUI/res/values-sq/strings.xml @@ -412,7 +412,8 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Deri në lindje të diellit"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Aktiv në <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Deri në <xliff:g id="TIME">%s</xliff:g>"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Redukto ndriçimin"</string> + <!-- no translation found for quick_settings_reduce_bright_colors_label (7537352080559075175) --> + <skip /> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC është çaktivizuar"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC është aktivizuar"</string> @@ -446,6 +447,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Shkyçe për të përdorur NFC-në"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Kjo pajisje i përket organizatës sate"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"Kjo pajisje i përket <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"Rrëshqit për të hapur telefonin"</string> <string name="voice_hint" msgid="7476017460191291417">"Rrëshqit për të hapur ndihmën zanore"</string> <string name="camera_hint" msgid="4519495795000658637">"Rrëshqit për të hapur kamerën"</string> @@ -625,6 +628,8 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Trokit për të çaktivizuar. Shërbimet e qasshmërisë mund të çaktivizohen."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Trokit për ta vendosur në dridhje."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Trokit për ta çaktivizuar."</string> + <!-- no translation found for volume_ringer_change (3574969197796055532) --> + <skip /> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"çaktivizo audion"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"aktivizo audion"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"lësho dridhje"</string> @@ -1038,6 +1043,7 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"Shto"</string> <string name="controls_dialog_message" msgid="342066938390663844">"Sugjeruar nga <xliff:g id="APP">%s</xliff:g>"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"Kontrollet u përditësuan"</string> + <string name="controls_tile_locked" msgid="731547768182831938">"Pajisja është e kyçur"</string> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"Kodi PIN përmban shkronja ose simbole"</string> <string name="controls_pin_verify" msgid="3452778292918877662">"Verifiko <xliff:g id="DEVICE">%s</xliff:g>"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"Kod PIN i gabuar"</string> diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml index c021bfa8502c..5c2fbac29e2d 100644 --- a/packages/SystemUI/res/values-sr/strings.xml +++ b/packages/SystemUI/res/values-sr/strings.xml @@ -414,7 +414,8 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"До изласка сунца"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Укључује се у <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"До <xliff:g id="TIME">%s</xliff:g>"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Смањи осветљеност"</string> + <!-- no translation found for quick_settings_reduce_bright_colors_label (7537352080559075175) --> + <skip /> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC је онемогућен"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC је омогућен"</string> @@ -448,6 +449,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Откључајте да бисте користили NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Овај уређај припада организацији"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"Овај уређај припада организацији <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"Превуците од иконе за телефон"</string> <string name="voice_hint" msgid="7476017460191291417">"Превуците од иконе за гласовну помоћ"</string> <string name="camera_hint" msgid="4519495795000658637">"Превуците од иконе за камеру"</string> @@ -628,6 +631,8 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Додирните да бисте искључили звук. Звук услуга приступачности ће можда бити искључен."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Додирните да бисте подесили на вибрацију."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Додирните да бисте искључили звук."</string> + <!-- no translation found for volume_ringer_change (3574969197796055532) --> + <skip /> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"искључите звук"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"укључите звук"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"вибрација"</string> @@ -1044,6 +1049,7 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"Додај"</string> <string name="controls_dialog_message" msgid="342066938390663844">"Предлаже <xliff:g id="APP">%s</xliff:g>"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"Контроле су ажуриране"</string> + <string name="controls_tile_locked" msgid="731547768182831938">"Уређај је закључан"</string> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN садржи слова или симболе"</string> <string name="controls_pin_verify" msgid="3452778292918877662">"Верификујте: <xliff:g id="DEVICE">%s</xliff:g>"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"Погрешан PIN"</string> diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml index e38d7cd0a7c3..5ca41ed1c7d7 100644 --- a/packages/SystemUI/res/values-sv/strings.xml +++ b/packages/SystemUI/res/values-sv/strings.xml @@ -412,7 +412,8 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Till soluppgången"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Aktivera kl. <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Till <xliff:g id="TIME">%s</xliff:g>"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Minska ljusstyrkan"</string> + <!-- no translation found for quick_settings_reduce_bright_colors_label (7537352080559075175) --> + <skip /> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC är inaktiverat"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC är aktiverat"</string> @@ -446,6 +447,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Lås upp om du vill använda NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Den här enheten tillhör organisationen"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"Den här enheten tillhör <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"Svep från ikonen och öppna telefonen"</string> <string name="voice_hint" msgid="7476017460191291417">"Svep från ikonen och öppna röstassistenten"</string> <string name="camera_hint" msgid="4519495795000658637">"Svep från ikonen och öppna kameran"</string> @@ -625,6 +628,8 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Tryck här om du vill stänga av ljudet. Tillgänglighetstjänsterna kanske inaktiveras."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Tryck här om du vill aktivera vibrationsläget."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Tryck här om du vill stänga av ljudet."</string> + <!-- no translation found for volume_ringer_change (3574969197796055532) --> + <skip /> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"stänga av ljudet"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"slå på ljudet"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"vibration"</string> @@ -1038,6 +1043,7 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"Lägg till"</string> <string name="controls_dialog_message" msgid="342066938390663844">"Förslag från <xliff:g id="APP">%s</xliff:g>"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"Snabbkontroller uppdaterade"</string> + <string name="controls_tile_locked" msgid="731547768182831938">"Enheten är låst"</string> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"Pinkoden innehåller bokstäver eller symboler"</string> <string name="controls_pin_verify" msgid="3452778292918877662">"Verifiera <xliff:g id="DEVICE">%s</xliff:g>"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"Fel pinkod"</string> diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml index a775d1426d97..768e10ccf881 100644 --- a/packages/SystemUI/res/values-sw/strings.xml +++ b/packages/SystemUI/res/values-sw/strings.xml @@ -412,7 +412,8 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Hadi macheo"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Itawashwa saa <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Hadi saa <xliff:g id="TIME">%s</xliff:g>"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Punguza Ung\'aavu"</string> + <!-- no translation found for quick_settings_reduce_bright_colors_label (7537352080559075175) --> + <skip /> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC imezimwa"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC imewashwa"</string> @@ -446,6 +447,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Fungua ili utumie NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Kifaa hiki kinamilikiwa na shirika lako"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"Kifaa hiki kinamilikiwa na <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"Telezesha kidole kutoka kwa aikoni ili ufikie simu"</string> <string name="voice_hint" msgid="7476017460191291417">"Telezesha kidole kutoka aikoni ili upate mapendekezo ya sauti"</string> <string name="camera_hint" msgid="4519495795000658637">"Telezesha kidole kutoka aikoni ili ufikie kamera"</string> @@ -625,6 +628,8 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Gusa ili ukomeshe. Huenda ikakomesha huduma za zana za walio na matatizo ya kuona au kusikia."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Gusa ili uweke mtetemo."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Gusa ili usitishe."</string> + <!-- no translation found for volume_ringer_change (3574969197796055532) --> + <skip /> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"zima sauti"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"washa sauti"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"tetema"</string> @@ -1038,6 +1043,7 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"Weka"</string> <string name="controls_dialog_message" msgid="342066938390663844">"Kimependekezwa na <xliff:g id="APP">%s</xliff:g>"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"Umesasisha vidhibiti"</string> + <string name="controls_tile_locked" msgid="731547768182831938">"Kifaa kimefungwa"</string> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN ina herufi au alama"</string> <string name="controls_pin_verify" msgid="3452778292918877662">"Thibitisha <xliff:g id="DEVICE">%s</xliff:g>"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"Nambari ya PIN si sahihi"</string> diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml index 335a529bb05b..2ea5a6a35c2f 100644 --- a/packages/SystemUI/res/values-ta/strings.xml +++ b/packages/SystemUI/res/values-ta/strings.xml @@ -412,7 +412,8 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"காலை வரை"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"<xliff:g id="TIME">%s</xliff:g>க்கு ஆன் செய்"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"<xliff:g id="TIME">%s</xliff:g> வரை"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"ஒளிர்வைக் குறை"</string> + <!-- no translation found for quick_settings_reduce_bright_colors_label (7537352080559075175) --> + <skip /> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC முடக்கப்பட்டது"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC இயக்கப்பட்டது"</string> @@ -446,6 +447,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFCயைப் பயன்படுத்த அன்லாக் செய்யவும்"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"இந்த சாதனம் உங்கள் நிறுவனத்துக்கு சொந்தமானது"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"இந்த சாதனம் <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> நிறுவனத்துக்கு சொந்தமானது"</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"ஃபோனிற்கு ஐகானிலிருந்து ஸ்வைப் செய்யவும்"</string> <string name="voice_hint" msgid="7476017460191291417">"குரல் உதவிக்கு ஐகானிலிருந்து ஸ்வைப் செய்யவும்"</string> <string name="camera_hint" msgid="4519495795000658637">"கேமராவிற்கு ஐகானிலிருந்து ஸ்வைப் செய்யவும்"</string> @@ -625,6 +628,8 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. ஒலியடக்க, தட்டவும். அணுகல்தன்மை சேவைகள் ஒலியடக்கப்படக்கூடும்."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. அதிர்விற்கு அமைக்க, தட்டவும்."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. ஒலியடக்க, தட்டவும்."</string> + <!-- no translation found for volume_ringer_change (3574969197796055532) --> + <skip /> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"ஒலியடக்கும்"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"ஒலி இயக்கும்"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"அதிர்வுறும்"</string> @@ -1038,6 +1043,7 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"சேர்"</string> <string name="controls_dialog_message" msgid="342066938390663844">"<xliff:g id="APP">%s</xliff:g> ஆப்ஸால் பரிந்துரைக்கப்பட்டது"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"கட்டுப்பாடுகள் மாற்றப்பட்டன"</string> + <string name="controls_tile_locked" msgid="731547768182831938">"சாதனம் பூட்டப்பட்டது"</string> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"பின்னில் எழுத்துகள் அல்லது குறிகள் உள்ளன"</string> <string name="controls_pin_verify" msgid="3452778292918877662">"<xliff:g id="DEVICE">%s</xliff:g> ஐச் சரிபார்த்தல்"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"தவறான பின்"</string> diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml index 8013d6ef94d0..03af2a0e3725 100644 --- a/packages/SystemUI/res/values-te/strings.xml +++ b/packages/SystemUI/res/values-te/strings.xml @@ -93,10 +93,8 @@ <string name="screenshot_scroll_description" msgid="7855773867093272175">"స్క్రీన్షాట్కు స్క్రోల్ చేయండి"</string> <string name="screenshot_dismiss_description" msgid="4702341245899508786">"స్క్రీన్షాట్ను విస్మరించు"</string> <string name="screenshot_preview_description" msgid="7606510140714080474">"స్క్రీన్షాట్ ప్రివ్యూ"</string> - <!-- no translation found for screenshot_top_boundary (1500569103321300856) --> - <skip /> - <!-- no translation found for screenshot_bottom_boundary (5657242629526407311) --> - <skip /> + <string name="screenshot_top_boundary" msgid="1500569103321300856">"ఎగువ సరిహద్దు"</string> + <string name="screenshot_bottom_boundary" msgid="5657242629526407311">"దిగువ సరిహద్దు"</string> <string name="screenrecord_name" msgid="2596401223859996572">"స్క్రీన్ రికార్డర్"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"స్క్రీన్ రికార్డింగ్ అవుతోంది"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"స్క్రీన్ రికార్డ్ సెషన్ కోసం ఆన్గోయింగ్ నోటిఫికేషన్"</string> @@ -414,7 +412,8 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"సూర్యోదయం వరకు"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"<xliff:g id="TIME">%s</xliff:g> కు ఆన్ అవుతుంది"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"<xliff:g id="TIME">%s</xliff:g> వరకు"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"ప్రకాశాన్ని తగ్గించండి"</string> + <!-- no translation found for quick_settings_reduce_bright_colors_label (7537352080559075175) --> + <skip /> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC నిలిపివేయబడింది"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC ప్రారంభించబడింది"</string> @@ -448,6 +447,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFCని ఉపయోగించడానికి అన్లాక్ చేయండి"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"ఈ పరికరం మీ సంస్థకు చెందినది"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"ఈ పరికరం <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>కు చెందినది"</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"ఫోన్ కోసం చిహ్నాన్ని స్వైప్ చేయండి"</string> <string name="voice_hint" msgid="7476017460191291417">"వాయిస్ అసిస్టెంట్ చిహ్నం నుండి స్వైప్"</string> <string name="camera_hint" msgid="4519495795000658637">"కెమెరా కోసం చిహ్నాన్ని స్వైప్ చేయండి"</string> @@ -546,8 +547,7 @@ <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"మీ కార్యాలయ ప్రొఫైల్లో మీ సంస్థ ఒక ప్రమాణపత్ర అధికారాన్ని ఇన్స్టాల్ చేసింది. మీ సురక్షిత నెట్వర్క్ ట్రాఫిక్ పర్యవేక్షించబడవచ్చు లేదా సవరించబడవచ్చు."</string> <string name="monitoring_description_ca_certificate" msgid="448923057059097497">"ఈ పరికరంలో ప్రమాణపత్ర అధికారం ఇన్స్టాల్ చేయబడింది. మీ సురక్షిత నెట్వర్క్ ట్రాఫిక్ పర్యవేక్షించబడవచ్చు లేదా సవరించబడవచ్చు."</string> <string name="monitoring_description_management_network_logging" msgid="216983105036994771">"మీ నిర్వాహకులు మీ పరికరంలోని ట్రాఫిక్ని పర్యవేక్షించగల నెట్వర్క్ లాగింగ్ని ఆన్ చేసారు."</string> - <!-- no translation found for monitoring_description_managed_profile_network_logging (6932303843097006037) --> - <skip /> + <string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"మీ అడ్మిన్ నెట్వర్క్ లాగింగ్ను ఆన్ చేశారు, ఇది మీ వర్క్ ప్రొఫైల్లోని ట్రాఫిక్ను పర్యవేక్షిస్తుంది కానీ మీ వ్యక్తిగత ప్రొఫైల్లో కాదు."</string> <string name="monitoring_description_named_vpn" msgid="5749932930634037027">"మీరు <xliff:g id="VPN_APP">%1$s</xliff:g>కి కనెక్ట్ చేయబడ్డారు, ఇది ఇమెయిల్లు, యాప్లు మరియు వెబ్సైట్లతో సహా మీ నెట్వర్క్ కార్యాచరణను పర్యవేక్షించగలదు."</string> <string name="monitoring_description_two_named_vpns" msgid="3516830755681229463">"మీరు ఇమెయిల్లు, యాప్లు మరియు వెబ్సైట్లతో సహా మీ నెట్వర్క్ కార్యాచరణను పర్యవేక్షించగల <xliff:g id="VPN_APP_0">%1$s</xliff:g> మరియు <xliff:g id="VPN_APP_1">%2$s</xliff:g>కి కనెక్ట్ చేయబడ్డారు."</string> <string name="monitoring_description_managed_profile_named_vpn" msgid="368812367182387320">"మీ కార్యాలయ ప్రొఫైల్ ఇమెయిల్లు, యాప్లు మరియు వెబ్సైట్లతో సహా మీ నెట్వర్క్ కార్యాచరణను పర్యవేక్షించగల <xliff:g id="VPN_APP">%1$s</xliff:g>కి కనెక్ట్ చేయబడింది."</string> @@ -628,6 +628,8 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. మ్యూట్ చేయడానికి నొక్కండి. యాక్సెస్ సామర్థ్య సేవలు మ్యూట్ చేయబడవచ్చు."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. వైబ్రేట్ అయ్యేలా సెట్ చేయడం కోసం నొక్కండి."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. మ్యూట్ చేయడానికి నొక్కండి."</string> + <!-- no translation found for volume_ringer_change (3574969197796055532) --> + <skip /> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"మ్యూట్ చేయి"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"అన్మ్యూట్ చేయి"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"వైబ్రేట్"</string> @@ -1041,6 +1043,7 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"జోడించండి"</string> <string name="controls_dialog_message" msgid="342066938390663844">"<xliff:g id="APP">%s</xliff:g> ద్వారా సూచించబడింది"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"నియంత్రణలు అప్డేట్ అయ్యాయి"</string> + <string name="controls_tile_locked" msgid="731547768182831938">"పరికరంలాక్ చేయబడింది"</string> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"పిన్ అక్షరాలను లేదా చిహ్నాలను కలిగి ఉంది"</string> <string name="controls_pin_verify" msgid="3452778292918877662">"<xliff:g id="DEVICE">%s</xliff:g>ను వెరిఫై చేయండి"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"పిన్ తప్పు"</string> diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml index c55b7f074221..5e37ed8a0fe8 100644 --- a/packages/SystemUI/res/values-th/strings.xml +++ b/packages/SystemUI/res/values-th/strings.xml @@ -412,7 +412,8 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"จนพระอาทิตย์ขึ้น"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"เปิดเวลา <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"จนถึง <xliff:g id="TIME">%s</xliff:g>"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"ลดความสว่าง"</string> + <!-- no translation found for quick_settings_reduce_bright_colors_label (7537352080559075175) --> + <skip /> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC ถูกปิดใช้งาน"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"เปิดใช้งาน NFC แล้ว"</string> @@ -446,6 +447,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"ปลดล็อกเพื่อใช้ NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"องค์กรของคุณเป็นเจ้าของอุปกรณ์นี้"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g> เป็นเจ้าของอุปกรณ์นี้"</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"เลื่อนไอคอนโทรศัพท์"</string> <string name="voice_hint" msgid="7476017460191291417">"เลื่อนไอคอนตัวช่วยเสียง"</string> <string name="camera_hint" msgid="4519495795000658637">"เลื่อนไอคอนกล้อง"</string> @@ -625,6 +628,8 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s แตะเพื่อปิดเสียง อาจมีการปิดเสียงบริการการเข้าถึง"</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s แตะเพื่อตั้งค่าให้สั่น"</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s แตะเพื่อปิดเสียง"</string> + <!-- no translation found for volume_ringer_change (3574969197796055532) --> + <skip /> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"ปิดเสียง"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"เปิดเสียง"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"สั่น"</string> @@ -1038,6 +1043,7 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"เพิ่ม"</string> <string name="controls_dialog_message" msgid="342066938390663844">"แนะนำโดย <xliff:g id="APP">%s</xliff:g>"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"อัปเดตตัวควบคุมแล้ว"</string> + <string name="controls_tile_locked" msgid="731547768182831938">"อุปกรณ์ถูกล็อก"</string> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN ประกอบด้วยตัวอักษรหรือสัญลักษณ์"</string> <string name="controls_pin_verify" msgid="3452778292918877662">"ยืนยัน <xliff:g id="DEVICE">%s</xliff:g>"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"PIN ไม่ถูกต้อง"</string> diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml index 33bd6593e08c..18313e405f98 100644 --- a/packages/SystemUI/res/values-tl/strings.xml +++ b/packages/SystemUI/res/values-tl/strings.xml @@ -412,7 +412,8 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Hanggang sunrise"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Ma-o-on nang <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Hanggang <xliff:g id="TIME">%s</xliff:g>"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Bawasan ang Liwanag"</string> + <!-- no translation found for quick_settings_reduce_bright_colors_label (7537352080559075175) --> + <skip /> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"Naka-disable ang NFC"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"Naka-enable ang NFC"</string> @@ -446,6 +447,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"I-unlock para magamit ang NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Pagmamay-ari ng iyong organisasyon ang device na ito"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"Pagmamay-ari ng <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> ang device na ito"</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"Mag-swipe mula sa icon para sa telepono"</string> <string name="voice_hint" msgid="7476017460191291417">"Mag-swipe mula sa icon para sa voice assist"</string> <string name="camera_hint" msgid="4519495795000658637">"Mag-swipe mula sa icon para sa camera"</string> @@ -625,6 +628,8 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. I-tap upang i-mute. Maaaring i-mute ang mga serbisyo sa Accessibility."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. I-tap upang itakda na mag-vibrate."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. I-tap upang i-mute."</string> + <!-- no translation found for volume_ringer_change (3574969197796055532) --> + <skip /> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"i-mute"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"i-unmute"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"i-vibrate"</string> @@ -1038,6 +1043,7 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"Idagdag"</string> <string name="controls_dialog_message" msgid="342066938390663844">"Iminungkahi ng <xliff:g id="APP">%s</xliff:g>"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"Na-update na ang mga kontrol"</string> + <string name="controls_tile_locked" msgid="731547768182831938">"Naka-lock ang device"</string> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"May mga titik o simbolo ang PIN"</string> <string name="controls_pin_verify" msgid="3452778292918877662">"I-verify ang <xliff:g id="DEVICE">%s</xliff:g>"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"Maling PIN"</string> diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml index 4bacfb9aaee9..6b3015c899c4 100644 --- a/packages/SystemUI/res/values-tr/strings.xml +++ b/packages/SystemUI/res/values-tr/strings.xml @@ -412,7 +412,8 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Sabaha kadar"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Açılacağı saat: <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Şu saate kadar: <xliff:g id="TIME">%s</xliff:g>"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Parlaklığı Azalt"</string> + <!-- no translation found for quick_settings_reduce_bright_colors_label (7537352080559075175) --> + <skip /> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC devre dışı"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC etkin"</string> @@ -446,6 +447,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC\'yi kullanmak için kilidi açın"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Bu cihaz, kuruluşunuza ait"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"Bu cihaz <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> adlı kuruluşa ait"</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"Telefon için, simgeden hızlıca kaydırın"</string> <string name="voice_hint" msgid="7476017460191291417">"Sesli yardım için, simgeden hızlıca kaydırın"</string> <string name="camera_hint" msgid="4519495795000658637">"Kamera için, simgeden hızlıca kaydırın"</string> @@ -625,6 +628,8 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Sesi kapatmak için dokunun. Erişilebilirlik hizmetlerinin sesi kapatılabilir."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Titreşime ayarlamak için dokunun."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Sesi kapatmak için dokunun."</string> + <!-- no translation found for volume_ringer_change (3574969197796055532) --> + <skip /> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"sesi kapat"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"sesi aç"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"titreşim"</string> @@ -1038,6 +1043,7 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"Ekle"</string> <string name="controls_dialog_message" msgid="342066938390663844">"<xliff:g id="APP">%s</xliff:g> tarafından önerildi"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"Denetimler güncellendi"</string> + <string name="controls_tile_locked" msgid="731547768182831938">"Cihaz kilitlendi"</string> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN, harf veya simge içerir"</string> <string name="controls_pin_verify" msgid="3452778292918877662">"<xliff:g id="DEVICE">%s</xliff:g> cihazını doğrulayın"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"Yanlış PIN"</string> diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml index 4a0746cdd140..12b48306a175 100644 --- a/packages/SystemUI/res/values-uk/strings.xml +++ b/packages/SystemUI/res/values-uk/strings.xml @@ -416,7 +416,8 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"До сходу сонця"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Вмикається о <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"До <xliff:g id="TIME">%s</xliff:g>"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Зменшувати яскравість"</string> + <!-- no translation found for quick_settings_reduce_bright_colors_label (7537352080559075175) --> + <skip /> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC вимкнено"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC ввімкнено"</string> @@ -450,6 +451,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Розблокуйте екран, щоб скористатись NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Цей пристрій належить вашій організації"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"Цей пристрій належить організації \"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>\""</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"Телефон: проведіть пальцем від значка"</string> <string name="voice_hint" msgid="7476017460191291417">"Голосові підказки: проведіть пальцем від значка"</string> <string name="camera_hint" msgid="4519495795000658637">"Камера: проведіть пальцем від значка"</string> @@ -631,6 +634,8 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Торкніться, щоб вимкнути звук. Спеціальні можливості може бути вимкнено."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Торкніться, щоб налаштувати вібросигнал."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Торкніться, щоб вимкнути звук."</string> + <!-- no translation found for volume_ringer_change (3574969197796055532) --> + <skip /> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"вимкнути звук"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"увімкнути звук"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"увімкнути вібросигнал"</string> @@ -1050,6 +1055,7 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"Додати"</string> <string name="controls_dialog_message" msgid="342066938390663844">"Запропоновано додатком <xliff:g id="APP">%s</xliff:g>"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"Елементи керування оновлено"</string> + <string name="controls_tile_locked" msgid="731547768182831938">"Пристрій заблоковано"</string> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN-код містить літери чи символи"</string> <string name="controls_pin_verify" msgid="3452778292918877662">"<xliff:g id="DEVICE">%s</xliff:g>"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"Неправильний PIN-код"</string> diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml index f2e0273440a5..3668f7e430c8 100644 --- a/packages/SystemUI/res/values-ur/strings.xml +++ b/packages/SystemUI/res/values-ur/strings.xml @@ -412,7 +412,8 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"طلوع آفتاب تک"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"آن ہوگی بوقت <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"<xliff:g id="TIME">%s</xliff:g> تک"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"چمک کم کریں"</string> + <!-- no translation found for quick_settings_reduce_bright_colors_label (7537352080559075175) --> + <skip /> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC غیر فعال ہے"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC فعال ہے"</string> @@ -446,6 +447,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC استعمال کرنے کیلئے غیر مقفل کریں"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"یہ آلہ آپ کی تنظیم کا ہے"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"یہ آلہ <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> کا ہے"</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"فون کیلئے آئیکن سے سوائپ کریں"</string> <string name="voice_hint" msgid="7476017460191291417">"صوتی معاون کیلئے آئیکن سے سوائپ کریں"</string> <string name="camera_hint" msgid="4519495795000658637">"کیمرہ کیلئے آئیکن سے سوائپ کریں"</string> @@ -625,6 +628,8 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s۔ خاموش کرنے کیلئے تھپتھپائیں۔ ایکسیسبیلٹی سروسز شاید خاموش ہوں۔"</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s۔ ارتعاش پر سیٹ کرنے کیلئے تھپتھپائیں۔"</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s۔ خاموش کرنے کیلئے تھپتھپائیں۔"</string> + <!-- no translation found for volume_ringer_change (3574969197796055532) --> + <skip /> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"خاموش کریں"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"غیر خاموش کریں"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"وائبریٹ"</string> @@ -1038,6 +1043,7 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"شامل کریں"</string> <string name="controls_dialog_message" msgid="342066938390663844">"<xliff:g id="APP">%s</xliff:g> کی طرف سے تجویز کردہ"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"کنٹرولز اپ ڈیٹ کیے گئے"</string> + <string name="controls_tile_locked" msgid="731547768182831938">"آلہ مقفل کر دیا گیا"</string> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN میں حروف یا علامات شامل ہیں"</string> <string name="controls_pin_verify" msgid="3452778292918877662">"<xliff:g id="DEVICE">%s</xliff:g> کی تصدیق کریں"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"غلط PIN"</string> diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml index fab65b116bda..0732c7f3e82b 100644 --- a/packages/SystemUI/res/values-uz/strings.xml +++ b/packages/SystemUI/res/values-uz/strings.xml @@ -93,10 +93,8 @@ <string name="screenshot_scroll_description" msgid="7855773867093272175">"Skrinshotni aylantirish"</string> <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Skrinshotni yopish"</string> <string name="screenshot_preview_description" msgid="7606510140714080474">"Skrinshotga razm solish"</string> - <!-- no translation found for screenshot_top_boundary (1500569103321300856) --> - <skip /> - <!-- no translation found for screenshot_bottom_boundary (5657242629526407311) --> - <skip /> + <string name="screenshot_top_boundary" msgid="1500569103321300856">"Yuqori chegara"</string> + <string name="screenshot_bottom_boundary" msgid="5657242629526407311">"Quyi chegara"</string> <string name="screenrecord_name" msgid="2596401223859996572">"Ekrandan yozib olish"</string> <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Ekran yozib olinmoqda"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"Ekrandan yozib olish seansi uchun joriy bildirishnoma"</string> @@ -414,7 +412,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Quyosh chiqqunicha"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"<xliff:g id="TIME">%s</xliff:g> da yoqiladi"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"<xliff:g id="TIME">%s</xliff:g> gacha"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Yorqinlikni pasaytirish"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"Yorqinlikni pasaytirish"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC o‘chiq"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC yoniq"</string> @@ -448,6 +446,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC ishlatish uchun qurilma qulfini oching"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Bu qurilma tashkilotingizga tegishli"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"Bu qurilma <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> tashkilotiga tegishli"</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"Telefonni ochish uchun suring"</string> <string name="voice_hint" msgid="7476017460191291417">"Ovozli yordam: belgidan boshlab suring"</string> <string name="camera_hint" msgid="4519495795000658637">"Kamerani ochish uchun suring"</string> @@ -546,8 +546,7 @@ <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Tashkilotingiz ishchi profilingizga CA sertifikatini o‘rnatdi. U himoyalangan tarmoq trafigini nazorat qilishi va o‘zgartirishi mumkin."</string> <string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Qurilmada CA sertifikati o‘rnatilgan. U himoyalangan tarmoq trafigini nazorat qilishi va o‘zgartirishi mumkin."</string> <string name="monitoring_description_management_network_logging" msgid="216983105036994771">"Administrator qurilmangizdagi trafikni nazorat qiluvchi tarmoq jurnalini yoqdi."</string> - <!-- no translation found for monitoring_description_managed_profile_network_logging (6932303843097006037) --> - <skip /> + <string name="monitoring_description_managed_profile_network_logging" msgid="6932303843097006037">"Administrator ish profilingizdagi trafikni nazorat qiluvchi tarmoq jurnalini yoqdi (shaxsiy profildan maʼlumotlar olinmaydi)."</string> <string name="monitoring_description_named_vpn" msgid="5749932930634037027">"<xliff:g id="VPN_APP">%1$s</xliff:g> ilovasi ishga tushirilgan. U internetdagi harakatlaringiz, jumladan, e-pochta, ilova va veb-saytlardagi xatti-harakatlaringizni kuzatishi mumkin."</string> <string name="monitoring_description_two_named_vpns" msgid="3516830755681229463">"<xliff:g id="VPN_APP_0">%1$s</xliff:g> va <xliff:g id="VPN_APP_1">%2$s</xliff:g> ilovalari ishga tushirilgan. Ular tarmoqdagi, jumladan, e-pochta, ilova va veb-saytlardagi xatti-harakatlaringizni kuzatishi mumkin."</string> <string name="monitoring_description_managed_profile_named_vpn" msgid="368812367182387320">"Ishchi profilingizda tarmoqdagi, jumladan, e-pochta, ilova va veb-saytlardagi xatti-harakatlaringizni kuzatishi mumkin bo‘lgan <xliff:g id="VPN_APP">%1$s</xliff:g> ilovasi ishga tushirilgan."</string> @@ -628,6 +627,7 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Ovozini o‘chirish uchun ustiga bosing. Maxsus imkoniyatlar ishlamasligi mumkin."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Tebranishni yoqish uchun ustiga bosing."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Ovozsiz qilish uchun ustiga bosing."</string> + <string name="volume_ringer_change" msgid="3574969197796055532">"Jiringlagich rejimini oʻzgartirish uchun bosing"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"ovozsiz qilish"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"ovozni yoqish"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"tebranish"</string> @@ -1041,6 +1041,7 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"Kiritish"</string> <string name="controls_dialog_message" msgid="342066938390663844">"<xliff:g id="APP">%s</xliff:g> taklif etgan"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"Boshqaruv elementlari yangilandi"</string> + <string name="controls_tile_locked" msgid="731547768182831938">"Qurilma qulflandi"</string> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"Harflar yoki maxsus belgilardan iborat PIN kod"</string> <string name="controls_pin_verify" msgid="3452778292918877662">"Tekshirish: <xliff:g id="DEVICE">%s</xliff:g>"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"PIN kod xato"</string> diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml index 366f755638a5..cc893037e1e5 100644 --- a/packages/SystemUI/res/values-vi/strings.xml +++ b/packages/SystemUI/res/values-vi/strings.xml @@ -412,7 +412,8 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Cho đến khi trời sáng"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Bật vào lúc <xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Cho đến <xliff:g id="TIME">%s</xliff:g>"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Giảm độ sáng"</string> + <!-- no translation found for quick_settings_reduce_bright_colors_label (7537352080559075175) --> + <skip /> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC đã được tắt"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC đã được bật"</string> @@ -446,6 +447,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Mở khóa để sử dụng NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Thiết bị này thuộc về tổ chức của bạn"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"Thiết bị này thuộc về <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"Vuốt từ biểu tượng để mở điện thoại"</string> <string name="voice_hint" msgid="7476017460191291417">"Vuốt từ biểu tượng để mở trợ lý thoại"</string> <string name="camera_hint" msgid="4519495795000658637">"Vuốt từ biểu tượng để mở máy ảnh"</string> @@ -625,6 +628,8 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Nhấn để tắt tiếng. Bạn có thể tắt tiếng dịch vụ trợ năng."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Nhấn để đặt chế độ rung."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Nhấn để tắt tiếng."</string> + <!-- no translation found for volume_ringer_change (3574969197796055532) --> + <skip /> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"tắt tiếng"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"bật tiếng"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"rung"</string> @@ -1038,6 +1043,7 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"Thêm"</string> <string name="controls_dialog_message" msgid="342066938390663844">"Do <xliff:g id="APP">%s</xliff:g> đề xuất"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"Đã cập nhật các tùy chọn điều khiển"</string> + <string name="controls_tile_locked" msgid="731547768182831938">"Đã khóa thiết bị"</string> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"Mã PIN chứa các ký tự hoặc ký hiệu"</string> <string name="controls_pin_verify" msgid="3452778292918877662">"Xác minh <xliff:g id="DEVICE">%s</xliff:g>"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"Mã PIN sai"</string> diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml index c25ad27df294..92f9e67f5f08 100644 --- a/packages/SystemUI/res/values-zh-rCN/strings.xml +++ b/packages/SystemUI/res/values-zh-rCN/strings.xml @@ -412,7 +412,8 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"在日出时关闭"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"在<xliff:g id="TIME">%s</xliff:g> 开启"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"直到<xliff:g id="TIME">%s</xliff:g>"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"调低亮度"</string> + <!-- no translation found for quick_settings_reduce_bright_colors_label (7537352080559075175) --> + <skip /> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC 已停用"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC 已启用"</string> @@ -446,6 +447,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"需要解锁才能使用 NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"此设备归贵单位所有"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"此设备归<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>所有"</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"滑动图标即可拨打电话"</string> <string name="voice_hint" msgid="7476017460191291417">"滑动图标即可打开语音助理"</string> <string name="camera_hint" msgid="4519495795000658637">"滑动图标即可打开相机"</string> @@ -625,6 +628,8 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s。点按即可设为静音,但可能会同时将无障碍服务设为静音。"</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s。点按即可设为振动。"</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s。点按即可设为静音。"</string> + <!-- no translation found for volume_ringer_change (3574969197796055532) --> + <skip /> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"静音"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"取消静音"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"振动"</string> @@ -1038,6 +1043,7 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"添加"</string> <string name="controls_dialog_message" msgid="342066938390663844">"来自<xliff:g id="APP">%s</xliff:g>的建议"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"控件已更新"</string> + <string name="controls_tile_locked" msgid="731547768182831938">"设备已锁定"</string> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN 码由字母或符号组成"</string> <string name="controls_pin_verify" msgid="3452778292918877662">"验证<xliff:g id="DEVICE">%s</xliff:g>"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"PIN 码错误"</string> diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml index aa7b47aace89..d2a232b6db22 100644 --- a/packages/SystemUI/res/values-zh-rHK/strings.xml +++ b/packages/SystemUI/res/values-zh-rHK/strings.xml @@ -412,7 +412,7 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"在日出時關閉"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"於<xliff:g id="TIME">%s</xliff:g>開啟"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"直至<xliff:g id="TIME">%s</xliff:g>"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"調低亮度"</string> + <string name="quick_settings_reduce_bright_colors_label" msgid="7537352080559075175">"調低亮度"</string> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC 已停用"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC 已啟用"</string> @@ -446,6 +446,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"解鎖方可使用 NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"此裝置屬於您的機構"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"此裝置屬於「<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>」"</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"從圖示滑動即可使用手機功能"</string> <string name="voice_hint" msgid="7476017460191291417">"從圖示滑動即可使用語音助手"</string> <string name="camera_hint" msgid="4519495795000658637">"從圖示滑動即可使用相機功能"</string> @@ -625,6 +627,7 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s。輕按即可設為靜音。無障礙功能服務可能已經設為靜音。"</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s。輕按即可設為震動。"</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s。輕按即可設為靜音。"</string> + <string name="volume_ringer_change" msgid="3574969197796055532">"輕按即可變更響鈴模式"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"靜音"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"取消靜音"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"震動"</string> @@ -1038,6 +1041,7 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"新增"</string> <string name="controls_dialog_message" msgid="342066938390663844">"由「<xliff:g id="APP">%s</xliff:g>」提供的建議"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"已更新控制項"</string> + <string name="controls_tile_locked" msgid="731547768182831938">"裝置已上鎖"</string> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN 含有字母或符號"</string> <string name="controls_pin_verify" msgid="3452778292918877662">"驗證<xliff:g id="DEVICE">%s</xliff:g>"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"PIN 錯誤"</string> diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml index ca8db2eae5d6..396484afb2ff 100644 --- a/packages/SystemUI/res/values-zh-rTW/strings.xml +++ b/packages/SystemUI/res/values-zh-rTW/strings.xml @@ -71,7 +71,7 @@ <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"目前登入這部裝置的使用者無法開啟無線偵錯功能。如要使用這項功能,請切換到主要使用者。"</string> <string name="usb_contaminant_title" msgid="894052515034594113">"USB 連接埠已停用"</string> <string name="usb_contaminant_message" msgid="7730476585174719805">"為了避免液體或灰塵導致你的裝置受損,系統已停用 USB 連接埠,因此目前無法偵測任何配件。\n\n系統會在可繼續使用 USB 連接埠時通知你。"</string> - <string name="usb_port_enabled" msgid="531823867664717018">"USB 通訊埠已啟用,可偵測充電器和配件"</string> + <string name="usb_port_enabled" msgid="531823867664717018">"USB 連接埠已啟用,可偵測充電器和配件"</string> <string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"啟用 USB 連接埠"</string> <string name="learn_more" msgid="4690632085667273811">"瞭解詳情"</string> <string name="compat_mode_on" msgid="4963711187149440884">"放大為全螢幕"</string> @@ -412,7 +412,8 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"於日出時關閉"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"開啟時間:<xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"關閉時間:<xliff:g id="TIME">%s</xliff:g>"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"調低亮度"</string> + <!-- no translation found for quick_settings_reduce_bright_colors_label (7537352080559075175) --> + <skip /> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC 已停用"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC 已啟用"</string> @@ -446,6 +447,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"如要使用 NFC,請先解鎖"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"這部裝置的擁有者為貴機構"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"這部裝置的擁有者為「<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>」"</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"滑動手機圖示即可啟用"</string> <string name="voice_hint" msgid="7476017460191291417">"滑動語音小幫手圖示即可啟用"</string> <string name="camera_hint" msgid="4519495795000658637">"滑動相機圖示即可啟用"</string> @@ -625,6 +628,8 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s。輕觸即可設為靜音,但系統可能會將無障礙服務一併設為靜音。"</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s。輕觸即可設為震動。"</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s。輕觸即可設為靜音。"</string> + <!-- no translation found for volume_ringer_change (3574969197796055532) --> + <skip /> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"靜音"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"取消靜音"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"震動"</string> @@ -1038,6 +1043,7 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"新增"</string> <string name="controls_dialog_message" msgid="342066938390663844">"來自「<xliff:g id="APP">%s</xliff:g>」的建議"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"已更新控制項"</string> + <string name="controls_tile_locked" msgid="731547768182831938">"裝置已鎖定"</string> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN 碼含有字母或符號"</string> <string name="controls_pin_verify" msgid="3452778292918877662">"驗證「<xliff:g id="DEVICE">%s</xliff:g>」"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"PIN 碼錯誤"</string> diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml index 371702fb7494..d4e05d0d29aa 100644 --- a/packages/SystemUI/res/values-zu/strings.xml +++ b/packages/SystemUI/res/values-zu/strings.xml @@ -412,7 +412,8 @@ <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Kuze kube sekuphumeni kwelanga"</string> <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Kuvulwe ngo-<xliff:g id="TIME">%s</xliff:g>"</string> <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Kuze kube ngu-<xliff:g id="TIME">%s</xliff:g>"</string> - <string name="quick_settings_reduce_bright_colors_label" msgid="4782053257950003419">"Nciphisa ukukhanya"</string> + <!-- no translation found for quick_settings_reduce_bright_colors_label (7537352080559075175) --> + <skip /> <string name="quick_settings_nfc_label" msgid="1054317416221168085">"I-NFC"</string> <string name="quick_settings_nfc_off" msgid="3465000058515424663">"I-NFC ikhutshaziwe"</string> <string name="quick_settings_nfc_on" msgid="1004976611203202230">"I-NFC inikwe amandla"</string> @@ -446,6 +447,8 @@ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Vula ukuze usebenzise i-NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Le divayisi eyenhlangano yakho"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"Le divayisi ngeye-<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> + <!-- no translation found for do_financed_disclosure_with_name (6723004643314467864) --> + <skip /> <string name="phone_hint" msgid="6682125338461375925">"Swayiphela ifoni kusukela kusithonjana"</string> <string name="voice_hint" msgid="7476017460191291417">"Swayiphela isilekeleli sezwi kusukela kusithonjana"</string> <string name="camera_hint" msgid="4519495795000658637">"Swayiphela ikhamela kusukela kusithonjana"</string> @@ -625,6 +628,8 @@ <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Thepha ukuze uthulise. Amasevisi okufinyelela angathuliswa."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Thepha ukuze usethele ekudlidlizeni."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Thepha ukuze uthulise."</string> + <!-- no translation found for volume_ringer_change (3574969197796055532) --> + <skip /> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"thulisa"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"susa ukuthula"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"dlidliza"</string> @@ -1038,6 +1043,7 @@ <string name="controls_dialog_ok" msgid="2770230012857881822">"Engeza"</string> <string name="controls_dialog_message" msgid="342066938390663844">"Kuphakanyiswe ngu-<xliff:g id="APP">%s</xliff:g>"</string> <string name="controls_dialog_confirmation" msgid="586517302736263447">"Izilawuli zibuyekeziwe"</string> + <string name="controls_tile_locked" msgid="731547768182831938">"Idivayisi ikhiyiwe"</string> <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"Iphinikhodi iqukethe amaletha namasimbui"</string> <string name="controls_pin_verify" msgid="3452778292918877662">"Qinisekisa i-<xliff:g id="DEVICE">%s</xliff:g>"</string> <string name="controls_pin_wrong" msgid="6162694056042164211">"Iphinikhodi engalungile"</string> diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml index acd671cb6297..3bc1c8053db3 100644 --- a/packages/SystemUI/res/values/colors.xml +++ b/packages/SystemUI/res/values/colors.xml @@ -265,7 +265,6 @@ <color name="control_enabled_cool_foreground">@color/GM2_blue_300</color> <color name="control_thumbnail_tint">#33000000</color> <color name="control_thumbnail_shadow_color">@*android:color/black</color> - <color name="controls_lockscreen_scrim">#AA000000</color> <!-- Docked misalignment message --> <color name="misalignment_text_color">#F28B82</color> diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index 89c849a0ef4a..ea0ea5e9472a 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -456,10 +456,12 @@ <dimen name="volume_dialog_panel_transparent_padding">20dp</dimen> - <dimen name="volume_dialog_stream_padding">8dp</dimen> + <dimen name="volume_dialog_stream_padding">12dp</dimen> <dimen name="volume_dialog_panel_width">64dp</dimen> + <dimen name="volume_dialog_panel_width_half">32dp</dimen> + <dimen name="volume_dialog_slider_height">116dp</dimen> <dimen name="volume_dialog_ringer_size">64dp</dimen> @@ -486,6 +488,13 @@ <dimen name="volume_tool_tip_arrow_corner_radius">2dp</dimen> + <!-- Size of each item in the ringer selector drawer. --> + <dimen name="volume_ringer_drawer_item_size">64dp</dimen> + <dimen name="volume_ringer_drawer_item_size_half">32dp</dimen> + + <!-- Size of the icon inside each item in the ringer selector drawer. --> + <dimen name="volume_ringer_drawer_icon_size">24dp</dimen> + <!-- Gravity for the notification panel --> <integer name="notification_panel_layout_gravity">0x31</integer><!-- center_horizontal|top --> @@ -966,7 +975,7 @@ <dimen name="volume_row_padding_start">4dp</dimen> <dimen name="volume_row_header_padding_start">16dp</dimen> <dimen name="volume_row_height">64dp</dimen> - <dimen name="volume_row_slider_height">48dp</dimen> + <dimen name="volume_row_slider_height">192dp</dimen> <dimen name="volume_row_slider_padding_start">12dp</dimen> <dimen name="volume_expander_margin_end">2dp</dimen> diff --git a/packages/SystemUI/res/values/flags.xml b/packages/SystemUI/res/values/flags.xml index 3e16cd47336c..e5518928c98c 100644 --- a/packages/SystemUI/res/values/flags.xml +++ b/packages/SystemUI/res/values/flags.xml @@ -44,4 +44,6 @@ <bool name="flag_toast_style">false</bool> <bool name="flag_navigation_bar_overlay">false</bool> + + <bool name="flag_pm_lite">false</bool> </resources> diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index 4b95c16a3602..5f8df5a13ad1 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -959,7 +959,7 @@ <!-- QuickSettings: Secondary text for when the Dark theme or some other tile will be on until some user-selected time. [CHAR LIMIT=20] --> <string name="quick_settings_dark_mode_secondary_label_until">Until <xliff:g id="time" example="7 am">%s</xliff:g></string> <!-- QuickSettings: Label for the toggle that controls whether Reduce Brightness is enabled. [CHAR LIMIT=NONE] --> - <string name="quick_settings_reduce_bright_colors_label">Reduce Brightness</string> + <string name="quick_settings_reduce_bright_colors_label">Reduce brightness</string> <!-- QuickSettings: NFC tile [CHAR LIMIT=NONE] --> <string name="quick_settings_nfc_label">NFC</string> @@ -1054,6 +1054,9 @@ <!-- Text on keyguard screen and in Quick Settings footer indicating that user's device belongs to their organization. [CHAR LIMIT=40] --> <string name="do_disclosure_with_name">This device belongs to <xliff:g id="organization_name" example="Foo, Inc.">%s</xliff:g></string> + <!-- Text on keyguard screen and in Quick Settings footer indicating that the user's device is provided by the Creditor. [CHAR LIMIT=60] --> + <string name="do_financed_disclosure_with_name">This device is provided by <xliff:g id="organization_name" example="Foo, Inc.">%s</xliff:g></string> + <!-- Shows when people have clicked on the phone icon [CHAR LIMIT=60] --> <string name="phone_hint">Swipe from icon for phone</string> @@ -1558,6 +1561,8 @@ <string name="volume_stream_content_description_vibrate_a11y">%1$s. Tap to set to vibrate.</string> <string name="volume_stream_content_description_mute_a11y">%1$s. Tap to mute.</string> + <string name="volume_ringer_change">Tap to change ringer mode</string> + <!-- Hint for accessibility. For example: double tap to mute [CHAR_LIMIT=NONE] --> <string name="volume_ringer_hint_mute">mute</string> <!-- Hint for accessibility. For example: double tap to unmute [CHAR_LIMIT=NONE] --> diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml index 14b376a8bf6c..2d202fb45bbc 100644 --- a/packages/SystemUI/res/values/styles.xml +++ b/packages/SystemUI/res/values/styles.xml @@ -663,16 +663,16 @@ </style> <style name="Theme.SystemUI.Dialog.Control.LockScreen" parent="@android:style/Theme.DeviceDefault.Dialog.NoActionBar"> - <item name="android:windowAnimationStyle">@style/Animation.Fade</item> + <item name="android:windowAnimationStyle">@style/Animation.ControlDialog</item> <item name="android:windowFullscreen">true</item> <item name="android:windowIsFloating">false</item> - <item name="android:windowBackground">@color/controls_lockscreen_scrim</item> + <item name="android:windowBackground">@null</item> <item name="android:backgroundDimEnabled">true</item> </style> - <style name="Animation.Fade"> - <item name="android:windowEnterAnimation">@android:anim/fade_in</item> - <item name="android:windowExitAnimation">@android:anim/fade_out</item> + <style name="Animation.ControlDialog"> + <item name="android:windowEnterAnimation">@*android:anim/dialog_enter</item> + <item name="android:windowExitAnimation">@*android:anim/dialog_exit</item> </style> <style name="Control" /> diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java index d9a1eb6c0b28..a4054bea1167 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java @@ -305,6 +305,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab private boolean mLogoutEnabled; // cached value to avoid IPCs private boolean mIsUdfpsEnrolled; + private boolean mKeyguardQsUserSwitchEnabled; // 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; @@ -1916,7 +1917,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab return isFaceAuthEnabledForUser(KeyguardUpdateMonitor.getCurrentUser()) && !isUdfpsEnrolled(); } - return true; + return !isKeyguardQsUserSwitchEnabled(); } /** @@ -1926,6 +1927,17 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab return mIsUdfpsEnrolled; } + /** + * @return true if the keyguard qs user switcher shortcut is enabled + */ + public boolean isKeyguardQsUserSwitchEnabled() { + return mKeyguardQsUserSwitchEnabled; + } + + public void setKeyguardQsUserSwitchEnabled(boolean enabled) { + mKeyguardQsUserSwitchEnabled = enabled; + } + private final UserSwitchObserver mUserSwitchObserver = new UserSwitchObserver() { @Override public void onUserSwitching(int newUserId, IRemoteCallback reply) { diff --git a/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java b/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java index 79f0688db869..2040347de1b5 100644 --- a/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java @@ -40,6 +40,7 @@ import android.util.SparseArray; import androidx.annotation.WorkerThread; +import com.android.internal.R; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.systemui.Dumpable; @@ -78,6 +79,7 @@ public class AppOpsControllerImpl extends BroadcastReceiver implements AppOpsCon private static final boolean DEBUG = false; private final BroadcastDispatcher mDispatcher; + private final Context mContext; private final AppOpsManager mAppOps; private final AudioManager mAudioManager; private final LocationManager mLocationManager; @@ -141,6 +143,7 @@ public class AppOpsControllerImpl extends BroadcastReceiver implements AppOpsCon mCameraDisabled = mSensorPrivacyController.isSensorBlocked(CAMERA); mLocationManager = context.getSystemService(LocationManager.class); mPackageManager = context.getPackageManager(); + mContext = context; dumpManager.registerDumpable(TAG, this); } @@ -357,6 +360,15 @@ public class AppOpsControllerImpl extends BroadcastReceiver implements AppOpsCon return mLocationProviderPackages.contains(packageName); } + private boolean isSpeechRecognizerUsage(int opCode, String packageName) { + if (AppOpsManager.OP_RECORD_AUDIO != opCode) { + return false; + } + + return packageName.equals( + mContext.getString(R.string.config_systemSpeechRecognizer)); + } + // TODO ntmyren: remove after teamfood is finished private boolean shouldShowAppPredictor(String pkgName) { if (!DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_PRIVACY, "permissions_hub_2_enabled", @@ -388,7 +400,8 @@ public class AppOpsControllerImpl extends BroadcastReceiver implements AppOpsCon } // TODO ntmyren: Replace this with more robust check if this moves beyond teamfood if ((appOpCode == AppOpsManager.OP_CAMERA && isLocationProvider(packageName)) - || shouldShowAppPredictor(packageName)) { + || shouldShowAppPredictor(packageName) + || isSpeechRecognizerUsage(appOpCode, packageName)) { return true; } diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java index 6451ad9fd5d2..71fba3302abc 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java @@ -68,6 +68,7 @@ public class UdfpsController implements DozeReceiver, HbmCallback { private final Context mContext; private final FingerprintManager mFingerprintManager; + @NonNull private final LayoutInflater mInflater; private final WindowManager mWindowManager; private final DelayableExecutor mFgExecutor; private final StatusBarStateController mStatusBarStateController; @@ -75,10 +76,8 @@ public class UdfpsController implements DozeReceiver, HbmCallback { // sensors, this, in addition to a lot of the code here, will be updated. @VisibleForTesting final FingerprintSensorPropertiesInternal mSensorProps; private final WindowManager.LayoutParams mCoreLayoutParams; - private final UdfpsView mView; - // Indicates whether the overlay is currently showing. Even if it has been requested, it might - // not be showing. - private boolean mIsOverlayShowing; + + @Nullable private UdfpsView mView; // Indicates whether the overlay has been requested. private boolean mIsOverlayRequested; // Reason the overlay has been requested. See IUdfpsOverlayController for definitions. @@ -111,20 +110,48 @@ public class UdfpsController implements DozeReceiver, HbmCallback { @Override public void onEnrollmentProgress(int sensorId, int remaining) { + if (mView == null) { + return; + } mView.onEnrollmentProgress(remaining); } @Override public void onEnrollmentHelp(int sensorId) { + if (mView == null) { + return; + } mView.onEnrollmentHelp(); } @Override public void setDebugMessage(int sensorId, String message) { + if (mView == null) { + return; + } mView.setDebugMessage(message); } } + @VisibleForTesting + final StatusBar.ExpansionChangedListener mStatusBarExpansionListener = + (expansion, expanded) -> { + if (mView != null) { + mView.onExpansionChanged(expansion, expanded); + } + }; + + @VisibleForTesting + final StatusBarStateController.StateListener mStatusBarStateListener = + new StatusBarStateController.StateListener() { + @Override + public void onStateChanged(int newState) { + if (mView != null) { + mView.onStateChanged(newState); + } + } + }; + @SuppressLint("ClickableViewAccessibility") private final UdfpsView.OnTouchListener mOnTouchListener = (v, event) -> { UdfpsView view = (UdfpsView) v; @@ -157,13 +184,14 @@ public class UdfpsController implements DozeReceiver, HbmCallback { @Inject public UdfpsController(@NonNull Context context, @Main Resources resources, - LayoutInflater inflater, + @NonNull LayoutInflater inflater, @Nullable FingerprintManager fingerprintManager, WindowManager windowManager, @NonNull StatusBarStateController statusBarStateController, @Main DelayableExecutor fgExecutor, @Nullable StatusBar statusBar) { mContext = context; + mInflater = inflater; // The fingerprint manager is queried for UDFPS before this class is constructed, so the // fingerprint manager should never be null. mFingerprintManager = checkNotNull(fingerprintManager); @@ -189,15 +217,10 @@ public class UdfpsController implements DozeReceiver, HbmCallback { WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; mCoreLayoutParams.privateFlags = WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY; - mView = (UdfpsView) inflater.inflate(R.layout.udfps_view, null, false); - mView.setSensorProperties(mSensorProps); - mView.setHbmCallback(this); - - statusBar.addExpansionChangedListener(mView); - statusBarStateController.addCallback(mView); + statusBar.addExpansionChangedListener(mStatusBarExpansionListener); + mStatusBarStateController.addCallback(mStatusBarStateListener); mFingerprintManager.setUdfpsOverlayController(new UdfpsOverlayController()); - mIsOverlayShowing = false; } @Nullable @@ -220,7 +243,13 @@ public class UdfpsController implements DozeReceiver, HbmCallback { * @return where the UDFPS exists on the screen in pixels. */ public RectF getSensorLocation() { - return mView.getSensorRect(); + // This is currently used to calculate the amount of space available for notifications + // on lockscreen. Keyguard is only shown in portrait mode for now, so this will need to + // be updated if that ever changes. + return new RectF(mSensorProps.sensorLocationX - mSensorProps.sensorRadius, + mSensorProps.sensorLocationY - mSensorProps.sensorRadius, + mSensorProps.sensorLocationX + mSensorProps.sensorRadius, + mSensorProps.sensorLocationY + mSensorProps.sensorRadius); } private void showOverlay(int reason) { @@ -298,14 +327,18 @@ public class UdfpsController implements DozeReceiver, HbmCallback { private void showUdfpsOverlay(int reason) { mFgExecutor.execute(() -> { - if (!mIsOverlayShowing) { + if (mView == null) { try { Log.v(TAG, "showUdfpsOverlay | adding window"); + + mView = (UdfpsView) mInflater.inflate(R.layout.udfps_view, null, false); + mView.setSensorProperties(mSensorProps); + mView.setHbmCallback(this); + final UdfpsAnimation animation = getUdfpsAnimationForReason(reason); mView.setExtras(animation, mEnrollHelper); mWindowManager.addView(mView, computeLayoutParams(animation)); mView.setOnTouchListener(mOnTouchListener); - mIsOverlayShowing = true; } catch (RuntimeException e) { Log.e(TAG, "showUdfpsOverlay | failed to add window", e); } @@ -334,14 +367,12 @@ public class UdfpsController implements DozeReceiver, HbmCallback { private void hideUdfpsOverlay() { mFgExecutor.execute(() -> { - if (mIsOverlayShowing) { + if (mView != null) { Log.v(TAG, "hideUdfpsOverlay | removing window"); - mView.setExtras(null, null); - mView.setOnTouchListener(null); // Reset the controller back to its starting state. onFingerUp(); mWindowManager.removeView(mView); - mIsOverlayShowing = false; + mView = null; } else { Log.v(TAG, "hideUdfpsOverlay | the overlay is already hidden"); } @@ -388,12 +419,20 @@ public class UdfpsController implements DozeReceiver, HbmCallback { // This method can be called from the UI thread. private void onFingerDown(int x, int y, float minor, float major) { + if (mView == null) { + Log.w(TAG, "Null view in onFingerDown"); + return; + } mView.startIllumination(() -> mFingerprintManager.onPointerDown(mSensorProps.sensorId, x, y, minor, major)); } // This method can be called from the UI thread. private void onFingerUp() { + if (mView == null) { + Log.w(TAG, "Null view in onFingerUp"); + return; + } mFingerprintManager.onPointerUp(mSensorProps.sensorId); mView.stopIllumination(); } diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.java index 6ffecdba883b..399794391700 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.java @@ -136,17 +136,13 @@ public class UdfpsView extends FrameLayout implements DozeReceiver, UdfpsIllumin } @Override - public void onExpandedChanged(boolean isExpanded) { - mNotificationShadeExpanded = isExpanded; - } - - @Override public void onStateChanged(int newState) { mStatusBarState = newState; } @Override public void onExpansionChanged(float expansion, boolean expanded) { + mNotificationShadeExpanded = expanded; mAnimationView.onExpansionChanged(expansion, expanded); } @@ -192,10 +188,6 @@ public class UdfpsView extends FrameLayout implements DozeReceiver, UdfpsIllumin } } - RectF getSensorRect() { - return new RectF(mSensorRect); - } - void setDebugMessage(String message) { mDebugMessage = message; postInvalidate(); diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsAnimations.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsAnimations.kt index cad166d7cd9e..1ea1d97cace5 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsAnimations.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsAnimations.kt @@ -41,7 +41,7 @@ import com.android.systemui.controls.ui.ControlsUiController object ControlsAnimations { - private const val ALPHA_EXIT_DURATION = 167L + private const val ALPHA_EXIT_DURATION = 183L private const val ALPHA_ENTER_DELAY = ALPHA_EXIT_DURATION private const val ALPHA_ENTER_DURATION = 350L - ALPHA_ENTER_DELAY diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt index 1c2f17c55671..2d647a907b17 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt @@ -313,6 +313,10 @@ class ControlsFavoritingActivity @Inject constructor( setOnClickListener { val i = Intent().apply { component = ComponentName(context, ControlsProviderSelectorActivity::class.java) + putExtra( + ControlsUiController.BACK_TO_GLOBAL_ACTIONS, + backToGlobalActions + ) } if (doneButton.isEnabled) { // The user has made changes diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsProviderSelectorActivity.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsProviderSelectorActivity.kt index 08147746a4c8..d5e41d031eac 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsProviderSelectorActivity.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsProviderSelectorActivity.kt @@ -32,6 +32,8 @@ import androidx.recyclerview.widget.RecyclerView.AdapterDataObserver import com.android.systemui.R import com.android.systemui.broadcast.BroadcastDispatcher import com.android.systemui.controls.controller.ControlsController +import com.android.systemui.controls.ui.ControlsDialog +import com.android.systemui.controls.ui.ControlsUiController import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.globalactions.GlobalActionsComponent @@ -49,13 +51,15 @@ class ControlsProviderSelectorActivity @Inject constructor( private val listingController: ControlsListingController, private val controlsController: ControlsController, private val globalActionsComponent: GlobalActionsComponent, - broadcastDispatcher: BroadcastDispatcher + private val broadcastDispatcher: BroadcastDispatcher, + private val uiController: ControlsUiController ) : LifecycleActivity() { companion object { private const val TAG = "ControlsProviderSelectorActivity" } + private var backToGlobalActions = true private lateinit var recyclerView: RecyclerView private val currentUserTracker = object : CurrentUserTracker(broadcastDispatcher) { private val startingUser = listingController.currentUserId @@ -101,10 +105,19 @@ class ControlsProviderSelectorActivity @Inject constructor( } } requireViewById<View>(R.id.done).visibility = View.GONE + + backToGlobalActions = intent.getBooleanExtra( + ControlsUiController.BACK_TO_GLOBAL_ACTIONS, + true + ) } override fun onBackPressed() { - globalActionsComponent.handleShowGlobalActionsMenu() + if (backToGlobalActions) { + globalActionsComponent.handleShowGlobalActionsMenu() + } else { + ControlsDialog(applicationContext, broadcastDispatcher).show(uiController) + } animateExitAndFinish() } @@ -152,8 +165,13 @@ class ControlsProviderSelectorActivity @Inject constructor( listingController.getAppLabel(it)) putExtra(Intent.EXTRA_COMPONENT_NAME, it) putExtra(ControlsFavoritingActivity.EXTRA_FROM_PROVIDER_SELECTOR, true) + putExtra( + ControlsUiController.BACK_TO_GLOBAL_ACTIONS, + backToGlobalActions + ) } startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(this).toBundle()) + animateExitAndFinish() } } } diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/NearestTouchFrame.java b/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/NearestTouchFrame.java index b1c85b5c530e..8ff7b7ae8e59 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/NearestTouchFrame.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/NearestTouchFrame.java @@ -84,19 +84,14 @@ public class NearestTouchFrame extends FrameLayout { } @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - super.onMeasure(widthMeasureSpec, heightMeasureSpec); + protected void onLayout(boolean changed, int left, int top, int right, int bottom) { + super.onLayout(changed, left, top, right, bottom); mClickableChildren.clear(); mAttachedChildren.clear(); mTouchableRegions.clear(); addClickableChildren(this); - cacheClosestChildLocations(); - } - - @Override - protected void onLayout(boolean changed, int left, int top, int right, int bottom) { - super.onLayout(changed, left, top, right, bottom); getLocationInWindow(mOffset); + cacheClosestChildLocations(); } /** diff --git a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java index eaf212362320..fcb56a4ec75d 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java +++ b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java @@ -71,7 +71,6 @@ public class PagedTileLayout extends ViewPager implements QSTileLayout { private int mMinRows = 1; private int mMaxColumns = TileLayout.NO_MAX_COLUMNS; - private boolean mShowLabels = true; private final boolean mSideLabels; public PagedTileLayout(Context context, AttributeSet attrs) { @@ -91,16 +90,6 @@ public class PagedTileLayout extends ViewPager implements QSTileLayout { } private int mLastMaxHeight = -1; - @Override - public void setShowLabels(boolean show) { - mShowLabels = show; - for (TileLayout p : mPages) { - p.setShowLabels(show); - } - mDistributeTiles = true; - requestLayout(); - } - public void saveInstanceState(Bundle outState) { outState.putInt(CURRENT_PAGE, getCurrentItem()); } @@ -239,7 +228,6 @@ public class PagedTileLayout extends ViewPager implements QSTileLayout { : R.layout.qs_paged_page, this, false); page.setMinRows(mMinRows); page.setMaxColumns(mMaxColumns); - page.setShowLabels(mShowLabels); return page; } diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFooterViewController.java b/packages/SystemUI/src/com/android/systemui/qs/QSFooterViewController.java index 16e519657a41..2bea72cc0c7e 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSFooterViewController.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSFooterViewController.java @@ -16,6 +16,8 @@ package com.android.systemui.qs; +import static com.android.systemui.qs.dagger.QSFlagsModule.PM_LITE_ENABLED; + import android.content.ClipData; import android.content.ClipboardManager; import android.content.Intent; @@ -41,6 +43,7 @@ import com.android.systemui.tuner.TunerService; import com.android.systemui.util.ViewController; import javax.inject.Inject; +import javax.inject.Named; /** * Controller for {@link QSFooterView}. @@ -63,6 +66,8 @@ public class QSFooterViewController extends ViewController<QSFooterView> impleme private final View mEdit; private final MultiUserSwitch mMultiUserSwitch; private final PageIndicator mPageIndicator; + private final View mPowerMenuLite; + private final boolean mShowPMLiteButton; private final UserInfoController.OnUserInfoChangedListener mOnUserInfoChangedListener = new UserInfoController.OnUserInfoChangedListener() { @@ -123,7 +128,8 @@ public class QSFooterViewController extends ViewController<QSFooterView> impleme DeviceProvisionedController deviceProvisionedController, UserTracker userTracker, QSPanelController qsPanelController, QSDetailDisplayer qsDetailDisplayer, QuickQSPanelController quickQSPanelController, - TunerService tunerService, MetricsLogger metricsLogger) { + TunerService tunerService, MetricsLogger metricsLogger, + @Named(PM_LITE_ENABLED) boolean showPMLiteButton) { super(view); mUserManager = userManager; mUserInfoController = userInfoController; @@ -141,10 +147,15 @@ public class QSFooterViewController extends ViewController<QSFooterView> impleme mEdit = mView.findViewById(android.R.id.edit); mMultiUserSwitch = mView.findViewById(R.id.multi_user_switch); mPageIndicator = mView.findViewById(R.id.footer_page_indicator); + mPowerMenuLite = mView.findViewById(R.id.pm_lite); + mShowPMLiteButton = showPMLiteButton; } @Override protected void onViewAttached() { + if (mShowPMLiteButton) { + mPowerMenuLite.setVisibility(View.VISIBLE); + } mView.addOnLayoutChangeListener( (v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> mView.updateAnimator( diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java index 05633071be86..7657dcead583 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java @@ -847,8 +847,6 @@ public class QSPanel extends LinearLayout implements Tunable { default void setExpansion(float expansion) {} int getNumVisibleTiles(); - - default void setShowLabels(boolean show) {} } interface OnConfigurationChangedListener { diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java index d60801ef2d03..eda1abb0997e 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java @@ -124,7 +124,6 @@ public class QSPanelController extends QSPanelControllerBase<QSPanel> { updateMediaDisappearParameters(); mTunerService.addTunable(mView, QS_SHOW_BRIGHTNESS); - mTunerService.addTunable(mTunable, QS_REMOVE_LABELS); mView.updateResources(); if (mView.isListening()) { refreshAllTiles(); @@ -138,13 +137,6 @@ public class QSPanelController extends QSPanelControllerBase<QSPanel> { } @Override - boolean switchTileLayout(boolean force) { - boolean result = super.switchTileLayout(force); - getTileLayout().setShowLabels(mShowLabels); - return result; - } - - @Override protected QSTileRevealController createTileRevealController() { return mQsTileRevealControllerFactory.create( this, (PagedTileLayout) mView.createRegularTileLayout()); @@ -152,7 +144,6 @@ public class QSPanelController extends QSPanelControllerBase<QSPanel> { @Override protected void onViewDetached() { - mTunerService.removeTunable(mTunable); mTunerService.removeTunable(mView); mView.removeOnConfigurationChangedListener(mOnConfigurationChangedListener); if (mBrightnessMirrorController != null) { @@ -318,22 +309,5 @@ public class QSPanelController extends QSPanelControllerBase<QSPanel> { public boolean isExpanded() { return mView.isExpanded(); } - - private TunerService.Tunable mTunable = new TunerService.Tunable() { - @Override - public void onTuningChanged(String key, String newValue) { - if (QS_REMOVE_LABELS.equals(key)) { - if (!mQSLabelFlag) return; - boolean newShowLabels = newValue == null || "0".equals(newValue); - if (mShowLabels == newShowLabels) return; - mShowLabels = newShowLabels; - for (TileRecord t : mRecords) { - t.tileView.setShowLabels(mShowLabels); - } - getTileLayout().setShowLabels(mShowLabels); - mView.requestLayout(); - } - } - }; } diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java index f1174fbe7aef..8ab17432524d 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java @@ -198,7 +198,6 @@ public abstract class QSPanelControllerBase<T extends QSPanel> extends ViewContr final TileRecord r = new TileRecord(); r.tile = tile; r.tileView = mHost.createTileView(tile, collapsedView); - r.tileView.setShowLabels(mShowLabels); mView.addTile(r); mRecords.add(r); mCachedSpecs = getTilesSpecs(); diff --git a/packages/SystemUI/src/com/android/systemui/qs/SideLabelTileLayout.kt b/packages/SystemUI/src/com/android/systemui/qs/SideLabelTileLayout.kt index 4de4a78e9e8a..c3cc3af10e83 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/SideLabelTileLayout.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/SideLabelTileLayout.kt @@ -34,8 +34,6 @@ open class SideLabelTileLayout( } } - override fun setShowLabels(show: Boolean) { } - override fun isFull(): Boolean { return mRecords.size >= maxTiles() } diff --git a/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java index 14cbf980df23..c1ce4a577dda 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java +++ b/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java @@ -36,7 +36,6 @@ public class TileLayout extends ViewGroup implements QSTileLayout { private int mCellMarginTop; protected boolean mListening; protected int mMaxAllowedRows = 3; - private boolean mShowLabels = true; // Prototyping with less rows private final boolean mLessRows; @@ -57,12 +56,6 @@ public class TileLayout extends ViewGroup implements QSTileLayout { } @Override - public void setShowLabels(boolean show) { - mShowLabels = show; - updateResources(); - } - - @Override public int getOffsetTop(TileRecord tile) { return getTop(); } @@ -128,12 +121,9 @@ public class TileLayout extends ViewGroup implements QSTileLayout { mMaxCellHeight = mContext.getResources().getDimensionPixelSize(R.dimen.qs_tile_height); mCellMarginHorizontal = res.getDimensionPixelSize(R.dimen.qs_tile_margin_horizontal); mCellMarginVertical= res.getDimensionPixelSize(R.dimen.qs_tile_margin_vertical); - if (!mShowLabels && mCellMarginVertical == 0) { - mCellMarginVertical = mCellMarginHorizontal; - } mCellMarginTop = res.getDimensionPixelSize(R.dimen.qs_tile_margin_top); mMaxAllowedRows = Math.max(1, getResources().getInteger(R.integer.quick_settings_max_rows)); - if (mLessRows && mShowLabels) mMaxAllowedRows = Math.max(mMinRows, mMaxAllowedRows - 1); + if (mLessRows) mMaxAllowedRows = Math.max(mMinRows, mMaxAllowedRows - 1); if (updateColumns()) { requestLayout(); return true; @@ -194,9 +184,8 @@ public class TileLayout extends ViewGroup implements QSTileLayout { + mCellMarginVertical; final int previousRows = mRows; mRows = availableHeight / (getCellHeight() + mCellMarginVertical); - final int minRows = mShowLabels ? mMinRows : mMinRows + 1; - if (mRows < minRows) { - mRows = minRows; + if (mRows < mMinRows) { + mRows = mMinRows; } else if (mRows >= mMaxAllowedRows) { mRows = mMaxAllowedRows; } @@ -216,7 +205,7 @@ public class TileLayout extends ViewGroup implements QSTileLayout { } protected int getCellHeight() { - return mShowLabels ? mMaxCellHeight : mMaxCellHeight / 2; + return mMaxCellHeight; } protected void layoutTileRecords(int numRecords) { diff --git a/packages/SystemUI/src/com/android/systemui/qs/carrier/QSCarrierGroupController.java b/packages/SystemUI/src/com/android/systemui/qs/carrier/QSCarrierGroupController.java index a567f512b204..0dc0b30748aa 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/carrier/QSCarrierGroupController.java +++ b/packages/SystemUI/src/com/android/systemui/qs/carrier/QSCarrierGroupController.java @@ -42,6 +42,7 @@ import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.statusbar.policy.NetworkController; +import com.android.systemui.statusbar.policy.NetworkController.MobileDataIndicators; import java.util.function.Consumer; @@ -74,30 +75,25 @@ public class QSCarrierGroupController { private final NetworkController.SignalCallback mSignalCallback = new NetworkController.SignalCallback() { @Override - public void setMobileDataIndicators(NetworkController.IconState statusIcon, - NetworkController.IconState qsIcon, int statusType, int qsType, - boolean activityIn, boolean activityOut, - CharSequence typeContentDescription, - CharSequence typeContentDescriptionHtml, CharSequence description, - boolean isWide, int subId, boolean roaming, boolean showTriangle) { + public void setMobileDataIndicators(MobileDataIndicators indicators) { if (mProviderModel) { return; } - int slotIndex = getSlotIndex(subId); + int slotIndex = getSlotIndex(indicators.subId); if (slotIndex >= SIM_SLOTS) { Log.w(TAG, "setMobileDataIndicators - slot: " + slotIndex); return; } if (slotIndex == SubscriptionManager.INVALID_SIM_SLOT_INDEX) { - Log.e(TAG, "Invalid SIM slot index for subscription: " + subId); + Log.e(TAG, "Invalid SIM slot index for subscription: " + indicators.subId); return; } mInfos[slotIndex] = new CellSignalState( - statusIcon.visible, - statusIcon.icon, - statusIcon.contentDescription, - typeContentDescription.toString(), - roaming + indicators.statusIcon.visible, + indicators.statusIcon.icon, + indicators.statusIcon.contentDescription, + indicators.typeContentDescription.toString(), + indicators.roaming ); mMainHandler.obtainMessage(H.MSG_UPDATE_STATE).sendToTarget(); } diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java index 9fe949b15933..dce081f21581 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java +++ b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java @@ -25,7 +25,6 @@ import android.util.TypedValue; import android.view.ContextThemeWrapper; import android.view.LayoutInflater; import android.view.Menu; -import android.view.MenuItem; import android.view.View; import android.widget.LinearLayout; import android.widget.Toolbar; @@ -48,7 +47,6 @@ import com.android.systemui.statusbar.phone.NotificationsQuickSettingsContainer; public class QSCustomizer extends LinearLayout { static final int MENU_RESET = Menu.FIRST; - static final int MENU_REMOVE_LABELS = Menu.FIRST + 1; static final String EXTRA_QS_CUSTOMIZING = "qs_customizing"; private final QSDetailClipper mClipper; @@ -77,10 +75,6 @@ public class QSCustomizer extends LinearLayout { toolbar.getMenu().add(Menu.NONE, MENU_RESET, 0, mContext.getString(com.android.internal.R.string.reset)); - // Prototype menu item - toolbar.getMenu() - .add(Menu.NONE, MENU_REMOVE_LABELS, Menu.NONE, R.string.qs_remove_labels) - .setCheckable(true); toolbar.setTitle(R.string.qs_edit); mRecyclerView = findViewById(android.R.id.list); mTransparentView = findViewById(R.id.customizer_transparent_view); @@ -89,11 +83,6 @@ public class QSCustomizer extends LinearLayout { mRecyclerView.setItemAnimator(animator); } - MenuItem getRemoveItem() { - return ((Toolbar) findViewById(com.android.internal.R.id.action_bar)) - .getMenu().findItem(MENU_REMOVE_LABELS); - } - void updateResources() { LayoutParams lp = (LayoutParams) mTransparentView.getLayoutParams(); lp.height = mContext.getResources().getDimensionPixelSize( diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizerController.java b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizerController.java index d4bab2197249..f56a2bbefaf7 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizerController.java +++ b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizerController.java @@ -17,9 +17,7 @@ package com.android.systemui.qs.customize; import static com.android.systemui.qs.customize.QSCustomizer.EXTRA_QS_CUSTOMIZING; -import static com.android.systemui.qs.customize.QSCustomizer.MENU_REMOVE_LABELS; import static com.android.systemui.qs.customize.QSCustomizer.MENU_RESET; -import static com.android.systemui.qs.dagger.QSFlagsModule.QS_LABELS_FLAG; import android.content.res.Configuration; import android.os.Bundle; @@ -38,7 +36,6 @@ import com.android.systemui.keyguard.ScreenLifecycle; import com.android.systemui.plugins.qs.QSTile; import com.android.systemui.qs.QSEditEvent; import com.android.systemui.qs.QSFragment; -import com.android.systemui.qs.QSPanelController; import com.android.systemui.qs.QSTileHost; import com.android.systemui.qs.dagger.QSScope; import com.android.systemui.statusbar.phone.LightBarController; @@ -46,14 +43,12 @@ import com.android.systemui.statusbar.phone.NotificationsQuickSettingsContainer; import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener; import com.android.systemui.statusbar.policy.KeyguardStateController; -import com.android.systemui.tuner.TunerService; import com.android.systemui.util.ViewController; import java.util.ArrayList; import java.util.List; import javax.inject.Inject; -import javax.inject.Named; /** {@link ViewController} for {@link QSCustomizer}. */ @QSScope @@ -67,8 +62,6 @@ public class QSCustomizerController extends ViewController<QSCustomizer> { private final ConfigurationController mConfigurationController; private final UiEventLogger mUiEventLogger; private final Toolbar mToolbar; - private final TunerService mTunerService; - private final boolean mQsLabelsFlag; private final OnMenuItemClickListener mOnMenuItemClickListener = new OnMenuItemClickListener() { @Override @@ -76,11 +69,6 @@ public class QSCustomizerController extends ViewController<QSCustomizer> { if (item.getItemId() == MENU_RESET) { mUiEventLogger.log(QSEditEvent.QS_EDIT_RESET); reset(); - } else if (item.getItemId() == MENU_REMOVE_LABELS) { - item.setChecked(!item.isChecked()); - mTunerService.setValue( - QSPanelController.QS_REMOVE_LABELS, item.isChecked() ? "1" : "0"); - return false; } return false; } @@ -111,20 +99,11 @@ public class QSCustomizerController extends ViewController<QSCustomizer> { } }; - private final TunerService.Tunable mTunable = new TunerService.Tunable() { - @Override - public void onTuningChanged(String key, String newValue) { - mToolbar.getMenu().findItem(MENU_REMOVE_LABELS) - .setChecked(newValue != null && !("0".equals(newValue))); - } - }; - @Inject protected QSCustomizerController(QSCustomizer view, TileQueryHelper tileQueryHelper, QSTileHost qsTileHost, TileAdapter tileAdapter, ScreenLifecycle screenLifecycle, KeyguardStateController keyguardStateController, LightBarController lightBarController, - ConfigurationController configurationController, UiEventLogger uiEventLogger, - TunerService tunerService, @Named(QS_LABELS_FLAG) boolean qsLabelsFlag) { + ConfigurationController configurationController, UiEventLogger uiEventLogger) { super(view); mTileQueryHelper = tileQueryHelper; mQsTileHost = qsTileHost; @@ -136,21 +115,12 @@ public class QSCustomizerController extends ViewController<QSCustomizer> { mUiEventLogger = uiEventLogger; mToolbar = mView.findViewById(com.android.internal.R.id.action_bar); - mQsLabelsFlag = qsLabelsFlag; - - mTunerService = tunerService; } - @Override - protected void onInit() { - super.onInit(); - mView.getRemoveItem().setVisible(mQsLabelsFlag); - } @Override protected void onViewAttached() { mView.updateNavBackDrop(getResources().getConfiguration(), mLightBarController); - mTunerService.addTunable(mTunable, QSPanelController.QS_REMOVE_LABELS); mConfigurationController.addCallback(mConfigurationListener); @@ -181,7 +151,6 @@ public class QSCustomizerController extends ViewController<QSCustomizer> { @Override protected void onViewDetached() { - mTunerService.removeTunable(mTunable); mTileQueryHelper.setListener(null); mToolbar.setOnMenuItemClickListener(null); mConfigurationController.removeCallback(mConfigurationListener); diff --git a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSFlagsModule.java b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSFlagsModule.java index 35a8257bd5a7..10192bc20df9 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSFlagsModule.java +++ b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSFlagsModule.java @@ -21,6 +21,7 @@ import android.hardware.display.ColorDisplayManager; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.statusbar.FeatureFlags; +import com.android.systemui.util.settings.GlobalSettings; import javax.inject.Named; @@ -31,6 +32,8 @@ import dagger.Provides; public interface QSFlagsModule { String QS_LABELS_FLAG = "qs_labels_flag"; String RBC_AVAILABLE = "rbc_available"; + String PM_LITE_ENABLED = "pm_lite"; + String PM_LITE_SETTING = "sysui_pm_lite"; @Provides @SysUISingleton @@ -46,4 +49,11 @@ public interface QSFlagsModule { static boolean isReduceBrightColorsAvailable(Context context) { return ColorDisplayManager.isReduceBrightColorsAvailable(context); } + + @Provides + @SysUISingleton + @Named(PM_LITE_ENABLED) + static boolean isPMLiteEnabled(FeatureFlags featureFlags, GlobalSettings globalSettings) { + return featureFlags.isPMLiteEnabled() && globalSettings.getInt(PM_LITE_SETTING, 0) != 0; + } } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileView.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileView.java index 424aafac1f7a..207b25d001b9 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileView.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileView.java @@ -174,9 +174,4 @@ public class QSTileView extends QSTileBaseView { mLabelContainer.setClickable(false); mLabelContainer.setLongClickable(false); } - - @Override - public void setShowLabels(boolean show) { - mHandler.post(() -> mLabelContainer.setVisibility(show ? VISIBLE : GONE)); - } } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewHorizontal.kt b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewHorizontal.kt index c98de8cb8fab..07d48f32ff20 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewHorizontal.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewHorizontal.kt @@ -16,6 +16,7 @@ package com.android.systemui.qs.tileimpl +import android.animation.ValueAnimator import android.content.Context import android.content.res.ColorStateList import android.graphics.Color @@ -31,12 +32,17 @@ import com.android.systemui.plugins.qs.QSIconView import com.android.systemui.plugins.qs.QSTile import com.android.systemui.qs.tileimpl.QSTileImpl.getColorForState +// Placeholder +private const val CORNER_RADIUS = 40f + class QSTileViewHorizontal( context: Context, icon: QSIconView ) : QSTileView(context, icon, false) { private var paintDrawable: PaintDrawable? = null + private var paintColor = Color.TRANSPARENT + private var paintAnimator: ValueAnimator? = null init { orientation = HORIZONTAL @@ -70,8 +76,8 @@ class QSTileViewHorizontal( override fun newTileBackground(): Drawable? { val d = super.newTileBackground() if (paintDrawable == null) { - paintDrawable = PaintDrawable(Color.WHITE).apply { - setCornerRadius(50f) + paintDrawable = PaintDrawable(paintColor).apply { + setCornerRadius(CORNER_RADIUS) } } if (d is RippleDrawable) { @@ -94,9 +100,39 @@ class QSTileViewHorizontal( override fun handleStateChanged(state: QSTile.State) { super.handleStateChanged(state) - paintDrawable?.setTint(getCircleColor(state.state)) mSecondLine.setTextColor(mLabel.textColors) mLabelContainer.background = null + + val allowAnimations = animationsEnabled() && paintColor != Color.TRANSPARENT + val newColor = getCircleColor(state.state) + if (allowAnimations) { + animateToNewState(newColor) + } else { + if (newColor != paintColor) { + clearAnimator() + paintDrawable?.paint?.color = newColor + paintDrawable?.invalidateSelf() + } + } + paintColor = newColor + } + + private fun animateToNewState(newColor: Int) { + if (newColor != paintColor) { + clearAnimator() + paintAnimator = ValueAnimator.ofArgb(paintColor, newColor) + .setDuration(QSIconViewImpl.QS_ANIM_LENGTH).apply { + addUpdateListener { animation: ValueAnimator -> + paintDrawable?.paint?.color = animation.animatedValue as Int + paintDrawable?.invalidateSelf() + } + start() + } + } + } + + private fun clearAnimator() { + paintAnimator?.cancel()?.also { paintAnimator = null } } override fun handleExpand(dualTarget: Boolean) {} diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java index 1dddc452ec1d..f03ce2c0b267 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java @@ -54,6 +54,7 @@ import com.android.systemui.statusbar.policy.CastController.CastDevice; import com.android.systemui.statusbar.policy.HotspotController; import com.android.systemui.statusbar.policy.KeyguardStateController; import com.android.systemui.statusbar.policy.NetworkController; +import com.android.systemui.statusbar.policy.NetworkController.WifiIndicators; import java.util.ArrayList; import java.util.LinkedHashMap; @@ -269,13 +270,10 @@ public class CastTile extends QSTileImpl<BooleanState> { private final NetworkController.SignalCallback mSignalCallback = new NetworkController.SignalCallback() { @Override - public void setWifiIndicators(boolean enabled, - NetworkController.IconState statusIcon, - NetworkController.IconState qsIcon, boolean activityIn, boolean activityOut, - String description, boolean isTransient, String statusLabel) { + public void setWifiIndicators(WifiIndicators indicators) { // statusIcon.visible has the connected status information - boolean enabledAndConnected = - enabled && (qsIcon == null ? false : qsIcon.visible); + boolean enabledAndConnected = indicators.enabled + && (indicators.qsIcon == null ? false : indicators.qsIcon.visible); if (enabledAndConnected != mWifiConnected) { mWifiConnected = enabledAndConnected; // Hotspot is not connected, so changes here should update diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java index 720c5dc7026f..6a574d1d314b 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java @@ -56,6 +56,7 @@ import com.android.systemui.qs.tileimpl.QSTileImpl; import com.android.systemui.statusbar.phone.SystemUIDialog; import com.android.systemui.statusbar.policy.NetworkController; import com.android.systemui.statusbar.policy.NetworkController.IconState; +import com.android.systemui.statusbar.policy.NetworkController.MobileDataIndicators; import com.android.systemui.statusbar.policy.NetworkController.SignalCallback; import javax.inject.Inject; @@ -264,21 +265,17 @@ public class CellularTile extends QSTileImpl<SignalState> { private final CallbackInfo mInfo = new CallbackInfo(); @Override - public void setMobileDataIndicators(IconState statusIcon, IconState qsIcon, int statusType, - int qsType, boolean activityIn, boolean activityOut, - CharSequence typeContentDescription, - CharSequence typeContentDescriptionHtml, CharSequence description, - boolean isWide, int subId, boolean roaming, boolean showTriangle) { - if (qsIcon == null) { + public void setMobileDataIndicators(MobileDataIndicators indicators) { + if (indicators.qsIcon == null) { // Not data sim, don't display. return; } mInfo.dataSubscriptionName = mController.getMobileDataNetworkName(); - mInfo.dataContentDescription = - (description != null) ? typeContentDescriptionHtml : null; - mInfo.activityIn = activityIn; - mInfo.activityOut = activityOut; - mInfo.roaming = roaming; + mInfo.dataContentDescription = indicators.description != null + ? indicators.typeContentDescriptionHtml : null; + mInfo.activityIn = indicators.activityIn; + mInfo.activityOut = indicators.activityOut; + mInfo.roaming = indicators.roaming; mInfo.multipleSubs = mController.getNumberSubscriptions() > 1; refreshState(mInfo); } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/InternetTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/InternetTile.java index 946d041bdd93..e1a1fd2679c5 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/InternetTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/InternetTile.java @@ -51,7 +51,9 @@ import com.android.systemui.qs.logging.QSLogger; import com.android.systemui.qs.tileimpl.QSTileImpl; import com.android.systemui.statusbar.policy.NetworkController; import com.android.systemui.statusbar.policy.NetworkController.IconState; +import com.android.systemui.statusbar.policy.NetworkController.MobileDataIndicators; import com.android.systemui.statusbar.policy.NetworkController.SignalCallback; +import com.android.systemui.statusbar.policy.NetworkController.WifiIndicators; import com.android.systemui.statusbar.policy.WifiIcons; import java.io.FileDescriptor; @@ -234,70 +236,44 @@ public class InternetTile extends QSTileImpl<SignalState> { @Override - public void setWifiIndicators(boolean enabled, IconState statusIcon, IconState qsIcon, - boolean activityIn, boolean activityOut, String description, boolean isTransient, - String statusLabel) { + public void setWifiIndicators(WifiIndicators indicators) { if (DEBUG) { - Log.d(TAG, "setWifiIndicators: " - + "enabled = " + enabled + "," - + "statusIcon = " + (statusIcon == null ? "" : statusIcon.toString()) + "," - + "qsIcon = " + (qsIcon == null ? "" : qsIcon.toString()) + "," - + "activityIn = " + activityIn + "," - + "activityOut = " + activityOut + "," - + "description = " + description + "," - + "isTransient = " + isTransient + "," - + "statusLabel = " + statusLabel); + Log.d(TAG, "setWifiIndicators: " + indicators); } - mWifiInfo.mEnabled = enabled; - if (qsIcon == null) { + mWifiInfo.mEnabled = indicators.enabled; + if (indicators.qsIcon == null) { return; } - mWifiInfo.mConnected = qsIcon.visible; - mWifiInfo.mWifiSignalIconId = qsIcon.icon; - mWifiInfo.mWifiSignalContentDescription = qsIcon.contentDescription; - mWifiInfo.mSsid = description; - mWifiInfo.mActivityIn = activityIn; - mWifiInfo.mActivityOut = activityOut; - mWifiInfo.mIsTransient = isTransient; - mWifiInfo.mStatusLabel = statusLabel; + mWifiInfo.mConnected = indicators.qsIcon.visible; + mWifiInfo.mWifiSignalIconId = indicators.qsIcon.icon; + mWifiInfo.mWifiSignalContentDescription = indicators.qsIcon.contentDescription; + mWifiInfo.mEnabled = indicators.enabled; + mWifiInfo.mSsid = indicators.description; + mWifiInfo.mActivityIn = indicators.activityIn; + mWifiInfo.mActivityOut = indicators.activityOut; + mWifiInfo.mIsTransient = indicators.isTransient; + mWifiInfo.mStatusLabel = indicators.statusLabel; refreshState(mWifiInfo); } @Override - public void setMobileDataIndicators(IconState statusIcon, IconState qsIcon, int statusType, - int qsType, boolean activityIn, boolean activityOut, - CharSequence typeContentDescription, - CharSequence typeContentDescriptionHtml, CharSequence description, - boolean isWide, int subId, boolean roaming, boolean showTriangle) { + public void setMobileDataIndicators(MobileDataIndicators indicators) { if (DEBUG) { - Log.d(TAG, "setMobileDataIndicators: " - + "statusIcon = " + (statusIcon == null ? "" : statusIcon.toString()) + "," - + "qsIcon = " + (qsIcon == null ? "" : qsIcon.toString()) + "," - + "statusType = " + statusType + "," - + "qsType = " + qsType + "," - + "activityIn = " + activityIn + "," - + "activityOut = " + activityOut + "," - + "typeContentDescription = " + typeContentDescription + "," - + "typeContentDescriptionHtml = " + typeContentDescriptionHtml + "," - + "description = " + description + "," - + "isWide = " + isWide + "," - + "subId = " + subId + "," - + "roaming = " + roaming + "," - + "showTriangle = " + showTriangle); + Log.d(TAG, "setMobileDataIndicators: " + indicators); } - if (qsIcon == null) { + if (indicators.qsIcon == null) { // Not data sim, don't display. return; } - mCellularInfo.mDataSubscriptionName = - description == null ? mController.getMobileDataNetworkName() : description; - mCellularInfo.mDataContentDescription = - (description != null) ? typeContentDescriptionHtml : null; - mCellularInfo.mMobileSignalIconId = qsIcon.icon; - mCellularInfo.mQsTypeIcon = qsType; - mCellularInfo.mActivityIn = activityIn; - mCellularInfo.mActivityOut = activityOut; - mCellularInfo.mRoaming = roaming; + mCellularInfo.mDataSubscriptionName = indicators.description == null + ? mController.getMobileDataNetworkName() : indicators.description; + mCellularInfo.mDataContentDescription = indicators.description != null + ? indicators.typeContentDescriptionHtml : null; + mCellularInfo.mMobileSignalIconId = indicators.qsIcon.icon; + mCellularInfo.mQsTypeIcon = indicators.qsType; + mCellularInfo.mActivityIn = indicators.activityIn; + mCellularInfo.mActivityOut = indicators.activityOut; + mCellularInfo.mRoaming = indicators.roaming; mCellularInfo.mMultipleSubs = mController.getNumberSubscriptions() > 1; refreshState(mCellularInfo); } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java index a6fd01108fad..341e67c9393f 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java @@ -51,8 +51,8 @@ import com.android.systemui.qs.tileimpl.QSIconViewImpl; import com.android.systemui.qs.tileimpl.QSTileImpl; import com.android.systemui.statusbar.policy.NetworkController; import com.android.systemui.statusbar.policy.NetworkController.AccessPointController; -import com.android.systemui.statusbar.policy.NetworkController.IconState; import com.android.systemui.statusbar.policy.NetworkController.SignalCallback; +import com.android.systemui.statusbar.policy.NetworkController.WifiIndicators; import com.android.systemui.statusbar.policy.WifiIcons; import com.android.wifitrackerlib.WifiEntry; @@ -303,22 +303,20 @@ public class WifiTile extends QSTileImpl<SignalState> { final CallbackInfo mInfo = new CallbackInfo(); @Override - public void setWifiIndicators(boolean enabled, IconState statusIcon, IconState qsIcon, - boolean activityIn, boolean activityOut, String description, boolean isTransient, - String statusLabel) { - if (DEBUG) Log.d(TAG, "onWifiSignalChanged enabled=" + enabled); - if (qsIcon == null) { + public void setWifiIndicators(WifiIndicators indicators) { + if (DEBUG) Log.d(TAG, "onWifiSignalChanged enabled=" + indicators.enabled); + if (indicators.qsIcon == null) { return; } - mInfo.enabled = enabled; - mInfo.connected = qsIcon.visible; - mInfo.wifiSignalIconId = qsIcon.icon; - mInfo.ssid = description; - mInfo.activityIn = activityIn; - mInfo.activityOut = activityOut; - mInfo.wifiSignalContentDescription = qsIcon.contentDescription; - mInfo.isTransient = isTransient; - mInfo.statusLabel = statusLabel; + mInfo.enabled = indicators.enabled; + mInfo.connected = indicators.qsIcon.visible; + mInfo.wifiSignalIconId = indicators.qsIcon.icon; + mInfo.ssid = indicators.description; + mInfo.activityIn = indicators.activityIn; + mInfo.activityOut = indicators.activityOut; + mInfo.wifiSignalContentDescription = indicators.qsIcon.contentDescription; + mInfo.isTransient = indicators.isTransient; + mInfo.statusLabel = indicators.statusLabel; if (isShowingDetail()) { mDetailAdapter.updateItems(); } diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/OWNERS b/packages/SystemUI/src/com/android/systemui/screenshot/OWNERS deleted file mode 100644 index 9b3e386bc0d8..000000000000 --- a/packages/SystemUI/src/com/android/systemui/screenshot/OWNERS +++ /dev/null @@ -1,12 +0,0 @@ -# Scroll Capture (Long Screenshots) -# Bug component: 801322 -# -# Referenced by: -# -# core/java/src/android/view/OWNERS -# core/java/src/com/android/internal/view/OWNERS -# core/tests/coretests/src/android/view/OWNERS -# core/tests/coretests/src/com/android/internal/view/OWNERS - -mrcasey@google.com -mrenouf@google.com diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScrollCaptureClient.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScrollCaptureClient.java index 70be601c3e09..54b99bbe74cc 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/ScrollCaptureClient.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScrollCaptureClient.java @@ -278,6 +278,7 @@ public class ScrollCaptureClient { mStarted = true; } catch (RemoteException e) { Log.w(TAG, "Failed to start", e); + mReader.close(); } } @@ -327,6 +328,7 @@ public class ScrollCaptureClient { } if (mStarted) { mShutdownListener = listener; + mReader.close(); try { // listener called from onConnectionClosed callback mConnection.endCapture(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/FeatureFlags.java b/packages/SystemUI/src/com/android/systemui/statusbar/FeatureFlags.java index cf77e290ebe3..1d59257c9c4f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/FeatureFlags.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/FeatureFlags.java @@ -86,4 +86,8 @@ public class FeatureFlags { public boolean isNavigationBarOverlayEnabled() { return mFlagReader.isEnabled(R.bool.flag_navigation_bar_overlay); } + + public boolean isPMLiteEnabled() { + return mFlagReader.isEnabled(R.bool.flag_pm_lite); + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java index 7e2d27ac728a..a4e97a1dc6d5 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java @@ -16,6 +16,7 @@ package com.android.systemui.statusbar; +import static android.app.admin.DevicePolicyManager.DEVICE_OWNER_TYPE_FINANCED; import static android.view.View.GONE; import static android.view.View.VISIBLE; @@ -41,6 +42,7 @@ import android.content.Intent; import android.content.IntentFilter; import android.content.pm.UserInfo; import android.content.res.ColorStateList; +import android.content.res.Resources; import android.graphics.Color; import android.hardware.biometrics.BiometricSourceType; import android.hardware.face.FaceManager; @@ -277,10 +279,7 @@ public class KeyguardIndicationController implements KeyguardStateController.Cal // avoid calling this method since it has an IPC if (whitelistIpcs(this::isOrganizationOwnedDevice)) { final CharSequence organizationName = getOrganizationOwnedDeviceOrganizationName(); - final CharSequence disclosure = organizationName != null - ? mContext.getResources().getString(R.string.do_disclosure_with_name, - organizationName) - : mContext.getResources().getText(R.string.do_disclosure_generic); + final CharSequence disclosure = getDisclosureText(organizationName); mRotateTextViewController.updateIndication( INDICATION_TYPE_DISCLOSURE, new KeyguardIndication.Builder() @@ -297,6 +296,22 @@ public class KeyguardIndicationController implements KeyguardStateController.Cal } } + private CharSequence getDisclosureText(@Nullable CharSequence organizationName) { + final Resources packageResources = mContext.getResources(); + if (organizationName == null) { + return packageResources.getText(R.string.do_disclosure_generic); + } else if (mDevicePolicyManager.isDeviceManaged() + && mDevicePolicyManager.getDeviceOwnerType( + mDevicePolicyManager.getDeviceOwnerComponentOnAnyUser()) + == DEVICE_OWNER_TYPE_FINANCED) { + return packageResources.getString(R.string.do_financed_disclosure_with_name, + organizationName); + } else { + return packageResources.getString(R.string.do_disclosure_with_name, + organizationName); + } + } + private void updateOwnerInfo() { if (!isKeyguardLayoutEnabled()) { mRotateTextViewController.hideIndication(INDICATION_TYPE_OWNER_INFO); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java index f427ba958b8f..76917612b910 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java @@ -17,15 +17,11 @@ package com.android.systemui.statusbar.notification.row; -import static android.provider.Settings.Global.NOTIFICATION_BUBBLES; -import static android.provider.Settings.Secure.SHOW_NOTIFICATION_SNOOZE; - import android.annotation.NonNull; import android.annotation.Nullable; import android.app.Notification; import android.app.PendingIntent; import android.content.Context; -import android.content.res.Resources; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.os.Build; @@ -1317,7 +1313,7 @@ public class NotificationContentView extends FrameLayout { private boolean isBubblesEnabled() { return Settings.Global.getInt(mContext.getContentResolver(), - NOTIFICATION_BUBBLES, 0) == 1; + Settings.Global.NOTIFICATION_BUBBLES, 0) == 1; } /** @@ -1373,27 +1369,26 @@ public class NotificationContentView extends FrameLayout { } ImageView snoozeButton = layout.findViewById(com.android.internal.R.id.snooze_button); View actionContainer = layout.findViewById(com.android.internal.R.id.actions_container); - LinearLayout actionContainerLayout = - layout.findViewById(com.android.internal.R.id.actions_container_layout); - if (snoozeButton == null || actionContainer == null || actionContainerLayout == null) { + if (snoozeButton == null || actionContainer == null) { return; } final boolean showSnooze = Settings.Secure.getInt(mContext.getContentResolver(), - SHOW_NOTIFICATION_SNOOZE, 0) == 1; - if (!showSnooze) { + Settings.Secure.SHOW_NOTIFICATION_SNOOZE, 0) == 1; + // Notification.Builder can 'disable' the snooze button to prevent it from being shown here + boolean snoozeDisabled = !snoozeButton.isEnabled(); + if (!showSnooze || snoozeDisabled) { snoozeButton.setVisibility(GONE); return; } - Resources res = mContext.getResources(); - Drawable snoozeDrawable = res.getDrawable(R.drawable.ic_snooze); + Drawable snoozeDrawable = mContext.getDrawable(R.drawable.ic_snooze); mContainingNotification.updateNotificationColor(); snoozeDrawable.setTint(mContainingNotification.getNotificationColor()); snoozeButton.setImageDrawable(snoozeDrawable); final NotificationSnooze snoozeGuts = (NotificationSnooze) LayoutInflater.from(mContext) .inflate(R.layout.notification_snooze, null, false); - final String snoozeDescription = res.getString( + final String snoozeDescription = mContext.getString( R.string.notification_menu_snooze_description); final NotificationMenuRowPlugin.MenuItem snoozeMenuItem = new NotificationMenuRow.NotificationMenuItem( diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java index 093f57adb21a..83c347b05012 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java @@ -605,6 +605,7 @@ public class NotificationPanelViewController extends PanelViewController { mKeyguardQsUserSwitchEnabled = mKeyguardUserSwitcherEnabled && mResources.getBoolean( R.bool.config_keyguard_user_switch_opens_qs_details); + keyguardUpdateMonitor.setKeyguardQsUserSwitchEnabled(mKeyguardQsUserSwitchEnabled); mView.setWillNotDraw(!DEBUG); mLayoutInflater = layoutInflater; mFalsingManager = falsingManager; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java index dacd9417b22a..9ee7b09589d8 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java @@ -27,6 +27,8 @@ import com.android.systemui.Dependency; import com.android.systemui.R; import com.android.systemui.statusbar.policy.NetworkController; import com.android.systemui.statusbar.policy.NetworkController.IconState; +import com.android.systemui.statusbar.policy.NetworkController.MobileDataIndicators; +import com.android.systemui.statusbar.policy.NetworkController.WifiIndicators; import com.android.systemui.statusbar.policy.NetworkControllerImpl; import com.android.systemui.statusbar.policy.SecurityController; import com.android.systemui.tuner.TunerService; @@ -143,24 +145,14 @@ public class StatusBarSignalPolicy implements NetworkControllerImpl.SignalCallba } @Override - public void setWifiIndicators(boolean enabled, IconState statusIcon, IconState qsIcon, - boolean activityIn, boolean activityOut, String description, boolean isTransient, - String statusLabel) { + public void setWifiIndicators(WifiIndicators indicators) { if (DEBUG) { - Log.d(TAG, "setWifiIndicators: " - + "enabled = " + enabled + "," - + "statusIcon = " + (statusIcon == null ? "" : statusIcon.toString()) + "," - + "qsIcon = " + (qsIcon == null ? "" : qsIcon.toString()) + "," - + "activityIn = " + activityIn + "," - + "activityOut = " + activityOut + "," - + "description = " + description + "," - + "isTransient = " + isTransient + "," - + "statusLabel = " + statusLabel); - } - boolean visible = statusIcon.visible && !mHideWifi; - boolean in = activityIn && mActivityEnabled && visible; - boolean out = activityOut && mActivityEnabled && visible; - mIsWifiEnabled = enabled; + Log.d(TAG, "setWifiIndicators: " + indicators); + } + boolean visible = indicators.statusIcon.visible && !mHideWifi; + boolean in = indicators.activityIn && mActivityEnabled && visible; + boolean out = indicators.activityOut && mActivityEnabled && visible; + mIsWifiEnabled = indicators.enabled; WifiIconState newState = mWifiIconState.copy(); @@ -174,10 +166,10 @@ public class StatusBarSignalPolicy implements NetworkControllerImpl.SignalCallba newState.resId = R.drawable.ic_qs_no_internet_available; } else { newState.visible = visible; - newState.resId = statusIcon.icon; + newState.resId = indicators.statusIcon.icon; newState.activityIn = in; newState.activityOut = out; - newState.contentDescription = statusIcon.contentDescription; + newState.contentDescription = indicators.statusIcon.contentDescription; MobileIconState first = getFirstMobileState(); newState.signalSpacerVisible = first != null && first.typeId != 0; } @@ -225,44 +217,28 @@ public class StatusBarSignalPolicy implements NetworkControllerImpl.SignalCallba } @Override - public void setMobileDataIndicators(IconState statusIcon, IconState qsIcon, int statusType, - int qsType, boolean activityIn, boolean activityOut, - CharSequence typeContentDescription, - CharSequence typeContentDescriptionHtml, CharSequence description, - boolean isWide, int subId, boolean roaming, boolean showTriangle) { + public void setMobileDataIndicators(MobileDataIndicators indicators) { if (DEBUG) { - Log.d(TAG, "setMobileDataIndicators: " - + "statusIcon = " + (statusIcon == null ? "" : statusIcon.toString()) + "," - + "qsIcon = " + (qsIcon == null ? "" : qsIcon.toString()) + "," - + "statusType = " + statusType + "," - + "qsType = " + qsType + "," - + "activityIn = " + activityIn + "," - + "activityOut = " + activityOut + "," - + "typeContentDescription = " + typeContentDescription + "," - + "typeContentDescriptionHtml = " + typeContentDescriptionHtml + "," - + "description = " + description + "," - + "isWide = " + isWide + "," - + "subId = " + subId + "," - + "roaming = " + roaming + "," - + "showTriangle = " + showTriangle); - } - MobileIconState state = getState(subId); + Log.d(TAG, "setMobileDataIndicators: " + indicators); + } + MobileIconState state = getState(indicators.subId); if (state == null) { return; } // Visibility of the data type indicator changed - boolean typeChanged = statusType != state.typeId && (statusType == 0 || state.typeId == 0); - - state.visible = statusIcon.visible && !mHideMobile; - state.strengthId = statusIcon.icon; - state.typeId = statusType; - state.contentDescription = statusIcon.contentDescription; - state.typeContentDescription = typeContentDescription; - state.showTriangle = showTriangle; - state.roaming = roaming; - state.activityIn = activityIn && mActivityEnabled; - state.activityOut = activityOut && mActivityEnabled; + boolean typeChanged = indicators.statusType != state.typeId + && (indicators.statusType == 0 || state.typeId == 0); + + state.visible = indicators.statusIcon.visible && !mHideMobile; + state.strengthId = indicators.statusIcon.icon; + state.typeId = indicators.statusType; + state.contentDescription = indicators.statusIcon.contentDescription; + state.typeContentDescription = indicators.typeContentDescription; + state.showTriangle = indicators.showTriangle; + state.roaming = indicators.roaming; + state.activityIn = indicators.activityIn && mActivityEnabled; + state.activityOut = indicators.activityOut && mActivityEnabled; if (DEBUG) { Log.d(TAG, "MobileIconStates: " diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CallbackHandler.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CallbackHandler.java index 528c0cbae0dd..b96cb5e36c82 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CallbackHandler.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CallbackHandler.java @@ -23,7 +23,9 @@ import android.telephony.SubscriptionInfo; import com.android.internal.annotations.VisibleForTesting; import com.android.systemui.statusbar.policy.NetworkController.EmergencyListener; import com.android.systemui.statusbar.policy.NetworkController.IconState; +import com.android.systemui.statusbar.policy.NetworkController.MobileDataIndicators; import com.android.systemui.statusbar.policy.NetworkController.SignalCallback; +import com.android.systemui.statusbar.policy.NetworkController.WifiIndicators; import java.io.PrintWriter; import java.text.SimpleDateFormat; @@ -119,63 +121,29 @@ public class CallbackHandler extends Handler implements EmergencyListener, Signa } @Override - public void setWifiIndicators(final boolean enabled, final IconState statusIcon, - final IconState qsIcon, final boolean activityIn, final boolean activityOut, - final String description, boolean isTransient, String secondaryLabel) { + public void setWifiIndicators(final WifiIndicators indicators) { String log = new StringBuilder() .append(SSDF.format(System.currentTimeMillis())).append(",") - .append("setWifiIndicators: ") - .append("enabled=").append(enabled).append(",") - .append("statusIcon=").append(statusIcon).append(",") - .append("qsIcon=").append(qsIcon).append(",") - .append("activityIn=").append(activityIn).append(",") - .append("activityOut=").append(activityOut).append(",") - .append("description=").append(description).append(",") - .append("isTransient=").append(isTransient).append(",") - .append("secondaryLabel=").append(secondaryLabel) + .append(indicators) .toString(); recordLastCallback(log); post(() -> { for (SignalCallback callback : mSignalCallbacks) { - callback.setWifiIndicators(enabled, statusIcon, qsIcon, activityIn, activityOut, - description, isTransient, secondaryLabel); + callback.setWifiIndicators(indicators); } }); - - } @Override - public void setMobileDataIndicators(final IconState statusIcon, final IconState qsIcon, - final int statusType, final int qsType, final boolean activityIn, - final boolean activityOut, final CharSequence typeContentDescription, - CharSequence typeContentDescriptionHtml, final CharSequence description, - final boolean isWide, final int subId, boolean roaming, boolean showTriangle) { + public void setMobileDataIndicators(final MobileDataIndicators indicators) { String log = new StringBuilder() .append(SSDF.format(System.currentTimeMillis())).append(",") - .append("setMobileDataIndicators: ") - .append("statusIcon=").append(statusIcon).append(",") - .append("qsIcon=").append(qsIcon).append(",") - .append("statusType=").append(statusType).append(",") - .append("qsType=").append(qsType).append(",") - .append("activityIn=").append(activityIn).append(",") - .append("activityOut=").append(activityOut).append(",") - .append("typeContentDescription=").append(typeContentDescription).append(",") - .append("typeContentDescriptionHtml=").append(typeContentDescriptionHtml) - .append(",") - .append("description=").append(description).append(",") - .append("isWide=").append(isWide).append(",") - .append("subId=").append(subId).append(",") - .append("roaming=").append(roaming).append(",") - .append("showTriangle=").append(showTriangle) + .append(indicators) .toString(); recordLastCallback(log); post(() -> { for (SignalCallback signalCluster : mSignalCallbacks) { - signalCluster.setMobileDataIndicators(statusIcon, qsIcon, statusType, qsType, - activityIn, activityOut, typeContentDescription, - typeContentDescriptionHtml, description, isWide, subId, roaming, - showTriangle); + signalCluster.setMobileDataIndicators(indicators); } }); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/InflatedSmartReplyViewHolder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/InflatedSmartReplyViewHolder.kt index 4f69cd6a1367..4e5c461b9643 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/InflatedSmartReplyViewHolder.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/InflatedSmartReplyViewHolder.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 The Android Open Source Project + * Copyright (C) 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java index 1ab7652d4280..6c097bdb08d3 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java @@ -59,6 +59,7 @@ import com.android.settingslib.mobile.TelephonyIcons; import com.android.settingslib.net.SignalStrengthUtil; import com.android.systemui.R; import com.android.systemui.statusbar.policy.NetworkController.IconState; +import com.android.systemui.statusbar.policy.NetworkController.MobileDataIndicators; import com.android.systemui.statusbar.policy.NetworkController.SignalCallback; import java.io.PrintWriter; @@ -402,10 +403,12 @@ public class MobileSignalController extends SignalController<MobileState, Mobile showDataIcon |= mCurrentState.roaming; IconState statusIcon = new IconState(showDataIcon && !mCurrentState.airplaneMode, getCurrentIconId(), contentDescription); - callback.setMobileDataIndicators(statusIcon, qsIcon, typeIcon, qsTypeIcon, + MobileDataIndicators mobileDataIndicators = new MobileDataIndicators( + statusIcon, qsIcon, typeIcon, qsTypeIcon, activityIn, activityOut, dataContentDescription, dataContentDescriptionHtml, description, icons.isWide, mSubscriptionInfo.getSubscriptionId(), mCurrentState.roaming, showTriangle); + callback.setMobileDataIndicators(mobileDataIndicators); } else { boolean showDataIcon = mCurrentState.dataConnected || dataDisabled; IconState statusIcon = new IconState( @@ -432,10 +435,12 @@ public class MobileSignalController extends SignalController<MobileState, Mobile showDataIcon &= mCurrentState.isDefault || dataDisabled; int typeIcon = (showDataIcon || mConfig.alwaysShowDataRatIcon) ? icons.dataType : 0; boolean showTriangle = mCurrentState.enabled && !mCurrentState.airplaneMode; - callback.setMobileDataIndicators(statusIcon, qsIcon, typeIcon, qsTypeIcon, + MobileDataIndicators mobileDataIndicators = new MobileDataIndicators( + statusIcon, qsIcon, typeIcon, qsTypeIcon, activityIn, activityOut, dataContentDescription, dataContentDescriptionHtml, description, icons.isWide, mSubscriptionInfo.getSubscriptionId(), mCurrentState.roaming, showTriangle); + callback.setMobileDataIndicators(mobileDataIndicators); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java index 0a9fead9cb64..ef2ca985858d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java @@ -46,34 +46,117 @@ public interface NetworkController extends CallbackController<SignalCallback>, D boolean isRadioOn(); + /** + * Wrapper class for all the WiFi signals used for WiFi indicators. + */ + final class WifiIndicators { + public boolean enabled; + public IconState statusIcon; + public IconState qsIcon; + public boolean activityIn; + public boolean activityOut; + public String description; + public boolean isTransient; + public String statusLabel; + + public WifiIndicators(boolean enabled, IconState statusIcon, IconState qsIcon, + boolean activityIn, boolean activityOut, String description, + boolean isTransient, String statusLabel) { + this.enabled = enabled; + this.statusIcon = statusIcon; + this.qsIcon = qsIcon; + this.activityIn = activityIn; + this.activityOut = activityOut; + this.description = description; + this.isTransient = isTransient; + this.statusLabel = statusLabel; + } + + @Override + public String toString() { + return new StringBuilder("WifiIndicators[") + .append("enabled=").append(enabled) + .append(",statusIcon=").append(statusIcon == null ? "" : statusIcon.toString()) + .append(",qsIcon=").append(qsIcon == null ? "" : qsIcon.toString()) + .append(",activityIn=").append(activityIn) + .append(",activityOut=").append(activityOut) + .append(",description=").append(description) + .append(",isTransient=").append(isTransient) + .append(",statusLabel=").append(statusLabel) + .append(']').toString(); + } + } + + /** + * Wrapper class for all the mobile signals used for mobile data indicators. + */ + final class MobileDataIndicators { + public IconState statusIcon; + public IconState qsIcon; + public int statusType; + public int qsType; + public boolean activityIn; + public boolean activityOut; + public CharSequence typeContentDescription; + public CharSequence typeContentDescriptionHtml; + public CharSequence description; + public boolean isWide; + public int subId; + public boolean roaming; + public boolean showTriangle; + + public MobileDataIndicators(IconState statusIcon, IconState qsIcon, int statusType, + int qsType, boolean activityIn, boolean activityOut, + CharSequence typeContentDescription, CharSequence typeContentDescriptionHtml, + CharSequence description, boolean isWide, int subId, boolean roaming, + boolean showTriangle) { + this.statusIcon = statusIcon; + this.qsIcon = qsIcon; + this.statusType = statusType; + this.qsType = qsType; + this.activityIn = activityIn; + this.activityOut = activityOut; + this.typeContentDescription = typeContentDescription; + this.typeContentDescriptionHtml = typeContentDescriptionHtml; + this.description = description; + this.isWide = isWide; + this.subId = subId; + this.roaming = roaming; + this.showTriangle = showTriangle; + } + + @Override + public String toString() { + return new StringBuilder("MobileDataIndicators[") + .append("statusIcon=").append(statusIcon == null ? "" : statusIcon.toString()) + .append(",qsIcon=").append(qsIcon == null ? "" : qsIcon.toString()) + .append(",statusType=").append(statusType) + .append(",qsType=").append(qsType) + .append(",activityIn=").append(activityIn) + .append(",activityOut=").append(activityOut) + .append(",typeContentDescription=").append(typeContentDescription) + .append(",typeContentDescriptionHtml=").append(typeContentDescriptionHtml) + .append(",description=").append(description) + .append(",isWide=").append(isWide) + .append(",subId=").append(subId) + .append(",roaming=").append(roaming) + .append(",showTriangle=").append(showTriangle) + .append(']').toString(); + } + } + public interface SignalCallback { - default void setWifiIndicators(boolean enabled, IconState statusIcon, IconState qsIcon, - boolean activityIn, boolean activityOut, String description, boolean isTransient, - String statusLabel) {} + /** + * Callback for listeners to be able to update the state of any UI tracking connectivity of + * WiFi networks. + */ + default void setWifiIndicators(WifiIndicators wifiIndicators) {} /** * Callback for listeners to be able to update the state of any UI tracking connectivity - * @param statusIcon the icon that should be shown in the status bar - * @param qsIcon the icon to show in Quick Settings - * @param statusType the resId of the data type icon (e.g. LTE) to show in the status bar - * @param qsType similar to above, the resId of the data type icon to show in Quick Settings - * @param activityIn indicates whether there is inbound activity - * @param activityOut indicates outbound activity - * @param typeContentDescription the contentDescription of the data type - * @param typeContentDescriptionHtml the (possibly HTML-styled) contentDescription of the - * data type. Suitable for display - * @param description description of the network (usually just the network name) - * @param isWide //TODO: unused? - * @param subId subscription ID for which to update the UI - * @param roaming indicates roaming - * @param showTriangle whether to show the mobile triangle the in status bar + * of Mobile networks. */ - default void setMobileDataIndicators(IconState statusIcon, IconState qsIcon, int statusType, - int qsType, boolean activityIn, boolean activityOut, - CharSequence typeContentDescription, - CharSequence typeContentDescriptionHtml, CharSequence description, - boolean isWide, int subId, boolean roaming, boolean showTriangle) { - } + default void setMobileDataIndicators(MobileDataIndicators mobileDataIndicators) {} default void setSubs(List<SubscriptionInfo> subs) {} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java index 9f921429f7b8..8eb1e6487046 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java @@ -165,7 +165,7 @@ public class NetworkControllerImpl extends BroadcastReceiver private int mCurrentUserId; private OnSubscriptionsChangedListener mSubscriptionListener; - + private NetworkCapabilities mLastDefaultNetworkCapabilities; // Handler that all broadcasts are received on. private final Handler mReceiverHandler; // Handler that all callbacks are made on. @@ -315,6 +315,7 @@ public class NetworkControllerImpl extends BroadcastReceiver public void onLost(Network network) { mLastNetwork = null; mLastNetworkCapabilities = null; + mLastDefaultNetworkCapabilities = null; String callback = new StringBuilder() .append(SSDF.format(System.currentTimeMillis())).append(",") .append("onLost: ") @@ -341,6 +342,7 @@ public class NetworkControllerImpl extends BroadcastReceiver } mLastNetwork = network; mLastNetworkCapabilities = networkCapabilities; + mLastDefaultNetworkCapabilities = networkCapabilities; String callback = new StringBuilder() .append(SSDF.format(System.currentTimeMillis())).append(",") .append("onCapabilitiesChanged: ") @@ -959,18 +961,17 @@ public class NetworkControllerImpl extends BroadcastReceiver private void updateConnectivity() { mConnectedTransports.clear(); mValidatedTransports.clear(); - for (NetworkCapabilities nc : - mConnectivityManager.getDefaultNetworkCapabilitiesForUser(mCurrentUserId)) { - for (int transportType : nc.getTransportTypes()) { + if (mLastDefaultNetworkCapabilities != null) { + for (int transportType : mLastDefaultNetworkCapabilities.getTransportTypes()) { if (transportType == NetworkCapabilities.TRANSPORT_CELLULAR - && Utils.tryGetWifiInfoForVcn(nc) != null) { + && Utils.tryGetWifiInfoForVcn(mLastDefaultNetworkCapabilities) != null) { mConnectedTransports.set(NetworkCapabilities.TRANSPORT_WIFI); - if (nc.hasCapability(NET_CAPABILITY_VALIDATED)) { + if (mLastDefaultNetworkCapabilities.hasCapability(NET_CAPABILITY_VALIDATED)) { mValidatedTransports.set(NetworkCapabilities.TRANSPORT_WIFI); } } else { mConnectedTransports.set(transportType); - if (nc.hasCapability(NET_CAPABILITY_VALIDATED)) { + if (mLastDefaultNetworkCapabilities.hasCapability(NET_CAPABILITY_VALIDATED)) { mValidatedTransports.set(transportType); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java index 16998d7be936..8d72c9c8810e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java @@ -38,7 +38,9 @@ import com.android.settingslib.mobile.TelephonyIcons; import com.android.settingslib.wifi.WifiStatusTracker; import com.android.systemui.R; import com.android.systemui.statusbar.policy.NetworkController.IconState; +import com.android.systemui.statusbar.policy.NetworkController.MobileDataIndicators; import com.android.systemui.statusbar.policy.NetworkController.SignalCallback; +import com.android.systemui.statusbar.policy.NetworkController.WifiIndicators; import java.io.PrintWriter; import java.util.Objects; @@ -113,18 +115,24 @@ public class WifiSignalController extends mWifiTracker.isCaptivePortal ? R.drawable.ic_qs_wifi_disconnected : getQsCurrentIconId(), contentDescription); } - callback.setWifiIndicators(mCurrentState.enabled, statusIcon, qsIcon, + WifiIndicators wifiIndicators = new WifiIndicators( + mCurrentState.enabled, statusIcon, qsIcon, ssidPresent && mCurrentState.activityIn, ssidPresent && mCurrentState.activityOut, - wifiDesc, mCurrentState.isTransient, mCurrentState.statusLabel); + wifiDesc, mCurrentState.isTransient, mCurrentState.statusLabel + ); + callback.setWifiIndicators(wifiIndicators); } else { IconState qsIcon = new IconState(mCurrentState.connected, mWifiTracker.isCaptivePortal ? R.drawable.ic_qs_wifi_disconnected : getQsCurrentIconId(), contentDescription); - callback.setWifiIndicators(mCurrentState.enabled, statusIcon, qsIcon, + WifiIndicators wifiIndicators = new WifiIndicators( + mCurrentState.enabled, statusIcon, qsIcon, ssidPresent && mCurrentState.activityIn, ssidPresent && mCurrentState.activityOut, - wifiDesc, mCurrentState.isTransient, mCurrentState.statusLabel); + wifiDesc, mCurrentState.isTransient, mCurrentState.statusLabel + ); + callback.setWifiIndicators(wifiIndicators); } } @@ -149,10 +157,13 @@ public class WifiSignalController extends mCurrentState.connected, getQsCurrentIconIdForCarrierWifi(), contentDescription); CharSequence description = mNetworkController.getNetworkNameForCarrierWiFi(mCurrentState.subId); - callback.setMobileDataIndicators(statusIcon, qsIcon, typeIcon, qsTypeIcon, + MobileDataIndicators mobileDataIndicators = new MobileDataIndicators( + statusIcon, qsIcon, typeIcon, qsTypeIcon, mCurrentState.activityIn, mCurrentState.activityOut, dataContentDescription, dataContentDescriptionHtml, description, icons.isWide, - mCurrentState.subId, /* roaming= */ false, /* showTriangle= */ true); + mCurrentState.subId, /* roaming= */ false, /* showTriangle= */ true + ); + callback.setMobileDataIndicators(mobileDataIndicators); } private int getCurrentIconIdForCarrierWifi() { diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java index df54eabca8e7..25345d5c4b4c 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java +++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java @@ -33,7 +33,11 @@ import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT; import static com.android.systemui.volume.Events.DISMISS_REASON_SETTINGS_CLICKED; +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; +import android.animation.ArgbEvaluator; import android.animation.ObjectAnimator; +import android.animation.ValueAnimator; import android.annotation.SuppressLint; import android.app.ActivityManager; import android.app.Dialog; @@ -51,6 +55,9 @@ import android.graphics.Color; import android.graphics.PixelFormat; import android.graphics.Region; import android.graphics.drawable.ColorDrawable; +import android.graphics.drawable.Drawable; +import android.graphics.drawable.LayerDrawable; +import android.graphics.drawable.RotateDrawable; import android.media.AudioManager; import android.media.AudioSystem; import android.os.Debug; @@ -81,6 +88,8 @@ import android.view.accessibility.AccessibilityNodeInfo; import android.view.animation.DecelerateInterpolator; import android.widget.FrameLayout; import android.widget.ImageButton; +import android.widget.ImageView; +import android.widget.LinearLayout; import android.widget.SeekBar; import android.widget.SeekBar.OnSeekBarChangeListener; import android.widget.TextView; @@ -88,6 +97,7 @@ import android.widget.Toast; import com.android.settingslib.Utils; import com.android.systemui.Dependency; +import com.android.systemui.Interpolators; import com.android.systemui.Prefs; import com.android.systemui.R; import com.android.systemui.media.dialog.MediaOutputDialogFactory; @@ -99,6 +109,8 @@ import com.android.systemui.plugins.VolumeDialogController.StreamState; import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper; import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.statusbar.policy.DeviceProvisionedController; +import com.android.systemui.util.AlphaTintDrawableWrapper; +import com.android.systemui.util.RoundedCornerProgressDrawable; import java.io.PrintWriter; import java.util.ArrayList; @@ -124,8 +136,14 @@ public class VolumeDialogImpl implements VolumeDialog, static final int DIALOG_ODI_CAPTIONS_TOOLTIP_TIMEOUT_MILLIS = 5000; static final int DIALOG_HOVERING_TIMEOUT_MILLIS = 16000; + private static final int DRAWER_ANIMATION_DURATION_SHORT = 175; + private static final int DRAWER_ANIMATION_DURATION = 250; + private final int mDialogShowAnimationDurationMs; private final int mDialogHideAnimationDurationMs; + private final int mRingerDrawerItemSize; + private final boolean mShowVibrate; + private final int mRingerCount; private final boolean mShowLowMediaVolumeIcon; private final boolean mChangeVolumeRowTintWhenInactive; @@ -140,6 +158,30 @@ public class VolumeDialogImpl implements VolumeDialog, private ViewGroup mDialogView; private ViewGroup mDialogRowsView; private ViewGroup mRinger; + + private ViewGroup mSelectedRingerContainer; + private ImageView mSelectedRingerIcon; + + private ViewGroup mRingerDrawerContainer; + private ViewGroup mRingerDrawerMute; + private ViewGroup mRingerDrawerVibrate; + private ViewGroup mRingerDrawerNormal; + private ImageView mRingerDrawerMuteIcon; + private ImageView mRingerDrawerVibrateIcon; + private ImageView mRingerDrawerNormalIcon; + + /** + * View that draws the 'selected' background behind one of the three ringer choices in the + * drawer. + */ + private ViewGroup mRingerDrawerNewSelectionBg; + + private final ValueAnimator mRingerDrawerIconColorAnimator = ValueAnimator.ofFloat(0f, 1f); + private ImageView mRingerDrawerIconAnimatingSelected; + private ImageView mRingerDrawerIconAnimatingDeselected; + + private boolean mIsRingerDrawerOpen = false; + private ImageButton mRingerIcon; private ViewGroup mODICaptionsView; private CaptionsToggleImageButton mODICaptionsIcon; @@ -191,6 +233,12 @@ public class VolumeDialogImpl implements VolumeDialog, mContext.getResources().getInteger(R.integer.config_dialogShowAnimationDurationMs); mDialogHideAnimationDurationMs = mContext.getResources().getInteger(R.integer.config_dialogHideAnimationDurationMs); + mRingerDrawerItemSize = mContext.getResources().getDimensionPixelSize( + R.dimen.volume_ringer_drawer_item_size); + mShowVibrate = mController.hasVibrator(); + + // Normal, mute, and possibly vibrate. + mRingerCount = mShowVibrate ? 3 : 2; } @Override @@ -314,6 +362,20 @@ public class VolumeDialogImpl implements VolumeDialog, mZenIcon = mRinger.findViewById(R.id.dnd_icon); } + mSelectedRingerIcon = mDialog.findViewById(R.id.volume_new_ringer_active_icon); + mSelectedRingerContainer = mDialog.findViewById( + R.id.volume_new_ringer_active_icon_container); + + mRingerDrawerMute = mDialog.findViewById(R.id.volume_drawer_mute); + mRingerDrawerNormal = mDialog.findViewById(R.id.volume_drawer_normal); + mRingerDrawerVibrate = mDialog.findViewById(R.id.volume_drawer_vibrate); + mRingerDrawerMuteIcon = mDialog.findViewById(R.id.volume_drawer_mute_icon); + mRingerDrawerVibrateIcon = mDialog.findViewById(R.id.volume_drawer_vibrate_icon); + mRingerDrawerNormalIcon = mDialog.findViewById(R.id.volume_drawer_normal_icon); + mRingerDrawerNewSelectionBg = mDialog.findViewById(R.id.volume_drawer_selection_background); + + setupRingerDrawer(); + mODICaptionsView = mDialog.findViewById(R.id.odi_captions); if (mODICaptionsView != null) { mODICaptionsIcon = mODICaptionsView.findViewById(R.id.odi_captions_icon); @@ -475,38 +537,273 @@ public class VolumeDialogImpl implements VolumeDialog, row.anim = null; + final LayerDrawable seekbarDrawable = + (LayerDrawable) mContext.getDrawable(R.drawable.volume_row_seekbar); + + final LayerDrawable seekbarBgDrawable = + (LayerDrawable) seekbarDrawable.findDrawableByLayerId(android.R.id.background); + + row.sliderBgSolid = seekbarBgDrawable.findDrawableByLayerId( + R.id.volume_seekbar_background_solid); + + row.sliderBgIcon = (AlphaTintDrawableWrapper) + ((RotateDrawable) seekbarBgDrawable.findDrawableByLayerId( + R.id.volume_seekbar_background_icon)).getDrawable(); + + final LayerDrawable seekbarProgressDrawable = (LayerDrawable) + ((RoundedCornerProgressDrawable) seekbarDrawable.findDrawableByLayerId( + android.R.id.progress)).getDrawable(); + + row.sliderProgressSolid = seekbarProgressDrawable.findDrawableByLayerId( + R.id.volume_seekbar_progress_solid); + + row.sliderProgressIcon = (AlphaTintDrawableWrapper) + ((RotateDrawable) seekbarProgressDrawable.findDrawableByLayerId( + R.id.volume_seekbar_progress_icon)).getDrawable(); + + row.slider.setProgressDrawable(seekbarDrawable); + row.slider.setThumb(null); + row.icon = row.view.findViewById(R.id.volume_row_icon); - row.icon.setImageResource(iconRes); - if (row.stream != AudioSystem.STREAM_ACCESSIBILITY) { - row.icon.setOnClickListener(v -> { - Events.writeEvent(Events.EVENT_ICON_CLICK, row.stream, row.iconState); - mController.setActiveStream(row.stream); - if (row.stream == AudioManager.STREAM_RING) { - final boolean hasVibrator = mController.hasVibrator(); - if (mState.ringerModeInternal == AudioManager.RINGER_MODE_NORMAL) { - if (hasVibrator) { - mController.setRingerMode(AudioManager.RINGER_MODE_VIBRATE, false); + + row.setIcon(iconRes, mContext.getTheme()); + + if (row.icon != null) { + if (row.stream != AudioSystem.STREAM_ACCESSIBILITY) { + row.icon.setOnClickListener(v -> { + Events.writeEvent(Events.EVENT_ICON_CLICK, row.stream, row.iconState); + mController.setActiveStream(row.stream); + if (row.stream == AudioManager.STREAM_RING) { + final boolean hasVibrator = mController.hasVibrator(); + if (mState.ringerModeInternal == AudioManager.RINGER_MODE_NORMAL) { + if (hasVibrator) { + mController.setRingerMode(AudioManager.RINGER_MODE_VIBRATE, false); + } else { + final boolean wasZero = row.ss.level == 0; + mController.setStreamVolume(stream, + wasZero ? row.lastAudibleLevel : 0); + } } else { - final boolean wasZero = row.ss.level == 0; - mController.setStreamVolume(stream, - wasZero ? row.lastAudibleLevel : 0); + mController.setRingerMode( + AudioManager.RINGER_MODE_NORMAL, false); + if (row.ss.level == 0) { + mController.setStreamVolume(stream, 1); + } } } else { - mController.setRingerMode(AudioManager.RINGER_MODE_NORMAL, false); - if (row.ss.level == 0) { - mController.setStreamVolume(stream, 1); - } + final boolean vmute = row.ss.level == row.ss.levelMin; + mController.setStreamVolume(stream, + vmute ? row.lastAudibleLevel : row.ss.levelMin); } - } else { - final boolean vmute = row.ss.level == row.ss.levelMin; - mController.setStreamVolume(stream, - vmute ? row.lastAudibleLevel : row.ss.levelMin); - } - row.userAttempt = 0; // reset the grace period, slider updates immediately - }); + row.userAttempt = 0; // reset the grace period, slider updates immediately + }); + } else { + row.icon.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO); + } + } + } + + private void setRingerMode(int newRingerMode) { + Events.writeEvent(Events.EVENT_RINGER_TOGGLE, newRingerMode); + incrementManualToggleCount(); + updateRingerH(); + provideTouchFeedbackH(newRingerMode); + mController.setRingerMode(newRingerMode, false); + maybeShowToastH(newRingerMode); + } + + private void setupRingerDrawer() { + mRingerDrawerContainer = mDialog.findViewById(R.id.volume_drawer_container); + + if (mRingerDrawerContainer == null) { + return; + } + + if (!mShowVibrate) { + mRingerDrawerVibrate.setVisibility(GONE); + } + + // In portrait, add padding to the bottom to account for the height of the open ringer + // drawer. + if (!isLandscape()) { + mDialogView.setPadding( + mDialogView.getPaddingLeft(), + mDialogView.getPaddingTop(), + mDialogView.getPaddingRight(), + mDialogView.getPaddingBottom() + (mRingerCount - 1) * mRingerDrawerItemSize); + } else { + mDialogView.setPadding( + mDialogView.getPaddingLeft() + (mRingerCount - 1) * mRingerDrawerItemSize, + mDialogView.getPaddingTop(), + mDialogView.getPaddingRight(), + mDialogView.getPaddingBottom()); + } + + ((LinearLayout) mRingerDrawerContainer.findViewById(R.id.volume_drawer_options)) + .setOrientation(isLandscape() ? LinearLayout.HORIZONTAL : LinearLayout.VERTICAL); + + mSelectedRingerContainer.setOnClickListener(view -> { + if (mIsRingerDrawerOpen) { + hideRingerDrawer(); + } else { + showRingerDrawer(); + } + }); + + mRingerDrawerVibrate.setOnClickListener( + new RingerDrawerItemClickListener(RINGER_MODE_VIBRATE)); + mRingerDrawerMute.setOnClickListener( + new RingerDrawerItemClickListener(RINGER_MODE_SILENT)); + mRingerDrawerNormal.setOnClickListener( + new RingerDrawerItemClickListener(RINGER_MODE_NORMAL)); + + final int unselectedColor = Utils.getColorAccentDefaultColor(mContext); + final int selectedColor = Utils.getColorAttrDefaultColor( + mContext, android.R.attr.colorBackgroundFloating); + + // Add an update listener that animates the deselected icon to the unselected color, and the + // selected icon to the selected color. + mRingerDrawerIconColorAnimator.addUpdateListener( + anim -> { + final float currentValue = (float) anim.getAnimatedValue(); + final int curUnselectedColor = (int) ArgbEvaluator.getInstance().evaluate( + currentValue, selectedColor, unselectedColor); + final int curSelectedColor = (int) ArgbEvaluator.getInstance().evaluate( + currentValue, unselectedColor, selectedColor); + + mRingerDrawerIconAnimatingDeselected.setColorFilter(curUnselectedColor); + mRingerDrawerIconAnimatingSelected.setColorFilter(curSelectedColor); + }); + mRingerDrawerIconColorAnimator.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + mRingerDrawerIconAnimatingDeselected.clearColorFilter(); + mRingerDrawerIconAnimatingSelected.clearColorFilter(); + } + }); + mRingerDrawerIconColorAnimator.setDuration(DRAWER_ANIMATION_DURATION_SHORT); + } + + private ImageView getDrawerIconViewForMode(int mode) { + if (mode == RINGER_MODE_VIBRATE) { + return mRingerDrawerVibrateIcon; + } else if (mode == RINGER_MODE_SILENT) { + return mRingerDrawerMuteIcon; + } else { + return mRingerDrawerNormalIcon; + } + } + + /** + * Translation to apply form the origin (either top or left) to overlap the selection background + * with the given mode in the drawer. + */ + private float getTranslationInDrawerForRingerMode(int mode) { + return mode == RINGER_MODE_VIBRATE + ? -mRingerDrawerItemSize * 2 + : mode == RINGER_MODE_SILENT + ? -mRingerDrawerItemSize + : 0; + } + + /** Animates in the ringer drawer. */ + private void showRingerDrawer() { + // Show all ringer icons except the currently selected one, since we're going to animate the + // ringer button to that position. + mRingerDrawerVibrateIcon.setVisibility( + mState.ringerModeInternal == RINGER_MODE_VIBRATE ? INVISIBLE : VISIBLE); + mRingerDrawerMuteIcon.setVisibility( + mState.ringerModeInternal == RINGER_MODE_SILENT ? INVISIBLE : VISIBLE); + mRingerDrawerNormalIcon.setVisibility( + mState.ringerModeInternal == RINGER_MODE_NORMAL ? INVISIBLE : VISIBLE); + + // Hide the selection background - we use this to show a selection when one is + // tapped, so it should be invisible until that happens. However, position it below + // the currently selected ringer so that it's ready to animate. + mRingerDrawerNewSelectionBg.setAlpha(0f); + + if (!isLandscape()) { + mRingerDrawerNewSelectionBg.setTranslationY( + getTranslationInDrawerForRingerMode(mState.ringerModeInternal)); + } else { + mRingerDrawerNewSelectionBg.setTranslationX( + getTranslationInDrawerForRingerMode(mState.ringerModeInternal)); + } + + // Move the drawer so that the top/rightmost ringer choice overlaps with the selected ringer + // icon. + if (!isLandscape()) { + mRingerDrawerContainer.setTranslationY(mRingerDrawerItemSize * (mRingerCount - 1)); + } else { + mRingerDrawerContainer.setTranslationX(mRingerDrawerItemSize * (mRingerCount - 1)); + } + mRingerDrawerContainer.setAlpha(0f); + mRingerDrawerContainer.setVisibility(VISIBLE); + + // Animate the drawer up and visible. + mRingerDrawerContainer.animate() + .setInterpolator(Interpolators.FAST_OUT_SLOW_IN) + // Vibrate is way farther up, so give the selected ringer icon a head start if + // vibrate is selected. + .setDuration(mState.ringerModeInternal == RINGER_MODE_VIBRATE + ? DRAWER_ANIMATION_DURATION_SHORT + : DRAWER_ANIMATION_DURATION) + .setStartDelay(mState.ringerModeInternal == RINGER_MODE_VIBRATE + ? DRAWER_ANIMATION_DURATION - DRAWER_ANIMATION_DURATION_SHORT + : 0) + .alpha(1f) + .translationX(0f) + .translationY(0f) + .start(); + + // Animate the selected ringer view up to that ringer's position in the drawer. + mSelectedRingerContainer.animate() + .setInterpolator(Interpolators.FAST_OUT_SLOW_IN) + .setDuration(DRAWER_ANIMATION_DURATION) + .withEndAction(() -> + getDrawerIconViewForMode(mState.ringerModeInternal).setVisibility(VISIBLE)); + + if (!isLandscape()) { + mSelectedRingerContainer.animate() + .translationY(getTranslationInDrawerForRingerMode(mState.ringerModeInternal)) + .start(); } else { - row.icon.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO); + mSelectedRingerContainer.animate() + .translationX(getTranslationInDrawerForRingerMode(mState.ringerModeInternal)) + .start(); } + + mIsRingerDrawerOpen = true; + } + + /** Animates away the ringer drawer. */ + private void hideRingerDrawer() { + // Hide the drawer icon for the selected ringer - it's visible in the ringer button and we + // don't want to be able to see it while it animates away. + getDrawerIconViewForMode(mState.ringerModeInternal).setVisibility(INVISIBLE); + + mRingerDrawerContainer.animate() + .alpha(0f) + .setDuration(DRAWER_ANIMATION_DURATION) + .setStartDelay(0) + .withEndAction(() -> mRingerDrawerContainer.setVisibility(INVISIBLE)); + + if (!isLandscape()) { + mRingerDrawerContainer.animate() + .translationY(mRingerDrawerItemSize * 2) + .start(); + } else { + mRingerDrawerContainer.animate() + .translationX(mRingerDrawerItemSize * 2) + .start(); + } + + mSelectedRingerContainer.animate() + .translationX(0f) + .translationY(0f) + .start(); + + mIsRingerDrawerOpen = false; } public void initSettingsH() { @@ -555,12 +852,8 @@ public class VolumeDialogImpl implements VolumeDialog, mController.setStreamVolume(AudioManager.STREAM_RING, 1); } } - Events.writeEvent(Events.EVENT_RINGER_TOGGLE, newRingerMode); - incrementManualToggleCount(); - updateRingerH(); - provideTouchFeedbackH(newRingerMode); - mController.setRingerMode(newRingerMode, false); - maybeShowToastH(newRingerMode); + + setRingerMode(newRingerMode); }); } updateRingerH(); @@ -809,6 +1102,8 @@ public class VolumeDialogImpl implements VolumeDialog, mDialog.dismiss(); tryToRemoveCaptionsTooltip(); mIsAnimatingDismiss = false; + + hideRingerDrawer(); }, 50)); if (!isLandscape()) animator.translationX(mDialogView.getWidth() / 2.0f); animator.start(); @@ -889,12 +1184,14 @@ public class VolumeDialogImpl implements VolumeDialog, switch (mState.ringerModeInternal) { case AudioManager.RINGER_MODE_VIBRATE: mRingerIcon.setImageResource(R.drawable.ic_volume_ringer_vibrate); + mSelectedRingerIcon.setImageResource(R.drawable.ic_volume_ringer_vibrate); addAccessibilityDescription(mRingerIcon, RINGER_MODE_VIBRATE, mContext.getString(R.string.volume_ringer_hint_mute)); mRingerIcon.setTag(Events.ICON_STATE_VIBRATE); break; case AudioManager.RINGER_MODE_SILENT: mRingerIcon.setImageResource(R.drawable.ic_volume_ringer_mute); + mSelectedRingerIcon.setImageResource(R.drawable.ic_volume_ringer_mute); mRingerIcon.setTag(Events.ICON_STATE_MUTE); addAccessibilityDescription(mRingerIcon, RINGER_MODE_SILENT, mContext.getString(R.string.volume_ringer_hint_unmute)); @@ -904,11 +1201,13 @@ public class VolumeDialogImpl implements VolumeDialog, boolean muted = (mAutomute && ss.level == 0) || ss.muted; if (!isZenMuted && muted) { mRingerIcon.setImageResource(R.drawable.ic_volume_ringer_mute); + mSelectedRingerIcon.setImageResource(R.drawable.ic_volume_ringer_mute); addAccessibilityDescription(mRingerIcon, RINGER_MODE_NORMAL, mContext.getString(R.string.volume_ringer_hint_unmute)); mRingerIcon.setTag(Events.ICON_STATE_MUTE); } else { mRingerIcon.setImageResource(R.drawable.ic_volume_ringer); + mSelectedRingerIcon.setImageResource(R.drawable.ic_volume_ringer); if (mController.hasVibrator()) { addAccessibilityDescription(mRingerIcon, RINGER_MODE_NORMAL, mContext.getString(R.string.volume_ringer_hint_vibrate)); @@ -1075,8 +1374,6 @@ public class VolumeDialogImpl implements VolumeDialog, // update icon final boolean iconEnabled = (mAutomute || ss.muteSupported) && !zenMuted; - row.icon.setEnabled(iconEnabled); - row.icon.setAlpha(iconEnabled ? 1 : 0.5f); final int iconRes; if (isRingVibrate) { iconRes = R.drawable.ic_volume_ringer_vibrate; @@ -1092,7 +1389,7 @@ public class VolumeDialogImpl implements VolumeDialog, ? R.drawable.ic_volume_media_low : row.iconRes; } - row.icon.setImageResource(iconRes); + row.setIcon(iconRes, mContext.getTheme()); row.iconState = iconRes == R.drawable.ic_volume_ringer_vibrate ? Events.ICON_STATE_VIBRATE : (iconRes == R.drawable.ic_volume_media_bt_mute || iconRes == row.iconMuteRes) @@ -1101,18 +1398,35 @@ public class VolumeDialogImpl implements VolumeDialog, || iconRes == R.drawable.ic_volume_media_low) ? Events.ICON_STATE_UNMUTE : Events.ICON_STATE_UNKNOWN; - if (iconEnabled) { - if (isRingStream) { - if (isRingVibrate) { - row.icon.setContentDescription(mContext.getString( - R.string.volume_stream_content_description_unmute, - getStreamLabelH(ss))); + + if (row.icon != null) { + if (iconEnabled) { + if (isRingStream) { + if (isRingVibrate) { + row.icon.setContentDescription(mContext.getString( + R.string.volume_stream_content_description_unmute, + getStreamLabelH(ss))); + } else { + if (mController.hasVibrator()) { + row.icon.setContentDescription(mContext.getString( + mShowA11yStream + ? R.string.volume_stream_content_description_vibrate_a11y + : R.string.volume_stream_content_description_vibrate, + getStreamLabelH(ss))); + } else { + row.icon.setContentDescription(mContext.getString( + mShowA11yStream + ? R.string.volume_stream_content_description_mute_a11y + : R.string.volume_stream_content_description_mute, + getStreamLabelH(ss))); + } + } + } else if (isA11yStream) { + row.icon.setContentDescription(getStreamLabelH(ss)); } else { - if (mController.hasVibrator()) { + if (ss.muted || mAutomute && ss.level == 0) { row.icon.setContentDescription(mContext.getString( - mShowA11yStream - ? R.string.volume_stream_content_description_vibrate_a11y - : R.string.volume_stream_content_description_vibrate, + R.string.volume_stream_content_description_unmute, getStreamLabelH(ss))); } else { row.icon.setContentDescription(mContext.getString( @@ -1122,23 +1436,9 @@ public class VolumeDialogImpl implements VolumeDialog, getStreamLabelH(ss))); } } - } else if (isA11yStream) { - row.icon.setContentDescription(getStreamLabelH(ss)); } else { - if (ss.muted || mAutomute && ss.level == 0) { - row.icon.setContentDescription(mContext.getString( - R.string.volume_stream_content_description_unmute, - getStreamLabelH(ss))); - } else { - row.icon.setContentDescription(mContext.getString( - mShowA11yStream - ? R.string.volume_stream_content_description_mute_a11y - : R.string.volume_stream_content_description_mute, - getStreamLabelH(ss))); - } + row.icon.setContentDescription(getStreamLabelH(ss)); } - } else { - row.icon.setContentDescription(getStreamLabelH(ss)); } // ensure tracking is disabled if zenMuted @@ -1167,22 +1467,29 @@ public class VolumeDialogImpl implements VolumeDialog, if (!useActiveColoring && !mChangeVolumeRowTintWhenInactive) { return; } - final ColorStateList tint = useActiveColoring + final ColorStateList colorTint = useActiveColoring ? Utils.getColorAccent(mContext) : Utils.getColorAttr(mContext, android.R.attr.colorForeground); final int alpha = useActiveColoring - ? Color.alpha(tint.getDefaultColor()) + ? Color.alpha(colorTint.getDefaultColor()) : getAlphaAttr(android.R.attr.secondaryContentAlpha); - if (tint == row.cachedTint) return; - row.slider.setProgressTintList(tint); - row.slider.setThumbTintList(tint); - row.slider.setProgressBackgroundTintList(tint); - row.slider.setAlpha(((float) alpha) / 255); - row.icon.setImageTintList(tint); - row.icon.setImageAlpha(alpha); - row.cachedTint = tint; + + final ColorStateList bgTint = Utils.getColorAttr( + mContext, android.R.attr.colorBackgroundFloating); + + row.sliderProgressSolid.setTintList(colorTint); + row.sliderBgIcon.setTintList(colorTint); + + row.sliderBgSolid.setTintList(bgTint); + row.sliderProgressIcon.setTintList(bgTint); + + if (row.icon != null) { + row.icon.setImageTintList(colorTint); + row.icon.setImageAlpha(alpha); + } + if (row.number != null) { - row.number.setTextColor(tint); + row.number.setTextColor(colorTint); row.number.setAlpha(alpha); } } @@ -1538,6 +1845,10 @@ public class VolumeDialogImpl implements VolumeDialog, private View view; private TextView header; private ImageButton icon; + private Drawable sliderBgSolid; + private AlphaTintDrawableWrapper sliderBgIcon; + private Drawable sliderProgressSolid; + private AlphaTintDrawableWrapper sliderProgressIcon; private SeekBar slider; private TextView number; private int stream; @@ -1555,5 +1866,69 @@ public class VolumeDialogImpl implements VolumeDialog, private int animTargetProgress; private int lastAudibleLevel = 1; private FrameLayout dndIcon; + + void setIcon(int iconRes, Resources.Theme theme) { + if (icon != null) { + icon.setImageResource(iconRes); + } + + sliderProgressIcon.setDrawable(view.getResources().getDrawable(iconRes, theme)); + sliderBgIcon.setDrawable(view.getResources().getDrawable(iconRes, theme)); + } + } + + /** + * Click listener added to each ringer option in the drawer. This will initiate the animation to + * select and then close the ringer drawer, and actually change the ringer mode. + */ + private class RingerDrawerItemClickListener implements View.OnClickListener { + private final int mClickedRingerMode; + + RingerDrawerItemClickListener(int clickedRingerMode) { + mClickedRingerMode = clickedRingerMode; + } + + @Override + public void onClick(View view) { + setRingerMode(mClickedRingerMode); + + mRingerDrawerIconAnimatingSelected = getDrawerIconViewForMode(mClickedRingerMode); + mRingerDrawerIconAnimatingDeselected = getDrawerIconViewForMode( + mState.ringerModeInternal); + + // Begin switching the selected icon and deselected icon colors since the background is + // going to animate behind the new selection. + mRingerDrawerIconColorAnimator.start(); + + mSelectedRingerContainer.setVisibility(View.INVISIBLE); + mRingerDrawerNewSelectionBg.setAlpha(1f); + mRingerDrawerNewSelectionBg.animate() + .setInterpolator(Interpolators.ACCELERATE_DECELERATE) + .setDuration(DRAWER_ANIMATION_DURATION_SHORT) + .withEndAction(() -> { + mRingerDrawerNewSelectionBg.setAlpha(0f); + + if (!isLandscape()) { + mSelectedRingerContainer.setTranslationY( + getTranslationInDrawerForRingerMode(mClickedRingerMode)); + } else { + mSelectedRingerContainer.setTranslationX( + getTranslationInDrawerForRingerMode(mClickedRingerMode)); + } + + mSelectedRingerContainer.setVisibility(VISIBLE); + hideRingerDrawer(); + }); + + if (!isLandscape()) { + mRingerDrawerNewSelectionBg.animate() + .translationY(getTranslationInDrawerForRingerMode(mClickedRingerMode)) + .start(); + } else { + mRingerDrawerNewSelectionBg.animate() + .translationX(getTranslationInDrawerForRingerMode(mClickedRingerMode)) + .start(); + } + } } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java index 3e873d1985fb..700f101e44b8 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java @@ -150,7 +150,10 @@ public class UdfpsControllerTest extends SysuiTestCase { } @Test - public void dozeTimeTick() { + public void dozeTimeTick() throws RemoteException { + mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID, + IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD); + mFgExecutor.runAllReady(); mUdfpsController.dozeTimeTick(); verify(mUdfpsView).dozeTimeTick(); } @@ -240,7 +243,8 @@ public class UdfpsControllerTest extends SysuiTestCase { @Test public void registersViewForCallbacks() throws RemoteException { - verify(mStatusBarStateController).addCallback(mUdfpsView); - verify(mStatusBar).addExpansionChangedListener(mUdfpsView); + verify(mStatusBarStateController).addCallback(mUdfpsController.mStatusBarStateListener); + verify(mStatusBar).addExpansionChangedListener( + mUdfpsController.mStatusBarExpansionListener); } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/buttons/NearestTouchFrameTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/buttons/NearestTouchFrameTest.java index 5c179d4e46b6..c8f223bdd72f 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/buttons/NearestTouchFrameTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/buttons/NearestTouchFrameTest.java @@ -69,7 +69,7 @@ public class NearestTouchFrameTest extends SysuiTestCase { mNearestTouchFrame.addView(left); mNearestTouchFrame.addView(right); - mNearestTouchFrame.onMeasure(0, 0); + mNearestTouchFrame.layout(0, 0, 30, 30); MotionEvent ev = MotionEvent.obtain(0, 0, 0, 12 /* x */, 5 /* y */, 0); @@ -86,7 +86,7 @@ public class NearestTouchFrameTest extends SysuiTestCase { mNearestTouchFrame.addView(left); mNearestTouchFrame.addView(right); - mNearestTouchFrame.onMeasure(0, 0); + mNearestTouchFrame.layout(0, 0, 30, 30); MotionEvent ev = MotionEvent.obtain(0, 0, 0, 12 /* x */, 5 /* y */, 0); @@ -105,7 +105,7 @@ public class NearestTouchFrameTest extends SysuiTestCase { mNearestTouchFrame.addView(left); mNearestTouchFrame.addView(right); - mNearestTouchFrame.onMeasure(0, 0); + mNearestTouchFrame.layout(0, 0, 30, 30); // Would go to left view if attached, but goes to right instead as left should be detached. MotionEvent ev = MotionEvent.obtain(0, 0, 0, @@ -122,7 +122,7 @@ public class NearestTouchFrameTest extends SysuiTestCase { mNearestTouchFrame.addView(left); mNearestTouchFrame.addView(right); - mNearestTouchFrame.onMeasure(0, 0); + mNearestTouchFrame.layout(0, 0, 30, 30); MotionEvent ev = MotionEvent.obtain(0, 0, 0, 12 /* x */, 5 /* y */, 0); @@ -138,7 +138,7 @@ public class NearestTouchFrameTest extends SysuiTestCase { mNearestTouchFrame.addView(left); mNearestTouchFrame.addView(right); - mNearestTouchFrame.onMeasure(0, 0); + mNearestTouchFrame.layout(0, 0, 30, 30); MotionEvent ev = MotionEvent.obtain(0, 0, 0, 18 /* x */, 5 /* y */, 0); @@ -154,7 +154,7 @@ public class NearestTouchFrameTest extends SysuiTestCase { mNearestTouchFrame.setIsVertical(true); mNearestTouchFrame.addView(top); mNearestTouchFrame.addView(bottom); - mNearestTouchFrame.onMeasure(0, 0); + mNearestTouchFrame.layout(0, 0, 30, 30); MotionEvent ev = MotionEvent.obtain(0, 0, 0, 5 /* x */, 12 /* y */, 0); @@ -170,7 +170,7 @@ public class NearestTouchFrameTest extends SysuiTestCase { mNearestTouchFrame.setIsVertical(true); mNearestTouchFrame.addView(top); mNearestTouchFrame.addView(bottom); - mNearestTouchFrame.onMeasure(0, 0); + mNearestTouchFrame.layout(0, 0, 30, 30); MotionEvent ev = MotionEvent.obtain(0, 0, 0, 5 /* x */, 18 /* y */, 0); @@ -184,7 +184,7 @@ public class NearestTouchFrameTest extends SysuiTestCase { View view = mockViewAt(0, 20, 10, 10); when(view.isAttachedToWindow()).thenReturn(false); mNearestTouchFrame.addView(view); - mNearestTouchFrame.onMeasure(0, 0); + mNearestTouchFrame.layout(0, 0, 30, 30); MotionEvent ev = MotionEvent.obtain(0, 0, 0, 5 /* x */, 18 /* y */, 0); mNearestTouchFrame.onTouchEvent(ev); @@ -201,7 +201,7 @@ public class NearestTouchFrameTest extends SysuiTestCase { mNearestTouchFrame.addView(view1); mNearestTouchFrame.addView(view2); mNearestTouchFrame.addView(view3); - mNearestTouchFrame.onMeasure(0, 0); + mNearestTouchFrame.layout(0, 0, 30, 30); MotionEvent ev = MotionEvent.obtain(0, 0, 0, 5 /* x */, 18 /* y */, 0); mNearestTouchFrame.onTouchEvent(ev); @@ -213,11 +213,9 @@ public class NearestTouchFrameTest extends SysuiTestCase { public void testCachedRegionsSplit_horizontal() { View left = mockViewAt(0, 0, 5, 20); View right = mockViewAt(15, 0, 5, 20); - mNearestTouchFrame.layout(0, 0, 20, 20); - mNearestTouchFrame.addView(left); mNearestTouchFrame.addView(right); - mNearestTouchFrame.onMeasure(0, 0); + mNearestTouchFrame.layout(0, 0, 20, 20); Map<View, Rect> childRegions = mNearestTouchFrame.getFullTouchableChildRegions(); assertEquals(2, childRegions.size()); @@ -231,12 +229,10 @@ public class NearestTouchFrameTest extends SysuiTestCase { public void testCachedRegionsSplit_vertical() { View top = mockViewAt(0, 0, 20, 5); View bottom = mockViewAt(0, 15, 20, 5); - mNearestTouchFrame.layout(0, 0, 20, 20); - mNearestTouchFrame.setIsVertical(true); - mNearestTouchFrame.addView(top); mNearestTouchFrame.addView(bottom); - mNearestTouchFrame.onMeasure(0, 0); + mNearestTouchFrame.setIsVertical(true); + mNearestTouchFrame.layout(0, 0, 20, 20); Map<View, Rect> childRegions = mNearestTouchFrame.getFullTouchableChildRegions(); assertEquals(2, childRegions.size()); @@ -256,6 +252,8 @@ public class NearestTouchFrameTest extends SysuiTestCase { }).when(v).getLocationInWindow(any()); when(v.isClickable()).thenReturn(true); when(v.isAttachedToWindow()).thenReturn(true); + when(v.getWidth()).thenReturn(width); + when(v.getHeight()).thenReturn(height); // Stupid final methods. v.setLeft(0); diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFooterViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFooterViewControllerTest.java index 2dfd38832997..d40e6a4586b8 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFooterViewControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFooterViewControllerTest.java @@ -89,6 +89,8 @@ public class QSFooterViewControllerTest extends LeakCheckedTest { private View mEdit; @Mock private MultiUserSwitch mMultiUserSwitch; + @Mock + private View mPowerMenuLiteView; private QSFooterViewController mController; @@ -111,11 +113,12 @@ public class QSFooterViewControllerTest extends LeakCheckedTest { when(mView.findViewById(R.id.build)).thenReturn(mBuildText); when(mView.findViewById(android.R.id.edit)).thenReturn(mEdit); when(mView.findViewById(R.id.multi_user_switch)).thenReturn(mMultiUserSwitch); + when(mView.findViewById(R.id.pm_lite)).thenReturn(mPowerMenuLiteView); mController = new QSFooterViewController(mView, mUserManager, mUserInfoController, mActivityStarter, mDeviceProvisionedController, mUserTracker, mQSPanelController, new QSDetailDisplayer(), mQuickQSPanelController, mFakeTunerService, - mMetricsLogger); + mMetricsLogger, false); mController.init(); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/carrier/QSCarrierGroupControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/carrier/QSCarrierGroupControllerTest.java index 1ec1da44c0b5..5a1bd5f72a02 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/carrier/QSCarrierGroupControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/carrier/QSCarrierGroupControllerTest.java @@ -36,6 +36,7 @@ import androidx.test.filters.SmallTest; import com.android.keyguard.CarrierTextController; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.statusbar.policy.NetworkController; +import com.android.systemui.statusbar.policy.NetworkController.MobileDataIndicators; import com.android.systemui.utils.leaks.LeakCheckedTest; import com.android.systemui.utils.os.FakeHandler; @@ -215,10 +216,11 @@ public class QSCarrierGroupControllerTest extends LeakCheckedTest { @Test // throws no Exception public void testSetMobileDataIndicators_invalidSim() { - mSignalCallback.setMobileDataIndicators( + MobileDataIndicators indicators = new MobileDataIndicators( mock(NetworkController.IconState.class), mock(NetworkController.IconState.class), 0, 0, true, true, "", "", "", true, 0, true, true); + mSignalCallback.setMobileDataIndicators(indicators); } @Test diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/CastTileTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/CastTileTest.java index faf43a21356e..1c29a8174359 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/CastTileTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/CastTileTest.java @@ -46,6 +46,7 @@ import com.android.systemui.statusbar.policy.CastController.CastDevice; import com.android.systemui.statusbar.policy.HotspotController; import com.android.systemui.statusbar.policy.KeyguardStateController; import com.android.systemui.statusbar.policy.NetworkController; +import com.android.systemui.statusbar.policy.NetworkController.WifiIndicators; import org.junit.Before; import org.junit.Test; @@ -134,9 +135,11 @@ public class CastTileTest extends SysuiTestCase { public void testStateUnavailable_wifiDisabled() { NetworkController.IconState qsIcon = new NetworkController.IconState(false, 0, ""); - mSignalCallback.setWifiIndicators(false, mock(NetworkController.IconState.class), + WifiIndicators indicators = new WifiIndicators( + false, mock(NetworkController.IconState.class), qsIcon, false,false, "", false, ""); + mSignalCallback.setWifiIndicators(indicators); mTestableLooper.processAllMessages(); assertEquals(Tile.STATE_UNAVAILABLE, mCastTile.getState().state); @@ -146,9 +149,11 @@ public class CastTileTest extends SysuiTestCase { public void testStateUnavailable_wifiNotConnected() { NetworkController.IconState qsIcon = new NetworkController.IconState(false, 0, ""); - mSignalCallback.setWifiIndicators(true, mock(NetworkController.IconState.class), + WifiIndicators indicators = new WifiIndicators( + true, mock(NetworkController.IconState.class), qsIcon, false,false, "", false, ""); + mSignalCallback.setWifiIndicators(indicators); mTestableLooper.processAllMessages(); assertEquals(Tile.STATE_UNAVAILABLE, mCastTile.getState().state); @@ -157,9 +162,11 @@ public class CastTileTest extends SysuiTestCase { private void enableWifiAndProcessMessages() { NetworkController.IconState qsIcon = new NetworkController.IconState(true, 0, ""); - mSignalCallback.setWifiIndicators(true, mock(NetworkController.IconState.class), + WifiIndicators indicators = new WifiIndicators( + true, mock(NetworkController.IconState.class), qsIcon, false,false, "", false, ""); + mSignalCallback.setWifiIndicators(indicators); mTestableLooper.processAllMessages(); } 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 ce14bca081ab..7ff056ead653 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java @@ -16,6 +16,8 @@ package com.android.systemui.statusbar; +import static android.app.admin.DevicePolicyManager.DEVICE_OWNER_TYPE_DEFAULT; +import static android.app.admin.DevicePolicyManager.DEVICE_OWNER_TYPE_FINANCED; import static android.content.pm.UserInfo.FLAG_MANAGED_PROFILE; import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_DISCLOSURE; @@ -40,6 +42,7 @@ import android.app.Instrumentation; import android.app.admin.DevicePolicyManager; import android.app.trust.TrustManager; import android.content.BroadcastReceiver; +import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.pm.UserInfo; @@ -94,8 +97,12 @@ public class KeyguardIndicationControllerTest extends SysuiTestCase { private static final String ORGANIZATION_NAME = "organization"; + private static final ComponentName DEVICE_OWNER_COMPONENT = new ComponentName("com.android.foo", + "bar"); + private String mDisclosureWithOrganization; private String mDisclosureGeneric; + private String mFinancedDisclosureWithOrganization; @Mock private DevicePolicyManager mDevicePolicyManager; @@ -156,6 +163,8 @@ public class KeyguardIndicationControllerTest extends SysuiTestCase { mDisclosureWithOrganization = mContext.getString(R.string.do_disclosure_with_name, ORGANIZATION_NAME); mDisclosureGeneric = mContext.getString(R.string.do_disclosure_generic); + mFinancedDisclosureWithOrganization = mContext.getString( + R.string.do_financed_disclosure_with_name, ORGANIZATION_NAME); when(mKeyguardUpdateMonitor.isUnlockingWithBiometricAllowed(anyBoolean())).thenReturn(true); when(mKeyguardUpdateMonitor.isScreenOn()).thenReturn(true); @@ -165,6 +174,11 @@ public class KeyguardIndicationControllerTest extends SysuiTestCase { .thenReturn(mIndicationAreaBottom); when(mIndicationArea.findViewById(R.id.keyguard_indication_text)).thenReturn(mTextView); + when(mDevicePolicyManager.getDeviceOwnerComponentOnAnyUser()) + .thenReturn(DEVICE_OWNER_COMPONENT); + when(mDevicePolicyManager.getDeviceOwnerType(DEVICE_OWNER_COMPONENT)) + .thenReturn(DEVICE_OWNER_TYPE_DEFAULT); + mWakeLock = new WakeLockFake(); mWakeLockBuilder = new WakeLockFake.Builder(mContext); mWakeLockBuilder.setWakeLock(mWakeLock); @@ -372,6 +386,22 @@ public class KeyguardIndicationControllerTest extends SysuiTestCase { } @Test + public void disclosure_deviceOwner_financedDeviceWithOrganizationName() { + createController(); + + when(mDevicePolicyManager.isDeviceManaged()).thenReturn(true); + when(mDevicePolicyManager.getDeviceOwnerOrganizationName()).thenReturn(ORGANIZATION_NAME); + when(mDevicePolicyManager.getDeviceOwnerType(DEVICE_OWNER_COMPONENT)) + .thenReturn(DEVICE_OWNER_TYPE_FINANCED); + sendUpdateDisclosureBroadcast(); + + verify(mRotateTextViewController).updateIndication(eq(INDICATION_TYPE_DISCLOSURE), + mKeyguardIndicationCaptor.capture(), eq(false)); + assertThat(mKeyguardIndicationCaptor.getValue().getMessage()) + .isEqualTo(mFinancedDisclosureWithOrganization); + } + + @Test public void transientIndication_holdsWakeLock_whenDozing() { createController(); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CallbackHandlerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CallbackHandlerTest.java index 67c1a086bb33..24182434f1ba 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CallbackHandlerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CallbackHandlerTest.java @@ -30,7 +30,9 @@ import com.android.settingslib.mobile.TelephonyIcons; import com.android.systemui.SysuiTestCase; import com.android.systemui.statusbar.policy.NetworkController.EmergencyListener; import com.android.systemui.statusbar.policy.NetworkController.IconState; +import com.android.systemui.statusbar.policy.NetworkController.MobileDataIndicators; import com.android.systemui.statusbar.policy.NetworkController.SignalCallback; +import com.android.systemui.statusbar.policy.NetworkController.WifiIndicators; import com.android.systemui.tests.R; import org.junit.Before; @@ -86,28 +88,24 @@ public class CallbackHandlerTest extends SysuiTestCase { boolean out = true; String description = "Test"; String secondaryLabel = "Secondary label"; - mHandler.setWifiIndicators(enabled, status, qs, in, out, description, true, secondaryLabel); + WifiIndicators indicators = new WifiIndicators( + enabled, status, qs, in, out, description, true, secondaryLabel); + mHandler.setWifiIndicators(indicators); waitForCallbacks(); - ArgumentCaptor<Boolean> enableArg = ArgumentCaptor.forClass(Boolean.class); - ArgumentCaptor<IconState> statusArg = ArgumentCaptor.forClass(IconState.class); - ArgumentCaptor<IconState> qsArg = ArgumentCaptor.forClass(IconState.class); - ArgumentCaptor<Boolean> inArg = ArgumentCaptor.forClass(Boolean.class); - ArgumentCaptor<Boolean> outArg = ArgumentCaptor.forClass(Boolean.class); - ArgumentCaptor<String> descArg = ArgumentCaptor.forClass(String.class); - ArgumentCaptor<Boolean> isTransient = ArgumentCaptor.forClass(Boolean.class); - ArgumentCaptor<String> secondary = ArgumentCaptor.forClass(String.class); - Mockito.verify(mSignalCallback).setWifiIndicators(enableArg.capture(), - statusArg.capture(), qsArg.capture(), inArg.capture(), outArg.capture(), - descArg.capture(), isTransient.capture(), secondary.capture()); - assertEquals(enabled, (boolean) enableArg.getValue()); - assertEquals(status, statusArg.getValue()); - assertEquals(qs, qsArg.getValue()); - assertEquals(in, (boolean) inArg.getValue()); - assertEquals(out, (boolean) outArg.getValue()); - assertEquals(description, descArg.getValue()); - assertTrue(isTransient.getValue()); - assertEquals(secondaryLabel, secondary.getValue()); + ArgumentCaptor<WifiIndicators> indicatorArg = + ArgumentCaptor.forClass(WifiIndicators.class); + Mockito.verify(mSignalCallback).setWifiIndicators(indicatorArg.capture()); + WifiIndicators expected = indicatorArg.getValue(); + + assertEquals(enabled, expected.enabled); + assertEquals(status, expected.statusIcon); + assertEquals(qs, expected.qsIcon); + assertEquals(in, expected.activityIn); + assertEquals(out, expected.activityOut); + assertEquals(description, expected.description); + assertTrue(expected.isTransient); + assertEquals(secondaryLabel, expected.statusLabel); } @Test @@ -124,37 +122,30 @@ public class CallbackHandlerTest extends SysuiTestCase { boolean wide = true; int subId = 5; boolean roaming = true; - mHandler.setMobileDataIndicators(status, qs, type, qsType, in, out, typeDescription, + MobileDataIndicators indicators = new MobileDataIndicators( + status, qs, type, qsType, in, out, typeDescription, typeDescriptionHtml, description, wide, subId, roaming, true); + mHandler.setMobileDataIndicators(indicators); waitForCallbacks(); - ArgumentCaptor<IconState> statusArg = ArgumentCaptor.forClass(IconState.class); - ArgumentCaptor<IconState> qsArg = ArgumentCaptor.forClass(IconState.class); - ArgumentCaptor<Integer> typeIconArg = ArgumentCaptor.forClass(Integer.class); - ArgumentCaptor<Integer> qsTypeIconArg = ArgumentCaptor.forClass(Integer.class); - ArgumentCaptor<Boolean> inArg = ArgumentCaptor.forClass(Boolean.class); - ArgumentCaptor<Boolean> outArg = ArgumentCaptor.forClass(Boolean.class); - ArgumentCaptor<CharSequence> typeContentArg = ArgumentCaptor.forClass(CharSequence.class); - ArgumentCaptor<CharSequence> typeContentHtmlArg = - ArgumentCaptor.forClass(CharSequence.class); - ArgumentCaptor<CharSequence> descArg = ArgumentCaptor.forClass(CharSequence.class); - ArgumentCaptor<Boolean> wideArg = ArgumentCaptor.forClass(Boolean.class); - ArgumentCaptor<Integer> subIdArg = ArgumentCaptor.forClass(Integer.class); - Mockito.verify(mSignalCallback).setMobileDataIndicators(statusArg.capture(), - qsArg.capture(), typeIconArg.capture(), qsTypeIconArg.capture(), inArg.capture(), - outArg.capture(), typeContentArg.capture(), typeContentHtmlArg.capture(), - descArg.capture(), wideArg.capture(), subIdArg.capture(), eq(roaming), eq(true)); - assertEquals(status, statusArg.getValue()); - assertEquals(qs, qsArg.getValue()); - assertEquals(type, (int) typeIconArg.getValue()); - assertEquals(qsType, (int) qsTypeIconArg.getValue()); - assertEquals(in, (boolean) inArg.getValue()); - assertEquals(out, (boolean) outArg.getValue()); - assertEquals(typeDescription, typeContentArg.getValue()); - assertEquals(typeDescriptionHtml, typeContentHtmlArg.getValue()); - assertEquals(description, descArg.getValue()); - assertEquals(wide, (boolean) wideArg.getValue()); - assertEquals(subId, (int) subIdArg.getValue()); + ArgumentCaptor<MobileDataIndicators> indicatorArg = + ArgumentCaptor.forClass(MobileDataIndicators.class); + Mockito.verify(mSignalCallback).setMobileDataIndicators(indicatorArg.capture()); + MobileDataIndicators expected = indicatorArg.getValue(); + + assertEquals(status, expected.statusIcon); + assertEquals(qs, expected.qsIcon); + assertEquals(type, expected.statusType); + assertEquals(qsType, expected.qsType); + assertEquals(in, expected.activityIn); + assertEquals(out, expected.activityOut); + assertEquals(typeDescription, expected.typeContentDescription); + assertEquals(typeDescriptionHtml, expected.typeContentDescriptionHtml); + assertEquals(description, expected.description); + assertEquals(wide, expected.isWide); + assertEquals(subId, expected.subId); + assertTrue(expected.roaming); + assertTrue(expected.showTriangle); } @SuppressWarnings("unchecked") diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java index 89cc2b574398..e52b92648670 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java @@ -21,9 +21,9 @@ import static android.telephony.NetworkRegistrationInfo.DOMAIN_PS; import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertNotNull; +import static junit.framework.Assert.assertTrue; import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyBoolean; import static org.mockito.Matchers.anyInt; import static org.mockito.Matchers.eq; import static org.mockito.Matchers.isA; @@ -76,6 +76,7 @@ import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.demomode.DemoModeController; import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceProvisionedListener; import com.android.systemui.statusbar.policy.NetworkController.IconState; +import com.android.systemui.statusbar.policy.NetworkController.MobileDataIndicators; import com.android.systemui.statusbar.policy.NetworkController.SignalCallback; import org.junit.After; @@ -173,8 +174,6 @@ public class NetworkControllerBaseTest extends SysuiTestCase { mMockSubDefaults = mock(SubscriptionDefaults.class); mNetCapabilities = new NetworkCapabilities(); when(mMockCm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE)).thenReturn(true); - when(mMockCm.getDefaultNetworkCapabilitiesForUser(0)).thenReturn( - new NetworkCapabilities[] { mNetCapabilities }); when(mMockTm.createForSubscriptionId(anyInt())).thenReturn(mMockTm); doAnswer(invocation -> { int rssi = invocation.getArgument(0); @@ -257,8 +256,11 @@ public class NetworkControllerBaseTest extends SysuiTestCase { ArgumentCaptor.forClass(ConnectivityManager.NetworkCallback.class); verify(mMockCm, atLeastOnce()) .registerDefaultNetworkCallback(callbackArg.capture(), isA(Handler.class)); - mDefaultCallbackInWifiTracker = callbackArg.getAllValues().get(0); - mDefaultCallbackInNetworkController = callbackArg.getAllValues().get(1); + int captureSize = callbackArg.getAllValues().size(); + assertTrue(captureSize > 1); + assertEquals(captureSize % 2, 0); + mDefaultCallbackInWifiTracker = callbackArg.getAllValues().get(captureSize - 2); + mDefaultCallbackInNetworkController = callbackArg.getAllValues().get(captureSize - 1); assertNotNull(mDefaultCallbackInWifiTracker); assertNotNull(mDefaultCallbackInNetworkController); verify(mMockCm, atLeastOnce()).registerNetworkCallback( @@ -307,14 +309,18 @@ public class NetworkControllerBaseTest extends SysuiTestCase { setLevel(DEFAULT_LEVEL); updateDataConnectionState(TelephonyManager.DATA_CONNECTED, TelephonyManager.NETWORK_TYPE_UMTS); + setConnectivityViaCallbackInNetworkController( + NetworkCapabilities.TRANSPORT_CELLULAR, true, true, null); setConnectivityViaBroadcast( - NetworkCapabilities.TRANSPORT_CELLULAR, true, true); + NetworkCapabilities.TRANSPORT_CELLULAR, true, true); } public void setConnectivityViaBroadcastForVcn( int networkType, boolean validated, boolean isConnected, VcnTransportInfo info) { mNetCapabilities.setTransportInfo(info); setConnectivityCommon(networkType, validated, isConnected); + mDefaultCallbackInNetworkController.onCapabilitiesChanged( + mock(Network.class), new NetworkCapabilities(mNetCapabilities)); Intent i = new Intent(ConnectivityManager.INET_CONDITION_ACTION); mNetworkController.onReceive(mContext, i); } @@ -322,6 +328,8 @@ public class NetworkControllerBaseTest extends SysuiTestCase { public void setConnectivityViaBroadcast( int networkType, boolean validated, boolean isConnected) { setConnectivityCommon(networkType, validated, isConnected); + mDefaultCallbackInNetworkController.onCapabilitiesChanged( + mock(Network.class), new NetworkCapabilities(mNetCapabilities)); Intent i = new Intent(ConnectivityManager.INET_CONDITION_ACTION); mNetworkController.onReceive(mContext, i); } @@ -487,28 +495,21 @@ public class NetworkControllerBaseTest extends SysuiTestCase { protected void verifyLastQsMobileDataIndicators(boolean visible, int icon, int typeIcon, boolean dataIn, boolean dataOut) { - ArgumentCaptor<IconState> iconArg = ArgumentCaptor.forClass(IconState.class); - ArgumentCaptor<Integer> typeIconArg = ArgumentCaptor.forClass(Integer.class); - ArgumentCaptor<Boolean> dataInArg = ArgumentCaptor.forClass(Boolean.class); - ArgumentCaptor<Boolean> dataOutArg = ArgumentCaptor.forClass(Boolean.class); + ArgumentCaptor<MobileDataIndicators> indicatorsArg = + ArgumentCaptor.forClass(MobileDataIndicators.class); verify(mCallbackHandler, Mockito.atLeastOnce()).setMobileDataIndicators( - any(), - iconArg.capture(), - anyInt(), - typeIconArg.capture(), dataInArg.capture(), dataOutArg.capture(), - any(CharSequence.class), any(CharSequence.class), any(CharSequence.class), - anyBoolean(), anyInt(), anyBoolean(), anyBoolean()); - IconState iconState = iconArg.getValue(); + indicatorsArg.capture()); + MobileDataIndicators expected = indicatorsArg.getValue(); int state = SignalDrawable.getState(icon, CellSignalStrength.getNumSignalStrengthLevels(), false); - assertEquals("Visibility in, quick settings", visible, iconState.visible); - assertEquals("Signal icon in, quick settings", state, iconState.icon); - assertEquals("Data icon in, quick settings", typeIcon, (int) typeIconArg.getValue()); + assertEquals("Visibility in, quick settings", visible, expected.qsIcon.visible); + assertEquals("Signal icon in, quick settings", state, expected.qsIcon.icon); + assertEquals("Data icon in, quick settings", typeIcon, expected.qsType); assertEquals("Data direction in, in quick settings", dataIn, - (boolean) dataInArg.getValue()); + expected.activityIn); assertEquals("Data direction out, in quick settings", dataOut, - (boolean) dataOutArg.getValue()); + expected.activityOut); } protected void verifyLastMobileDataIndicators(boolean visible, int icon, int typeIcon) { @@ -522,44 +523,35 @@ public class NetworkControllerBaseTest extends SysuiTestCase { protected void verifyLastMobileDataIndicators(boolean visible, int icon, int typeIcon, boolean roaming, boolean inet) { - ArgumentCaptor<IconState> iconArg = ArgumentCaptor.forClass(IconState.class); - ArgumentCaptor<Integer> typeIconArg = ArgumentCaptor.forClass(Integer.class); + ArgumentCaptor<MobileDataIndicators> indicatorsArg = + ArgumentCaptor.forClass(MobileDataIndicators.class); // TODO: Verify all fields. verify(mCallbackHandler, Mockito.atLeastOnce()).setMobileDataIndicators( - iconArg.capture(), - any(), - typeIconArg.capture(), - anyInt(), anyBoolean(), anyBoolean(), - any(CharSequence.class), any(CharSequence.class), any(), - anyBoolean(), anyInt(), eq(roaming), anyBoolean()); - IconState iconState = iconArg.getValue(); + indicatorsArg.capture()); + MobileDataIndicators expected = indicatorsArg.getValue(); int state = icon == -1 ? 0 : SignalDrawable.getState(icon, CellSignalStrength.getNumSignalStrengthLevels(), !inet); - assertEquals("Signal icon in status bar", state, iconState.icon); - assertEquals("Data icon in status bar", typeIcon, (int) typeIconArg.getValue()); - assertEquals("Visibility in status bar", visible, iconState.visible); + assertEquals("Signal icon in status bar", state, expected.statusIcon.icon); + assertEquals("Data icon in status bar", typeIcon, expected.statusType); + assertEquals("Visibility in status bar", visible, expected.statusIcon.visible); } protected void verifyLastMobileDataIndicatorsForVcn(boolean visible, int level, int typeIcon, boolean inet) { - ArgumentCaptor<IconState> iconArg = ArgumentCaptor.forClass(IconState.class); - ArgumentCaptor<Integer> typeIconArg = ArgumentCaptor.forClass(Integer.class); + ArgumentCaptor<MobileDataIndicators> indicatorsArg = + ArgumentCaptor.forClass(MobileDataIndicators.class); verify(mCallbackHandler, Mockito.atLeastOnce()).setMobileDataIndicators( - iconArg.capture(), - any(), - typeIconArg.capture(), - anyInt(), anyBoolean(), anyBoolean(), - any(CharSequence.class), any(CharSequence.class), any(), - anyBoolean(), anyInt(), anyBoolean(), anyBoolean()); - IconState iconState = iconArg.getValue(); + indicatorsArg.capture()); + + MobileDataIndicators expected = indicatorsArg.getValue(); int state = SignalDrawable.getState( level, CellSignalStrength.getNumSignalStrengthLevels(), !inet); - assertEquals("Signal icon in status bar", state, iconState.icon); - assertEquals("Data icon in status bar", typeIcon, (int) typeIconArg.getValue()); - assertEquals("Visibility in status bar", visible, iconState.visible); + assertEquals("Signal icon in status bar", state, expected.statusIcon.icon); + assertEquals("Data icon in status bar", typeIcon, expected.statusType); + assertEquals("Visibility in status bar", visible, expected.statusIcon.visible); } protected void verifyLastMobileDataIndicators(boolean visible, int icon, int typeIcon, @@ -580,6 +572,8 @@ public class NetworkControllerBaseTest extends SysuiTestCase { boolean qsVisible, int qsIcon, int qsTypeIcon, boolean dataIn, boolean dataOut, boolean cutOut, CharSequence typeContentDescription, CharSequence typeContentDescriptionHtml) { + ArgumentCaptor<MobileDataIndicators> indicatorsArg = + ArgumentCaptor.forClass(MobileDataIndicators.class); ArgumentCaptor<IconState> iconArg = ArgumentCaptor.forClass(IconState.class); ArgumentCaptor<Integer> typeIconArg = ArgumentCaptor.forClass(Integer.class); ArgumentCaptor<IconState> qsIconArg = ArgumentCaptor.forClass(IconState.class); @@ -592,17 +586,9 @@ public class NetworkControllerBaseTest extends SysuiTestCase { ArgumentCaptor.forClass(CharSequence.class); verify(mCallbackHandler, Mockito.atLeastOnce()).setMobileDataIndicators( - iconArg.capture(), - qsIconArg.capture(), - typeIconArg.capture(), - qsTypeIconArg.capture(), - dataInArg.capture(), - dataOutArg.capture(), - typeContentDescriptionArg.capture(), - typeContentDescriptionHtmlArg.capture(), - any(), anyBoolean(), anyInt(), anyBoolean(), anyBoolean()); + indicatorsArg.capture()); - IconState iconState = iconArg.getValue(); + MobileDataIndicators expected = indicatorsArg.getValue(); int numSignalStrengthBins = CellSignalStrength.getNumSignalStrengthLevels(); if (mMobileSignalController.mInflateSignalStrengths) { @@ -610,29 +596,28 @@ public class NetworkControllerBaseTest extends SysuiTestCase { icon++; } int state = SignalDrawable.getState(icon, numSignalStrengthBins, cutOut); - assertEquals("Data icon in status bar", typeIcon, (int) typeIconArg.getValue()); - assertEquals("Signal icon in status bar", state, iconState.icon); - assertEquals("Visibility in status bar", visible, iconState.visible); + assertEquals("Data icon in status bar", typeIcon, expected.statusType); + assertEquals("Signal icon in status bar", state, expected.statusIcon.icon); + assertEquals("Visibility in status bar", visible, expected.statusIcon.visible); - iconState = qsIconArg.getValue(); if (visible) { - assertEquals("Visibility in quick settings", qsVisible, iconState.visible); - assertEquals("Signal icon in quick settings", state, iconState.icon); + assertEquals("Visibility in quick settings", qsVisible, expected.qsIcon.visible); + assertEquals("Signal icon in quick settings", state, expected.qsIcon.icon); } else { - assertEquals("Cellular is not default", null, iconState); + assertEquals("Cellular is not default", null, expected.qsIcon); } - assertEquals("Data icon in quick settings", qsTypeIcon, (int) qsTypeIconArg.getValue()); + assertEquals("Data icon in quick settings", qsTypeIcon, expected.qsType); assertEquals("Data direction in in quick settings", dataIn, - (boolean) dataInArg.getValue()); + expected.activityIn); assertEquals("Data direction out in quick settings", dataOut, - (boolean) dataOutArg.getValue()); + expected.activityOut); if (typeContentDescription != null) { // Only check if it was provided assertEquals("Type content description", typeContentDescription, - typeContentDescriptionArg.getValue()); + expected.typeContentDescription); } if (typeContentDescriptionHtml != null) { // Only check if it was provided assertEquals("Type content description (html)", typeContentDescriptionHtml, - typeContentDescriptionHtmlArg.getValue()); + expected.typeContentDescriptionHtml); } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java index fc1a08ac3874..c6812a26c20b 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java @@ -3,7 +3,6 @@ package com.android.systemui.statusbar.policy; import static junit.framework.Assert.assertEquals; import static org.junit.Assert.assertTrue; -import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyBoolean; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -21,7 +20,7 @@ import android.testing.AndroidTestingRunner; import android.testing.TestableLooper.RunWithLooper; import com.android.settingslib.mobile.TelephonyIcons; -import com.android.systemui.statusbar.policy.NetworkController.IconState; +import com.android.systemui.statusbar.policy.NetworkController.WifiIndicators; import org.junit.Before; import org.junit.Test; @@ -316,44 +315,42 @@ public class NetworkControllerWifiTest extends NetworkControllerBaseTest { } protected void verifyLastQsDataDirection(boolean in, boolean out) { - ArgumentCaptor<Boolean> inArg = ArgumentCaptor.forClass(Boolean.class); - ArgumentCaptor<Boolean> outArg = ArgumentCaptor.forClass(Boolean.class); + ArgumentCaptor<WifiIndicators> indicatorsArg = + ArgumentCaptor.forClass(WifiIndicators.class); Mockito.verify(mCallbackHandler, Mockito.atLeastOnce()).setWifiIndicators( - anyBoolean(), any(), any(), inArg.capture(), outArg.capture(), any(), anyBoolean(), - any()); - assertEquals("WiFi data in, in quick settings", in, (boolean) inArg.getValue()); - assertEquals("WiFi data out, in quick settings", out, (boolean) outArg.getValue()); + indicatorsArg.capture()); + WifiIndicators expected = indicatorsArg.getValue(); + assertEquals("WiFi data in, in quick settings", in, expected.activityIn); + assertEquals("WiFi data out, in quick settings", out, expected.activityOut); } protected void verifyLastQsWifiIcon(boolean enabled, boolean connected, int icon, String description) { - ArgumentCaptor<IconState> iconArg = ArgumentCaptor.forClass(IconState.class); - ArgumentCaptor<Boolean> enabledArg = ArgumentCaptor.forClass(Boolean.class); - ArgumentCaptor<String> descArg = ArgumentCaptor.forClass(String.class); + ArgumentCaptor<WifiIndicators> indicatorsArg = + ArgumentCaptor.forClass(WifiIndicators.class); Mockito.verify(mCallbackHandler, Mockito.atLeastOnce()).setWifiIndicators( - enabledArg.capture(), any(), iconArg.capture(), anyBoolean(), - anyBoolean(), descArg.capture(), anyBoolean(), any()); - IconState iconState = iconArg.getValue(); - assertEquals("WiFi enabled, in quick settings", enabled, (boolean) enabledArg.getValue()); - assertEquals("WiFI desc (ssid), in quick settings", description, descArg.getValue()); + indicatorsArg.capture()); + WifiIndicators expected = indicatorsArg.getValue(); + assertEquals("WiFi enabled, in quick settings", enabled, expected.enabled); + assertEquals("WiFI desc (ssid), in quick settings", description, expected.description); if (enabled && connected) { - assertEquals("WiFi connected, in quick settings", connected, iconState.visible); - assertEquals("WiFi signal, in quick settings", icon, iconState.icon); + assertEquals("WiFi connected, in quick settings", connected, expected.qsIcon.visible); + assertEquals("WiFi signal, in quick settings", icon, expected.qsIcon.icon); } else { - assertEquals("WiFi is not default", null, iconState); + assertEquals("WiFi is not default", null, expected.qsIcon); } } protected void verifyLastWifiIcon(boolean visible, int icon) { - ArgumentCaptor<IconState> iconArg = ArgumentCaptor.forClass(IconState.class); + ArgumentCaptor<WifiIndicators> indicatorsArg = + ArgumentCaptor.forClass(WifiIndicators.class); Mockito.verify(mCallbackHandler, Mockito.atLeastOnce()).setWifiIndicators( - anyBoolean(), iconArg.capture(), any(), anyBoolean(), anyBoolean(), - any(), anyBoolean(), any()); - IconState iconState = iconArg.getValue(); - assertEquals("WiFi visible, in status bar", visible, iconState.visible); - assertEquals("WiFi signal, in status bar", icon, iconState.icon); + indicatorsArg.capture()); + WifiIndicators expected = indicatorsArg.getValue(); + assertEquals("WiFi visible, in status bar", visible, expected.statusIcon.visible); + assertEquals("WiFi signal, in status bar", icon, expected.statusIcon.icon); } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java index c0856892dc44..3cea17567173 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java @@ -22,6 +22,7 @@ import static junit.framework.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import android.app.KeyguardManager; @@ -37,6 +38,8 @@ import android.view.accessibility.AccessibilityManager; import androidx.test.filters.SmallTest; +import com.android.systemui.Prefs; +import com.android.systemui.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.plugins.VolumeDialogController; import com.android.systemui.plugins.VolumeDialogController.State; @@ -58,6 +61,11 @@ import java.util.function.Predicate; public class VolumeDialogImplTest extends SysuiTestCase { VolumeDialogImpl mDialog; + View mActiveRinger; + View mDrawerContainer; + View mDrawerVibrate; + View mDrawerMute; + View mDrawerNormal; @Mock VolumeDialogController mController; @@ -80,6 +88,17 @@ public class VolumeDialogImplTest extends SysuiTestCase { mDialog.init(0, null); State state = createShellState(); mDialog.onStateChangedH(state); + + mActiveRinger = mDialog.getDialogView().findViewById( + R.id.volume_new_ringer_active_icon_container); + mDrawerContainer = mDialog.getDialogView().findViewById(R.id.volume_drawer_container); + mDrawerVibrate = mDrawerContainer.findViewById(R.id.volume_drawer_vibrate); + mDrawerMute = mDrawerContainer.findViewById(R.id.volume_drawer_mute); + mDrawerNormal = mDrawerContainer.findViewById(R.id.volume_drawer_normal); + + Prefs.putInt(mContext, + Prefs.Key.SEEN_RINGER_GUIDANCE_COUNT, + VolumePrefs.SHOW_RINGER_TOAST_COUNT + 1); } private State createShellState() { @@ -207,6 +226,48 @@ public class VolumeDialogImplTest extends SysuiTestCase { verify(mController, never()).vibrate(any()); } + @Test + public void testSelectVibrateFromDrawer() { + final State initialUnsetState = new State(); + initialUnsetState.ringerModeInternal = AudioManager.RINGER_MODE_NORMAL; + mDialog.onStateChangedH(initialUnsetState); + + mActiveRinger.performClick(); + mDrawerVibrate.performClick(); + + // Make sure we've actually changed the ringer mode. + verify(mController, times(1)).setRingerMode( + AudioManager.RINGER_MODE_VIBRATE, false); + } + + @Test + public void testSelectMuteFromDrawer() { + final State initialUnsetState = new State(); + initialUnsetState.ringerModeInternal = AudioManager.RINGER_MODE_NORMAL; + mDialog.onStateChangedH(initialUnsetState); + + mActiveRinger.performClick(); + mDrawerMute.performClick(); + + // Make sure we've actually changed the ringer mode. + verify(mController, times(1)).setRingerMode( + AudioManager.RINGER_MODE_SILENT, false); + } + + @Test + public void testSelectNormalFromDrawer() { + final State initialUnsetState = new State(); + initialUnsetState.ringerModeInternal = AudioManager.RINGER_MODE_VIBRATE; + mDialog.onStateChangedH(initialUnsetState); + + mActiveRinger.performClick(); + mDrawerNormal.performClick(); + + // Make sure we've actually changed the ringer mode. + verify(mController, times(1)).setRingerMode( + AudioManager.RINGER_MODE_NORMAL, false); + } + /* @Test public void testContentDescriptions() { diff --git a/services/api/Android.bp b/services/api/Android.bp index b8ca5488c5cd..e69de29bb2d1 100644 --- a/services/api/Android.bp +++ b/services/api/Android.bp @@ -1,29 +0,0 @@ -// Copyright (C) 2021 The Android Open Source Project -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package { - default_visibility: ["//visibility:private"], -} - -filegroup { - name: "non-updatable-system-server-current.txt", - srcs: ["non-updatable-current.txt"], - visibility: ["//frameworks/base/api"], -} - -filegroup { - name: "non-updatable-system-server-removed.txt", - srcs: ["non-updatable-removed.txt"], - visibility: ["//frameworks/base/api"], -}
\ No newline at end of file diff --git a/services/contentsuggestions/java/com/android/server/contentsuggestions/ContentSuggestionsManagerService.java b/services/contentsuggestions/java/com/android/server/contentsuggestions/ContentSuggestionsManagerService.java index 00c91fee845e..57c643bb08a1 100644 --- a/services/contentsuggestions/java/com/android/server/contentsuggestions/ContentSuggestionsManagerService.java +++ b/services/contentsuggestions/java/com/android/server/contentsuggestions/ContentSuggestionsManagerService.java @@ -21,6 +21,7 @@ import static android.content.pm.PackageManager.PERMISSION_GRANTED; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.UserIdInt; import android.app.contentsuggestions.ClassificationsRequest; import android.app.contentsuggestions.ContentSuggestionsManager; import android.app.contentsuggestions.IClassificationsCallback; @@ -253,6 +254,23 @@ public class ContentSuggestionsManagerService extends receiver.send(isDisabled ? 0 : 1, null); } + @Override + public void resetTemporaryService(@UserIdInt int userId) { + ContentSuggestionsManagerService.this.resetTemporaryService(userId); + } + + @Override + public void setTemporaryService( + @UserIdInt int userId, @NonNull String serviceName, int duration) { + ContentSuggestionsManagerService.this.setTemporaryService( + userId, serviceName, duration); + } + + @Override + public void setDefaultServiceEnabled(@UserIdInt int userId, boolean enabled) { + ContentSuggestionsManagerService.this.setDefaultServiceEnabled(userId, enabled); + } + public void onShellCommand(@Nullable FileDescriptor in, @Nullable FileDescriptor out, @Nullable FileDescriptor err, @NonNull String[] args, @Nullable ShellCallback callback, diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index f4138d10a84d..542d527177a1 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -44,6 +44,7 @@ import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED; +import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN; import static android.net.NetworkCapabilities.NET_CAPABILITY_OEM_PAID; import static android.net.NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE; @@ -91,7 +92,6 @@ import android.net.IConnectivityManager; import android.net.IDnsResolver; import android.net.INetd; import android.net.INetworkActivityListener; -import android.net.INetworkManagementEventObserver; import android.net.INetworkMonitor; import android.net.INetworkMonitorCallbacks; import android.net.INetworkPolicyListener; @@ -194,6 +194,7 @@ import com.android.internal.util.IndentingPrintWriter; import com.android.internal.util.LocationPermissionChecker; import com.android.internal.util.MessageUtils; import com.android.modules.utils.BasicShellCommandHandler; +import com.android.net.module.util.BaseNetdUnsolicitedEventListener; import com.android.net.module.util.CollectionUtils; import com.android.net.module.util.LinkPropertiesUtils.CompareOrUpdateResult; import com.android.net.module.util.LinkPropertiesUtils.CompareResult; @@ -214,7 +215,6 @@ import com.android.server.connectivity.NetworkRanker; import com.android.server.connectivity.PermissionMonitor; import com.android.server.connectivity.ProxyTracker; import com.android.server.connectivity.QosCallbackTracker; -import com.android.server.net.BaseNetworkObserver; import com.android.server.net.NetworkPolicyManagerInternal; import com.android.server.utils.PriorityDump; @@ -332,6 +332,7 @@ public class ConnectivityService extends IConnectivityManager.Stub private INetworkStatsService mStatsService; private NetworkPolicyManager mPolicyManager; private NetworkPolicyManagerInternal mPolicyManagerInternal; + private final NetdCallback mNetdCallback; /** * TestNetworkService (lazily) created upon first usage. Locked to prevent creation of multiple @@ -1204,6 +1205,13 @@ public class ConnectivityService extends IConnectivityManager.Stub mNetworkActivityTracker = new LegacyNetworkActivityTracker(mContext, mHandler, mNMS, mNetd); + mNetdCallback = new NetdCallback(); + try { + mNetd.registerUnsolicitedEventListener(mNetdCallback); + } catch (RemoteException | ServiceSpecificException e) { + loge("Error registering event listener :" + e); + } + mSettingsObserver = new SettingsObserver(mContext, mHandler); registerSettingsCallbacks(); @@ -1241,6 +1249,7 @@ public class ConnectivityService extends IConnectivityManager.Stub private static NetworkCapabilities createDefaultNetworkCapabilitiesForUid(int uid) { final NetworkCapabilities netCap = new NetworkCapabilities(); netCap.addCapability(NET_CAPABILITY_INTERNET); + netCap.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED); netCap.removeCapability(NET_CAPABILITY_NOT_VPN); netCap.setSingleUid(uid); return netCap; @@ -1255,6 +1264,7 @@ public class ConnectivityService extends IConnectivityManager.Stub int transportType, NetworkRequest.Type type) { final NetworkCapabilities netCap = new NetworkCapabilities(); netCap.addCapability(NET_CAPABILITY_INTERNET); + netCap.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED); netCap.setRequestorUidAndPackageName(Process.myUid(), mContext.getPackageName()); if (transportType > TYPE_NONE) { netCap.addTransportType(transportType); @@ -8649,6 +8659,14 @@ public class ConnectivityService extends IConnectivityManager.Stub notifyDataStallSuspected(p, network.getNetId()); } + private class NetdCallback extends BaseNetdUnsolicitedEventListener { + @Override + public void onInterfaceClassActivityChanged(boolean isActive, int timerLabel, + long timestampNs, int uid) { + mNetworkActivityTracker.setAndReportNetworkActive(isActive, timerLabel, timestampNs); + } + } + private final LegacyNetworkActivityTracker mNetworkActivityTracker; /** @@ -8659,7 +8677,6 @@ public class ConnectivityService extends IConnectivityManager.Stub private static final int NO_UID = -1; private final Context mContext; private final INetd mNetd; - private final INetworkManagementService mNMS; private final RemoteCallbackList<INetworkActivityListener> mNetworkActivityListeners = new RemoteCallbackList<>(); // Indicate the current system default network activity is active or not. @@ -8682,41 +8699,27 @@ public class ConnectivityService extends IConnectivityManager.Stub LegacyNetworkActivityTracker(@NonNull Context context, @NonNull Handler handler, @NonNull INetworkManagementService nms, @NonNull INetd netd) { mContext = context; - mNMS = nms; mNetd = netd; mHandler = handler; - try { - mNMS.registerObserver(mDataActivityObserver); - } catch (RemoteException e) { - loge("Error registering observer :" + e); - } - } - - // TODO: Migrate away the dependency with INetworkManagementEventObserver. - private final INetworkManagementEventObserver mDataActivityObserver = - new BaseNetworkObserver() { - @Override - public void interfaceClassDataActivityChanged(int transportType, boolean active, - long tsNanos, int uid) { - sendDataActivityBroadcast(transportTypeToLegacyType(transportType), active, - tsNanos); - synchronized (mActiveIdleTimers) { - mNetworkActive = active; - // If there are no idle timers, it means that system is not monitoring - // activity, so the system default network for those default network - // unspecified apps is always considered active. - // - // TODO: If the mActiveIdleTimers is empty, netd will actually not send - // any network activity change event. Whenever this event is received, - // the mActiveIdleTimers should be always not empty. The legacy behavior - // is no-op. Remove to refer to mNetworkActive only. - if (mNetworkActive || mActiveIdleTimers.isEmpty()) { - mHandler.sendMessage( - mHandler.obtainMessage(EVENT_REPORT_NETWORK_ACTIVITY)); - } - } - } - }; + } + + public void setAndReportNetworkActive(boolean active, int transportType, long tsNanos) { + sendDataActivityBroadcast(transportTypeToLegacyType(transportType), active, tsNanos); + synchronized (mActiveIdleTimers) { + mNetworkActive = active; + // If there are no idle timers, it means that system is not monitoring + // activity, so the system default network for those default network + // unspecified apps is always considered active. + // + // TODO: If the mActiveIdleTimers is empty, netd will actually not send + // any network activity change event. Whenever this event is received, + // the mActiveIdleTimers should be always not empty. The legacy behavior + // is no-op. Remove to refer to mNetworkActive only. + if (mNetworkActive || mActiveIdleTimers.isEmpty()) { + mHandler.sendMessage(mHandler.obtainMessage(EVENT_REPORT_NETWORK_ACTIVITY)); + } + } + } // The network activity should only be updated from ConnectivityService handler thread // when mActiveIdleTimers lock is held. diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java index 6be7f05f6cc6..233a50d417ad 100644 --- a/services/core/java/com/android/server/StorageManagerService.java +++ b/services/core/java/com/android/server/StorageManagerService.java @@ -3338,6 +3338,39 @@ class StorageManagerService extends IStorageManager.Stub } } + @Override + public void notifyAppIoBlocked(String volumeUuid, int uid, int tid, int reason) { + enforceExternalStorageService(); + + mStorageSessionController.notifyAppIoBlocked(volumeUuid, uid, tid, reason); + } + + @Override + public void notifyAppIoResumed(String volumeUuid, int uid, int tid, int reason) { + enforceExternalStorageService(); + + mStorageSessionController.notifyAppIoResumed(volumeUuid, uid, tid, reason); + } + + private boolean isAppIoBlocked(int uid) { + return mStorageSessionController.isAppIoBlocked(uid); + } + + /** + * Enforces that the caller is the {@link ExternalStorageService} + * + * @throws SecurityException if the caller doesn't have the + * {@link android.Manifest.permission.WRITE_MEDIA_STORAGE} permission or is not the + * {@link ExternalStorageService} + */ + private void enforceExternalStorageService() { + enforcePermission(android.Manifest.permission.WRITE_MEDIA_STORAGE); + int callingAppId = UserHandle.getAppId(Binder.getCallingUid()); + if (callingAppId != mMediaStoreAuthorityAppId) { + throw new SecurityException("Only the ExternalStorageService is permitted"); + } + } + /** Not thread safe */ class AppFuseMountScope extends AppFuseBridge.MountScope { private boolean mMounted = false; diff --git a/services/core/java/com/android/server/TEST_MAPPING b/services/core/java/com/android/server/TEST_MAPPING index a09dbc7e599d..95af84293377 100644 --- a/services/core/java/com/android/server/TEST_MAPPING +++ b/services/core/java/com/android/server/TEST_MAPPING @@ -21,9 +21,7 @@ } ], "file_patterns": ["NotificationManagerService\\.java"] - } - ], - "presubmit-large": [ + }, { "name": "CtsScopedStorageCoreHostTest", "file_patterns": ["StorageManagerService\\.java"] diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 5e61f94826c1..7cd494976c94 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -15127,13 +15127,6 @@ public class ActivityManagerService extends IActivityManager.Stub } @Override - public void setPendingIntentWhitelistDuration(IIntentSender target, IBinder allowlistToken, - long duration, int type) { - mPendingIntentController.setPendingIntentAllowlistDuration(target, allowlistToken, - duration, type, REASON_UNKNOWN, ""); - } - - @Override public int getPendingIntentFlags(IIntentSender target) { return mPendingIntentController.getPendingIntentFlags(target); } diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java index 24953fc9c5d6..06e879b549af 100644 --- a/services/core/java/com/android/server/am/OomAdjuster.java +++ b/services/core/java/com/android/server/am/OomAdjuster.java @@ -522,8 +522,6 @@ public final class OomAdjuster { computeOomAdjLSP(app, cachedAdj, TOP_APP, doingAll, now, false, true); - boolean success = applyOomAdjLSP(app, doingAll, now, SystemClock.elapsedRealtime()); - if (uidRec != null) { // After uidRec.reset() above, for UidRecord with multiple processes (ProcessRecord), // we need to apply all ProcessRecord into UidRecord. @@ -540,7 +538,7 @@ public final class OomAdjuster { } } - return success; + return applyOomAdjLSP(app, doingAll, now, SystemClock.elapsedRealtime()); } /** diff --git a/services/core/java/com/android/server/am/PreBootBroadcaster.java b/services/core/java/com/android/server/am/PreBootBroadcaster.java index 60b246726593..984fe409b086 100644 --- a/services/core/java/com/android/server/am/PreBootBroadcaster.java +++ b/services/core/java/com/android/server/am/PreBootBroadcaster.java @@ -17,6 +17,8 @@ package com.android.server.am; import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY; +import static android.os.PowerWhitelistManager.REASON_PRE_BOOT_COMPLETED; +import static android.os.PowerWhitelistManager.TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED; import android.app.ActivityManagerInternal; import android.app.AppOpsManager; @@ -117,9 +119,9 @@ public abstract class PreBootBroadcaster extends IIntentReceiver.Stub { duration = amInternal.getBootTimeTempAllowListDuration(); } final BroadcastOptions bOptions = BroadcastOptions.makeBasic(); - bOptions.setTemporaryAppWhitelistDuration( - BroadcastOptions.TEMPORARY_WHITELIST_TYPE_FOREGROUND_SERVICE_ALLOWED, - duration); + bOptions.setTemporaryAppAllowlist(duration, + TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED, + REASON_PRE_BOOT_COMPLETED, ""); synchronized (mService) { mService.broadcastIntentLocked(null, null, null, mIntent, null, this, 0, null, null, null, AppOpsManager.OP_NONE, bOptions.toBundle(), true, diff --git a/services/core/java/com/android/server/am/TEST_MAPPING b/services/core/java/com/android/server/am/TEST_MAPPING index 4061df4f3f62..03eddc9634d7 100644 --- a/services/core/java/com/android/server/am/TEST_MAPPING +++ b/services/core/java/com/android/server/am/TEST_MAPPING @@ -44,6 +44,23 @@ "exclude-annotation": "androidx.test.filters.FlakyTest" } ] + }, + { + "file_patterns": ["Battery[^/]*\\.java", "MeasuredEnergy[^/]*\\.java"], + "name": "FrameworksCoreTests", + "options": [ + { "include-filter": "com.android.internal.os.BatteryStatsTests" }, + { "exclude-annotation": "com.android.internal.os.SkipPresubmit" } + ] + }, + { + "file_patterns": ["Battery[^/]*\\.java", "MeasuredEnergy[^/]*\\.java"], + "name": "FrameworksServicesTests", + "options": [ + { "include-filter": "com.android.server.am.BatteryStatsServiceTest" }, + { "include-filter": "com.android.server.am.MeasuredEnergySnapshotTest" }, + { "include-filter": "com.android.server.am.BatteryExternalStatsWorkerTest" } + ] } ], "postsubmit": [ diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java index 6dd78e77aafb..caf2510e5b1c 100644 --- a/services/core/java/com/android/server/am/UserController.java +++ b/services/core/java/com/android/server/am/UserController.java @@ -27,6 +27,9 @@ import static android.app.ActivityManagerInternal.ALLOW_ALL_PROFILE_PERMISSIONS_ import static android.app.ActivityManagerInternal.ALLOW_FULL_ONLY; import static android.app.ActivityManagerInternal.ALLOW_NON_FULL; import static android.app.ActivityManagerInternal.ALLOW_NON_FULL_IN_PROFILE; +import static android.os.PowerWhitelistManager.REASON_BOOT_COMPLETED; +import static android.os.PowerWhitelistManager.REASON_LOCKED_BOOT_COMPLETED; +import static android.os.PowerWhitelistManager.TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED; import static android.os.Process.SHELL_UID; import static android.os.Process.SYSTEM_UID; @@ -74,6 +77,7 @@ import android.os.IRemoteCallback; import android.os.IUserManager; import android.os.Looper; import android.os.Message; +import android.os.PowerWhitelistManager; import android.os.Process; import android.os.RemoteCallbackList; import android.os.RemoteException; @@ -522,7 +526,8 @@ class UserController implements Handler.Callback { mInjector.broadcastIntent(intent, null, resultTo, 0, null, null, new String[]{android.Manifest.permission.RECEIVE_BOOT_COMPLETED}, AppOpsManager.OP_NONE, - getTemporaryAppWhitelistBroadcastOptions().toBundle(), true, + getTemporaryAppAllowlistBroadcastOptions(REASON_LOCKED_BOOT_COMPLETED) + .toBundle(), true, false, MY_PID, SYSTEM_UID, Binder.getCallingUid(), Binder.getCallingPid(), userId); } @@ -770,9 +775,8 @@ class UserController implements Handler.Callback { }, 0, null, null, new String[]{android.Manifest.permission.RECEIVE_BOOT_COMPLETED}, AppOpsManager.OP_NONE, - getTemporaryAppWhitelistBroadcastOptions().toBundle(), true, - false, MY_PID, SYSTEM_UID, - callingUid, callingPid, userId); + getTemporaryAppAllowlistBroadcastOptions(REASON_BOOT_COMPLETED).toBundle(), + true, false, MY_PID, SYSTEM_UID, callingUid, callingPid, userId); }); } @@ -2811,7 +2815,8 @@ class UserController implements Handler.Callback { } } - private BroadcastOptions getTemporaryAppWhitelistBroadcastOptions() { + private BroadcastOptions getTemporaryAppAllowlistBroadcastOptions( + @PowerWhitelistManager.ReasonCode int reasonCode) { long duration = 10_000; final ActivityManagerInternal amInternal = LocalServices.getService(ActivityManagerInternal.class); @@ -2819,9 +2824,8 @@ class UserController implements Handler.Callback { duration = amInternal.getBootTimeTempAllowListDuration(); } final BroadcastOptions bOptions = BroadcastOptions.makeBasic(); - bOptions.setTemporaryAppWhitelistDuration( - BroadcastOptions.TEMPORARY_WHITELIST_TYPE_FOREGROUND_SERVICE_ALLOWED, - duration); + bOptions.setTemporaryAppAllowlist(duration, + TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED, reasonCode, ""); return bOptions; } diff --git a/services/core/java/com/android/server/apphibernation/AppHibernationService.java b/services/core/java/com/android/server/apphibernation/AppHibernationService.java index 33bdac270c53..32ae87898085 100644 --- a/services/core/java/com/android/server/apphibernation/AppHibernationService.java +++ b/services/core/java/com/android/server/apphibernation/AppHibernationService.java @@ -57,10 +57,13 @@ import android.util.SparseArray; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.util.DumpUtils; +import com.android.internal.util.IndentingPrintWriter; import com.android.server.SystemService; import java.io.File; import java.io.FileDescriptor; +import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -511,6 +514,37 @@ public final class AppHibernationService extends SystemService { return mIsServiceEnabled; } + private void dump(PrintWriter pw) { + // Check usage stats permission since hibernation indirectly informs usage. + if (!DumpUtils.checkDumpAndUsageStatsPermission(getContext(), TAG, pw)) return; + + IndentingPrintWriter idpw = new IndentingPrintWriter(pw, " "); + + synchronized (mLock) { + final int userCount = mUserStates.size(); + for (int i = 0; i < userCount; i++) { + final int userId = mUserStates.keyAt(i); + idpw.print("User Level Hibernation States, "); + idpw.printPair("user", userId); + idpw.println(); + Map<String, UserLevelState> stateMap = mUserStates.get(i); + idpw.increaseIndent(); + for (UserLevelState state : stateMap.values()) { + idpw.print(state); + idpw.println(); + } + idpw.decreaseIndent(); + } + idpw.println(); + idpw.print("Global Level Hibernation States"); + idpw.println(); + for (GlobalLevelState state : mGlobalHibernationStates.values()) { + idpw.print(state); + idpw.println(); + } + } + } + private final AppHibernationServiceStub mServiceStub = new AppHibernationServiceStub(this); static final class AppHibernationServiceStub extends IAppHibernationService.Stub { @@ -547,6 +581,12 @@ public final class AppHibernationService extends SystemService { new AppHibernationShellCommand(mService).exec(this, in, out, err, args, callback, resultReceiver); } + + @Override + protected void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter fout, + @Nullable String[] args) { + mService.dump(fout); + } } // Broadcast receiver for package add/removal events diff --git a/services/core/java/com/android/server/apphibernation/GlobalLevelState.java b/services/core/java/com/android/server/apphibernation/GlobalLevelState.java index 4f756756c2ab..baa84b7070ff 100644 --- a/services/core/java/com/android/server/apphibernation/GlobalLevelState.java +++ b/services/core/java/com/android/server/apphibernation/GlobalLevelState.java @@ -22,4 +22,12 @@ package com.android.server.apphibernation; final class GlobalLevelState { public String packageName; public boolean hibernated; + + @Override + public String toString() { + return "GlobalLevelState{" + + "packageName='" + packageName + '\'' + + ", hibernated=" + hibernated + + '}'; + } } diff --git a/services/core/java/com/android/server/apphibernation/UserLevelState.java b/services/core/java/com/android/server/apphibernation/UserLevelState.java index c66dad87c891..272d3d1122a1 100644 --- a/services/core/java/com/android/server/apphibernation/UserLevelState.java +++ b/services/core/java/com/android/server/apphibernation/UserLevelState.java @@ -22,4 +22,12 @@ package com.android.server.apphibernation; final class UserLevelState { public String packageName; public boolean hibernated; + + @Override + public String toString() { + return "UserLevelState{" + + "packageName='" + packageName + '\'' + + ", hibernated=" + hibernated + + '}'; + } } diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index 8363c9d203d5..f5b94177a2d9 100644 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -6958,10 +6958,7 @@ public class AudioService extends IAudioService.Stub private void onSetVolumeIndexOnDevice(@NonNull DeviceVolumeUpdate update) { final VolumeStreamState streamState = mStreamStates[update.mStreamType]; if (update.hasVolumeIndex()) { - int index = update.getVolumeIndex(); - if (!checkSafeMediaVolume(update.mStreamType, index, update.mDevice)) { - index = safeMediaVolumeIndex(update.mDevice); - } + final int index = update.getVolumeIndex(); streamState.setIndex(index, update.mDevice, update.mCaller, // trusted as index is always validated before message is posted true /*hasModifyAudioSettings*/); diff --git a/services/core/java/com/android/server/clipboard/ClipboardService.java b/services/core/java/com/android/server/clipboard/ClipboardService.java index 322c210f6e5b..2de709ebe71d 100644 --- a/services/core/java/com/android/server/clipboard/ClipboardService.java +++ b/services/core/java/com/android/server/clipboard/ClipboardService.java @@ -246,8 +246,8 @@ public class ClipboardService extends SystemService { ClipData primaryClip; /** UID that set {@link #primaryClip}. */ int primaryClipUid = android.os.Process.NOBODY_UID; - /** Application label of the app that set {@link #primaryClip}. */ - CharSequence mPrimaryClipAppLabel; + /** Package of the app that set {@link #primaryClip}. */ + String mPrimaryClipPackage; final HashSet<String> activePermissionOwners = new HashSet<String>(); @@ -528,20 +528,9 @@ public class ClipboardService extends SystemService { } } - // Retrieve the app label of the source of the clip data - CharSequence sourceAppLabel = null; - if (clip != null && sourcePackage != null) { - try { - sourceAppLabel = - mPm.getApplicationLabel(mPm.getApplicationInfo(sourcePackage, 0)); - } catch (PackageManager.NameNotFoundException e) { - // leave label as null - } - } - // Update this user final int userId = UserHandle.getUserId(uid); - setPrimaryClipInternal(getClipboard(userId), clip, uid, sourceAppLabel); + setPrimaryClipInternal(getClipboard(userId), clip, uid, sourcePackage); // Update related users List<UserInfo> related = getRelatedProfiles(userId); @@ -576,7 +565,7 @@ public class ClipboardService extends SystemService { UserManager.DISALLOW_SHARE_INTO_MANAGED_PROFILE, id); if (canCopyIntoProfile) { setPrimaryClipInternal( - getClipboard(id), clip, uid, sourceAppLabel); + getClipboard(id), clip, uid, sourcePackage); } } } @@ -590,7 +579,7 @@ public class ClipboardService extends SystemService { } private void setPrimaryClipInternal(PerUserClipboard clipboard, @Nullable ClipData clip, - int uid, @Nullable CharSequence sourceAppLabel) { + int uid, @Nullable String sourcePackage) { revokeUris(clipboard); clipboard.activePermissionOwners.clear(); if (clip == null && clipboard.primaryClip == null) { @@ -599,10 +588,10 @@ public class ClipboardService extends SystemService { clipboard.primaryClip = clip; if (clip != null) { clipboard.primaryClipUid = uid; - clipboard.mPrimaryClipAppLabel = sourceAppLabel; + clipboard.mPrimaryClipPackage = sourcePackage; } else { clipboard.primaryClipUid = android.os.Process.NOBODY_UID; - clipboard.mPrimaryClipAppLabel = null; + clipboard.mPrimaryClipPackage = null; } if (clip != null) { final ClipDescription description = clip.getDescription(); @@ -887,12 +876,23 @@ public class ClipboardService extends SystemService { return; } + // Retrieve the app label of the source of the clip data + CharSequence sourceAppLabel = null; + if (clipboard.mPrimaryClipPackage != null) { + try { + sourceAppLabel = mPm.getApplicationLabel( + mPm.getApplicationInfo(clipboard.mPrimaryClipPackage, 0)); + } catch (PackageManager.NameNotFoundException e) { + // leave label as null + } + } + try { CharSequence callingAppLabel = mPm.getApplicationLabel( mPm.getApplicationInfo(callingPackage, 0)); String message; - if (clipboard.mPrimaryClipAppLabel != null) { - message = callingAppLabel + " pasted from " + clipboard.mPrimaryClipAppLabel; + if (sourceAppLabel != null) { + message = callingAppLabel + " pasted from " + sourceAppLabel; } else { message = callingAppLabel + " pasted from clipboard"; } diff --git a/services/core/java/com/android/server/compat/CompatConfig.java b/services/core/java/com/android/server/compat/CompatConfig.java index 422991e082a9..66a652053857 100644 --- a/services/core/java/com/android/server/compat/CompatConfig.java +++ b/services/core/java/com/android/server/compat/CompatConfig.java @@ -50,6 +50,7 @@ import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.PrintWriter; +import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -595,18 +596,24 @@ final class CompatConfig { * Rechecks all the existing overrides for a package. */ void recheckOverrides(String packageName) { + // Local cache of compat changes. Holding a lock on mChanges for the whole duration of the + // method will cause a deadlock. + List<CompatChange> changes; synchronized (mChanges) { - boolean shouldInvalidateCache = false; + changes = new ArrayList<>(mChanges.size()); for (int idx = 0; idx < mChanges.size(); ++idx) { - CompatChange c = mChanges.valueAt(idx); - OverrideAllowedState allowedState = - mOverrideValidator.getOverrideAllowedState(c.getId(), packageName); - shouldInvalidateCache |= c.recheckOverride(packageName, allowedState, mContext); - } - if (shouldInvalidateCache) { - invalidateCache(); + changes.add(mChanges.valueAt(idx)); } } + boolean shouldInvalidateCache = false; + for (CompatChange c: changes) { + OverrideAllowedState allowedState = + mOverrideValidator.getOverrideAllowedState(c.getId(), packageName); + shouldInvalidateCache |= c.recheckOverride(packageName, allowedState, mContext); + } + if (shouldInvalidateCache) { + invalidateCache(); + } } void registerContentObserver() { diff --git a/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java b/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java index 21ef356c962c..4ecc7594a79c 100644 --- a/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java +++ b/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java @@ -26,6 +26,7 @@ import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; import static android.net.NetworkPolicy.LIMIT_DISABLED; import static android.net.NetworkPolicy.WARNING_DISABLED; import static android.net.NetworkTemplate.NETWORK_TYPE_ALL; +import static android.net.NetworkTemplate.OEM_MANAGED_ALL; import static android.provider.Settings.Global.NETWORK_DEFAULT_DAILY_MULTIPATH_QUOTA_BYTES; import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID; @@ -226,7 +227,7 @@ public class MultipathPolicyTracker { mNetworkTemplate = new NetworkTemplate( NetworkTemplate.MATCH_MOBILE, subscriberId, new String[] { subscriberId }, null, NetworkStats.METERED_ALL, NetworkStats.ROAMING_ALL, - NetworkStats.DEFAULT_NETWORK_NO, NETWORK_TYPE_ALL); + NetworkStats.DEFAULT_NETWORK_NO, NETWORK_TYPE_ALL, OEM_MANAGED_ALL); mUsageCallback = new UsageCallback() { @Override public void onThresholdReached(int networkType, String subscriberId) { @@ -274,7 +275,8 @@ public class MultipathPolicyTracker { null /* networkId, unused for matching mobile networks */, !nc.hasCapability(NET_CAPABILITY_NOT_ROAMING), !nc.hasCapability(NET_CAPABILITY_NOT_METERED), - false /* defaultNetwork, templates should have DEFAULT_NETWORK_ALL */); + false /* defaultNetwork, templates should have DEFAULT_NETWORK_ALL */, + OEM_MANAGED_ALL); } private long getRemainingDailyBudget(long limitBytes, diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java index 86142bc1797d..011732682ace 100644 --- a/services/core/java/com/android/server/display/DisplayPowerController.java +++ b/services/core/java/com/android/server/display/DisplayPowerController.java @@ -858,8 +858,10 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call private void cleanupHandlerThreadAfterStop() { setProximitySensorEnabled(false); mHandler.removeCallbacksAndMessages(null); - mPowerState.stop(); - mPowerState = null; + if (mPowerState != null) { + mPowerState.stop(); + mPowerState = null; + } } private void updatePowerState() { diff --git a/services/core/java/com/android/server/hdmi/cec_key_handling.md b/services/core/java/com/android/server/hdmi/cec_key_handling.md index 1b41a6740869..69877bee0034 100644 --- a/services/core/java/com/android/server/hdmi/cec_key_handling.md +++ b/services/core/java/com/android/server/hdmi/cec_key_handling.md @@ -1,36 +1,37 @@ # CEC Key Handling -The mapping of CEC key codes to Android key codes are at -[HdmiCecKeycode](HdmiCecKeycode.java) +The mapping of CEC keycodes to Android keycodes is done at [HdmiCecKeycode](HdmiCecKeycode.java). # Android TV -Android TV requires special handling of some keys. +Android TV (ATV) requires special handling of some keys. -The general action for key handling is described in the table +The general action for key handling is described in the table below. | Android Key | TV Panel | OTT | Soundbar | | ----------- | ----------------- | ------------------- | ------------------- | -| general | Send to active source | handle on device | handle on device | | POWER | Toggle the device power state | Toggle the OTT power state, TV power state follows | Toggle the soundbar power state, TV power state follows| | TV_POWER | Toggle the device power state | Toggle the TV power state, OTT power state follows | Toggle the TV power state, soundbar power state follows| | HOME | Turn on TV, Set active Source to TV, go to home screen | OTP, and go to home screen | OTP, and go to home screen | -| volume keys | Handle on device or send to soundbar | Send to TV or soundbar | Handle on device or send to TV | +| Volume keys | Handle on device or send to soundbar | Send to TV or soundbar | Handle on device or send to TV | +| Other keys | Forward to active source | Handle on device | Handle on device | -Special cases and flags for each key are described below +Special cases and flags per key are described below. -## POWER +## TV_POWER ### TV Panel -TODO +For ATV TV panel devices, TV_POWER is an alias of POWER. -### OTT +### Source Devices (OTT and Soundbar) -TODO +For ATV source devices with POWER_CONTROL_MODE set to none or CEC control disabled, TV_POWER is an alias of POWER. -### Soundbar +For all other source devices, TV_POWER toggles the TV power state and makes the OTT power state follow. -TODO +### Other Devices + +For any device that is not connected to a TV via HDMI and not an ATV device, TV_POWER is ignored. diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java index 1e6658930840..0dc7445d5b4e 100644 --- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java +++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java @@ -3647,12 +3647,9 @@ public class InputMethodManagerService extends IInputMethodManager.Stub hideCurrentInputLocked(mCurFocusedWindow, 0, null, SoftInputShowHideReason.HIDE_SAME_WINDOW_FOCUSED_WITHOUT_EDITOR); } - res = startInputUncheckedLocked(cs, inputContext, missingMethods, attribute, - startInputFlags, startInputReason); - } else { - res = startInputUncheckedLocked(cs, inputContext, missingMethods, attribute, - startInputFlags, startInputReason); } + res = startInputUncheckedLocked(cs, inputContext, missingMethods, attribute, + startInputFlags, startInputReason); } else { res = InputBindResult.NULL_EDITOR_INFO; } @@ -5414,37 +5411,38 @@ public class InputMethodManagerService extends IInputMethodManager.Stub @BinderThread @ShellCommandResult private int onCommandWithSystemIdentity(@Nullable String cmd) { - if ("get-last-switch-user-id".equals(cmd)) { - return mService.getLastSwitchUserId(this); - } - - // For existing "adb shell ime <command>". - if ("ime".equals(cmd)) { - final String imeCommand = getNextArg(); - if (imeCommand == null || "help".equals(imeCommand) || "-h".equals(imeCommand)) { - onImeCommandHelp(); - return ShellCommandResult.SUCCESS; - } - switch (imeCommand) { - case "list": - return mService.handleShellCommandListInputMethods(this); - case "enable": - return mService.handleShellCommandEnableDisableInputMethod(this, true); - case "disable": - return mService.handleShellCommandEnableDisableInputMethod(this, false); - case "set": - return mService.handleShellCommandSetInputMethod(this); - case "reset": - return mService.handleShellCommandResetInputMethod(this); - case "tracing": - return mService.handleShellCommandTraceInputMethod(this); - default: - getOutPrintWriter().println("Unknown command: " + imeCommand); - return ShellCommandResult.FAILURE; + switch (TextUtils.emptyIfNull(cmd)) { + case "get-last-switch-user-id": + return mService.getLastSwitchUserId(this); + case "tracing": + return mService.handleShellCommandTraceInputMethod(this); + case "ime": { // For "adb shell ime <command>". + final String imeCommand = TextUtils.emptyIfNull(getNextArg()); + switch (imeCommand) { + case "": + case "-h": + case "help": + return onImeCommandHelp(); + case "list": + return mService.handleShellCommandListInputMethods(this); + case "enable": + return mService.handleShellCommandEnableDisableInputMethod(this, true); + case "disable": + return mService.handleShellCommandEnableDisableInputMethod(this, false); + case "set": + return mService.handleShellCommandSetInputMethod(this); + case "reset": + return mService.handleShellCommandResetInputMethod(this); + case "tracing": // TODO(b/180765389): Unsupport "adb shell ime tracing" + return mService.handleShellCommandTraceInputMethod(this); + default: + getOutPrintWriter().println("Unknown command: " + imeCommand); + return ShellCommandResult.FAILURE; + } } + default: + return handleDefaultCommands(cmd); } - - return handleDefaultCommands(cmd); } @BinderThread @@ -5458,10 +5456,16 @@ public class InputMethodManagerService extends IInputMethodManager.Stub pw.println(" Synonym of dumpsys."); pw.println(" ime <command> [options]"); pw.println(" Manipulate IMEs. Run \"ime help\" for details."); + pw.println(" tracing <command>"); + pw.println(" start: Start tracing."); + pw.println(" stop : Stop tracing."); + pw.println(" help : Show help."); } } - private void onImeCommandHelp() { + @BinderThread + @ShellCommandResult + private int onImeCommandHelp() { try (IndentingPrintWriter pw = new IndentingPrintWriter(getOutPrintWriter(), " ", 100)) { pw.println("ime <command>:"); @@ -5516,6 +5520,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub pw.decreaseIndent(); } + return ShellCommandResult.SUCCESS; } } diff --git a/services/core/java/com/android/server/location/LocationManagerService.java b/services/core/java/com/android/server/location/LocationManagerService.java index 57e9fc9cb719..2920ddb2d76d 100644 --- a/services/core/java/com/android/server/location/LocationManagerService.java +++ b/services/core/java/com/android/server/location/LocationManagerService.java @@ -52,6 +52,7 @@ import android.location.GnssCapabilities; import android.location.GnssMeasurementCorrections; import android.location.GnssMeasurementRequest; import android.location.IGeocodeListener; +import android.location.IGnssAntennaInfoListener; import android.location.IGnssMeasurementsListener; import android.location.IGnssNavigationMessageListener; import android.location.IGnssNmeaListener; @@ -463,7 +464,7 @@ public class LocationManagerService extends ILocationManager.Stub { .build(); final LocationProviderManager manager = getOrAddLocationProviderManager(name); manager.setMockProvider(new MockLocationProvider(properties, - CallerIdentity.fromContext(mContext), /*locationTags*/ null)); + CallerIdentity.fromContext(mContext), Collections.emptySet())); } } @@ -930,6 +931,22 @@ public class LocationManagerService extends ILocationManager.Stub { } @Override + public void addGnssAntennaInfoListener(IGnssAntennaInfoListener listener, String packageName, + @Nullable String attributionTag, String listenerId) { + if (mGnssManagerService != null) { + mGnssManagerService.addGnssAntennaInfoListener(listener, packageName, attributionTag, + listenerId); + } + } + + @Override + public void removeGnssAntennaInfoListener(IGnssAntennaInfoListener listener) { + if (mGnssManagerService != null) { + mGnssManagerService.removeGnssAntennaInfoListener(listener); + } + } + + @Override public void addProviderRequestListener(IProviderRequestListener listener) { for (LocationProviderManager manager : mProviderManagers) { manager.addProviderRequestListener(listener); @@ -1153,7 +1170,7 @@ public class LocationManagerService extends ILocationManager.Stub { @Override public void addTestProvider(String provider, ProviderProperties properties, - List<String> locationTags, String packageName, String attributionTag) { + List<String> extraAttributionTags, String packageName, String attributionTag) { // unsafe is ok because app ops will verify the package name CallerIdentity identity = CallerIdentity.fromBinderUnsafe(packageName, attributionTag); if (!mInjector.getAppOpsHelper().noteOp(AppOpsManager.OP_MOCK_LOCATION, identity)) { @@ -1162,7 +1179,7 @@ public class LocationManagerService extends ILocationManager.Stub { final LocationProviderManager manager = getOrAddLocationProviderManager(provider); manager.setMockProvider(new MockLocationProvider(properties, identity, - (locationTags != null) ? new ArraySet<>(locationTags) : null)); + new ArraySet<>(extraAttributionTags))); } @Override diff --git a/services/core/java/com/android/server/location/LocationShellCommand.java b/services/core/java/com/android/server/location/LocationShellCommand.java index 21a9b0442b74..5dc3ed8c47bd 100644 --- a/services/core/java/com/android/server/location/LocationShellCommand.java +++ b/services/core/java/com/android/server/location/LocationShellCommand.java @@ -26,6 +26,8 @@ import com.android.modules.utils.BasicShellCommandHandler; import java.io.PrintWriter; import java.util.Arrays; +import java.util.Collections; +import java.util.List; import java.util.Objects; /** @@ -50,15 +52,11 @@ class LocationShellCommand extends BasicShellCommandHandler { switch (cmd) { case "is-location-enabled": { - int userId = parseUserId(); - boolean enabled = mService.isLocationEnabledForUser(userId); - getOutPrintWriter().println(enabled); + handleIsLocationEnabled(); return 0; } case "set-location-enabled": { - int userId = parseUserId(); - boolean enabled = Boolean.parseBoolean(getNextArgRequired()); - mService.setLocationEnabledForUser(enabled, userId); + handleSetLocationEnabled(); return 0; } case "providers": { @@ -73,36 +71,23 @@ class LocationShellCommand extends BasicShellCommandHandler { private int parseProvidersCommand(String cmd) { switch (cmd) { case "add-test-provider": { - String provider = getNextArgRequired(); - ProviderProperties properties = parseTestProviderProviderProperties(); - mService.addTestProvider(provider, properties, /*locationTags*/ null, - mContext.getOpPackageName(), mContext.getFeatureId()); + handleAddTestProvider(); return 0; } case "remove-test-provider": { - String provider = getNextArgRequired(); - mService.removeTestProvider(provider, mContext.getOpPackageName(), - mContext.getFeatureId()); + handleRemoveTestProvider(); return 0; } case "set-test-provider-enabled": { - String provider = getNextArgRequired(); - boolean enabled = Boolean.parseBoolean(getNextArgRequired()); - mService.setTestProviderEnabled(provider, enabled, mContext.getOpPackageName(), - mContext.getFeatureId()); + handleSetTestProviderEnabled(); return 0; } case "set-test-provider-location": { - String provider = getNextArgRequired(); - Location location = parseTestProviderLocation(provider); - mService.setTestProviderLocation(provider, location, mContext.getOpPackageName(), - mContext.getFeatureId()); + handleSetTestProviderLocation(); return 0; } case "send-extra-command": { - String provider = getNextArgRequired(); - String command = getNextArgRequired(); - mService.sendExtraCommand(provider, command, null); + handleSendExtraCommand(); return 0; } default: @@ -110,21 +95,47 @@ class LocationShellCommand extends BasicShellCommandHandler { } } - private int parseUserId() { - final String option = getNextOption(); - if (option != null) { - if (option.equals("--user")) { - return UserHandle.parseUserArg(getNextArgRequired()); + private void handleIsLocationEnabled() { + int userId = UserHandle.USER_CURRENT_OR_SELF; + + do { + String option = getNextOption(); + if (option == null) { + break; + } + if ("--user".equals(option)) { + userId = UserHandle.parseUserArg(getNextArgRequired()); } else { - throw new IllegalArgumentException( - "Expected \"--user\" option, but got \"" + option + "\" instead"); + throw new IllegalArgumentException("Unknown option: " + option); } - } + } while (true); - return UserHandle.USER_CURRENT_OR_SELF; + getOutPrintWriter().println(mService.isLocationEnabledForUser(userId)); } - private ProviderProperties parseTestProviderProviderProperties() { + private void handleSetLocationEnabled() { + boolean enabled = Boolean.parseBoolean(getNextArgRequired()); + + int userId = UserHandle.USER_CURRENT_OR_SELF; + + do { + String option = getNextOption(); + if (option == null) { + break; + } + if ("--user".equals(option)) { + userId = UserHandle.parseUserArg(getNextArgRequired()); + } else { + throw new IllegalArgumentException("Unknown option: " + option); + } + } while (true); + + mService.setLocationEnabledForUser(enabled, userId); + } + + private void handleAddTestProvider() { + String provider = getNextArgRequired(); + boolean requiresNetwork = false; boolean requiresSatellite = false; boolean requiresCell = false; @@ -135,8 +146,13 @@ class LocationShellCommand extends BasicShellCommandHandler { int powerRequirement = Criteria.POWER_LOW; int accuracy = Criteria.ACCURACY_FINE; - String option = getNextOption(); - while (option != null) { + List<String> extraAttributionTags = Collections.emptyList(); + + do { + String option = getNextOption(); + if (option == null) { + break; + } switch (option) { case "--requiresNetwork": { requiresNetwork = true; @@ -174,12 +190,15 @@ class LocationShellCommand extends BasicShellCommandHandler { accuracy = Integer.parseInt(getNextArgRequired()); break; } + case "--extraAttributionTags": { + extraAttributionTags = Arrays.asList(getNextArgRequired().split(",")); + break; + } default: throw new IllegalArgumentException( "Received unexpected option: " + option); } - option = getNextOption(); - } + } while(true); ProviderProperties properties = new ProviderProperties.Builder() .setHasNetworkRequirement(requiresNetwork) @@ -192,30 +211,50 @@ class LocationShellCommand extends BasicShellCommandHandler { .setPowerUsage(powerRequirement) .setAccuracy(accuracy) .build(); + mService.addTestProvider(provider, properties, extraAttributionTags, + mContext.getOpPackageName(), mContext.getAttributionTag()); + } - return properties; + private void handleRemoveTestProvider() { + String provider = getNextArgRequired(); + mService.removeTestProvider(provider, mContext.getOpPackageName(), + mContext.getAttributionTag()); } - private Location parseTestProviderLocation(String provider) { - boolean hasLatitude = false; - boolean hasLongitude = false; + private void handleSetTestProviderEnabled() { + String provider = getNextArgRequired(); + boolean enabled = Boolean.parseBoolean(getNextArgRequired()); + mService.setTestProviderEnabled(provider, enabled, mContext.getOpPackageName(), + mContext.getAttributionTag()); + } + + private void handleSetTestProviderLocation() { + String provider = getNextArgRequired(); + + boolean hasLatLng = false; Location location = new Location(provider); location.setAccuracy(DEFAULT_TEST_LOCATION_ACCURACY); location.setTime(System.currentTimeMillis()); + location.setElapsedRealtimeNanos(System.nanoTime()); - String option = getNextOption(); - while (option != null) { + do { + String option = getNextOption(); + if (option == null) { + break; + } switch (option) { case "--location": { String[] locationInput = getNextArgRequired().split(","); if (locationInput.length != 2) { - throw new IllegalArgumentException( - "Unexpected location format: " + Arrays.toString(locationInput)); + throw new IllegalArgumentException("Location argument must be in the form " + + "of \"<LATITUDE>,<LONGITUDE>\", not " + + Arrays.toString(locationInput)); } location.setLatitude(Double.parseDouble(locationInput[0])); location.setLongitude(Double.parseDouble(locationInput[1])); + hasLatLng = true; break; } case "--accuracy": { @@ -227,15 +266,22 @@ class LocationShellCommand extends BasicShellCommandHandler { break; } default: - throw new IllegalArgumentException( - "Received unexpected option: " + option); + throw new IllegalArgumentException("Unknown option: " + option); } - option = getNextOption(); + } while (true); + + if (!hasLatLng) { + throw new IllegalArgumentException("Option \"--location\" is required"); } - location.setElapsedRealtimeNanos(System.nanoTime()); + mService.setTestProviderLocation(provider, location, mContext.getOpPackageName(), + mContext.getAttributionTag()); + } - return location; + private void handleSendExtraCommand() { + String provider = getNextArgRequired(); + String command = getNextArgRequired(); + mService.sendExtraCommand(provider, command, null); } @Override @@ -245,24 +291,29 @@ class LocationShellCommand extends BasicShellCommandHandler { pw.println(" help or -h"); pw.println(" Print this help text."); pw.println(" is-location-enabled [--user <USER_ID>]"); - pw.println(" Gets the master location switch enabled state."); - pw.println(" set-location-enabled [--user <USER_ID>] true|false"); - pw.println(" Sets the master location switch enabled state."); + pw.println(" Gets the master location switch enabled state. If no user is specified,"); + pw.println(" the current user is assumed."); + pw.println(" set-location-enabled true|false [--user <USER_ID>]"); + pw.println(" Sets the master location switch enabled state. If no user is specified,"); + pw.println(" the current user is assumed."); pw.println(" providers"); + pw.println(" The providers command is followed by a subcommand, as listed below:"); + pw.println(); pw.println(" add-test-provider <PROVIDER> [--requiresNetwork] [--requiresSatellite]"); pw.println(" [--requiresCell] [--hasMonetaryCost] [--supportsAltitude]"); pw.println(" [--supportsSpeed] [--supportsBearing]"); pw.println(" [--powerRequirement <POWER_REQUIREMENT>]"); + pw.println(" [--extraAttributionTags <TAG>,<TAG>,...]"); pw.println(" Add the given test provider. Requires MOCK_LOCATION permissions which"); pw.println(" can be enabled by running \"adb shell appops set <uid>"); pw.println(" android:mock_location allow\". There are optional flags that can be"); - pw.println(" used to configure the provider properties. If no flags are included,"); - pw.println(" then default values will be used."); + pw.println(" used to configure the provider properties and additional arguments. If"); + pw.println(" no flags are included, then default values will be used."); pw.println(" remove-test-provider <PROVIDER>"); pw.println(" Remove the given test provider."); pw.println(" set-test-provider-enabled <PROVIDER> true|false"); pw.println(" Sets the given test provider enabled state."); - pw.println(" set-test-provider-location <PROVIDER> [--location <LATITUDE>,<LONGITUDE>]"); + pw.println(" set-test-provider-location <PROVIDER> --location <LATITUDE>,<LONGITUDE>"); pw.println(" [--accuracy <ACCURACY>] [--time <TIME>]"); pw.println(" Set location for given test provider. Accuracy and time are optional."); pw.println(" send-extra-command <PROVIDER> <COMMAND>"); diff --git a/services/core/java/com/android/server/location/gnss/GnssAntennaInfoProvider.java b/services/core/java/com/android/server/location/gnss/GnssAntennaInfoProvider.java new file mode 100644 index 000000000000..1967e026e46c --- /dev/null +++ b/services/core/java/com/android/server/location/gnss/GnssAntennaInfoProvider.java @@ -0,0 +1,144 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.location.gnss; + +import static com.android.server.location.gnss.GnssManagerService.TAG; + +import android.annotation.Nullable; +import android.location.GnssAntennaInfo; +import android.location.IGnssAntennaInfoListener; +import android.location.util.identity.CallerIdentity; +import android.os.Binder; +import android.os.IBinder; + +import com.android.server.location.gnss.hal.GnssNative; +import com.android.server.location.listeners.BinderListenerRegistration; +import com.android.server.location.listeners.ListenerMultiplexer; +import com.android.server.location.listeners.ListenerRegistration; + +import java.util.Collection; +import java.util.List; + +/** + * Antenna info HAL module and listener multiplexer. + */ +public class GnssAntennaInfoProvider extends + ListenerMultiplexer<IBinder, IGnssAntennaInfoListener, + ListenerRegistration<IGnssAntennaInfoListener>, Void> implements + GnssNative.BaseCallbacks, GnssNative.AntennaInfoCallbacks { + + /** + * Registration object for GNSS listeners. + */ + protected class AntennaInfoListenerRegistration extends + BinderListenerRegistration<Void, IGnssAntennaInfoListener> { + + protected AntennaInfoListenerRegistration(CallerIdentity callerIdentity, + IGnssAntennaInfoListener listener) { + super(null, callerIdentity, listener); + } + + @Override + protected GnssAntennaInfoProvider getOwner() { + return GnssAntennaInfoProvider.this; + } + } + + private final GnssNative mGnssNative; + + private volatile @Nullable List<GnssAntennaInfo> mAntennaInfos; + + GnssAntennaInfoProvider(GnssNative gnssNative) { + mGnssNative = gnssNative; + mGnssNative.addBaseCallbacks(this); + mGnssNative.addAntennaInfoCallbacks(this); + } + + @Nullable List<GnssAntennaInfo> getAntennaInfos() { + return mAntennaInfos; + } + + @Override + public String getTag() { + return TAG; + } + + public boolean isSupported() { + return mGnssNative.isAntennaInfoSupported(); + } + + public void addListener(CallerIdentity callerIdentity, IGnssAntennaInfoListener listener) { + long identity = Binder.clearCallingIdentity(); + try { + putRegistration(listener.asBinder(), + new AntennaInfoListenerRegistration(callerIdentity, listener)); + } finally { + Binder.restoreCallingIdentity(identity); + } + } + + public void removeListener(IGnssAntennaInfoListener listener) { + long identity = Binder.clearCallingIdentity(); + try { + removeRegistration(listener.asBinder()); + } finally { + Binder.restoreCallingIdentity(identity); + } + } + + @Override + protected boolean registerWithService(Void merged, + Collection<ListenerRegistration<IGnssAntennaInfoListener>> listenerRegistrations) { + return true; + } + + @Override + protected void unregisterWithService() {} + + @Override + protected boolean isActive(ListenerRegistration<IGnssAntennaInfoListener> registration) { + return true; + } + + @Override + protected Void mergeRegistrations( + Collection<ListenerRegistration<IGnssAntennaInfoListener>> listenerRegistrations) { + return null; + } + + @Override + public void onHalStarted() { + mGnssNative.startAntennaInfoListening(); + } + + @Override + public void onHalRestarted() { + mGnssNative.startAntennaInfoListening(); + } + + @Override + public void onReportAntennaInfo(List<GnssAntennaInfo> antennaInfos) { + if (antennaInfos.equals(mAntennaInfos)) { + return; + } + + mAntennaInfos = antennaInfos; + deliverToListeners(listener -> { + listener.onGnssAntennaInfoChanged(antennaInfos); + }); + } +} diff --git a/services/core/java/com/android/server/location/gnss/GnssListenerMultiplexer.java b/services/core/java/com/android/server/location/gnss/GnssListenerMultiplexer.java index 87e6ef4110ee..5e6ae68c02f2 100644 --- a/services/core/java/com/android/server/location/gnss/GnssListenerMultiplexer.java +++ b/services/core/java/com/android/server/location/gnss/GnssListenerMultiplexer.java @@ -229,7 +229,7 @@ public abstract class GnssListenerMultiplexer<TRequest, TListener extends IInter * registrations will be treated as inactive and the backing service will never be registered. * */ - protected boolean isServiceSupported() { + public boolean isSupported() { return true; } @@ -276,7 +276,7 @@ public abstract class GnssListenerMultiplexer<TRequest, TListener extends IInter @Override protected boolean isActive(GnssListenerRegistration registration) { - if (!isServiceSupported()) { + if (!isSupported()) { return false; } @@ -339,7 +339,7 @@ public abstract class GnssListenerMultiplexer<TRequest, TListener extends IInter @Override protected void onRegister() { - if (!isServiceSupported()) { + if (!isSupported()) { return; } @@ -356,7 +356,7 @@ public abstract class GnssListenerMultiplexer<TRequest, TListener extends IInter @Override protected void onUnregister() { - if (!isServiceSupported()) { + if (!isSupported()) { return; } @@ -404,7 +404,7 @@ public abstract class GnssListenerMultiplexer<TRequest, TListener extends IInter @Override protected String getServiceState() { - if (!isServiceSupported()) { + if (!isSupported()) { return "unsupported"; } else { return super.getServiceState(); diff --git a/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java b/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java index 29da177ee4a1..1df29ab5791f 100644 --- a/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java +++ b/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java @@ -103,6 +103,7 @@ import com.android.server.location.provider.AbstractLocationProvider; import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; +import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Objects; @@ -372,7 +373,7 @@ public class GnssLocationProvider extends AbstractLocationProvider implements public GnssLocationProvider(Context context, Injector injector, GnssNative gnssNative, GnssMetrics gnssMetrics) { super(FgThread.getExecutor(), CallerIdentity.fromContext(context), PROPERTIES, - /*locationTags*/ null); + Collections.emptySet()); mContext = context; mGnssNative = gnssNative; diff --git a/services/core/java/com/android/server/location/gnss/GnssManagerService.java b/services/core/java/com/android/server/location/gnss/GnssManagerService.java index 8312c6361835..bcdfed45bd9c 100644 --- a/services/core/java/com/android/server/location/gnss/GnssManagerService.java +++ b/services/core/java/com/android/server/location/gnss/GnssManagerService.java @@ -27,6 +27,7 @@ import android.location.GnssAntennaInfo; import android.location.GnssCapabilities; import android.location.GnssMeasurementCorrections; import android.location.GnssMeasurementRequest; +import android.location.IGnssAntennaInfoListener; import android.location.IGnssMeasurementsListener; import android.location.IGnssNavigationMessageListener; import android.location.IGnssNmeaListener; @@ -49,7 +50,6 @@ import com.android.server.location.gnss.hal.GnssNative; import com.android.server.location.injector.Injector; import java.io.FileDescriptor; -import java.util.ArrayList; import java.util.List; /** Manages Gnss providers and related Gnss functions for LocationManagerService. */ @@ -68,11 +68,11 @@ public class GnssManagerService { private final GnssNmeaProvider mGnssNmeaProvider; private final GnssMeasurementsProvider mGnssMeasurementsProvider; private final GnssNavigationMessageProvider mGnssNavigationMessageProvider; + private final GnssAntennaInfoProvider mGnssAntennaInfoProvider; private final IGpsGeofenceHardware mGnssGeofenceProxy; private final GnssGeofenceHalModule mGeofenceHalModule; private final GnssCapabilitiesHalModule mCapabilitiesHalModule; - private final GnssAntennaInfoHalModule mAntennaInfoHalModule; private final GnssMetrics mGnssMetrics; @@ -89,11 +89,11 @@ public class GnssManagerService { mGnssNmeaProvider = new GnssNmeaProvider(injector, mGnssNative); mGnssMeasurementsProvider = new GnssMeasurementsProvider(injector, mGnssNative); mGnssNavigationMessageProvider = new GnssNavigationMessageProvider(injector, mGnssNative); + mGnssAntennaInfoProvider = new GnssAntennaInfoProvider(mGnssNative); mGnssGeofenceProxy = new GnssGeofenceProxy(mGnssNative); mGeofenceHalModule = new GnssGeofenceHalModule(mGnssNative); mCapabilitiesHalModule = new GnssCapabilitiesHalModule(mGnssNative); - mAntennaInfoHalModule = new GnssAntennaInfoHalModule(mGnssNative); // allow gnss access to begin - we must assume that callbacks can start immediately mGnssNative.register(); @@ -140,7 +140,7 @@ public class GnssManagerService { * Get GNSS antenna information. */ public @Nullable List<GnssAntennaInfo> getGnssAntennaInfos() { - return mAntennaInfoHalModule.getAntennaInfos(); + return mGnssAntennaInfoProvider.getAntennaInfos(); } /** @@ -242,6 +242,24 @@ public class GnssManagerService { } /** + * Adds a GNSS antenna info listener. + */ + public void addGnssAntennaInfoListener(IGnssAntennaInfoListener listener, String packageName, + @Nullable String attributionTag, String listenerId) { + + CallerIdentity identity = CallerIdentity.fromBinder(mContext, packageName, attributionTag, + listenerId); + mGnssAntennaInfoProvider.addListener(identity, listener); + } + + /** + * Removes a GNSS antenna info listener. + */ + public void removeGnssAntennaInfoListener(IGnssAntennaInfoListener listener) { + mGnssAntennaInfoProvider.removeListener(listener); + } + + /** * Send Ni Response, indicating a location request initiated by a network carrier. */ public void sendNiResponse(int notifId, int userResponse) { @@ -263,25 +281,34 @@ public class GnssManagerService { ipw.println("Capabilities: " + mGnssNative.getCapabilities()); - List<GnssAntennaInfo> infos = mAntennaInfoHalModule.getAntennaInfos(); - if (infos != null) { - ipw.println("Antenna Infos: " + infos); + if (mGnssStatusProvider.isSupported()) { + ipw.println("Status Provider:"); + ipw.increaseIndent(); + mGnssStatusProvider.dump(fd, ipw, args); + ipw.decreaseIndent(); } - ipw.println("Measurements Provider:"); - ipw.increaseIndent(); - mGnssMeasurementsProvider.dump(fd, ipw, args); - ipw.decreaseIndent(); + if (mGnssMeasurementsProvider.isSupported()) { + ipw.println("Measurements Provider:"); + ipw.increaseIndent(); + mGnssMeasurementsProvider.dump(fd, ipw, args); + ipw.decreaseIndent(); + } - ipw.println("Navigation Message Provider:"); - ipw.increaseIndent(); - mGnssNavigationMessageProvider.dump(fd, ipw, args); - ipw.decreaseIndent(); + if (mGnssNavigationMessageProvider.isSupported()) { + ipw.println("Navigation Message Provider:"); + ipw.increaseIndent(); + mGnssNavigationMessageProvider.dump(fd, ipw, args); + ipw.decreaseIndent(); + } - ipw.println("Status Provider:"); - ipw.increaseIndent(); - mGnssStatusProvider.dump(fd, ipw, args); - ipw.decreaseIndent(); + if (mGnssAntennaInfoProvider.isSupported()) { + ipw.println("Navigation Message Provider:"); + ipw.increaseIndent(); + ipw.println("Antenna Infos: " + mGnssAntennaInfoProvider.getAntennaInfos()); + mGnssAntennaInfoProvider.dump(fd, ipw, args); + ipw.decreaseIndent(); + } GnssPowerStats powerStats = mGnssNative.getPowerStats(); if (powerStats != null) { @@ -399,53 +426,4 @@ public class GnssManagerService { } } } - - private class GnssAntennaInfoHalModule implements GnssNative.BaseCallbacks, - GnssNative.AntennaInfoCallbacks { - - private final GnssNative mGnssNative; - - private volatile @Nullable List<GnssAntennaInfo> mAntennaInfos; - - GnssAntennaInfoHalModule(GnssNative gnssNative) { - mGnssNative = gnssNative; - mGnssNative.addBaseCallbacks(this); - mGnssNative.addAntennaInfoCallbacks(this); - } - - @Nullable List<GnssAntennaInfo> getAntennaInfos() { - return mAntennaInfos; - } - - @Override - public void onHalStarted() { - mGnssNative.startAntennaInfoListening(); - } - - @Override - public void onHalRestarted() { - mGnssNative.startAntennaInfoListening(); - } - - @Override - public void onReportAntennaInfo(List<GnssAntennaInfo> antennaInfos) { - if (antennaInfos.equals(mAntennaInfos)) { - return; - } - - mAntennaInfos = antennaInfos; - - long ident = Binder.clearCallingIdentity(); - try { - Intent intent = new Intent(LocationManager.ACTION_GNSS_ANTENNA_INFOS_CHANGED) - .putParcelableArrayListExtra(LocationManager.EXTRA_GNSS_ANTENNA_INFOS, - new ArrayList<>(antennaInfos)) - .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY) - .addFlags(Intent.FLAG_RECEIVER_FOREGROUND); - mContext.sendBroadcastAsUser(intent, UserHandle.ALL); - } finally { - Binder.restoreCallingIdentity(ident); - } - } - } } diff --git a/services/core/java/com/android/server/location/gnss/GnssMeasurementsProvider.java b/services/core/java/com/android/server/location/gnss/GnssMeasurementsProvider.java index 305bc9b69e39..b3119d7aa53e 100644 --- a/services/core/java/com/android/server/location/gnss/GnssMeasurementsProvider.java +++ b/services/core/java/com/android/server/location/gnss/GnssMeasurementsProvider.java @@ -99,7 +99,7 @@ public final class GnssMeasurementsProvider extends } @Override - protected boolean isServiceSupported() { + public boolean isSupported() { return mGnssNative.isMeasurementSupported(); } diff --git a/services/core/java/com/android/server/location/gnss/GnssNavigationMessageProvider.java b/services/core/java/com/android/server/location/gnss/GnssNavigationMessageProvider.java index ff9ad65b4ca5..e9fce0514a18 100644 --- a/services/core/java/com/android/server/location/gnss/GnssNavigationMessageProvider.java +++ b/services/core/java/com/android/server/location/gnss/GnssNavigationMessageProvider.java @@ -70,7 +70,7 @@ public class GnssNavigationMessageProvider extends } @Override - protected boolean isServiceSupported() { + public boolean isSupported() { return mGnssNative.isNavigationMessageCollectionSupported(); } diff --git a/services/core/java/com/android/server/location/gnss/hal/GnssNative.java b/services/core/java/com/android/server/location/gnss/hal/GnssNative.java index 7e2f089d32c9..f275663a1309 100644 --- a/services/core/java/com/android/server/location/gnss/hal/GnssNative.java +++ b/services/core/java/com/android/server/location/gnss/hal/GnssNative.java @@ -699,11 +699,11 @@ public class GnssNative { } /** - * Returns true if antenna info listening is supported. + * Returns true if antenna info is supported. */ - public boolean isAntennaInfoListeningSupported() { + public boolean isAntennaInfoSupported() { Preconditions.checkState(mRegistered); - return mGnssHal.isAntennaInfoListeningSupported(); + return mGnssHal.isAntennaInfoSupported(); } /** @@ -1259,7 +1259,7 @@ public class GnssNative { return native_stop_navigation_message_collection(); } - protected boolean isAntennaInfoListeningSupported() { + protected boolean isAntennaInfoSupported() { return native_is_antenna_info_supported(); } diff --git a/services/core/java/com/android/server/location/provider/AbstractLocationProvider.java b/services/core/java/com/android/server/location/provider/AbstractLocationProvider.java index 9ff6e6bc8e32..ba7f44f2818b 100644 --- a/services/core/java/com/android/server/location/provider/AbstractLocationProvider.java +++ b/services/core/java/com/android/server/location/provider/AbstractLocationProvider.java @@ -28,6 +28,7 @@ import com.android.internal.util.Preconditions; import java.io.FileDescriptor; import java.io.PrintWriter; +import java.util.Collections; import java.util.Objects; import java.util.Set; import java.util.concurrent.Executor; @@ -66,9 +67,10 @@ public abstract class AbstractLocationProvider { /** * Default state value for a location provider that is disabled with no properties and an - * empty provider package list. + * empty extra attribution tag set. */ - public static final State EMPTY_STATE = new State(false, null, null, null); + public static final State EMPTY_STATE = new State(false, null, null, + Collections.emptySet()); /** * The provider's allowed state. @@ -85,14 +87,18 @@ public abstract class AbstractLocationProvider { */ @Nullable public final CallerIdentity identity; - @Nullable public final Set<String> locationTags; + /** + * A set of attribution tags also associated with this provider - these attribution tags may + * be afforded special privileges. + */ + public final Set<String> extraAttributionTags; private State(boolean allowed, ProviderProperties properties, CallerIdentity identity, - Set<String> locationTags) { + Set<String> extraAttributionTags) { this.allowed = allowed; this.properties = properties; this.identity = identity; - this.locationTags = locationTags; + this.extraAttributionTags = Objects.requireNonNull(extraAttributionTags); } /** @@ -102,7 +108,7 @@ public abstract class AbstractLocationProvider { if (allowed == this.allowed) { return this; } else { - return new State(allowed, properties, identity, locationTags); + return new State(allowed, properties, identity, extraAttributionTags); } } @@ -113,7 +119,7 @@ public abstract class AbstractLocationProvider { if (Objects.equals(properties, this.properties)) { return this; } else { - return new State(allowed, properties, identity, locationTags); + return new State(allowed, properties, identity, extraAttributionTags); } } @@ -124,18 +130,18 @@ public abstract class AbstractLocationProvider { if (Objects.equals(identity, this.identity)) { return this; } else { - return new State(allowed, properties, identity, locationTags); + return new State(allowed, properties, identity, extraAttributionTags); } } /** - * Returns a state the same as the current but with location tags set as specified. + * Returns a state the same as the current but with extra attribution tags set as specified. */ - public State withLocationTags(@Nullable Set<String> locationTags) { - if (Objects.equals(locationTags, this.locationTags)) { + public State withExtraAttributionTags(Set<String> extraAttributionTags) { + if (extraAttributionTags.equals(this.extraAttributionTags)) { return this; } else { - return new State(allowed, properties, identity, locationTags); + return new State(allowed, properties, identity, extraAttributionTags); } } @@ -151,12 +157,12 @@ public abstract class AbstractLocationProvider { State state = (State) o; return allowed == state.allowed && properties == state.properties && Objects.equals(identity, state.identity) - && Objects.equals(locationTags, state.locationTags); + && extraAttributionTags.equals(state.extraAttributionTags); } @Override public int hashCode() { - return Objects.hash(allowed, properties, identity, locationTags); + return Objects.hash(allowed, properties, identity, extraAttributionTags); } } @@ -213,14 +219,14 @@ public abstract class AbstractLocationProvider { * An optional identity and properties may be provided to initialize the location provider. */ protected AbstractLocationProvider(Executor executor, @Nullable CallerIdentity identity, - @Nullable ProviderProperties properties, @Nullable Set<String> locationTags) { + @Nullable ProviderProperties properties, Set<String> extraAttributionTags) { Preconditions.checkArgument(identity == null || identity.getListenerId() == null); - mExecutor = executor; + mExecutor = Objects.requireNonNull(executor); mInternalState = new AtomicReference<>(new InternalState(null, State.EMPTY_STATE .withIdentity(identity) - .withProperties(properties).withLocationTags(locationTags)) - ); + .withProperties(properties) + .withExtraAttributionTags(extraAttributionTags))); mController = new Controller(); } @@ -292,7 +298,7 @@ public abstract class AbstractLocationProvider { } /** - * Call this method to report a change in provider packages. + * Call this method to report a change in the provider's identity. */ protected void setIdentity(@Nullable CallerIdentity identity) { Preconditions.checkArgument(identity == null || identity.getListenerId() == null); @@ -300,10 +306,10 @@ public abstract class AbstractLocationProvider { } /** - * Call this method to report a change in provider location tags. + * Call this method to report a change in the provider's extra attribution tags. */ - protected void setLocationTags(@Nullable Set<String> locationTags) { - setState(state -> state.withLocationTags(locationTags)); + protected void setExtraAttributionTags(Set<String> extraAttributionTags) { + setState(state -> state.withExtraAttributionTags(extraAttributionTags)); } /** diff --git a/services/core/java/com/android/server/location/provider/DelegateLocationProvider.java b/services/core/java/com/android/server/location/provider/DelegateLocationProvider.java index 49f6e64a1e0c..423f833bf7e0 100644 --- a/services/core/java/com/android/server/location/provider/DelegateLocationProvider.java +++ b/services/core/java/com/android/server/location/provider/DelegateLocationProvider.java @@ -24,6 +24,7 @@ import com.android.internal.util.Preconditions; import java.io.FileDescriptor; import java.io.PrintWriter; +import java.util.Collections; import java.util.concurrent.Executor; /** @@ -40,7 +41,7 @@ class DelegateLocationProvider extends AbstractLocationProvider private boolean mInitialized = false; DelegateLocationProvider(Executor executor, AbstractLocationProvider delegate) { - super(executor, null, null, null); + super(executor, null, null, Collections.emptySet()); mDelegate = delegate; } diff --git a/services/core/java/com/android/server/location/provider/LocationProviderManager.java b/services/core/java/com/android/server/location/provider/LocationProviderManager.java index 1ecf3ee40a53..fef30f9ea811 100644 --- a/services/core/java/com/android/server/location/provider/LocationProviderManager.java +++ b/services/core/java/com/android/server/location/provider/LocationProviderManager.java @@ -2265,8 +2265,8 @@ public class LocationProviderManager extends onEnabledChanged(UserHandle.USER_ALL); } - if (!Objects.equals(oldState.locationTags, newState.locationTags)) { - if (mOnLocationTagsChangeListener != null) { + if (mOnLocationTagsChangeListener != null) { + if (!oldState.extraAttributionTags.equals(newState.extraAttributionTags)) { if (oldState.identity != null) { FgThread.getHandler().sendMessage(PooledLambda.obtainMessage( OnProviderLocationTagsChangeListener::onLocationTagsChanged, @@ -2280,7 +2280,7 @@ public class LocationProviderManager extends OnProviderLocationTagsChangeListener::onLocationTagsChanged, mOnLocationTagsChangeListener, new LocationTagInfo( newState.identity.getUid(), newState.identity.getPackageName(), - newState.locationTags) + newState.extraAttributionTags) )); } } diff --git a/services/core/java/com/android/server/location/provider/MockLocationProvider.java b/services/core/java/com/android/server/location/provider/MockLocationProvider.java index 7660f56f1580..52b04d4bab14 100644 --- a/services/core/java/com/android/server/location/provider/MockLocationProvider.java +++ b/services/core/java/com/android/server/location/provider/MockLocationProvider.java @@ -40,9 +40,9 @@ public class MockLocationProvider extends AbstractLocationProvider { @Nullable private Location mLocation; public MockLocationProvider(ProviderProperties properties, CallerIdentity identity, - @Nullable Set<String> locationTags) { + Set<String> extraAttributionTags) { // using a direct executor is ok because this class has no locks that could deadlock - super(DIRECT_EXECUTOR, identity, properties, locationTags); + super(DIRECT_EXECUTOR, identity, properties, extraAttributionTags); } /** Sets the allowed state of this mock provider. */ diff --git a/services/core/java/com/android/server/location/provider/MockableLocationProvider.java b/services/core/java/com/android/server/location/provider/MockableLocationProvider.java index 4ffa9a509a23..81936440f6a7 100644 --- a/services/core/java/com/android/server/location/provider/MockableLocationProvider.java +++ b/services/core/java/com/android/server/location/provider/MockableLocationProvider.java @@ -31,6 +31,7 @@ import com.android.internal.util.Preconditions; import java.io.FileDescriptor; import java.io.PrintWriter; +import java.util.Collections; /** * Represents a location provider that may switch between a mock implementation and a real @@ -75,7 +76,7 @@ public class MockableLocationProvider extends AbstractLocationProvider { public MockableLocationProvider(Object ownerLock) { // using a direct executor is acceptable because all inbound calls are delegated to the // actual provider implementations which will use their own executors - super(DIRECT_EXECUTOR, null, null, null); + super(DIRECT_EXECUTOR, null, null, Collections.emptySet()); mOwnerLock = ownerLock; mRequest = ProviderRequest.EMPTY_REQUEST; } diff --git a/services/core/java/com/android/server/location/provider/PassiveLocationProvider.java b/services/core/java/com/android/server/location/provider/PassiveLocationProvider.java index ee9d35d21798..68ede88c6a4a 100644 --- a/services/core/java/com/android/server/location/provider/PassiveLocationProvider.java +++ b/services/core/java/com/android/server/location/provider/PassiveLocationProvider.java @@ -30,6 +30,7 @@ import android.os.Bundle; import java.io.FileDescriptor; import java.io.PrintWriter; +import java.util.Collections; /** * A passive location provider reports locations received from other providers @@ -48,7 +49,7 @@ public class PassiveLocationProvider extends AbstractLocationProvider { public PassiveLocationProvider(Context context) { // using a direct executor is ok because this class has no locks that could deadlock super(DIRECT_EXECUTOR, CallerIdentity.fromContext(context), PROPERTIES, - /*locationTags*/ null); + Collections.emptySet()); setAllowed(true); } diff --git a/services/core/java/com/android/server/location/provider/proxy/ProxyLocationProvider.java b/services/core/java/com/android/server/location/provider/proxy/ProxyLocationProvider.java index f00478a3488a..44b62b3659dc 100644 --- a/services/core/java/com/android/server/location/provider/proxy/ProxyLocationProvider.java +++ b/services/core/java/com/android/server/location/provider/proxy/ProxyLocationProvider.java @@ -18,7 +18,6 @@ package com.android.server.location.provider.proxy; import static com.android.internal.util.ConcurrentUtils.DIRECT_EXECUTOR; -import android.annotation.NonNull; import android.annotation.Nullable; import android.content.ComponentName; import android.content.Context; @@ -44,6 +43,7 @@ import com.android.server.location.provider.AbstractLocationProvider; import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Objects; @@ -52,8 +52,8 @@ import java.util.Objects; */ public class ProxyLocationProvider extends AbstractLocationProvider { - private static final String KEY_LOCATION_TAGS = "android:location_allow_listed_tags"; - private static final String LOCATION_TAGS_SEPARATOR = ";"; + private static final String KEY_EXTRA_ATTRIBUTION_TAGS = "android:location_allow_listed_tags"; + private static final String EXTRA_ATTRIBUTION_TAGS_SEPARATOR = ";"; /** * Creates and registers this proxy. If no suitable service is available for the proxy, returns @@ -90,7 +90,7 @@ public class ProxyLocationProvider extends AbstractLocationProvider { int nonOverlayPackageResId) { // safe to use direct executor since our locks are not acquired in a code path invoked by // our owning provider - super(DIRECT_EXECUTOR, null, null, null); + super(DIRECT_EXECUTOR, null, null, Collections.emptySet()); mContext = context; mServiceWatcher = new ServiceWatcher(context, action, this::onBind, @@ -100,16 +100,6 @@ public class ProxyLocationProvider extends AbstractLocationProvider { mRequest = ProviderRequest.EMPTY_REQUEST; } - private void updateLocationTagInfo(@NonNull BoundService boundService) { - if (boundService.metadata != null) { - final String tagsList = boundService.metadata.getString(KEY_LOCATION_TAGS); - if (tagsList != null) { - final String[] tags = tagsList.split(LOCATION_TAGS_SEPARATOR); - setLocationTags(new ArraySet<>(tags)); - } - } - } - private boolean checkServiceResolves() { return mServiceWatcher.checkServiceResolves(); } @@ -120,14 +110,22 @@ public class ProxyLocationProvider extends AbstractLocationProvider { synchronized (mLock) { mProxy = new Proxy(); mService = boundService.component; + + // update extra attribution tag info from manifest + if (boundService.metadata != null) { + String tagsList = boundService.metadata.getString(KEY_EXTRA_ATTRIBUTION_TAGS); + if (tagsList != null) { + setExtraAttributionTags( + new ArraySet<>(tagsList.split(EXTRA_ATTRIBUTION_TAGS_SEPARATOR))); + } + } + provider.setLocationProviderManager(mProxy); ProviderRequest request = mRequest; if (!request.equals(ProviderRequest.EMPTY_REQUEST)) { provider.setRequest(request); } - - updateLocationTagInfo(boundService); } } diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java index 2dd54482e2d8..43c736544ee6 100644 --- a/services/core/java/com/android/server/locksettings/LockSettingsService.java +++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java @@ -479,8 +479,8 @@ public class LockSettingsService extends ILockSettings.Stub { return KeyStore.getInstance(); } - public RecoverableKeyStoreManager getRecoverableKeyStoreManager(KeyStore keyStore) { - return RecoverableKeyStoreManager.getInstance(mContext, keyStore); + public RecoverableKeyStoreManager getRecoverableKeyStoreManager() { + return RecoverableKeyStoreManager.getInstance(mContext); } public IStorageManager getStorageManager() { @@ -561,7 +561,7 @@ public class LockSettingsService extends ILockSettings.Stub { mInjector = injector; mContext = injector.getContext(); mKeyStore = injector.getKeyStore(); - mRecoverableKeyStoreManager = injector.getRecoverableKeyStoreManager(mKeyStore); + mRecoverableKeyStoreManager = injector.getRecoverableKeyStoreManager(); mHandler = injector.getHandler(injector.getServiceThread()); mStrongAuth = injector.getStrongAuth(); mActivityManager = injector.getActivityManager(); diff --git a/services/core/java/com/android/server/locksettings/OWNERS b/services/core/java/com/android/server/locksettings/OWNERS index 08b8a8c106b7..7577ee5c9fde 100644 --- a/services/core/java/com/android/server/locksettings/OWNERS +++ b/services/core/java/com/android/server/locksettings/OWNERS @@ -1,3 +1,4 @@ jaggies@google.com kchyn@google.com rubinxu@google.com +xunchang@google.com diff --git a/services/core/java/com/android/server/locksettings/RebootEscrowProviderServerBasedImpl.java b/services/core/java/com/android/server/locksettings/RebootEscrowProviderServerBasedImpl.java index b3b45460899d..697bf08a232e 100644 --- a/services/core/java/com/android/server/locksettings/RebootEscrowProviderServerBasedImpl.java +++ b/services/core/java/com/android/server/locksettings/RebootEscrowProviderServerBasedImpl.java @@ -44,7 +44,7 @@ class RebootEscrowProviderServerBasedImpl implements RebootEscrowProviderInterfa * Use the default lifetime of 10 minutes. The lifetime covers the following activities: * Server wrap secret -> device reboot -> server unwrap blob. */ - private static final long DEFAULT_SERVER_BLOB_LIFETIME_IN_MILLIS = 600_1000; + private static final long DEFAULT_SERVER_BLOB_LIFETIME_IN_MILLIS = 600_000; private final LockSettingsStorage mStorage; diff --git a/services/core/java/com/android/server/locksettings/recoverablekeystore/KeyStoreProxyImpl.java b/services/core/java/com/android/server/locksettings/recoverablekeystore/KeyStoreProxyImpl.java index 9857fb637b59..f5941361bd89 100644 --- a/services/core/java/com/android/server/locksettings/recoverablekeystore/KeyStoreProxyImpl.java +++ b/services/core/java/com/android/server/locksettings/recoverablekeystore/KeyStoreProxyImpl.java @@ -16,8 +16,6 @@ package com.android.server.locksettings.recoverablekeystore; -import android.security.keystore2.AndroidKeyStoreProvider; - import java.io.IOException; import java.security.Key; import java.security.KeyStore; @@ -31,22 +29,9 @@ import java.security.cert.CertificateException; */ public class KeyStoreProxyImpl implements KeyStoreProxy { - private final KeyStore mKeyStore; - - /** - * TODO This function redirects keystore access to the legacy keystore during a transitional - * phase during which not all calling code has been adjusted to use Keystore 2.0. - * This can be reverted to a constant of "AndroidKeyStore" when b/171305684 is complete. - * The specific bug for this component is b/171305545. - */ - static String androidKeystoreProviderName() { - if (AndroidKeyStoreProvider.isInstalled()) { - return "AndroidKeyStoreLegacy"; - } else { - return "AndroidKeyStore"; - } + public static final String ANDROID_KEY_STORE_PROVIDER = "AndroidKeyStore"; - } + private final KeyStore mKeyStore; /** * A new instance, delegating to {@code keyStore}. @@ -84,7 +69,7 @@ public class KeyStoreProxyImpl implements KeyStoreProxy { * @throws KeyStoreException if there was a problem getting or initializing the key store. */ public static KeyStore getAndLoadAndroidKeyStore() throws KeyStoreException { - KeyStore keyStore = KeyStore.getInstance(androidKeystoreProviderName()); + KeyStore keyStore = KeyStore.getInstance(ANDROID_KEY_STORE_PROVIDER); try { keyStore.load(/*param=*/ null); } catch (CertificateException | IOException | NoSuchAlgorithmException e) { diff --git a/services/core/java/com/android/server/locksettings/recoverablekeystore/PlatformKeyManager.java b/services/core/java/com/android/server/locksettings/recoverablekeystore/PlatformKeyManager.java index dff1df7afa11..f448a6ef8c0b 100644 --- a/services/core/java/com/android/server/locksettings/recoverablekeystore/PlatformKeyManager.java +++ b/services/core/java/com/android/server/locksettings/recoverablekeystore/PlatformKeyManager.java @@ -470,7 +470,7 @@ public class PlatformKeyManager { * @throws KeyStoreException if there was a problem getting or initializing the key store. */ private static KeyStore getAndLoadAndroidKeyStore() throws KeyStoreException { - KeyStore keyStore = KeyStore.getInstance(KeyStoreProxyImpl.androidKeystoreProviderName()); + KeyStore keyStore = KeyStore.getInstance(KeyStoreProxyImpl.ANDROID_KEY_STORE_PROVIDER); try { keyStore.load(/*param=*/ null); } catch (CertificateException | IOException | NoSuchAlgorithmException e) { diff --git a/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java b/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java index 6d97ed7a69a7..b49bced4e567 100644 --- a/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java +++ b/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java @@ -34,7 +34,6 @@ import android.os.Binder; import android.os.RemoteException; import android.os.ServiceSpecificException; import android.os.UserHandle; -import android.security.KeyStore; import android.security.keystore.recovery.KeyChainProtectionParams; import android.security.keystore.recovery.KeyChainSnapshot; import android.security.keystore.recovery.RecoveryCertPath; @@ -110,14 +109,14 @@ public class RecoverableKeyStoreManager { * @hide */ public static synchronized RecoverableKeyStoreManager - getInstance(Context context, KeyStore keystore) { + getInstance(Context context) { if (mInstance == null) { RecoverableKeyStoreDb db = RecoverableKeyStoreDb.newInstance(context); PlatformKeyManager platformKeyManager; ApplicationKeyStorage applicationKeyStorage; try { platformKeyManager = PlatformKeyManager.getInstance(context, db); - applicationKeyStorage = ApplicationKeyStorage.getInstance(keystore); + applicationKeyStorage = ApplicationKeyStorage.getInstance(); } catch (NoSuchAlgorithmException e) { // Impossible: all algorithms must be supported by AOSP throw new RuntimeException(e); diff --git a/services/core/java/com/android/server/locksettings/recoverablekeystore/storage/ApplicationKeyStorage.java b/services/core/java/com/android/server/locksettings/recoverablekeystore/storage/ApplicationKeyStorage.java index 84ddbf778c70..2398f56f847c 100644 --- a/services/core/java/com/android/server/locksettings/recoverablekeystore/storage/ApplicationKeyStorage.java +++ b/services/core/java/com/android/server/locksettings/recoverablekeystore/storage/ApplicationKeyStorage.java @@ -21,9 +21,13 @@ import static android.security.keystore.recovery.RecoveryController.ERROR_SERVIC import android.annotation.Nullable; import android.os.ServiceSpecificException; import android.security.Credentials; +import android.security.KeyStore; +import android.security.KeyStore2; import android.security.keystore.KeyProperties; import android.security.keystore.KeyProtection; -import android.security.KeyStore; +import android.system.keystore2.Domain; +import android.system.keystore2.KeyDescriptor; +import android.system.keystore2.KeyPermission; import android.util.Log; import com.android.internal.annotations.VisibleForTesting; @@ -47,32 +51,37 @@ public class ApplicationKeyStorage { private static final String APPLICATION_KEY_ALIAS_PREFIX = "com.android.server.locksettings.recoverablekeystore/application/"; + private static final String APPLICATION_KEY_GRANT_PREFIX = "recoverable_key:"; private final KeyStoreProxy mKeyStore; - private final KeyStore mKeystoreService; - public static ApplicationKeyStorage getInstance(KeyStore keystoreService) + /** + * Creates a new instance. + */ + public static ApplicationKeyStorage getInstance() throws KeyStoreException { return new ApplicationKeyStorage( - new KeyStoreProxyImpl(KeyStoreProxyImpl.getAndLoadAndroidKeyStore()), - keystoreService); + new KeyStoreProxyImpl(KeyStoreProxyImpl.getAndLoadAndroidKeyStore())); } @VisibleForTesting - ApplicationKeyStorage(KeyStoreProxy keyStore, KeyStore keystoreService) { + ApplicationKeyStorage(KeyStoreProxy keyStore) { mKeyStore = keyStore; - mKeystoreService = keystoreService; } /** - * Returns grant alias, valid in Applications namespace. + * Returns String representation of {@code KeyDescriptor} valid in application's namespace. */ public @Nullable String getGrantAlias(int userId, int uid, String alias) { - // Aliases used by {@link KeyStore} are different than used by public API. - // {@code USER_PRIVATE_KEY} prefix is used secret keys. Log.i(TAG, String.format(Locale.US, "Get %d/%d/%s", userId, uid, alias)); - String keystoreAlias = Credentials.USER_PRIVATE_KEY + getInternalAlias(userId, uid, alias); - return mKeystoreService.grant(keystoreAlias, uid); + String keystoreAlias = getInternalAlias(userId, uid, alias); + if (useKeyStore2()) { + return makeKeystoreEngineGrantString(uid, keystoreAlias); + } else { + // Aliases used by {@link KeyStore} are different than used by public API. + // {@code USER_PRIVATE_KEY} prefix is used secret keys. + return KeyStore.getInstance().grant(Credentials.USER_PRIVATE_KEY + keystoreAlias, uid); + } } public void setSymmetricKeyEntry(int userId, int uid, String alias, byte[] secretKey) @@ -117,4 +126,31 @@ public class ApplicationKeyStorage { private String getInternalAlias(int userId, int uid, String alias) { return APPLICATION_KEY_ALIAS_PREFIX + userId + "/" + uid + "/" + alias; } + + private String makeKeystoreEngineGrantString(int uid, String alias) { + if (alias == null) { + return null; + } + + KeyDescriptor key = new KeyDescriptor(); + key.domain = Domain.APP; + key.nspace = KeyProperties.NAMESPACE_APPLICATION; + key.alias = alias; + key.blob = null; + + int grantAccessVector = KeyPermission.USE | KeyPermission.GET_INFO | KeyPermission.DELETE; + + try { + key = KeyStore2.getInstance().grant(key, uid, grantAccessVector); + } catch (android.security.KeyStoreException e) { + Log.e(TAG, "Failed to get grant for KeyStore key.", e); + throw new ServiceSpecificException(ERROR_SERVICE_INTERNAL_ERROR, e.getMessage()); + } + return String.format("%s%016X", APPLICATION_KEY_GRANT_PREFIX, key.nspace); + } + + private static boolean useKeyStore2() { + return android.security.keystore2.AndroidKeyStoreProvider.isInstalled(); + } + } diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java index 18f2d8450246..23d84298b41e 100644 --- a/services/core/java/com/android/server/media/MediaSessionService.java +++ b/services/core/java/com/android/server/media/MediaSessionService.java @@ -40,10 +40,10 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageManager; -import android.content.pm.ParceledListSlice; import android.media.AudioManager; import android.media.AudioPlaybackConfiguration; import android.media.IRemoteSessionCallback; +import android.media.MediaCommunicationManager; import android.media.Session2Token; import android.media.session.IActiveSessionsListener; import android.media.session.IOnMediaKeyEventDispatchedListener; @@ -151,6 +151,25 @@ public class MediaSessionService extends SystemService implements Monitor { private MediaSessionPolicyProvider mCustomMediaSessionPolicyProvider; private MediaKeyDispatcher mCustomMediaKeyDispatcher; + private MediaCommunicationManager mCommunicationManager; + private final MediaCommunicationManager.SessionCallback mSession2TokenCallback = + new MediaCommunicationManager.SessionCallback() { + @Override + public void onSession2TokenCreated(Session2Token token) { + if (DEBUG) { + Log.d(TAG, "Session2 is created " + token); + } + MediaSession2Record record = new MediaSession2Record(token, + MediaSessionService.this, mRecordThread.getLooper(), 0); + synchronized (mLock) { + FullUserRecord user = getFullUserRecordLocked(record.getUserId()); + if (user != null) { + user.mPriorityStack.addSession(record); + } + } + } + }; + public MediaSessionService(Context context) { super(context); mContext = context; @@ -202,6 +221,19 @@ public class MediaSessionService extends SystemService implements Monitor { mContext.registerReceiver(mNotificationListenerEnabledChangedReceiver, filter); } + @Override + public void onBootPhase(int phase) { + super.onBootPhase(phase); + switch (phase) { + // This ensures MediaCommunicationService is started + case PHASE_BOOT_COMPLETED: + mCommunicationManager = mContext.getSystemService(MediaCommunicationManager.class); + mCommunicationManager.registerSessionCallback(new HandlerExecutor(mHandler), + mSession2TokenCallback); + break; + } + } + private final BroadcastReceiver mNotificationListenerEnabledChangedReceiver = new BroadcastReceiver() { @Override @@ -1139,31 +1171,6 @@ public class MediaSessionService extends SystemService implements Monitor { } @Override - public void notifySession2Created(Session2Token sessionToken) throws RemoteException { - final int pid = Binder.getCallingPid(); - final int uid = Binder.getCallingUid(); - final long token = Binder.clearCallingIdentity(); - try { - if (DEBUG) { - Log.d(TAG, "Session2 is created " + sessionToken); - } - if (uid != sessionToken.getUid()) { - throw new SecurityException("Unexpected Session2Token's UID, expected=" + uid - + " but actually=" + sessionToken.getUid()); - } - MediaSession2Record record = new MediaSession2Record(sessionToken, - MediaSessionService.this, mRecordThread.getLooper(), 0); - synchronized (mLock) { - FullUserRecord user = getFullUserRecordLocked(record.getUserId()); - user.mPriorityStack.addSession(record); - } - // Do not immediately notify changes -- do so when framework can dispatch command - } finally { - Binder.restoreCallingIdentity(token); - } - } - - @Override public List<MediaSession.Token> getSessions(ComponentName componentName, int userId) { final int pid = Binder.getCallingPid(); final int uid = Binder.getCallingUid(); @@ -1185,26 +1192,6 @@ public class MediaSessionService extends SystemService implements Monitor { } @Override - public ParceledListSlice getSession2Tokens(int userId) { - final int pid = Binder.getCallingPid(); - final int uid = Binder.getCallingUid(); - final long token = Binder.clearCallingIdentity(); - - try { - // Check that they can make calls on behalf of the user and get the final user id - int resolvedUserId = handleIncomingUser(pid, uid, userId, null); - List<Session2Token> result; - synchronized (mLock) { - FullUserRecord user = getFullUserRecordLocked(userId); - result = user.mPriorityStack.getSession2Tokens(resolvedUserId); - } - return new ParceledListSlice(result); - } finally { - Binder.restoreCallingIdentity(token); - } - } - - @Override public void addSessionsListener(IActiveSessionsListener listener, ComponentName componentName, int userId) throws RemoteException { final int pid = Binder.getCallingPid(); diff --git a/services/core/java/com/android/server/net/NetworkIdentitySet.java b/services/core/java/com/android/server/net/NetworkIdentitySet.java index bce80696f72c..22ed781da92d 100644 --- a/services/core/java/com/android/server/net/NetworkIdentitySet.java +++ b/services/core/java/com/android/server/net/NetworkIdentitySet.java @@ -40,6 +40,7 @@ public class NetworkIdentitySet extends HashSet<NetworkIdentity> implements private static final int VERSION_ADD_NETWORK_ID = 3; private static final int VERSION_ADD_METERED = 4; private static final int VERSION_ADD_DEFAULT_NETWORK = 5; + private static final int VERSION_ADD_OEM_MANAGED_NETWORK = 6; public NetworkIdentitySet() { } @@ -84,13 +85,20 @@ public class NetworkIdentitySet extends HashSet<NetworkIdentity> implements defaultNetwork = true; } + final int oemNetCapabilities; + if (version >= VERSION_ADD_OEM_MANAGED_NETWORK) { + oemNetCapabilities = in.readInt(); + } else { + oemNetCapabilities = NetworkIdentity.OEM_NONE; + } + add(new NetworkIdentity(type, subType, subscriberId, networkId, roaming, metered, - defaultNetwork)); + defaultNetwork, oemNetCapabilities)); } } public void writeToStream(DataOutput out) throws IOException { - out.writeInt(VERSION_ADD_DEFAULT_NETWORK); + out.writeInt(VERSION_ADD_OEM_MANAGED_NETWORK); out.writeInt(size()); for (NetworkIdentity ident : this) { out.writeInt(ident.getType()); @@ -100,6 +108,7 @@ public class NetworkIdentitySet extends HashSet<NetworkIdentity> implements out.writeBoolean(ident.getRoaming()); out.writeBoolean(ident.getMetered()); out.writeBoolean(ident.getDefaultNetwork()); + out.writeInt(ident.getOemManaged()); } } diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java index 2b9dd2d84ac6..067c5c0e7620 100644 --- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java +++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java @@ -54,6 +54,7 @@ import static android.net.INetd.FIREWALL_RULE_DENY; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING; import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; +import static android.net.NetworkIdentity.OEM_NONE; import static android.net.NetworkPolicy.LIMIT_DISABLED; import static android.net.NetworkPolicy.SNOOZE_NEVER; import static android.net.NetworkPolicy.WARNING_DISABLED; @@ -1404,7 +1405,11 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { final String subscriberId = mSubIdToSubscriberId.valueAt(i); final NetworkIdentity probeIdent = new NetworkIdentity(TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, null, false, true, - true); + true, OEM_NONE); + /* While OEM_NONE indicates "any non OEM managed network", OEM_NONE is meant to be a + * placeholder value here. The probeIdent is matched against a NetworkTemplate which + * should have its OEM managed value set to OEM_MANAGED_ALL, which will cause the + * template to match probeIdent without regard to OEM managed status. */ if (template.matches(probeIdent)) { return subId; } @@ -1634,7 +1639,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { // find and update the mobile NetworkPolicy for this subscriber id boolean policyUpdated = false; final NetworkIdentity probeIdent = new NetworkIdentity(TYPE_MOBILE, - TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, null, false, true, true); + TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, null, false, true, true, + OEM_NONE); for (int i = mNetworkPolicy.size() - 1; i >= 0; i--) { final NetworkTemplate template = mNetworkPolicy.keyAt(i); if (template.matches(probeIdent)) { @@ -1863,7 +1869,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { final NetworkIdentity probeIdent = new NetworkIdentity(TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, null, false, true, - true); + true, OEM_NONE); // Template is matched when subscriber id matches. if (template.matches(probeIdent)) { matchingSubIds.add(subId); @@ -2178,7 +2184,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { private boolean ensureActiveMobilePolicyAL(int subId, String subscriberId) { // Poke around to see if we already have a policy final NetworkIdentity probeIdent = new NetworkIdentity(TYPE_MOBILE, - TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, null, false, true, true); + TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, null, false, true, true, + OEM_NONE); for (int i = mNetworkPolicy.size() - 1; i >= 0; i--) { final NetworkTemplate template = mNetworkPolicy.keyAt(i); if (template.matches(probeIdent)) { diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java index 9706bcece924..5b9a11bc5a31 100644 --- a/services/core/java/com/android/server/net/NetworkStatsService.java +++ b/services/core/java/com/android/server/net/NetworkStatsService.java @@ -1319,7 +1319,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { NetworkIdentity vtIdent = new NetworkIdentity(ident.getType(), ident.getSubType(), ident.getSubscriberId(), ident.getNetworkId(), ident.getRoaming(), true /* metered */, - true /* onDefaultNetwork */); + true /* onDefaultNetwork */, ident.getOemManaged()); findOrCreateNetworkIdentitySet(mActiveIfaces, IFACE_VT).add(vtIdent); findOrCreateNetworkIdentitySet(mActiveUidIfaces, IFACE_VT).add(vtIdent); } diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index f8cb2e4cecfc..73db7054cec5 100755 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -64,6 +64,8 @@ import static android.media.AudioAttributes.FLAG_BYPASS_INTERRUPTION_POLICY; import static android.media.AudioAttributes.USAGE_NOTIFICATION_RINGTONE; import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_CRITICAL; import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_NORMAL; +import static android.os.PowerWhitelistManager.REASON_NOTIFICATION_SERVICE; +import static android.os.PowerWhitelistManager.TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED; import static android.os.UserHandle.USER_NULL; import static android.os.UserHandle.USER_SYSTEM; import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_ALERTING; @@ -73,6 +75,8 @@ import static android.service.notification.NotificationListenerService.FLAG_FILT import static android.service.notification.NotificationListenerService.HINT_HOST_DISABLE_CALL_EFFECTS; import static android.service.notification.NotificationListenerService.HINT_HOST_DISABLE_EFFECTS; import static android.service.notification.NotificationListenerService.HINT_HOST_DISABLE_NOTIFICATION_EFFECTS; +import static android.service.notification.NotificationListenerService.META_DATA_DEFAULT_FILTER_TYPES; +import static android.service.notification.NotificationListenerService.META_DATA_DISABLED_FILTER_TYPES; import static android.service.notification.NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_ADDED; import static android.service.notification.NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_DELETED; import static android.service.notification.NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_UPDATED; @@ -6001,10 +6005,11 @@ public class NotificationManagerService extends SystemService { for (int i = 0; i < intentCount; i++) { PendingIntent pendingIntent = notification.allPendingIntents.valueAt(i); if (pendingIntent != null) { - am.setPendingIntentWhitelistDuration(pendingIntent.getTarget(), + am.setPendingIntentAllowlistDuration(pendingIntent.getTarget(), ALLOWLIST_TOKEN, duration, - BroadcastOptions.TEMPORARY_WHITELIST_TYPE_FOREGROUND_SERVICE_ALLOWED - ); + TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED, + REASON_NOTIFICATION_SERVICE, + "NotificationManagerService"); am.setPendingIntentAllowBgActivityStarts(pendingIntent.getTarget(), ALLOWLIST_TOKEN, (FLAG_ACTIVITY_SENDER | FLAG_BROADCAST_SENDER | FLAG_SERVICE_SENDER)); @@ -9863,33 +9868,54 @@ public class NotificationManagerService extends SystemService { Pair listener = Pair.create(si.getComponentName(), userId); NotificationListenerFilter existingNlf = mRequestedNotificationListeners.get(listener); - if (existingNlf == null) { - // no stored filters for this listener; see if they provided a default - if (si.metaData != null) { - String typeList = si.metaData.getString( - NotificationListenerService.META_DATA_DEFAULT_FILTER_TYPES); - if (typeList != null) { - int types = 0; - String[] typeStrings = typeList.split(XML_SEPARATOR); - for (int i = 0; i < typeStrings.length; i++) { - if (TextUtils.isEmpty(typeStrings[i])) { - continue; - } - try { - types |= Integer.parseInt(typeStrings[i]); - } catch (NumberFormatException e) { - // skip - } + if (si.metaData != null) { + if (existingNlf == null) { + // no stored filters for this listener; see if they provided a default + if (si.metaData.containsKey(META_DATA_DEFAULT_FILTER_TYPES)) { + String typeList = + si.metaData.get(META_DATA_DEFAULT_FILTER_TYPES).toString(); + if (typeList != null) { + int types = getTypesFromStringList(typeList); + NotificationListenerFilter nlf = + new NotificationListenerFilter(types, new ArraySet<>()); + mRequestedNotificationListeners.put(listener, nlf); } + } + } - NotificationListenerFilter nlf = - new NotificationListenerFilter(types, new ArraySet<>()); + // also check the types they never want bridged + if (si.metaData.containsKey(META_DATA_DISABLED_FILTER_TYPES)) { + int neverBridge = getTypesFromStringList(si.metaData.get( + META_DATA_DISABLED_FILTER_TYPES).toString()); + if (neverBridge != 0) { + NotificationListenerFilter nlf = + mRequestedNotificationListeners.getOrDefault( + listener, new NotificationListenerFilter()); + nlf.setTypes(nlf.getTypes() & ~neverBridge); mRequestedNotificationListeners.put(listener, nlf); } } } } + private int getTypesFromStringList(String typeList) { + int types = 0; + if (typeList != null) { + String[] typeStrings = typeList.split(XML_SEPARATOR); + for (int i = 0; i < typeStrings.length; i++) { + if (TextUtils.isEmpty(typeStrings[i])) { + continue; + } + try { + types |= Integer.parseInt(typeStrings[i]); + } catch (NumberFormatException e) { + // skip + } + } + } + return types; + } + @GuardedBy("mNotificationLock") public void setOnNotificationPostedTrimLocked(ManagedServiceInfo info, int trim) { if (trim == TRIM_LIGHT) { diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 8123951eadff..16ba4d6a5013 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -97,6 +97,10 @@ import static android.content.pm.PackageManager.UNINSTALL_REASON_UNKNOWN; import static android.content.pm.PackageManagerInternal.LAST_KNOWN_PACKAGE; import static android.content.pm.PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V4; import static android.content.pm.parsing.ApkLiteParseUtils.isApkFile; +import static android.os.PowerWhitelistManager.REASON_LOCKED_BOOT_COMPLETED; +import static android.os.PowerWhitelistManager.REASON_PACKAGE_REPLACED; +import static android.os.PowerWhitelistManager.REASON_PACKAGE_VERIFIER; +import static android.os.PowerWhitelistManager.TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED; import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER; import static android.os.incremental.IncrementalManager.isIncrementalPath; import static android.os.storage.StorageManager.FLAG_STORAGE_CE; @@ -270,6 +274,7 @@ import android.os.Parcel; import android.os.ParcelableException; import android.os.PatternMatcher; import android.os.PersistableBundle; +import android.os.PowerWhitelistManager; import android.os.Process; import android.os.RemoteCallbackList; import android.os.RemoteException; @@ -2604,10 +2609,22 @@ public class PackageManagerService extends IPackageManager.Stub final ArrayList<ResolveInfo> matchAllList = new ArrayList<>(); final ArrayList<ResolveInfo> undefinedList = new ArrayList<>(); + // Blocking instant apps is usually done in applyPostResolutionFilter, but since + // domain verification can resolve to a single result, which can be an instant app, + // it will then be filtered to an empty list in that method. Instead, do blocking + // here so that instant apps can be ignored for approval filtering and a lower + // priority result chosen instead. + final boolean blockInstant = intent.isWebIntent() && areWebInstantAppsDisabled(userId); + final int count = candidates.size(); // First, try to use approved apps. for (int n = 0; n < count; n++) { ResolveInfo info = candidates.get(n); + if (blockInstant && (info.isInstantAppAvailable + || isInstantApp(info.activityInfo.packageName, userId))) { + continue; + } + // Add to the special match all list (Browser use case) if (info.handleAllWebDataURI) { matchAllList.add(info); @@ -5092,23 +5109,12 @@ public class PackageManagerService extends IPackageManager.Stub InstallArgs args = data.args; PackageInstalledInfo parentRes = data.res; - final boolean grantPermissions = (args.installFlags - & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0; final boolean killApp = (args.installFlags & PackageManager.INSTALL_DONT_KILL_APP) == 0; final boolean virtualPreload = ((args.installFlags & PackageManager.INSTALL_VIRTUAL_PRELOAD) != 0); - final String[] grantedPermissions = args.installGrantPermissions; - final List<String> whitelistedRestrictedPermissions = ((args.installFlags - & PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS) != 0 - && parentRes.pkg != null) - ? parentRes.pkg.getRequestedPermissions() - : args.whitelistedRestrictedPermissions; - int autoRevokePermissionsMode = args.autoRevokePermissionsMode; - - handlePackagePostInstall(parentRes, grantPermissions, - killApp, virtualPreload, grantedPermissions, - whitelistedRestrictedPermissions, autoRevokePermissionsMode, + + handlePackagePostInstall(parentRes, killApp, virtualPreload, didRestore, args.installSource.installerPackageName, args.observer, args.mDataLoaderType); @@ -5387,11 +5393,8 @@ public class PackageManagerService extends IPackageManager.Stub } } - private void handlePackagePostInstall(PackageInstalledInfo res, boolean grantPermissions, - boolean killApp, boolean virtualPreload, - String[] grantedPermissions, List<String> allowlistedRestrictedPermissions, - int autoRevokePermissionsMode, - boolean launchedForRestore, String installerPackage, + private void handlePackagePostInstall(PackageInstalledInfo res, boolean killApp, + boolean virtualPreload, boolean launchedForRestore, String installerPackage, IPackageInstallObserver2 installObserver, int dataLoaderType) { boolean succeeded = res.returnCode == PackageManager.INSTALL_SUCCEEDED; final boolean update = res.removedInfo != null && res.removedInfo.removedPackage != null; @@ -5422,29 +5425,6 @@ public class PackageManagerService extends IPackageManager.Stub res.removedInfo.sendPackageRemovedBroadcasts(killApp, false /*removedBySystem*/); } - final PermissionManagerServiceInternal.PackageInstalledParams.Builder - permissionParamsBuilder = - new PermissionManagerServiceInternal.PackageInstalledParams.Builder(); - final List<String> grantedPermissionsList; - if (grantPermissions) { - if (grantedPermissions != null) { - permissionParamsBuilder.setGrantedPermissions(Arrays.asList( - grantedPermissions)); - } else { - permissionParamsBuilder.setGrantedPermissions( - res.pkg.getRequestedPermissions()); - } - } - if (allowlistedRestrictedPermissions != null) { - permissionParamsBuilder.setAllowlistedRestrictedPermissions( - allowlistedRestrictedPermissions); - } - permissionParamsBuilder.setAutoRevokePermissionsMode(autoRevokePermissionsMode); - for (final int userId : res.newUsers) { - mPermissionManager.onPackageInstalled(res.pkg, permissionParamsBuilder.build(), - userId); - } - final String installerPackageName = res.installerPackageName != null ? res.installerPackageName @@ -5577,7 +5557,8 @@ public class PackageManagerService extends IPackageManager.Stub packageName /*targetPackage*/, null /*finishedReceiver*/, updateUserIds, instantUserIds, null /*broadcastAllowList*/, - getTemporaryAppWhitelistBroadcastOptions().toBundle()); + getTemporaryAppAllowlistBroadcastOptions(REASON_PACKAGE_REPLACED) + .toBundle()); } else if (launchedForRestore && !res.pkg.isSystem()) { // First-install and we did a restore, so we're responsible for the // first-launch broadcast. @@ -15218,7 +15199,8 @@ public class PackageManagerService extends IPackageManager.Stub lockedBcIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); } final String[] requiredPermissions = {Manifest.permission.RECEIVE_BOOT_COMPLETED}; - final BroadcastOptions bOptions = getTemporaryAppWhitelistBroadcastOptions(); + final BroadcastOptions bOptions = getTemporaryAppAllowlistBroadcastOptions( + REASON_LOCKED_BOOT_COMPLETED); am.broadcastIntentWithFeature(null, null, lockedBcIntent, null, null, 0, null, null, requiredPermissions, android.app.AppOpsManager.OP_NONE, bOptions.toBundle(), false, false, @@ -17607,7 +17589,9 @@ public class PackageManagerService extends IPackageManager.Stub mInjector.getLocalService(DeviceIdleInternal.class); final long idleDuration = getVerificationTimeout(); final BroadcastOptions options = BroadcastOptions.makeBasic(); - options.setTemporaryAppWhitelistDuration(idleDuration); + options.setTemporaryAppAllowlist(idleDuration, + TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED, + REASON_PACKAGE_VERIFIER, ""); /* * If any sufficient verifiers were listed in the package @@ -17623,7 +17607,8 @@ public class PackageManagerService extends IPackageManager.Stub final ComponentName verifierComponent = sufficientVerifiers.get(i); idleController.addPowerSaveTempWhitelistApp(Process.myUid(), verifierComponent.getPackageName(), idleDuration, - verifierUser.getIdentifier(), false, "package verifier"); + verifierUser.getIdentifier(), false, + REASON_PACKAGE_VERIFIER,"package verifier"); final Intent sufficientIntent = new Intent(verification); sufficientIntent.setComponent(verifierComponent); @@ -17645,7 +17630,8 @@ public class PackageManagerService extends IPackageManager.Stub verification.setComponent(requiredVerifierComponent); idleController.addPowerSaveTempWhitelistApp(Process.myUid(), mRequiredVerifierPackage, idleDuration, - verifierUser.getIdentifier(), false, "package verifier"); + verifierUser.getIdentifier(), false, + REASON_PACKAGE_VERIFIER, "package verifier"); mContext.sendOrderedBroadcastAsUser(verification, verifierUser, android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, /* appOp= */ AppOpsManager.OP_NONE, @@ -18445,6 +18431,37 @@ public class PackageManagerService extends IPackageManager.Stub } mSettings.writeKernelMappingLPr(ps); + + final PermissionManagerServiceInternal.PackageInstalledParams.Builder + permissionParamsBuilder = + new PermissionManagerServiceInternal.PackageInstalledParams.Builder(); + final boolean grantPermissions = (installArgs.installFlags + & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0; + if (grantPermissions) { + final List<String> grantedPermissions = + installArgs.installGrantPermissions != null + ? Arrays.asList(installArgs.installGrantPermissions) + : pkg.getRequestedPermissions(); + permissionParamsBuilder.setGrantedPermissions(grantedPermissions); + } + final boolean allowlistAllRestrictedPermissions = + (installArgs.installFlags + & PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS) != 0; + final List<String> allowlistedRestrictedPermissions = + allowlistAllRestrictedPermissions ? pkg.getRequestedPermissions() + : installArgs.whitelistedRestrictedPermissions; + if (allowlistedRestrictedPermissions != null) { + permissionParamsBuilder.setAllowlistedRestrictedPermissions( + allowlistedRestrictedPermissions); + } + final int autoRevokePermissionsMode = installArgs.autoRevokePermissionsMode; + permissionParamsBuilder.setAutoRevokePermissionsMode(autoRevokePermissionsMode); + for (int currentUserId : allUsersList) { + if (ps.getInstalled(currentUserId)) { + mPermissionManager.onPackageInstalled(pkg, permissionParamsBuilder.build(), + currentUserId); + } + } } res.name = pkgName; res.uid = pkg.getUid(); @@ -20965,7 +20982,7 @@ public class PackageManagerService extends IPackageManager.Stub extras, 0, null /*targetPackage*/, null, null, null, broadcastAllowList, null); packageSender.sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, null, null, 0, removedPackage, null, null, null, null /* broadcastAllowList */, - getTemporaryAppWhitelistBroadcastOptions().toBundle()); + getTemporaryAppAllowlistBroadcastOptions(REASON_PACKAGE_REPLACED).toBundle()); if (installerPackageName != null) { packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, removedPackage, extras, 0 /*flags*/, @@ -22673,7 +22690,7 @@ public class PackageManagerService extends IPackageManager.Stub } final Intent intent = getHomeIntent(); final List<ResolveInfo> resolveInfos = queryIntentActivitiesInternal(intent, null, - PackageManager.GET_META_DATA, userId); + MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, userId); final ResolveInfo preferredResolveInfo = findPreferredActivityNotLocked( intent, null, 0, resolveInfos, 0, true, false, false, userId); final String packageName = preferredResolveInfo != null @@ -27812,7 +27829,8 @@ public class PackageManagerService extends IPackageManager.Stub return result.toArray(new PerUidReadTimeouts[result.size()]); } - static @NonNull BroadcastOptions getTemporaryAppWhitelistBroadcastOptions() { + static @NonNull BroadcastOptions getTemporaryAppAllowlistBroadcastOptions( + @PowerWhitelistManager.ReasonCode int reasonCode) { long duration = 10_000; final ActivityManagerInternal amInternal = LocalServices.getService(ActivityManagerInternal.class); @@ -27820,9 +27838,9 @@ public class PackageManagerService extends IPackageManager.Stub duration = amInternal.getBootTimeTempAllowListDuration(); } final BroadcastOptions bOptions = BroadcastOptions.makeBasic(); - bOptions.setTemporaryAppWhitelistDuration( - BroadcastOptions.TEMPORARY_WHITELIST_TYPE_FOREGROUND_SERVICE_ALLOWED, - duration); + bOptions.setTemporaryAppAllowlist(duration, + TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED, + reasonCode, ""); return bOptions; } diff --git a/services/core/java/com/android/server/pm/PackageSettingBase.java b/services/core/java/com/android/server/pm/PackageSettingBase.java index a83a3f81bc00..38e100e80cd3 100644 --- a/services/core/java/com/android/server/pm/PackageSettingBase.java +++ b/services/core/java/com/android/server/pm/PackageSettingBase.java @@ -787,6 +787,10 @@ public abstract class PackageSettingBase extends SettingBase { return firstInstallTime; } + public String getName() { + return name; + } + protected PackageSettingBase updateFrom(PackageSettingBase other) { super.copyFrom(other); setPath(other.getPath()); diff --git a/services/core/java/com/android/server/pm/ShortcutPackage.java b/services/core/java/com/android/server/pm/ShortcutPackage.java index bb4ec16be0a8..a604afc22c09 100644 --- a/services/core/java/com/android/server/pm/ShortcutPackage.java +++ b/services/core/java/com/android/server/pm/ShortcutPackage.java @@ -19,15 +19,22 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; import android.app.Person; +import android.app.appsearch.AppSearchManager; +import android.app.appsearch.AppSearchSession; +import android.app.appsearch.PackageIdentifier; +import android.app.appsearch.SetSchemaRequest; import android.content.ComponentName; import android.content.Intent; import android.content.IntentFilter; import android.content.LocusId; +import android.content.pm.AppSearchPerson; +import android.content.pm.AppSearchShortcutInfo; import android.content.pm.PackageInfo; import android.content.pm.ShortcutInfo; import android.content.pm.ShortcutManager; import android.content.res.Resources; import android.graphics.drawable.Icon; +import android.os.Binder; import android.os.PersistableBundle; import android.text.format.Formatter; import android.util.ArrayMap; @@ -39,9 +46,11 @@ import android.util.TypedXmlPullParser; import android.util.TypedXmlSerializer; import android.util.Xml; +import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.ArrayUtils; import com.android.internal.util.CollectionUtils; +import com.android.internal.util.ConcurrentUtils; import com.android.internal.util.Preconditions; import com.android.internal.util.XmlUtils; import com.android.server.pm.ShortcutService.DumpFilter; @@ -64,8 +73,12 @@ import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; +import java.util.Map; import java.util.Objects; import java.util.Set; +import java.util.concurrent.CountDownLatch; +import java.util.function.Consumer; +import java.util.function.Function; import java.util.function.Predicate; /** @@ -155,6 +168,16 @@ class ShortcutPackage extends ShortcutPackageItem { private long mLastKnownForegroundElapsedTime; + private final Object mLock = new Object(); + + /** + * All external packages that have gained access to the shortcuts from this package + */ + private final Map<String, PackageIdentifier> mPackageIdentifiers = new ArrayMap<>(0); + + @GuardedBy("mLock") + private AppSearchSession mAppSearchSession; + private ShortcutPackage(ShortcutUser shortcutUser, int packageUserId, String packageName, ShortcutPackageInfo spi) { super(shortcutUser, packageUserId, packageName, @@ -2140,6 +2163,15 @@ class ShortcutPackage extends ShortcutPackageItem { } } + void updateVisibility(String packageName, byte[] certificate, boolean visible) { + if (visible) { + mPackageIdentifiers.put(packageName, new PackageIdentifier(packageName, certificate)); + } else { + mPackageIdentifiers.remove(packageName); + } + resetAppSearch(null); + } + private boolean verifyRanksSequential(List<ShortcutInfo> list) { boolean failed = false; @@ -2153,4 +2185,128 @@ class ShortcutPackage extends ShortcutPackageItem { } return failed; } + + private void runInAppSearch( + Function<SearchSessionObservable, Consumer<AppSearchSession>>... observers) { + if (mShortcutUser == null) { + Slog.w(TAG, "shortcut user is null"); + return; + } + synchronized (mLock) { + if (mAppSearchSession != null) { + final CountDownLatch latch = new CountDownLatch(1); + final long callingIdentity = Binder.clearCallingIdentity(); + try { + final SearchSessionObservable upstream = + new SearchSessionObservable(mAppSearchSession, latch); + for (Function<SearchSessionObservable, Consumer<AppSearchSession>> observer + : observers) { + upstream.map(observer); + } + upstream.next(); + } finally { + Binder.restoreCallingIdentity(callingIdentity); + } + ConcurrentUtils.waitForCountDownNoInterrupt(latch, 500, + "timeout accessing shortcut"); + } else { + resetAppSearch(observers); + } + } + } + + private void resetAppSearch( + Function<SearchSessionObservable, Consumer<AppSearchSession>>... observers) { + final CountDownLatch latch = new CountDownLatch(1); + final AppSearchManager.SearchContext searchContext = + new AppSearchManager.SearchContext.Builder() + .setDatabaseName(getPackageName()).build(); + mShortcutUser.runInAppSearch(searchContext, result -> { + if (!result.isSuccess()) { + Slog.e(TAG, "error getting search session during lazy init, " + + result.getErrorMessage()); + latch.countDown(); + return; + } + // TODO: Flatten callback chain with proper async framework + final SearchSessionObservable upstream = + new SearchSessionObservable(result.getResultValue(), latch) + .map(this::setupSchema); + if (observers != null) { + for (Function<SearchSessionObservable, Consumer<AppSearchSession>> observer + : observers) { + upstream.map(observer); + } + } + upstream.map(observable -> session -> { + mAppSearchSession = session; + observable.next(); + }); + upstream.next(); + }); + ConcurrentUtils.waitForCountDownNoInterrupt(latch, 1500, + "timeout accessing shortcut during lazy initialization"); + } + + /** + * creates the schema for shortcut in the database + */ + private Consumer<AppSearchSession> setupSchema(SearchSessionObservable observable) { + return session -> { + SetSchemaRequest.Builder schemaBuilder = new SetSchemaRequest.Builder() + .addSchemas(AppSearchPerson.SCHEMA, AppSearchShortcutInfo.SCHEMA); + for (PackageIdentifier pi : mPackageIdentifiers.values()) { + schemaBuilder = schemaBuilder + .setSchemaTypeVisibilityForPackage( + AppSearchPerson.SCHEMA_TYPE, true, pi) + .setSchemaTypeVisibilityForPackage( + AppSearchShortcutInfo.SCHEMA_TYPE, true, pi); + } + session.setSchema(schemaBuilder.build(), mShortcutUser.mExecutor, result -> { + if (!result.isSuccess()) { + observable.error("failed to instantiate app search schema: " + + result.getErrorMessage()); + return; + } + observable.next(); + }); + }; + } + + /** + * TODO: Replace this temporary implementation with proper async framework + */ + private class SearchSessionObservable { + + final AppSearchSession mSession; + final CountDownLatch mLatch; + final ArrayList<Consumer<AppSearchSession>> mObservers = new ArrayList<>(1); + + SearchSessionObservable(@NonNull final AppSearchSession session, + @NonNull final CountDownLatch latch) { + mSession = session; + mLatch = latch; + } + + SearchSessionObservable map( + Function<SearchSessionObservable, Consumer<AppSearchSession>> observer) { + mObservers.add(observer.apply(this)); + return this; + } + + void next() { + if (mObservers.isEmpty()) { + mLatch.countDown(); + return; + } + mObservers.remove(0).accept(mSession); + } + + void error(@Nullable final String errorMessage) { + if (errorMessage != null) { + Slog.e(TAG, errorMessage); + } + mLatch.countDown(); + } + } } diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java index 4d8abea8acd4..209a143f665d 100644 --- a/services/core/java/com/android/server/pm/ShortcutService.java +++ b/services/core/java/com/android/server/pm/ShortcutService.java @@ -2150,6 +2150,15 @@ public class ShortcutService extends IShortcutService.Stub { } @Override + public void updateShortcutVisibility(String callingPkg, String packageName, byte[] certificate, + boolean visible, int userId) { + synchronized (mLock) { + getPackageShortcutsForPublisherLocked(callingPkg, userId) + .updateVisibility(packageName, certificate, visible); + } + } + + @Override public boolean requestPinShortcut(String packageName, ShortcutInfo shortcut, IntentSender resultIntent, int userId) { Objects.requireNonNull(shortcut); diff --git a/services/core/java/com/android/server/pm/ShortcutUser.java b/services/core/java/com/android/server/pm/ShortcutUser.java index 3e3aa677912b..6cbc47fb59c4 100644 --- a/services/core/java/com/android/server/pm/ShortcutUser.java +++ b/services/core/java/com/android/server/pm/ShortcutUser.java @@ -18,9 +18,14 @@ package com.android.server.pm; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; +import android.app.appsearch.AppSearchManager; +import android.app.appsearch.AppSearchResult; +import android.app.appsearch.AppSearchSession; import android.content.pm.ShortcutManager; import android.metrics.LogMaker; +import android.os.Binder; import android.os.FileUtils; +import android.os.UserHandle; import android.text.TextUtils; import android.text.format.Formatter; import android.util.ArrayMap; @@ -32,6 +37,7 @@ import android.util.TypedXmlSerializer; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; +import com.android.server.FgThread; import com.android.server.pm.ShortcutService.DumpFilter; import com.android.server.pm.ShortcutService.InvalidFileFormatException; @@ -45,6 +51,7 @@ import java.io.File; import java.io.IOException; import java.io.PrintWriter; import java.util.Objects; +import java.util.concurrent.Executor; import java.util.function.Consumer; /** @@ -111,6 +118,8 @@ class ShortcutUser { } final ShortcutService mService; + final AppSearchManager mAppSearchManager; + final Executor mExecutor; @UserIdInt private final int mUserId; @@ -132,6 +141,9 @@ class ShortcutUser { public ShortcutUser(ShortcutService service, int userId) { mService = service; mUserId = userId; + mAppSearchManager = service.mContext.createContextAsUser(UserHandle.of(userId), 0) + .getSystemService(AppSearchManager.class); + mExecutor = FgThread.getExecutor(); } public int getUserId() { @@ -693,4 +705,18 @@ class ShortcutUser { logger.write(logMaker.setType(MetricsEvent.SHORTCUTS_CHANGED_SHORTCUT_COUNT) .setSubtype(totalSharingShortcutCount)); } + + void runInAppSearch(@NonNull final AppSearchManager.SearchContext searchContext, + @NonNull final Consumer<AppSearchResult<AppSearchSession>> callback) { + if (mAppSearchManager == null) { + Slog.e(TAG, "app search manager is null"); + return; + } + final long callingIdentity = Binder.clearCallingIdentity(); + try { + mAppSearchManager.createSearchSession(searchContext, mExecutor, callback); + } finally { + Binder.restoreCallingIdentity(callingIdentity); + } + } } diff --git a/services/core/java/com/android/server/pm/UserManagerInternal.java b/services/core/java/com/android/server/pm/UserManagerInternal.java index c17d2e4b0c62..eb2de6012745 100644 --- a/services/core/java/com/android/server/pm/UserManagerInternal.java +++ b/services/core/java/com/android/server/pm/UserManagerInternal.java @@ -63,8 +63,13 @@ public abstract class UserManagerInternal { */ public interface UserLifecycleListener { - /** Called when a new user is created. */ - default void onUserCreated(UserInfo user) {} + /** + * Called when a new user is created. + * + * @param user new user. + * @param token token passed to the method that created the user. + */ + default void onUserCreated(UserInfo user, @Nullable Object token) {} /** Called when an existing user is removed. */ default void onUserRemoved(UserInfo user) {} @@ -179,10 +184,12 @@ public abstract class UserManagerInternal { * {@link UserManager#DISALLOW_ADD_USER} and {@link UserManager#DISALLOW_ADD_MANAGED_PROFILE} * * <p>Called by the {@link com.android.server.devicepolicy.DevicePolicyManagerService} when - * createAndManageUser is called by the device owner. + * createAndManageUser is called by the device owner; it uses {@code token} to block until + * the user is created (as it will be passed back to it through + * {@link UserLifecycleListener#onUserCreated(UserInfo, Object)}); */ public abstract UserInfo createUserEvenWhenDisallowed(String name, String userType, - int flags, String[] disallowedPackages) + int flags, String[] disallowedPackages, @Nullable Object token) throws UserManager.CheckedUserOperationException; /** diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java index c75dd27a383a..871576e7c795 100644 --- a/services/core/java/com/android/server/pm/UserManagerService.java +++ b/services/core/java/com/android/server/pm/UserManagerService.java @@ -1526,11 +1526,18 @@ public class UserManagerService extends IUserManager.Stub { } @Override - public boolean isUserForeground() { - int callingUserId = Binder.getCallingUserHandle().getIdentifier(); + public boolean isUserForeground(@UserIdInt int userId) { + final int callingUserId = UserHandle.getCallingUserId(); + if (callingUserId != userId + && !hasManageUsersOrPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)) { + throw new SecurityException("Caller from user " + callingUserId + " needs MANAGE_USERS " + + "or INTERACT_ACROSS_USERS permission to check if another user (" + userId + + ") is running in the foreground"); + } + int currentUser = Binder.withCleanCallingIdentity(() -> ActivityManager.getCurrentUser()); // TODO(b/179163496): should return true for profile users of the current user as well - return currentUser == callingUserId; + return currentUser == userId; } @Override @@ -3316,7 +3323,7 @@ public class UserManagerService extends IUserManager.Stub { checkManageOrCreateUsersPermission(flags); try { return createUserInternalUnchecked(name, userType, flags, userId, - /* preCreate= */ false, disallowedPackages); + /* preCreate= */ false, disallowedPackages, /* token= */ null); } catch (UserManager.CheckedUserOperationException e) { throw e.toServiceSpecificException(); } @@ -3349,7 +3356,7 @@ public class UserManagerService extends IUserManager.Stub { try { return createUserInternalUnchecked(/* name= */ null, userType, flags, /* parentId= */ UserHandle.USER_NULL, /* preCreate= */ true, - /* disallowedPackages= */ null); + /* disallowedPackages= */ null, /* token= */ null); } catch (UserManager.CheckedUserOperationException e) { throw e.toServiceSpecificException(); } @@ -3365,12 +3372,13 @@ public class UserManagerService extends IUserManager.Stub { enforceUserRestriction(restriction, UserHandle.getCallingUserId(), "Cannot add user"); return createUserInternalUnchecked(name, userType, flags, parentId, - /* preCreate= */ false, disallowedPackages); + /* preCreate= */ false, disallowedPackages, /* token= */ null); } private UserInfo createUserInternalUnchecked(@Nullable String name, @NonNull String userType, @UserInfoFlag int flags, @UserIdInt int parentId, - boolean preCreate, @Nullable String[] disallowedPackages) + boolean preCreate, @Nullable String[] disallowedPackages, + @Nullable Object token) throws UserManager.CheckedUserOperationException { final int nextProbableUserId = getNextAvailableId(); final TimingsTraceAndSlog t = new TimingsTraceAndSlog(); @@ -3379,7 +3387,7 @@ public class UserManagerService extends IUserManager.Stub { UserInfo newUser = null; try { newUser = createUserInternalUncheckedNoTracing(name, userType, flags, parentId, - preCreate, disallowedPackages, t); + preCreate, disallowedPackages, t, token); return newUser; } finally { logUserCreateJourneyFinish(sessionId, nextProbableUserId, newUser != null); @@ -3390,7 +3398,8 @@ public class UserManagerService extends IUserManager.Stub { private UserInfo createUserInternalUncheckedNoTracing(@Nullable String name, @NonNull String userType, @UserInfoFlag int flags, @UserIdInt int parentId, boolean preCreate, @Nullable String[] disallowedPackages, - @NonNull TimingsTraceAndSlog t) throws UserManager.CheckedUserOperationException { + @NonNull TimingsTraceAndSlog t, @Nullable Object token) + throws UserManager.CheckedUserOperationException { final UserTypeDetails userTypeDetails = mUserTypes.get(userType); if (userTypeDetails == null) { Slog.e(LOG_TAG, "Cannot create user of invalid user type: " + userType); @@ -3416,7 +3425,8 @@ public class UserManagerService extends IUserManager.Stub { // Try to use a pre-created user (if available). if (!preCreate && parentId < 0 && isUserTypeEligibleForPreCreation(userTypeDetails)) { - final UserInfo preCreatedUser = convertPreCreatedUserIfPossible(userType, flags, name); + final UserInfo preCreatedUser = convertPreCreatedUserIfPossible(userType, flags, name, + token); if (preCreatedUser != null) { return preCreatedUser; } @@ -3595,7 +3605,7 @@ public class UserManagerService extends IUserManager.Stub { Slog.w(LOG_TAG, "could not start pre-created user " + userId, e); } } else { - dispatchUserAdded(userInfo); + dispatchUserAdded(userInfo, token); } } finally { @@ -3695,7 +3705,7 @@ public class UserManagerService extends IUserManager.Stub { * @return the converted user, or {@code null} if no pre-created user could be converted. */ private @Nullable UserInfo convertPreCreatedUserIfPossible(String userType, - @UserInfoFlag int flags, String name) { + @UserInfoFlag int flags, String name, @Nullable Object token) { final UserData preCreatedUserData; synchronized (mUsersLock) { preCreatedUserData = getPreCreatedUserLU(userType); @@ -3733,7 +3743,7 @@ public class UserManagerService extends IUserManager.Stub { } updateUserIds(); mPm.onNewUserCreated(preCreatedUser.id, /* convertedFromPreCreated= */ true); - dispatchUserAdded(preCreatedUser); + dispatchUserAdded(preCreatedUser, token); return preCreatedUser; } @@ -3765,11 +3775,11 @@ public class UserManagerService extends IUserManager.Stub { return (now > EPOCH_PLUS_30_YEARS) ? now : 0; } - private void dispatchUserAdded(@NonNull UserInfo userInfo) { + private void dispatchUserAdded(@NonNull UserInfo userInfo, @Nullable Object token) { // Notify internal listeners first... synchronized (mUserLifecycleListeners) { for (int i = 0; i < mUserLifecycleListeners.size(); i++) { - mUserLifecycleListeners.get(i).onUserCreated(userInfo); + mUserLifecycleListeners.get(i).onUserCreated(userInfo, token); } } @@ -5374,10 +5384,10 @@ public class UserManagerService extends IUserManager.Stub { @Override public UserInfo createUserEvenWhenDisallowed(String name, @NonNull String userType, - @UserInfoFlag int flags, String[] disallowedPackages) + @UserInfoFlag int flags, String[] disallowedPackages, @Nullable Object token) throws UserManager.CheckedUserOperationException { return createUserInternalUnchecked(name, userType, flags, - UserHandle.USER_NULL, /* preCreated= */ false, disallowedPackages); + UserHandle.USER_NULL, /* preCreated= */ false, disallowedPackages, token); } @Override diff --git a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java index 44a2187aed8e..e3ccb7521b58 100644 --- a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java +++ b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java @@ -1277,12 +1277,7 @@ final class DefaultPermissionGrantPolicy { newFlags |= (flags & PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT); // If we are allowlisting the permission, update the exempt flag before grant. - // If the permission can't be allowlisted by an installer, skip it here because - // this is where the platform takes the role of the installer for exempting - // preinstalled apps. - if (whitelistRestrictedPermissions && pm.isPermissionRestricted(permission) - && !pm.getPermissionInfo(permission).isInstallerExemptIgnored()) { - + if (whitelistRestrictedPermissions && pm.isPermissionRestricted(permission)) { pm.updatePermissionFlags(permission, pkg, PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT, PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT, user); diff --git a/services/core/java/com/android/server/pm/permission/Permission.java b/services/core/java/com/android/server/pm/permission/Permission.java index 32bee5809b11..ac50f29fbf32 100644 --- a/services/core/java/com/android/server/pm/permission/Permission.java +++ b/services/core/java/com/android/server/pm/permission/Permission.java @@ -239,10 +239,6 @@ public final class Permission { return (mPermissionInfo.flags & PermissionInfo.FLAG_IMMUTABLY_RESTRICTED) != 0; } - public boolean isInstallerExemptIgnored() { - return (mPermissionInfo.flags & PermissionInfo.FLAG_INSTALLER_EXEMPT_IGNORED) != 0; - } - public boolean isSignature() { return (mPermissionInfo.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE) == PermissionInfo.PROTECTION_SIGNATURE; diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java index 7a936ec29498..2dfb6ff3e9a8 100644 --- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java +++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java @@ -24,14 +24,12 @@ import static android.app.AppOpsManager.MODE_IGNORED; import static android.content.pm.ApplicationInfo.AUTO_REVOKE_DISALLOWED; import static android.content.pm.ApplicationInfo.AUTO_REVOKE_DISCOURAGED; import static android.content.pm.PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT; -import static android.content.pm.PackageManager.FLAG_PERMISSION_ALLOWLIST_ROLE; import static android.content.pm.PackageManager.FLAG_PERMISSION_APPLY_RESTRICTION; import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT; import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_ROLE; import static android.content.pm.PackageManager.FLAG_PERMISSION_ONE_TIME; import static android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED; import static android.content.pm.PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT; -import static android.content.pm.PackageManager.FLAG_PERMISSION_RESTRICTION_ROLE_EXEMPT; import static android.content.pm.PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT; import static android.content.pm.PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT; import static android.content.pm.PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED; @@ -771,10 +769,6 @@ public class PermissionManagerService extends IPermissionManager.Stub { isRuntimePermission = bp.isRuntime(); - if (bp.isInstallerExemptIgnored()) { - flagValues &= ~FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT; - } - final UidPermissionState uidState = getUidStateLocked(pkg, userId); if (uidState == null) { Slog.e(TAG, "Missing permissions state for " + packageName + " and user " + userId); @@ -1018,8 +1012,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { Preconditions.checkFlagsArgument(flags, PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE | PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM - | PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER - | PackageManager.FLAG_PERMISSION_ALLOWLIST_ROLE); + | PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER); Preconditions.checkArgumentNonNegative(userId, null); if (UserHandle.getCallingUserId() != userId) { @@ -1043,9 +1036,9 @@ public class PermissionManagerService extends IPermissionManager.Stub { final boolean isCallerInstallerOnRecord = mPackageManagerInt.isCallerInstallerOfRecord(pkg, callingUid); - if ((flags & (PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM - | PackageManager.FLAG_PERMISSION_ALLOWLIST_ROLE)) != 0 && !isCallerPrivileged) { - throw new SecurityException("Querying system or role allowlist requires " + if ((flags & PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM) != 0 + && !isCallerPrivileged) { + throw new SecurityException("Querying system allowlist requires " + Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS); } @@ -1087,9 +1080,6 @@ public class PermissionManagerService extends IPermissionManager.Stub { if ((flags & PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER) != 0) { queryFlags |= FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT; } - if ((flags & PackageManager.FLAG_PERMISSION_ALLOWLIST_ROLE) != 0) { - queryFlags |= FLAG_PERMISSION_RESTRICTION_ROLE_EXEMPT; - } ArrayList<String> allowlistedPermissions = null; @@ -1182,8 +1172,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { Preconditions.checkFlagsArgument(flags, PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE | PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM - | PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER - | PackageManager.FLAG_PERMISSION_ALLOWLIST_ROLE); + | PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER); Preconditions.checkArgument(Integer.bitCount(flags) == 1); Preconditions.checkArgumentNonNegative(userId, null); @@ -1209,10 +1198,8 @@ public class PermissionManagerService extends IPermissionManager.Stub { final boolean isCallerInstallerOnRecord = mPackageManagerInt.isCallerInstallerOfRecord(pkg, callingUid); - if ((flags & (PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM - | PackageManager.FLAG_PERMISSION_ALLOWLIST_ROLE)) != 0 - && !isCallerPrivileged) { - throw new SecurityException("Modifying system or role allowlist requires " + if ((flags & PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM) != 0 && !isCallerPrivileged) { + throw new SecurityException("Modifying system allowlist requires " + Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS); } @@ -3718,15 +3705,6 @@ public class PermissionManagerService extends IPermissionManager.Stub { } } break; - case FLAG_PERMISSION_ALLOWLIST_ROLE: { - mask |= FLAG_PERMISSION_RESTRICTION_ROLE_EXEMPT; - if (permissions != null && permissions.contains(permissionName)) { - newFlags |= FLAG_PERMISSION_RESTRICTION_ROLE_EXEMPT; - } else { - newFlags &= ~FLAG_PERMISSION_RESTRICTION_ROLE_EXEMPT; - } - } - break; } } diff --git a/services/core/java/com/android/server/pm/verify/domain/DomainVerificationCollector.java b/services/core/java/com/android/server/pm/verify/domain/DomainVerificationCollector.java index 080de73ff933..e3cf67c34dad 100644 --- a/services/core/java/com/android/server/pm/verify/domain/DomainVerificationCollector.java +++ b/services/core/java/com/android/server/pm/verify/domain/DomainVerificationCollector.java @@ -42,6 +42,8 @@ public class DomainVerificationCollector { private static final Pattern DOMAIN_NAME_WITH_WILDCARD = Pattern.compile("(\\*\\.)?" + Patterns.DOMAIN_NAME.pattern()); + private static final int MAX_DOMAINS_BYTE_SIZE = 1024 * 1024; + @NonNull private final PlatformCompat mPlatformCompat; @@ -71,7 +73,7 @@ public class DomainVerificationCollector { * <li>- Only IntentFilter.SCHEME_HTTP and/or IntentFilter.SCHEME_HTTPS, * with no other schemes</li> * </ul> - * + * <p> * On prior versions of Android, Intent.CATEGORY_BROWSABLE was not a requirement, other * schemes were allowed, and setting autoVerify to true in any intent filter would implicitly * pretend that all intent filters were set to autoVerify="true". @@ -86,8 +88,8 @@ public class DomainVerificationCollector { } /** - * Effectively {@link #collectAllWebDomains(AndroidPackage)}, but requires - * {@link IntentFilter#getAutoVerify()} == true. + * Effectively {@link #collectAllWebDomains(AndroidPackage)}, but requires {@link + * IntentFilter#getAutoVerify()} == true. */ @NonNull public ArraySet<String> collectAutoVerifyDomains(@NonNull AndroidPackage pkg) { @@ -100,24 +102,21 @@ public class DomainVerificationCollector { boolean restrictDomains = DomainVerificationUtils.isChangeEnabled(mPlatformCompat, pkg, RESTRICT_DOMAINS); - ArraySet<String> domains = new ArraySet<>(); - if (restrictDomains) { - collectDomains(domains, pkg, checkAutoVerify); + return collectDomainsInternal(pkg, checkAutoVerify); } else { - collectDomainsLegacy(domains, pkg, checkAutoVerify); + return collectDomainsLegacy(pkg, checkAutoVerify); } - - return domains; } - /** @see #RESTRICT_DOMAINS */ - private void collectDomainsLegacy(@NonNull Set<String> domains, - @NonNull AndroidPackage pkg, boolean checkAutoVerify) { + /** + * @see #RESTRICT_DOMAINS + */ + private ArraySet<String> collectDomainsLegacy(@NonNull AndroidPackage pkg, + boolean checkAutoVerify) { if (!checkAutoVerify) { // Per-domain user selection state doesn't have a V1 equivalent on S, so just use V2 - collectDomains(domains, pkg, false); - return; + return collectDomainsInternal(pkg, false); } List<ParsedActivity> activities = pkg.getActivities(); @@ -140,39 +139,54 @@ public class DomainVerificationCollector { } if (!needsAutoVerify) { - return; + return new ArraySet<>(); } } - for (int activityIndex = 0; activityIndex < activitiesSize; activityIndex++) { + ArraySet<String> domains = new ArraySet<>(); + int totalSize = 0; + boolean underMaxSize = true; + for (int activityIndex = 0; activityIndex < activitiesSize && underMaxSize; + activityIndex++) { ParsedActivity activity = activities.get(activityIndex); List<ParsedIntentInfo> intents = activity.getIntents(); int intentsSize = intents.size(); - for (int intentIndex = 0; intentIndex < intentsSize; intentIndex++) { + for (int intentIndex = 0; intentIndex < intentsSize && underMaxSize; intentIndex++) { ParsedIntentInfo intent = intents.get(intentIndex); if (intent.handlesWebUris(false)) { int authorityCount = intent.countDataAuthorities(); for (int index = 0; index < authorityCount; index++) { String host = intent.getDataAuthority(index).getHost(); if (isValidHost(host)) { + totalSize += byteSizeOf(host); + underMaxSize = totalSize < MAX_DOMAINS_BYTE_SIZE; domains.add(host); } } } } } + + return domains; } - /** @see #RESTRICT_DOMAINS */ - private void collectDomains(@NonNull Set<String> domains, - @NonNull AndroidPackage pkg, boolean checkAutoVerify) { + /** + * @see #RESTRICT_DOMAINS + */ + private ArraySet<String> collectDomainsInternal(@NonNull AndroidPackage pkg, + boolean checkAutoVerify) { + ArraySet<String> domains = new ArraySet<>(); + int totalSize = 0; + boolean underMaxSize = true; + List<ParsedActivity> activities = pkg.getActivities(); int activitiesSize = activities.size(); - for (int activityIndex = 0; activityIndex < activitiesSize; activityIndex++) { + for (int activityIndex = 0; activityIndex < activitiesSize && underMaxSize; + activityIndex++) { ParsedActivity activity = activities.get(activityIndex); List<ParsedIntentInfo> intents = activity.getIntents(); int intentsSize = intents.size(); - for (int intentIndex = 0; intentIndex < intentsSize; intentIndex++) { + for (int intentIndex = 0; intentIndex < intentsSize && underMaxSize; intentIndex++) { ParsedIntentInfo intent = intents.get(intentIndex); if (checkAutoVerify && !intent.getAutoVerify()) { continue; @@ -198,14 +212,27 @@ public class DomainVerificationCollector { // app developer by declaring a separate intent-filter. This may not be worth // fixing. int authorityCount = intent.countDataAuthorities(); - for (int index = 0; index < authorityCount; index++) { + for (int index = 0; index < authorityCount && underMaxSize; index++) { String host = intent.getDataAuthority(index).getHost(); if (isValidHost(host)) { + totalSize += byteSizeOf(host); + underMaxSize = totalSize < MAX_DOMAINS_BYTE_SIZE; domains.add(host); } } } } + + return domains; + } + + /** + * Ballpark the size of domains to avoid a ridiculous amount of domains that could slow + * down client-server communication. + */ + private int byteSizeOf(String string) { + // Use the same method from core for the data objects so that restrictions are consistent + return android.content.pm.verify.domain.DomainVerificationUtils.estimatedByteSizeOf(string); } /** diff --git a/services/core/java/com/android/server/pm/verify/domain/DomainVerificationEnforcer.java b/services/core/java/com/android/server/pm/verify/domain/DomainVerificationEnforcer.java index 275dd053fdde..ed37fa0da01f 100644 --- a/services/core/java/com/android/server/pm/verify/domain/DomainVerificationEnforcer.java +++ b/services/core/java/com/android/server/pm/verify/domain/DomainVerificationEnforcer.java @@ -185,6 +185,29 @@ public class DomainVerificationEnforcer { return !mCallback.filterAppAccess(packageName, callingUid, targetUserId); } + /** + * Querying for the owners of a domain. Because this API cannot filter the returned list of + * packages, enforces {@link android.Manifest.permission.QUERY_ALL_PACKAGES}, but also enforces + * {@link android.Manifest.permission.INTERACT_ACROSS_USERS} because each user has a different + * state. + */ + public void assertOwnerQuerent(int callingUid, @UserIdInt int callingUserId, + @UserIdInt int targetUserId) { + final int callingPid = Binder.getCallingPid(); + if (callingUserId != targetUserId) { + mContext.enforcePermission(android.Manifest.permission.INTERACT_ACROSS_USERS, + callingPid, callingUid, "Caller is not allowed to query other users"); + } + + mContext.enforcePermission(android.Manifest.permission.QUERY_ALL_PACKAGES, + callingPid, callingUid, "Caller " + callingUid + " does not hold " + + android.Manifest.permission.QUERY_ALL_PACKAGES); + + mContext.enforcePermission( + android.Manifest.permission.UPDATE_DOMAIN_VERIFICATION_USER_SELECTION, + callingPid, callingUid, "Caller is not allowed to query user selections"); + } + public interface Callback { /** * @return true if access to the given package should be filtered and the method failed as diff --git a/services/core/java/com/android/server/pm/verify/domain/DomainVerificationManagerStub.java b/services/core/java/com/android/server/pm/verify/domain/DomainVerificationManagerStub.java index 8aa63372b826..6f2810785c60 100644 --- a/services/core/java/com/android/server/pm/verify/domain/DomainVerificationManagerStub.java +++ b/services/core/java/com/android/server/pm/verify/domain/DomainVerificationManagerStub.java @@ -20,13 +20,14 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; import android.content.pm.PackageManager.NameNotFoundException; +import android.content.pm.verify.domain.DomainOwner; +import android.content.pm.verify.domain.DomainSet; +import android.content.pm.verify.domain.DomainVerificationInfo; import android.content.pm.verify.domain.DomainVerificationManager.InvalidDomainSetException; import android.content.pm.verify.domain.DomainVerificationManagerImpl; -import android.content.pm.verify.domain.DomainVerificationInfo; import android.content.pm.verify.domain.DomainVerificationUserSelection; import android.content.pm.verify.domain.IDomainVerificationManager; import android.os.ServiceSpecificException; -import android.util.ArraySet; import java.util.List; import java.util.UUID; @@ -61,11 +62,11 @@ class DomainVerificationManagerStub extends IDomainVerificationManager.Stub { } @Override - public void setDomainVerificationStatus(String domainSetId, List<String> domains, + public void setDomainVerificationStatus(String domainSetId, @NonNull DomainSet domainSet, int state) { try { mService.setDomainVerificationStatus(UUID.fromString(domainSetId), - new ArraySet<>(domains), state); + domainSet.getDomains(), state); } catch (Exception e) { throw rethrow(e); } @@ -82,11 +83,11 @@ class DomainVerificationManagerStub extends IDomainVerificationManager.Stub { } @Override - public void setDomainVerificationUserSelection(String domainSetId, List<String> domains, + public void setDomainVerificationUserSelection(String domainSetId, @NonNull DomainSet domainSet, boolean enabled, @UserIdInt int userId) { try { mService.setDomainVerificationUserSelection(UUID.fromString(domainSetId), - new ArraySet<>(domains), enabled, userId); + domainSet.getDomains(), enabled, userId); } catch (Exception e) { throw rethrow(e); } @@ -103,6 +104,17 @@ class DomainVerificationManagerStub extends IDomainVerificationManager.Stub { } } + @Nullable + @Override + public List<DomainOwner> getOwnersForDomain(@NonNull String domain, + @UserIdInt int userId) { + try { + return mService.getOwnersForDomain(domain, userId); + } catch (Exception e) { + throw rethrow(e); + } + } + private RuntimeException rethrow(Exception exception) throws RuntimeException { if (exception instanceof InvalidDomainSetException) { int packedErrorCode = DomainVerificationManagerImpl.ERROR_INVALID_DOMAIN_SET; diff --git a/services/core/java/com/android/server/pm/verify/domain/DomainVerificationService.java b/services/core/java/com/android/server/pm/verify/domain/DomainVerificationService.java index 8dcb45ff5ab6..b58c1ff374d5 100644 --- a/services/core/java/com/android/server/pm/verify/domain/DomainVerificationService.java +++ b/services/core/java/com/android/server/pm/verify/domain/DomainVerificationService.java @@ -17,6 +17,7 @@ package com.android.server.pm.verify.domain; import static java.util.Collections.emptyList; +import static java.util.Collections.emptySet; import android.annotation.NonNull; import android.annotation.Nullable; @@ -30,6 +31,7 @@ import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.ResolveInfo; import android.content.pm.parsing.component.ParsedActivity; +import android.content.pm.verify.domain.DomainOwner; import android.content.pm.verify.domain.DomainVerificationInfo; import android.content.pm.verify.domain.DomainVerificationManager; import android.content.pm.verify.domain.DomainVerificationState; @@ -291,6 +293,8 @@ public class DomainVerificationService extends SystemService throws InvalidDomainSetException, NameNotFoundException { mEnforcer.assertApprovedVerifier(callingUid, mProxy); synchronized (mLock) { + List<String> verifiedDomains = new ArrayList<>(); + DomainVerificationPkgState pkgState = getAndValidateAttachedLocked(domainSetId, domains, true /* forAutoVerify */, callingUid, null /* userId */); ArrayMap<String, Integer> stateMap = pkgState.getStateMap(); @@ -301,8 +305,17 @@ public class DomainVerificationService extends SystemService continue; } + if (DomainVerificationManager.isStateVerified(state)) { + verifiedDomains.add(domain); + } + stateMap.put(domain, state); } + + int size = verifiedDomains.size(); + for (int index = 0; index < size; index++) { + removeUserSelectionsForDomain(verifiedDomains.get(index)); + } } mConnection.scheduleWriteSettings(); @@ -387,6 +400,20 @@ public class DomainVerificationService extends SystemService } } + private void removeUserSelectionsForDomain(@NonNull String domain) { + synchronized (mLock) { + final int size = mAttachedPkgStates.size(); + for (int index = 0; index < size; index++) { + DomainVerificationPkgState pkgState = mAttachedPkgStates.valueAt(index); + SparseArray<DomainVerificationUserState> array = pkgState.getUserSelectionStates(); + int arraySize = array.size(); + for (int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++) { + array.valueAt(arrayIndex).removeHost(domain); + } + } + } + } + @Override public void setDomainVerificationLinkHandlingAllowed(@NonNull String packageName, boolean allowed) throws NameNotFoundException { @@ -470,19 +497,59 @@ public class DomainVerificationService extends SystemService InvalidDomainSetException.REASON_ID_INVALID); } + DomainVerificationPkgState pkgState = getAndValidateAttachedLocked(domainSetId, domains, + false /* forAutoVerify */, callingUid, userId); + DomainVerificationUserState userState = pkgState.getOrCreateUserSelectionState(userId); + + // Disable other packages if approving this one. Note that this check is only done for + // enabling. This allows an escape hatch in case multiple packages somehow get selected. + // They can be disabled without blocking in a circular dependency. if (enabled) { + // Cache the approved packages from the 1st pass because the search is expensive + ArrayMap<String, List<String>> domainToApprovedPackages = new ArrayMap<>(); + for (String domain : domains) { - if (!getApprovedPackages(domain, userId, APPROVAL_LEVEL_LEGACY_ALWAYS + 1, - mConnection::getPackageSettingLocked).first.isEmpty()) { + if (userState.getEnabledHosts().contains(domain)) { + continue; + } + + Pair<List<String>, Integer> packagesToLevel = getApprovedPackages(domain, + userId, APPROVAL_LEVEL_NONE + 1, mConnection::getPackageSettingLocked); + int highestApproval = packagesToLevel.second; + if (highestApproval > APPROVAL_LEVEL_SELECTION) { throw new InvalidDomainSetException(domainSetId, null, InvalidDomainSetException.REASON_UNABLE_TO_APPROVE); } + + domainToApprovedPackages.put(domain, packagesToLevel.first); + } + + // The removal for other packages must be done in a 2nd pass after it's determined + // that no higher priority owners exist for all of the domains in the set. + int mapSize = domainToApprovedPackages.size(); + for (int mapIndex = 0; mapIndex < mapSize; mapIndex++) { + String domain = domainToApprovedPackages.keyAt(mapIndex); + List<String> approvedPackages = domainToApprovedPackages.valueAt(mapIndex); + int approvedSize = approvedPackages.size(); + for (int approvedIndex = 0; approvedIndex < approvedSize; approvedIndex++) { + String approvedPackage = approvedPackages.get(approvedIndex); + DomainVerificationPkgState approvedPkgState = + mAttachedPkgStates.get(approvedPackage); + if (approvedPkgState == null) { + continue; + } + + DomainVerificationUserState approvedUserState = + approvedPkgState.getUserSelectionState(userId); + if (approvedUserState == null) { + continue; + } + + approvedUserState.removeHost(domain); + } } } - DomainVerificationPkgState pkgState = getAndValidateAttachedLocked(domainSetId, domains, - false /* forAutoVerify */, callingUid, userId); - DomainVerificationUserState userState = pkgState.getOrCreateUserSelectionState(userId); if (enabled) { userState.addHosts(domains); } else { @@ -600,28 +667,109 @@ public class DomainVerificationService extends SystemService throw DomainVerificationUtils.throwPackageUnavailable(packageName); } - ArrayMap<String, Boolean> hostToUserSelectionMap = new ArrayMap<>(); - - ArraySet<String> domains = mCollector.collectAllWebDomains(pkg); - int domainsSize = domains.size(); - for (int index = 0; index < domainsSize; index++) { - hostToUserSelectionMap.put(domains.valueAt(index), false); - } + ArraySet<String> webDomains = mCollector.collectAllWebDomains(pkg); + int webDomainsSize = webDomains.size(); + Map<String, Integer> domains = new ArrayMap<>(webDomainsSize); + ArrayMap<String, Integer> stateMap = pkgState.getStateMap(); DomainVerificationUserState userState = pkgState.getUserSelectionState(userId); - boolean linkHandlingAllowed = true; - if (userState != null) { - linkHandlingAllowed = userState.isLinkHandlingAllowed(); - ArraySet<String> enabledHosts = userState.getEnabledHosts(); - int hostsSize = enabledHosts.size(); - for (int index = 0; index < hostsSize; index++) { - hostToUserSelectionMap.put(enabledHosts.valueAt(index), true); + Set<String> enabledHosts = userState == null ? emptySet() : userState.getEnabledHosts(); + + for (int index = 0; index < webDomainsSize; index++) { + String host = webDomains.valueAt(index); + Integer state = stateMap.get(host); + + int domainState; + if (state != null && DomainVerificationManager.isStateVerified(state)) { + domainState = DomainVerificationUserSelection.DOMAIN_STATE_VERIFIED; + } else if (enabledHosts.contains(host)) { + domainState = DomainVerificationUserSelection.DOMAIN_STATE_SELECTED; + } else { + domainState = DomainVerificationUserSelection.DOMAIN_STATE_NONE; } + + domains.put(host, domainState); } + boolean linkHandlingAllowed = userState == null || userState.isLinkHandlingAllowed(); + return new DomainVerificationUserSelection(pkgState.getId(), packageName, - UserHandle.of(userId), linkHandlingAllowed, hostToUserSelectionMap); + UserHandle.of(userId), linkHandlingAllowed, domains); + } + } + + @NonNull + @Override + public List<DomainOwner> getOwnersForDomain(@NonNull String domain) { + return getOwnersForDomain(domain, mConnection.getCallingUserId()); + } + + public List<DomainOwner> getOwnersForDomain(@NonNull String domain, @UserIdInt int userId) { + mEnforcer.assertOwnerQuerent(mConnection.getCallingUid(), mConnection.getCallingUserId(), + userId); + + SparseArray<List<String>> levelToPackages = new SparseArray<>(); + + // First, collect the raw approval level values + synchronized (mLock) { + final int size = mAttachedPkgStates.size(); + for (int index = 0; index < size; index++) { + DomainVerificationPkgState pkgState = mAttachedPkgStates.valueAt(index); + String packageName = pkgState.getPackageName(); + PackageSetting pkgSetting = mConnection.getPackageSettingLocked(packageName); + if (pkgSetting == null) { + continue; + } + + int level = approvalLevelForDomain(pkgSetting, domain, userId, domain); + if (level <= APPROVAL_LEVEL_NONE) { + continue; + } + List<String> list = levelToPackages.get(level); + if (list == null) { + list = new ArrayList<>(); + levelToPackages.put(level, list); + } + list.add(packageName); + } + } + + final int size = levelToPackages.size(); + if (size == 0) { + return emptyList(); + } + + // Then sort them ascending by first installed time, with package name as the tie breaker + for (int index = 0; index < size; index++) { + levelToPackages.valueAt(index).sort((first, second) -> { + PackageSetting firstPkgSetting = mConnection.getPackageSettingLocked(first); + PackageSetting secondPkgSetting = mConnection.getPackageSettingLocked(second); + + long firstInstallTime = + firstPkgSetting == null ? -1L : firstPkgSetting.getFirstInstallTime(); + long secondInstallTime = + secondPkgSetting == null ? -1L : secondPkgSetting.getFirstInstallTime(); + + if (firstInstallTime != secondInstallTime) { + return (int) (firstInstallTime - secondInstallTime); + } + + return first.compareToIgnoreCase(second); + }); } + + List<DomainOwner> owners = new ArrayList<>(); + for (int index = 0; index < size; index++) { + int level = levelToPackages.keyAt(index); + boolean overrideable = level <= APPROVAL_LEVEL_SELECTION; + List<String> packages = levelToPackages.valueAt(index); + int packagesSize = packages.size(); + for (int packageIndex = 0; packageIndex < packagesSize; packageIndex++) { + owners.add(new DomainOwner(packages.get(packageIndex), overrideable)); + } + } + + return owners; } @NonNull @@ -634,7 +782,7 @@ public class DomainVerificationService extends SystemService @Override public void migrateState(@NonNull PackageSetting oldPkgSetting, @NonNull PackageSetting newPkgSetting) { - String pkgName = newPkgSetting.name; + String pkgName = newPkgSetting.getName(); boolean sendBroadcast; synchronized (mLock) { @@ -730,7 +878,7 @@ public class DomainVerificationService extends SystemService // gains or loses all domains. UUID domainSetId = newPkgSetting.getDomainSetId(); - String pkgName = newPkgSetting.name; + String pkgName = newPkgSetting.getName(); boolean sendBroadcast = true; @@ -1347,7 +1495,7 @@ public class DomainVerificationService extends SystemService @Override public int approvalLevelForDomain(@NonNull PackageSetting pkgSetting, @NonNull Intent intent, @PackageManager.ResolveInfoFlags int resolveInfoFlags, @UserIdInt int userId) { - String packageName = pkgSetting.name; + String packageName = pkgSetting.getName(); if (!DomainVerificationUtils.isDomainVerificationIntent(intent, resolveInfoFlags)) { if (DEBUG_APPROVAL) { debugApproval(packageName, intent, userId, false, "not valid intent"); @@ -1364,7 +1512,7 @@ public class DomainVerificationService extends SystemService */ private int approvalLevelForDomain(@NonNull PackageSetting pkgSetting, @NonNull String host, @UserIdInt int userId, @NonNull Object debugObject) { - String packageName = pkgSetting.name; + String packageName = pkgSetting.getName(); final AndroidPackage pkg = pkgSetting.getPkg(); // Should never be null, but if it is, skip this and assume that v2 is enabled diff --git a/services/core/java/com/android/server/pm/verify/domain/OWNERS b/services/core/java/com/android/server/pm/verify/domain/OWNERS new file mode 100644 index 000000000000..c669112e0512 --- /dev/null +++ b/services/core/java/com/android/server/pm/verify/domain/OWNERS @@ -0,0 +1,5 @@ +# Bug component: 36137 + +chiuwinson@google.com +patb@google.com +toddke@google.com
\ No newline at end of file diff --git a/services/core/java/com/android/server/pm/verify/domain/models/DomainVerificationUserState.java b/services/core/java/com/android/server/pm/verify/domain/models/DomainVerificationUserState.java index 22468640800e..8fbb33afb6ca 100644 --- a/services/core/java/com/android/server/pm/verify/domain/models/DomainVerificationUserState.java +++ b/services/core/java/com/android/server/pm/verify/domain/models/DomainVerificationUserState.java @@ -58,6 +58,11 @@ public class DomainVerificationUserState { return this; } + public DomainVerificationUserState removeHost(String host) { + mEnabledHosts.remove(host); + return this; + } + public DomainVerificationUserState removeHosts(@NonNull ArraySet<String> newHosts) { mEnabledHosts.removeAll(newHosts); return this; diff --git a/services/core/java/com/android/server/storage/StorageSessionController.java b/services/core/java/com/android/server/storage/StorageSessionController.java index 0087c0c29853..917d05ca85b8 100644 --- a/services/core/java/com/android/server/storage/StorageSessionController.java +++ b/services/core/java/com/android/server/storage/StorageSessionController.java @@ -32,6 +32,7 @@ import android.os.ParcelFileDescriptor; import android.os.RemoteException; import android.os.ServiceSpecificException; import android.os.UserHandle; +import android.os.storage.StorageManager; import android.os.storage.StorageVolume; import android.os.storage.VolumeInfo; import android.provider.MediaStore; @@ -371,6 +372,60 @@ public final class StorageSessionController { return mExternalStorageServiceComponent; } + /** + * Notify the controller that an app with {@code uid} and {@code tid} is blocked on an IO + * request on {@code volumeUuid} for {@code reason}. + * + * This blocked state can be queried with {@link #isAppIoBlocked} + * + * @hide + */ + public void notifyAppIoBlocked(String volumeUuid, int uid, int tid, + @StorageManager.AppIoBlockedReason int reason) { + final int userId = UserHandle.getUserId(uid); + final StorageUserConnection connection; + synchronized (mLock) { + connection = mConnections.get(userId); + } + + if (connection != null) { + connection.notifyAppIoBlocked(volumeUuid, uid, tid, reason); + } + } + + /** + * Notify the controller that an app with {@code uid} and {@code tid} has resmed a previously + * blocked IO request on {@code volumeUuid} for {@code reason}. + * + * All app IO will be automatically marked as unblocked if {@code volumeUuid} is unmounted. + */ + public void notifyAppIoResumed(String volumeUuid, int uid, int tid, + @StorageManager.AppIoBlockedReason int reason) { + final int userId = UserHandle.getUserId(uid); + final StorageUserConnection connection; + synchronized (mLock) { + connection = mConnections.get(userId); + } + + if (connection != null) { + connection.notifyAppIoResumed(volumeUuid, uid, tid, reason); + } + } + + /** Returns {@code true} if {@code uid} is blocked on IO, {@code false} otherwise */ + public boolean isAppIoBlocked(int uid) { + final int userId = UserHandle.getUserId(uid); + final StorageUserConnection connection; + synchronized (mLock) { + connection = mConnections.get(userId); + } + + if (connection != null) { + return connection.isAppIoBlocked(uid); + } + return false; + } + private void killExternalStorageService(int userId) { IActivityManager am = ActivityManager.getService(); try { diff --git a/services/core/java/com/android/server/storage/StorageUserConnection.java b/services/core/java/com/android/server/storage/StorageUserConnection.java index 709d558ea0bc..9880d32d5cd1 100644 --- a/services/core/java/com/android/server/storage/StorageUserConnection.java +++ b/services/core/java/com/android/server/storage/StorageUserConnection.java @@ -38,10 +38,12 @@ import android.os.ParcelableException; import android.os.RemoteCallback; import android.os.RemoteException; import android.os.UserHandle; +import android.os.storage.StorageManager; import android.os.storage.StorageManagerInternal; import android.os.storage.StorageVolume; import android.service.storage.ExternalStorageService; import android.service.storage.IExternalStorageService; +import android.util.ArraySet; import android.util.Slog; import com.android.internal.annotations.GuardedBy; @@ -73,6 +75,7 @@ public final class StorageUserConnection { private final StorageSessionController mSessionController; private final ActiveConnection mActiveConnection = new ActiveConnection(); @GuardedBy("mLock") private final Map<String, Session> mSessions = new HashMap<>(); + @GuardedBy("mLock") private final Set<Integer> mUidsBlockedOnIo = new ArraySet<>(); private final HandlerThread mHandlerThread; public StorageUserConnection(Context context, int userId, StorageSessionController controller) { @@ -170,6 +173,7 @@ public final class StorageUserConnection { **/ public Session removeSession(String sessionId) { synchronized (mSessionsLock) { + mUidsBlockedOnIo.clear(); return mSessions.remove(sessionId); } } @@ -232,6 +236,41 @@ public final class StorageUserConnection { } } + /** + * Notify the controller that an app with {@code uid} and {@code tid} is blocked on an IO + * request on {@code volumeUuid} for {@code reason}. + * + * This blocked state can be queried with {@link #isAppIoBlocked} + * + * @hide + */ + public void notifyAppIoBlocked(String volumeUuid, int uid, int tid, + @StorageManager.AppIoBlockedReason int reason) { + synchronized (mSessionsLock) { + mUidsBlockedOnIo.add(uid); + } + } + + /** + * Notify the connection that an app with {@code uid} and {@code tid} has resmed a previously + * blocked IO request on {@code volumeUuid} for {@code reason}. + * + * All app IO will be automatically marked as unblocked if {@code volumeUuid} is unmounted. + */ + public void notifyAppIoResumed(String volumeUuid, int uid, int tid, + @StorageManager.AppIoBlockedReason int reason) { + synchronized (mSessionsLock) { + mUidsBlockedOnIo.remove(uid); + } + } + + /** Returns {@code true} if {@code uid} is blocked on IO, {@code false} otherwise */ + public boolean isAppIoBlocked(int uid) { + synchronized (mSessionsLock) { + return mUidsBlockedOnIo.contains(uid); + } + } + @FunctionalInterface interface AsyncStorageServiceCall { void run(@NonNull IExternalStorageService service, RemoteCallback callback) throws diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index dd9619ae815a..f40f4a98964a 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -40,8 +40,11 @@ import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS; import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; import static android.app.WindowConfiguration.ROTATION_UNDEFINED; +import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; +import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import static android.app.WindowConfiguration.activityTypeToString; +import static android.app.WindowConfiguration.isSplitScreenWindowingMode; import static android.app.servertransaction.TransferSplashScreenViewStateItem.ATTACH_TO; import static android.app.servertransaction.TransferSplashScreenViewStateItem.HANDOVER_TO; import static android.content.Intent.ACTION_MAIN; @@ -209,6 +212,7 @@ import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; import static com.android.server.wm.WindowManagerService.LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND; import static com.android.server.wm.WindowManagerService.LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND_FLOATING; import static com.android.server.wm.WindowManagerService.LETTERBOX_BACKGROUND_SOLID_COLOR; +import static com.android.server.wm.WindowManagerService.MIN_TASK_LETTERBOX_ASPECT_RATIO; import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_NORMAL; import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_PLACE_SURFACES; import static com.android.server.wm.WindowState.LEGACY_POLICY_VISIBILITY; @@ -557,7 +561,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A /** * The precomputed display insets for resolving configuration. It will be non-null if - * {@link #shouldUseSizeCompatMode} returns {@code true}. + * {@link #shouldCreateCompatDisplayInsets} returns {@code true}. */ private CompatDisplayInsets mCompatDisplayInsets; @@ -648,6 +652,18 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A */ private Rect mSizeCompatBounds; + // Whether this activity is in size compatibility mode because its bounds don't fit in parent + // naturally. + private boolean mInSizeCompatModeForBounds = false; + + // Whether this activity is letterboxed for fixed orientation. If letterboxed due to fixed + // orientation then aspect ratio restrictions are also already respected. + // This happens when an activity has fixed orientation which doesn't match orientation of the + // parent because a display is ignoring orientation request or fixed to user rotation. + // See WindowManagerService#getIgnoreOrientationRequest and + // WindowManagerService#getFixedToUserRotation for more context. + private boolean mIsLetterboxedForFixedOrientationAndAspectRatio = false; + // activity is not displayed? // TODO: rename to mNoDisplay @VisibleForTesting @@ -1296,9 +1312,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A // TODO(b/36505427): Maybe this call should be moved inside // updateOverrideConfiguration() newTask.updateOverrideConfigurationFromLaunchBounds(); - // Make sure override configuration is up-to-date before using to create window - // controller. - updateSizeCompatMode(); // When an activity is started directly into a split-screen fullscreen root task, we // need to update the initial multi-window modes so that the callbacks are scheduled // correctly when the user leaves that mode. @@ -6718,12 +6731,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } if (onDescendantOrientationChanged(this)) { - // The app is just becoming visible, and the parent Task has updated with the - // orientation request. Update the size compat mode. - updateSizeCompatMode(); - // WM Shell can override WM Core positioning (e.g. for letterboxing) so ensure - // that WM Shell is called when an activity becomes visible. Without this, WM Core - // will handle positioning instead of WM Shell when an app is reopened. + // WM Shell can show additional UI elements, e.g. a restart button for size compat mode + // so ensure that WM Shell is called when an activity becomes visible. task.dispatchTaskInfoChangedIfNeeded(/* force= */ true); } } @@ -6788,7 +6797,10 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A * density than its parent or its bounds don't fit in parent naturally. */ boolean inSizeCompatMode() { - if (mCompatDisplayInsets == null || !shouldUseSizeCompatMode() + if (mInSizeCompatModeForBounds) { + return true; + } + if (mCompatDisplayInsets == null || !shouldCreateCompatDisplayInsets() // The orientation is different from parent when transforming. || isFixedRotationTransforming()) { return false; @@ -6798,70 +6810,30 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A // The app bounds hasn't been computed yet. return false; } - final Configuration parentConfig = getParent().getConfiguration(); // Although colorMode, screenLayout, smallestScreenWidthDp are also fixed, generally these // fields should be changed with density and bounds, so here only compares the most // significant field. - if (parentConfig.densityDpi != getConfiguration().densityDpi) { - return true; - } - - final Rect parentAppBounds = parentConfig.windowConfiguration.getAppBounds(); - final int appWidth = appBounds.width(); - final int appHeight = appBounds.height(); - final int parentAppWidth = parentAppBounds.width(); - final int parentAppHeight = parentAppBounds.height(); - if (parentAppWidth == appWidth && parentAppHeight == appHeight) { - // Matched the parent bounds. - return false; - } - if (parentAppWidth > appWidth && parentAppHeight > appHeight) { - // Both sides are smaller than the parent. - return true; - } - if (parentAppWidth < appWidth || parentAppHeight < appHeight) { - // One side is larger than the parent. - return true; - } - - // The rest of the condition is that only one side is smaller than the parent, but it still - // needs to exclude the cases where the size is limited by the fixed aspect ratio. - if (info.maxAspectRatio > 0) { - final float aspectRatio = (0.5f + Math.max(appWidth, appHeight)) - / Math.min(appWidth, appHeight); - if (aspectRatio >= info.maxAspectRatio) { - // The current size has reached the max aspect ratio. - return false; - } - } - if (info.minAspectRatio > 0) { - // The activity should have at least the min aspect ratio, so this checks if the parent - // still has available space to provide larger aspect ratio. - final float parentAspectRatio = (0.5f + Math.max(parentAppWidth, parentAppHeight)) - / Math.min(parentAppWidth, parentAppHeight); - if (parentAspectRatio <= info.minAspectRatio) { - // The long side has reached the parent. - return false; - } - } - return true; + return parentConfig.densityDpi != getConfiguration().densityDpi; } /** * Indicates the activity will keep the bounds and screen configuration when it was first * launched, no matter how its parent changes. * + * <p>If {@true}, then {@link CompatDisplayInsets} will be created in {@link + * #resolveOverrideConfiguration} to "freeze" activity bounds and insets. + * * @return {@code true} if this activity is declared as non-resizable and fixed orientation or * aspect ratio. */ - boolean shouldUseSizeCompatMode() { + boolean shouldCreateCompatDisplayInsets() { if (info.supportsSizeChanges() != ActivityInfo.SIZE_CHANGES_UNSUPPORTED) { return false; } if (inMultiWindowMode() || getWindowConfiguration().hasWindowDecorCaption()) { final ActivityRecord root = task != null ? task.getRootActivity() : null; - if (root != null && root != this && !root.shouldUseSizeCompatMode()) { + if (root != null && root != this && !root.shouldCreateCompatDisplayInsets()) { // If the root activity doesn't use size compatibility mode, the activities above // are forced to be the same for consistent visual appearance. return false; @@ -6883,25 +6855,11 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } // TODO(b/36505427): Consider moving this method and similar ones to ConfigurationContainer. - private void updateSizeCompatMode() { - if (mCompatDisplayInsets != null || !shouldUseSizeCompatMode()) { + private void updateCompatDisplayInsets(@Nullable Rect fixedOrientationBounds) { + if (mCompatDisplayInsets != null || !shouldCreateCompatDisplayInsets()) { // The override configuration is set only once in size compatibility mode. return; } - final Configuration parentConfig = getParent().getConfiguration(); - if (!hasProcess() && !isConfigurationCompatible(parentConfig)) { - // Don't compute when launching in fullscreen and the fixed orientation is not the - // current orientation. It is more accurately to compute the override bounds from - // the updated configuration after the fixed orientation is applied. - return; - } - - if (task == null || (!handlesOrientationChangeFromDescendant() - && task.getLastTaskBoundsComputeActivity() != this)) { - // Don't compute when Task hasn't computed its bounds for this app, because the Task can - // be letterboxed, and its bounds may not be accurate until then. - return; - } Configuration overrideConfig = getRequestedOverrideConfiguration(); final Configuration fullConfig = getConfiguration(); @@ -6924,17 +6882,18 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } // The role of CompatDisplayInsets is like the override bounds. - mCompatDisplayInsets = new CompatDisplayInsets(mDisplayContent, this); + mCompatDisplayInsets = + new CompatDisplayInsets(mDisplayContent, this, fixedOrientationBounds); } @VisibleForTesting void clearSizeCompatMode() { + mInSizeCompatModeForBounds = false; mSizeCompatScale = 1f; mSizeCompatBounds = null; mCompatDisplayInsets = null; - // Recompute from Task because letterbox can also happen on Task level. - task.onRequestedOverrideConfigurationChanged(task.getRequestedOverrideConfiguration()); + onRequestedOverrideConfigurationChanged(getRequestedOverrideConfiguration()); } @Override @@ -6969,23 +6928,41 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A mTmpConfig.updateFrom(resolvedConfig); newParentConfiguration = mTmpConfig; } + + final int windowingMode = getWindowingMode(); + // TODO(b/181207944): Consider removing the if condition and always run + // resolveFixedOrientationConfiguration() since this should be applied for all cases. + if (isSplitScreenWindowingMode(windowingMode) + || windowingMode == WINDOWING_MODE_MULTI_WINDOW + || windowingMode == WINDOWING_MODE_FULLSCREEN) { + resolveFixedOrientationConfiguration(newParentConfiguration); + } + final Rect fixedOrientationBounds = isLetterboxedForFixedOrientationAndAspectRatio() + ? new Rect(resolvedConfig.windowConfiguration.getBounds()) : null; + if (mCompatDisplayInsets != null) { resolveSizeCompatModeConfiguration(newParentConfiguration); - } else { - if (inMultiWindowMode()) { - // We ignore activities' requested orientation in multi-window modes. Task level may - // take them into consideration when calculating bounds. - resolvedConfig.orientation = Configuration.ORIENTATION_UNDEFINED; - // If the activity has requested override bounds, the configuration needs to be - // computed accordingly. - if (!matchParentBounds()) { - task.computeConfigResourceOverrides(resolvedConfig, newParentConfiguration); - } - } else { - resolveFullscreenConfiguration(newParentConfiguration); + } else if (inMultiWindowMode()) { + // We ignore activities' requested orientation in multi-window modes. They may be + // taken into consideration in resolveFixedOrientationConfiguration call above. + resolvedConfig.orientation = Configuration.ORIENTATION_UNDEFINED; + // If the activity has requested override bounds, the configuration needs to be + // computed accordingly. + if (!matchParentBounds()) { + task.computeConfigResourceOverrides(resolvedConfig, newParentConfiguration); } + // If activity in fullscreen mode is letterboxed because of fixed orientation then bounds + // are already calculated in resolveFixedOrientationConfiguration. + } else if (!isLetterboxedForFixedOrientationAndAspectRatio()) { + resolveFullscreenConfiguration(newParentConfiguration); } + if (mVisibleRequested) { + updateCompatDisplayInsets(fixedOrientationBounds); + } + + // TODO(b/175212232): Consolidate position logic from each "resolve" method above here. + // Assign configuration sequence number into hierarchy because there is a different way than // ensureActivityConfiguration() in this class that uses configuration in WindowState during // layout traversals. @@ -6994,6 +6971,109 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } /** + * Whether this activity is letterboxed for fixed orientation. If letterboxed due to fixed + * orientation then aspect ratio restrictions are also already respected. + * + * <p>This happens when an activity has fixed orientation which doesn't match orientation of the + * parent because a display setting 'ignoreOrientationRequest' is set to true. See {@link + * WindowManagerService#getIgnoreOrientationRequest} for more context. + */ + boolean isLetterboxedForFixedOrientationAndAspectRatio() { + return mIsLetterboxedForFixedOrientationAndAspectRatio; + } + + /** + * Computes bounds (letterbox or pillarbox) when the parent doesn't handle the orientation + * change and the requested orientation is different from the parent. + * + * <p>If letterboxed due to fixed orientation then aspect ratio restrictions are also applied + * in this methiod. + */ + private void resolveFixedOrientationConfiguration(@NonNull Configuration newParentConfig) { + mIsLetterboxedForFixedOrientationAndAspectRatio = false; + if (handlesOrientationChangeFromDescendant()) { + // No need to letterbox because of fixed orientation. Display will handle + // fixed-orientation requests. + return; + } + + final Rect resolvedBounds = + getResolvedOverrideConfiguration().windowConfiguration.getBounds(); + final int parentOrientation = newParentConfig.orientation; + + // If the activity requires a different orientation (either by override or activityInfo), + // make it fit the available bounds by scaling down its bounds. + final int forcedOrientation = getRequestedConfigurationOrientation(); + if (forcedOrientation == ORIENTATION_UNDEFINED || forcedOrientation == parentOrientation) { + return; + } + + if (mCompatDisplayInsets != null && !mCompatDisplayInsets.mIsInFixedOrientationLetterbox) { + // App prefers to keep its original size. + // If the size compat is from previous fixed orientation letterboxing, we may want to + // have fixed orientation letterbox again, otherwise it will show the size compat + // restart button even if the restart bounds will be the same. + return; + } + + final Rect parentBounds = newParentConfig.windowConfiguration.getBounds(); + final int parentWidth = parentBounds.width(); + final int parentHeight = parentBounds.height(); + float aspect = Math.max(parentWidth, parentHeight) + / (float) Math.min(parentWidth, parentHeight); + + // Adjust the fixed orientation letterbox bounds to fit the app request aspect ratio in + // order to use the extra available space. + final float maxAspectRatio = info.maxAspectRatio; + final float minAspectRatio = info.minAspectRatio; + if (aspect > maxAspectRatio && maxAspectRatio != 0) { + aspect = maxAspectRatio; + } else if (aspect < minAspectRatio) { + aspect = minAspectRatio; + } + + // Override from config_letterboxAspectRatio or via ADB with set-letterbox-aspect-ratio. + // TODO(b/175212232): Rename getTaskLetterboxAspectRatio and all related methods since fixed + // orientation letterbox is on the activity level now. + final float letterboxAspectRatioOverride = mWmService.getTaskLetterboxAspectRatio(); + // Activity min/max aspect ratio restrictions will be respected by the activity-level + // letterboxing (size-compat mode). Therefore this override can control the maximum screen + // area that can be occupied by the app in the letterbox mode. + aspect = letterboxAspectRatioOverride > MIN_TASK_LETTERBOX_ASPECT_RATIO + ? letterboxAspectRatioOverride : aspect; + + // Store the current bounds to be able to revert to size compat mode values below if needed. + Rect mTmpFullBounds = new Rect(resolvedBounds); + if (forcedOrientation == ORIENTATION_LANDSCAPE) { + final int height = (int) Math.rint(parentWidth / aspect); + final int top = parentBounds.centerY() - height / 2; + resolvedBounds.set(parentBounds.left, top, parentBounds.right, top + height); + } else { + final int width = (int) Math.rint(parentHeight / aspect); + final int left = parentBounds.centerX() - width / 2; + resolvedBounds.set(left, parentBounds.top, left + width, parentBounds.bottom); + } + + if (mCompatDisplayInsets != null) { + mCompatDisplayInsets.getBoundsByRotation( + mTmpBounds, newParentConfig.windowConfiguration.getRotation()); + if (resolvedBounds.width() != mTmpBounds.width() + || resolvedBounds.height() != mTmpBounds.height()) { + // The app shouldn't be resized, we only do fixed orientation letterboxing if the + // compat bounds are also from the same fixed orientation letterbox. Otherwise, + // clear the fixed orientation bounds to show app in size compat mode. + resolvedBounds.set(mTmpFullBounds); + return; + } + } + + // Calculate app bounds using fixed orientation bounds because they will be needed later + // for comparison with size compat app bounds in {@link resolveSizeCompatModeConfiguration}. + task.computeConfigResourceOverrides(getResolvedOverrideConfiguration(), newParentConfig); + mIsLetterboxedForFixedOrientationAndAspectRatio = true; + } + + /** * Resolves the configuration of activity in fullscreen mode. If the bounds are restricted by * aspect ratio, the position will be centered horizontally in parent's app bounds to balance * the visual appearance. The policy of aspect ratio has higher priority than the requested @@ -7037,6 +7117,18 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A private void resolveSizeCompatModeConfiguration(Configuration newParentConfiguration) { final Configuration resolvedConfig = getResolvedOverrideConfiguration(); final Rect resolvedBounds = resolvedConfig.windowConfiguration.getBounds(); + + // When an activity needs to be letterboxed because of fixed orientation, use fixed + // orientation bounds (stored in resolved bounds) instead of parent bounds since the + // activity will be displayed within them even if it is in size compat mode. They should be + // saved here before resolved bounds are overridden below. + final Rect containerBounds = isLetterboxedForFixedOrientationAndAspectRatio() + ? new Rect(resolvedBounds) + : newParentConfiguration.windowConfiguration.getBounds(); + final Rect containerAppBounds = isLetterboxedForFixedOrientationAndAspectRatio() + ? new Rect(getResolvedOverrideConfiguration().windowConfiguration.getAppBounds()) + : newParentConfiguration.windowConfiguration.getAppBounds(); + final int requestedOrientation = getRequestedConfigurationOrientation(); final boolean orientationRequested = requestedOrientation != ORIENTATION_UNDEFINED; final int orientation = orientationRequested @@ -7095,7 +7187,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A // Below figure is an example that puts an activity which was launched in a larger container // into a smaller container. // The outermost rectangle is the real display bounds. - // "@" is the parent app bounds. + // "@" is the container app bounds (parent bounds or fixed orientation bouds) // "#" is the {@code resolvedBounds} that applies to application. // "*" is the {@code mSizeCompatBounds} that used to show on screen if scaled. // ------------------------------ @@ -7111,19 +7203,18 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A // The application is still layouted in "#" since it was launched, and it will be visually // scaled and positioned to "*". + final Rect resolvedAppBounds = resolvedConfig.windowConfiguration.getAppBounds(); + // Calculates the scale and offset to horizontal center the size compatibility bounds into // the region which is available to application. - final Rect parentBounds = newParentConfiguration.windowConfiguration.getBounds(); - final Rect parentAppBounds = newParentConfiguration.windowConfiguration.getAppBounds(); - final Rect resolvedAppBounds = resolvedConfig.windowConfiguration.getAppBounds(); final int contentW = resolvedAppBounds.width(); final int contentH = resolvedAppBounds.height(); - final int viewportW = parentAppBounds.width(); - final int viewportH = parentAppBounds.height(); + final int viewportW = containerAppBounds.width(); + final int viewportH = containerAppBounds.height(); // Only allow to scale down. mSizeCompatScale = (contentW <= viewportW && contentH <= viewportH) ? 1f : Math.min((float) viewportW / contentW, (float) viewportH / contentH); - final int screenTopInset = parentAppBounds.top - parentBounds.top; + final int screenTopInset = containerAppBounds.top - containerBounds.top; final boolean topNotAligned = screenTopInset != resolvedAppBounds.top - resolvedBounds.top; if (mSizeCompatScale != 1f || topNotAligned) { if (mSizeCompatBounds == null) { @@ -7143,8 +7234,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A final int offsetX = getHorizontalCenterOffset( (int) viewportW, (int) (contentW * mSizeCompatScale)); // Above coordinates are in "@" space, now place "*" and "#" to screen space. - final int screenPosX = (fillContainer ? parentBounds.left : parentAppBounds.left) + offsetX; - final int screenPosY = parentBounds.top; + final int screenPosX = (fillContainer + ? containerBounds.left : containerAppBounds.left) + offsetX; + final int screenPosY = containerBounds.top; if (screenPosX != 0 || screenPosY != 0) { if (mSizeCompatBounds != null) { mSizeCompatBounds.offset(screenPosX, screenPosY); @@ -7154,6 +7246,52 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A final int dy = screenPosY - resolvedBounds.top; offsetBounds(resolvedConfig, dx, dy); } + + mInSizeCompatModeForBounds = + isInSizeCompatModeForBounds(resolvedAppBounds, containerAppBounds); + } + + private boolean isInSizeCompatModeForBounds(final Rect appBounds, final Rect containerBounds) { + final int appWidth = appBounds.width(); + final int appHeight = appBounds.height(); + final int containerAppWidth = containerBounds.width(); + final int containerAppHeight = containerBounds.height(); + + if (containerAppWidth == appWidth && containerAppHeight == appHeight) { + // Matched the container bounds. + return false; + } + if (containerAppWidth > appWidth && containerAppHeight > appHeight) { + // Both sides are smaller than the container. + return true; + } + if (containerAppWidth < appWidth || containerAppHeight < appHeight) { + // One side is larger than the container. + return true; + } + + // The rest of the condition is that only one side is smaller than the container, but it + // still needs to exclude the cases where the size is limited by the fixed aspect ratio. + if (info.maxAspectRatio > 0) { + final float aspectRatio = (0.5f + Math.max(appWidth, appHeight)) + / Math.min(appWidth, appHeight); + if (aspectRatio >= info.maxAspectRatio) { + // The current size has reached the max aspect ratio. + return false; + } + } + if (info.minAspectRatio > 0) { + // The activity should have at least the min aspect ratio, so this checks if the + // container still has available space to provide larger aspect ratio. + final float containerAspectRatio = + (0.5f + Math.max(containerAppWidth, containerAppHeight)) + / Math.min(containerAppWidth, containerAppHeight); + if (containerAspectRatio <= info.minAspectRatio) { + // The long side has reached the parent. + return false; + } + } + return true; } /** @return The horizontal offset of putting the content in the center of viewport. */ @@ -7305,7 +7443,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A final Task rootTask = getRootTask(); final float minAspectRatio = info.minAspectRatio; - if (task == null || rootTask == null || (inMultiWindowMode() && !shouldUseSizeCompatMode()) + if (task == null || rootTask == null + || (inMultiWindowMode() && !shouldCreateCompatDisplayInsets()) || (maxAspectRatio == 0 && minAspectRatio == 0) || isInVrUiMode(getConfiguration())) { // We don't enforce aspect ratio if the activity task is in multiwindow unless it @@ -7443,8 +7582,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A if (displayChanged) { mLastReportedDisplayId = newDisplayId; } - // TODO(b/36505427): Is there a better place to do this? - updateSizeCompatMode(); // Short circuit: if the two full configurations are equal (the common case), then there is // nothing to do. We test the full configuration instead of the global and merged override @@ -7723,11 +7860,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A // Reset the existing override configuration so it can be updated according to the latest // configuration. clearSizeCompatMode(); - if (mVisibleRequested) { - // Configuration will be ensured when becoming visible, so if it is already visible, - // then the manual update is needed. - updateSizeCompatMode(); - } if (!attachedToProcess()) { return; @@ -8134,8 +8266,11 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A private final int mHeight; /** Whether the {@link Task} windowingMode represents a floating window*/ final boolean mIsFloating; - /** Whether the {@link Task} is letterboxed when the unresizable activity is first shown. */ - final boolean mIsTaskLetterboxed; + /** + * Whether is letterboxed because of fixed orientation when the unresizable activity is + * first shown. + */ + final boolean mIsInFixedOrientationLetterbox; /** * The nonDecorInsets for each rotation. Includes the navigation bar and cutout insets. It * is used to compute the appBounds. @@ -8149,7 +8284,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A final Rect[] mStableInsets = new Rect[4]; /** Constructs the environment to simulate the bounds behavior of the given container. */ - CompatDisplayInsets(DisplayContent display, ActivityRecord container) { + CompatDisplayInsets(DisplayContent display, ActivityRecord container, + @Nullable Rect fixedOrientationBounds) { mIsFloating = container.getWindowConfiguration().tasksAreFloating(); if (mIsFloating) { final Rect containerBounds = container.getWindowConfiguration().getBounds(); @@ -8162,24 +8298,34 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A mNonDecorInsets[rotation] = emptyRect; mStableInsets[rotation] = emptyRect; } - mIsTaskLetterboxed = false; + mIsInFixedOrientationLetterbox = false; return; } final Task task = container.getTask(); - mIsTaskLetterboxed = task != null && task.isTaskLetterboxed(); + + mIsInFixedOrientationLetterbox = fixedOrientationBounds != null; // Store the bounds of the Task for the non-resizable activity to use in size compat // mode so that the activity will not be resized regardless the windowing mode it is // currently in. - final WindowContainer filledContainer = task != null ? task : display; - final Point dimensions = getRotationZeroDimensions(filledContainer); + // When an activity needs to be letterboxed because of fixed orientation, use fixed + // orientation bounds instead of task bounds since the activity will be displayed + // within these even if it is in size compat mode. + final Rect filledContainerBounds = mIsInFixedOrientationLetterbox + ? fixedOrientationBounds + : task != null ? task.getBounds() : display.getBounds(); + final int filledContainerRotation = task != null + ? task.getConfiguration().windowConfiguration.getRotation() + : display.getConfiguration().windowConfiguration.getRotation(); + final Point dimensions = getRotationZeroDimensions( + filledContainerBounds, filledContainerRotation); mWidth = dimensions.x; mHeight = dimensions.y; // Bounds of the filled container if it doesn't fill the display. final Rect unfilledContainerBounds = - filledContainer.getBounds().equals(display.getBounds()) ? null : new Rect(); + filledContainerBounds.equals(display.getBounds()) ? null : new Rect(); final DisplayPolicy policy = display.getDisplayPolicy(); for (int rotation = 0; rotation < 4; rotation++) { mNonDecorInsets[rotation] = new Rect(); @@ -8199,9 +8345,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A // The insets is based on the display, but the container may be smaller than the // display, so update the insets to exclude parts that are not intersected with the // container. - unfilledContainerBounds.set(filledContainer.getBounds()); + unfilledContainerBounds.set(filledContainerBounds); display.rotateBounds( - filledContainer.getConfiguration().windowConfiguration.getRotation(), + filledContainerRotation, rotation, unfilledContainerBounds); updateInsetsForBounds(unfilledContainerBounds, dw, dh, mNonDecorInsets[rotation]); @@ -8214,9 +8360,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A * the display is rotated, we can calculate the bounds by rotating the dimensions. * @see #getBoundsByRotation */ - private static Point getRotationZeroDimensions(WindowContainer container) { - final Rect bounds = container.getBounds(); - final int rotation = container.getConfiguration().windowConfiguration.getRotation(); + private static Point getRotationZeroDimensions(final Rect bounds, int rotation) { final boolean rotated = (rotation == ROTATION_90 || rotation == ROTATION_270); final int width = bounds.width(); final int height = bounds.height(); diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java index f64f04cc0829..32152ec85493 100644 --- a/services/core/java/com/android/server/wm/DisplayPolicy.java +++ b/services/core/java/com/android/server/wm/DisplayPolicy.java @@ -2686,8 +2686,9 @@ public class DisplayPolicy { boolean newImmersiveMode = isImmersiveMode(win); if (oldImmersiveMode != newImmersiveMode) { mLastImmersiveMode = newImmersiveMode; - final String pkg = win.getOwningPackage(); - mImmersiveModeConfirmation.immersiveModeChangedLw(pkg, newImmersiveMode, + // The immersive confirmation window should be attached to the immersive window root. + final int rootDisplayAreaId = win.getRootDisplayArea().mFeatureId; + mImmersiveModeConfirmation.immersiveModeChangedLw(rootDisplayAreaId, newImmersiveMode, mService.mPolicy.isUserSetupComplete(), isNavBarEmpty(disableFlags)); } diff --git a/services/core/java/com/android/server/wm/ImmersiveModeConfirmation.java b/services/core/java/com/android/server/wm/ImmersiveModeConfirmation.java index 9286a4693711..567b6c2b964e 100644 --- a/services/core/java/com/android/server/wm/ImmersiveModeConfirmation.java +++ b/services/core/java/com/android/server/wm/ImmersiveModeConfirmation.java @@ -19,9 +19,11 @@ package com.android.server.wm; import static android.app.ActivityManager.LOCK_TASK_MODE_LOCKED; import static android.app.ActivityManager.LOCK_TASK_MODE_NONE; import static android.view.Display.DEFAULT_DISPLAY; +import static android.window.DisplayAreaOrganizer.FEATURE_UNDEFINED; import android.animation.ArgbEvaluator; import android.animation.ValueAnimator; +import android.annotation.Nullable; import android.app.ActivityManager; import android.app.ActivityThread; import android.content.BroadcastReceiver; @@ -32,10 +34,12 @@ import android.graphics.Insets; import android.graphics.PixelFormat; import android.graphics.drawable.ColorDrawable; import android.os.Binder; +import android.os.Bundle; import android.os.Handler; import android.os.IBinder; import android.os.Looper; import android.os.Message; +import android.os.RemoteException; import android.os.UserHandle; import android.os.UserManager; import android.provider.Settings; @@ -43,6 +47,7 @@ import android.util.DisplayMetrics; import android.util.Slog; import android.view.Display; import android.view.Gravity; +import android.view.IWindowManager; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; @@ -50,6 +55,7 @@ import android.view.ViewTreeObserver; import android.view.WindowInsets; import android.view.WindowInsets.Type; import android.view.WindowManager; +import android.view.WindowManagerGlobal; import android.view.animation.Animation; import android.view.animation.AnimationUtils; import android.view.animation.Interpolator; @@ -67,6 +73,8 @@ public class ImmersiveModeConfirmation { private static final boolean DEBUG = false; private static final boolean DEBUG_SHOW_EVERY_TIME = false; // super annoying, use with caution private static final String CONFIRMED = "confirmed"; + private static final int IMMERSIVE_MODE_CONFIRMATION_WINDOW_TYPE = + WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL; private static boolean sConfirmed; @@ -78,7 +86,15 @@ public class ImmersiveModeConfirmation { private ClingWindowView mClingWindow; private long mPanicTime; + /** The last {@link WindowManager} that is used to add the confirmation window. */ + @Nullable private WindowManager mWindowManager; + /** + * The WindowContext that is registered with {@link #mWindowManager} with options to specify the + * {@link RootDisplayArea} to attach the confirmation window. + */ + @Nullable + private Context mWindowContext; // Local copy of vr mode enabled state, to avoid calling into VrManager with // the lock held. private boolean mVrModeEnabled; @@ -132,7 +148,7 @@ public class ImmersiveModeConfirmation { } } - void immersiveModeChangedLw(String pkg, boolean isImmersiveMode, + void immersiveModeChangedLw(int rootDisplayAreaId, boolean isImmersiveMode, boolean userSetupComplete, boolean navBarEmpty) { mHandler.removeMessages(H.SHOW); if (isImmersiveMode) { @@ -143,7 +159,9 @@ public class ImmersiveModeConfirmation { && !navBarEmpty && !UserManager.isDeviceInDemoMode(mContext) && (mLockTaskState != LOCK_TASK_MODE_LOCKED)) { - mHandler.sendEmptyMessageDelayed(H.SHOW, mShowDelayMs); + final Message msg = mHandler.obtainMessage(H.SHOW); + msg.arg1 = rootDisplayAreaId; + mHandler.sendMessageDelayed(msg, mShowDelayMs); } } else { mHandler.sendEmptyMessage(H.HIDE); @@ -175,7 +193,8 @@ public class ImmersiveModeConfirmation { private void handleHide() { if (mClingWindow != null) { if (DEBUG) Slog.d(TAG, "Hiding immersive mode confirmation"); - getWindowManager().removeView(mClingWindow); + // We don't care which root display area the window manager is specifying for removal. + getWindowManager(FEATURE_UNDEFINED).removeView(mClingWindow); mClingWindow = null; } } @@ -184,7 +203,7 @@ public class ImmersiveModeConfirmation { final WindowManager.LayoutParams lp = new WindowManager.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT, - WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL, + IMMERSIVE_MODE_CONFIRMATION_WINDOW_TYPE, WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL, @@ -353,23 +372,57 @@ public class ImmersiveModeConfirmation { * DO HOLD THE WINDOW MANAGER LOCK WHEN CALLING THIS METHOD * The reason why we add this method is to avoid the deadlock of WMG->WMS and WMS->WMG * when ImmersiveModeConfirmation object is created. + * + * @return the WindowManager specifying with the {@code rootDisplayAreaId} to attach the + * confirmation window. */ - private WindowManager getWindowManager() { - if (mWindowManager == null) { - mWindowManager = (WindowManager) - mContext.getSystemService(Context.WINDOW_SERVICE); + private WindowManager getWindowManager(int rootDisplayAreaId) { + if (mWindowManager == null || mWindowContext == null) { + // Create window context to specify the RootDisplayArea + final Bundle options = getOptionsForWindowContext(rootDisplayAreaId); + mWindowContext = mContext.createWindowContext( + IMMERSIVE_MODE_CONFIRMATION_WINDOW_TYPE, options); + mWindowManager = mWindowContext.getSystemService(WindowManager.class); + return mWindowManager; + } + + // Update the window context and window manager to specify the RootDisplayArea + final Bundle options = getOptionsForWindowContext(rootDisplayAreaId); + final IWindowManager wms = WindowManagerGlobal.getWindowManagerService(); + try { + wms.registerWindowContextListener(mWindowContext.getWindowContextToken(), + IMMERSIVE_MODE_CONFIRMATION_WINDOW_TYPE, mContext.getDisplayId(), options); + } catch (RemoteException e) { + throw e.rethrowAsRuntimeException(); } + return mWindowManager; } - private void handleShow() { + /** + * Returns options that specify the {@link RootDisplayArea} to attach the confirmation window. + * {@code null} if the {@code rootDisplayAreaId} is {@link FEATURE_UNDEFINED}. + */ + @Nullable + private Bundle getOptionsForWindowContext(int rootDisplayAreaId) { + // In case we don't care which root display area the window manager is specifying. + if (rootDisplayAreaId == FEATURE_UNDEFINED) { + return null; + } + + final Bundle options = new Bundle(); + options.putInt(DisplayAreaPolicyBuilder.KEY_ROOT_DISPLAY_AREA_ID, rootDisplayAreaId); + return options; + } + + private void handleShow(int rootDisplayAreaId) { if (DEBUG) Slog.d(TAG, "Showing immersive mode confirmation"); mClingWindow = new ClingWindowView(mContext, mConfirm); // show the confirmation WindowManager.LayoutParams lp = getClingWindowLayoutParams(); - getWindowManager().addView(mClingWindow, lp); + getWindowManager(rootDisplayAreaId).addView(mClingWindow, lp); } private final Runnable mConfirm = new Runnable() { @@ -396,7 +449,7 @@ public class ImmersiveModeConfirmation { public void handleMessage(Message msg) { switch(msg.what) { case SHOW: - handleShow(); + handleShow(msg.arg1); break; case HIDE: handleHide(); diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java index 29c7ff118595..7085156daa81 100644 --- a/services/core/java/com/android/server/wm/Task.java +++ b/services/core/java/com/android/server/wm/Task.java @@ -35,7 +35,6 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMAR import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static android.app.WindowConfiguration.activityTypeToString; -import static android.app.WindowConfiguration.isSplitScreenWindowingMode; import static android.app.WindowConfiguration.windowingModeToString; import static android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT; import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; @@ -148,7 +147,6 @@ import static com.android.server.wm.WindowContainerChildProto.TASK; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ROOT_TASK; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TASK_MOVEMENT; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; -import static com.android.server.wm.WindowManagerService.MIN_TASK_LETTERBOX_ASPECT_RATIO; import static com.android.server.wm.WindowManagerService.dipToPixel; import static com.android.server.wm.WindowStateAnimator.ROOT_TASK_CLIP_BEFORE_ANIM; @@ -597,10 +595,6 @@ class Task extends WindowContainer<WindowContainer> { @Nullable private ActivityRecord mResumedActivity = null; - /** Last activity that is used to compute the Task bounds. */ - @Nullable - private ActivityRecord mLastTaskBoundsComputeActivity; - private boolean mForceShowForAllUsers; /** When set, will force the task to report as invisible. */ @@ -1496,11 +1490,6 @@ class Task extends WindowContainer<WindowContainer> { } void cleanUpActivityReferences(ActivityRecord r) { - // mLastTaskBoundsComputeActivity is set at leaf Task - if (mLastTaskBoundsComputeActivity == r) { - mLastTaskBoundsComputeActivity = null; - } - // mPausingActivity is set at leaf task if (mPausingActivity != null && mPausingActivity == r) { mPausingActivity = null; @@ -2863,7 +2852,6 @@ class Task extends WindowContainer<WindowContainer> { private void resolveLeafOnlyOverrideConfigs(Configuration newParentConfig, Rect previousBounds) { - mLastTaskBoundsComputeActivity = getTopNonFinishingActivity(false /* includeOverlays */); int windowingMode = getResolvedOverrideConfiguration().windowConfiguration.getWindowingMode(); @@ -2877,7 +2865,8 @@ class Task extends WindowContainer<WindowContainer> { getResolvedOverrideConfiguration().windowConfiguration.getBounds(); if (windowingMode == WINDOWING_MODE_FULLSCREEN) { - computeFullscreenBounds(outOverrideBounds, newParentConfig); + // Use empty bounds to indicate "fill parent". + outOverrideBounds.setEmpty(); // The bounds for fullscreen mode shouldn't be adjusted by minimal size. Otherwise if // the parent or display is smaller than the size, the content may be cropped. return; @@ -2888,21 +2877,6 @@ class Task extends WindowContainer<WindowContainer> { computeFreeformBounds(outOverrideBounds, newParentConfig); return; } - - if (isSplitScreenWindowingMode(windowingMode) - || windowingMode == WINDOWING_MODE_MULTI_WINDOW) { - // This is to compute whether the task should be letterboxed to handle non-resizable app - // in multi window. There is no split screen only logic. - computeLetterboxBounds(outOverrideBounds, newParentConfig); - } - } - - /** Computes bounds for {@link WindowConfiguration#WINDOWING_MODE_FULLSCREEN}. */ - @VisibleForTesting - void computeFullscreenBounds(@NonNull Rect outBounds, @NonNull Configuration newParentConfig) { - // In FULLSCREEN mode, always start with empty bounds to indicate "fill parent". - outBounds.setEmpty(); - computeLetterboxBounds(outBounds, newParentConfig); } /** Computes bounds for {@link WindowConfiguration#WINDOWING_MODE_FREEFORM}. */ @@ -2934,94 +2908,6 @@ class Task extends WindowContainer<WindowContainer> { } } - /** - * Computes bounds (letterbox or pillarbox) when the parent doesn't handle the orientation - * change and the requested orientation is different from the parent. - */ - private void computeLetterboxBounds(@NonNull Rect outBounds, - @NonNull Configuration newParentConfig) { - if (handlesOrientationChangeFromDescendant()) { - // No need to letterbox at task level. Display will handle fixed-orientation requests. - return; - } - - final int parentOrientation = newParentConfig.orientation; - // Use the top activity as the reference of orientation. Don't include overlays because - // it is usually not the actual content or just temporarily shown. - // E.g. ForcedResizableInfoActivity. - final ActivityRecord refActivity = getTopNonFinishingActivity(false /* includeOverlays */); - - // If the task or the reference activity requires a different orientation (either by - // override or activityInfo), make it fit the available bounds by scaling down its bounds. - final int overrideOrientation = getRequestedOverrideConfiguration().orientation; - final int forcedOrientation = - (overrideOrientation != ORIENTATION_UNDEFINED || refActivity == null) - ? overrideOrientation : refActivity.getRequestedConfigurationOrientation(); - if (forcedOrientation == ORIENTATION_UNDEFINED || forcedOrientation == parentOrientation) { - return; - } - - final ActivityRecord.CompatDisplayInsets compatDisplayInsets = - refActivity == null ? null : refActivity.getCompatDisplayInsets(); - if (compatDisplayInsets != null && !compatDisplayInsets.mIsTaskLetterboxed) { - // App prefers to keep its original size. - // If the size compat is from previous task letterboxing, we may want to have task - // letterbox again, otherwise it will show the size compat restart button even if the - // restart bounds will be the same. - return; - } - - final Rect parentBounds = newParentConfig.windowConfiguration.getBounds(); - final int parentWidth = parentBounds.width(); - final int parentHeight = parentBounds.height(); - float aspect = Math.max(parentWidth, parentHeight) - / (float) Math.min(parentWidth, parentHeight); - - // Adjust the Task letterbox bounds to fit the app request aspect ratio in order to use the - // extra available space. - if (refActivity != null) { - final float maxAspectRatio = refActivity.info.maxAspectRatio; - final float minAspectRatio = refActivity.info.minAspectRatio; - if (aspect > maxAspectRatio && maxAspectRatio != 0) { - aspect = maxAspectRatio; - } else if (aspect < minAspectRatio) { - aspect = minAspectRatio; - } - } - - // Override from config_letterboxAspectRatio or via ADB with set-letterbox-aspect-ratio. - final float letterboxAspectRatioOverride = mWmService.getTaskLetterboxAspectRatio(); - // Activity min/max aspect ratio restrictions will be respected by the activity-level - // letterboxing (size-compat mode). Therefore this override can control the maximum screen - // area that can be occupied by the app in the letterbox mode. - aspect = letterboxAspectRatioOverride > MIN_TASK_LETTERBOX_ASPECT_RATIO - ? letterboxAspectRatioOverride : aspect; - - // Store the current bounds to be able to revert to size compat mode values below if needed. - mTmpFullBounds.set(outBounds); - if (forcedOrientation == ORIENTATION_LANDSCAPE) { - final int height = (int) Math.rint(parentWidth / aspect); - final int top = parentBounds.centerY() - height / 2; - outBounds.set(parentBounds.left, top, parentBounds.right, top + height); - } else { - final int width = (int) Math.rint(parentHeight / aspect); - final int left = parentBounds.centerX() - width / 2; - outBounds.set(left, parentBounds.top, left + width, parentBounds.bottom); - } - - if (compatDisplayInsets != null) { - compatDisplayInsets.getBoundsByRotation( - mTmpBounds, newParentConfig.windowConfiguration.getRotation()); - if (outBounds.width() != mTmpBounds.width() - || outBounds.height() != mTmpBounds.height()) { - // The app shouldn't be resized, we only do task letterboxing if the compat bounds - // is also from the same task letterbox. Otherwise, clear the task bounds to show - // app in size compat mode. - outBounds.set(mTmpFullBounds); - } - } - } - Rect updateOverrideConfigurationFromLaunchBounds() { // If the task is controlled by another organized task, do not set override // configurations and let its parent (organized task) to control it; @@ -3036,11 +2922,6 @@ class Task extends WindowContainer<WindowContainer> { return bounds; } - @Nullable - ActivityRecord getLastTaskBoundsComputeActivity() { - return mLastTaskBoundsComputeActivity; - } - /** Updates the task's bounds and override configuration to match what is expected for the * input root task. */ void updateOverrideConfigurationForRootTask(Task inRootTask) { @@ -3939,12 +3820,6 @@ class Task extends WindowContainer<WindowContainer> { || activityType == ACTIVITY_TYPE_ASSISTANT; } - boolean isTaskLetterboxed() { - // No letterbox for multi window root task - return !matchParentBounds() - && (getWindowingMode() == WINDOWING_MODE_FULLSCREEN || !isRootTask()); - } - @Override boolean fillsParent() { // From the perspective of policy, we still want to report that this task fills parent diff --git a/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java b/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java index 106db0b15c46..82d9c214ece7 100644 --- a/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java +++ b/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java @@ -234,19 +234,28 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier { } } - // STEP 2.3: Adjust launch parameters as needed for freeform display. We enforce the policy - // that legacy (pre-D) apps and those apps that can't handle multiple screen density well - // are forced to be maximized. The rest of this step is to define the default policy when - // there is no initial bounds or a fully resolved current params from callers. + // STEP 2.3: Adjust launch parameters as needed for freeform display. We enforce the + // policies related to unresizable apps here. If an app is unresizable and the freeform + // size-compat mode is enabled, it can be launched in freeform depending on other properties + // such as orientation. Otherwise, the app is forcefully launched in maximized. The rest of + // this step is to define the default policy when there is no initial bounds or a fully + // resolved current params from callers. if (display.inFreeformWindowingMode()) { if (launchMode == WINDOWING_MODE_PINNED) { if (DEBUG) appendLog("picture-in-picture"); - } else if (!mSupervisor.mService.mSizeCompatFreeform && !root.isResizeable()) { - // We're launching an activity in size-compat mode and they aren't allowed in - // freeform, so force it to be maximized. - launchMode = WINDOWING_MODE_FULLSCREEN; - outParams.mBounds.setEmpty(); - if (DEBUG) appendLog("forced-maximize"); + } else if (!root.isResizeable()) { + if (shouldLaunchUnresizableAppInFreeform(root, suggestedDisplayArea)) { + launchMode = WINDOWING_MODE_FREEFORM; + if (outParams.mBounds.isEmpty()) { + getTaskBounds(root, display, layout, launchMode, hasInitialBounds, + outParams.mBounds); + } + if (DEBUG) appendLog("unresizable-freeform"); + } else { + launchMode = WINDOWING_MODE_FULLSCREEN; + outParams.mBounds.setEmpty(); + if (DEBUG) appendLog("unresizable-forced-maximize"); + } } } else { if (DEBUG) appendLog("non-freeform-display"); @@ -322,7 +331,6 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier { } getTaskBounds(root, display, layout, resolvedMode, hasInitialBounds, outParams.mBounds); } - return RESULT_CONTINUE; } @@ -562,6 +570,28 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier { outBounds.offset(xOffset, yOffset); } + private boolean shouldLaunchUnresizableAppInFreeform(ActivityRecord activity, + TaskDisplayArea displayArea) { + // TODO(176061101): Migrate |mSizeCompatFreeform| to |mSupportsNonResizableMultiWindow|. + if (!mSupervisor.mService.mSizeCompatFreeform || activity.isResizeable()) { + return false; + } + final DisplayContent display = displayArea.getDisplayContent(); + if (display == null) { + return false; + } + + final int displayOrientation = orientationFromBounds(displayArea.getBounds()); + final int activityOrientation = resolveOrientation(activity, display, + displayArea.getBounds()); + if (displayArea.getWindowingMode() == WINDOWING_MODE_FREEFORM + && displayOrientation != activityOrientation) { + return true; + } + + return false; + } + /** * Resolves activity requested orientation to 4 categories: * 1) {@link ActivityInfo#SCREEN_ORIENTATION_LOCKED} indicating app wants to lock down diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 9ae5beb625f8..1fc7041c0fe2 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -3827,13 +3827,21 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP /** @return true when the window should be letterboxed. */ boolean isLetterboxedAppWindow() { // Fullscreen mode but doesn't fill display area. - return (!inMultiWindowMode() && !matchesDisplayAreaBounds()) - // Activity in size compat. - || (mActivityRecord != null && mActivityRecord.inSizeCompatMode()) - // Task letterboxed. - || (getTask() != null && getTask().isTaskLetterboxed()) - // Letterboxed for display cutout. - || isLetterboxedForDisplayCutout(); + if (!inMultiWindowMode() && !matchesDisplayAreaBounds()) { + return true; + } + if (mActivityRecord != null) { + // Activity in size compat. + if (mActivityRecord.inSizeCompatMode()) { + return true; + } + // Letterbox for fixed orientation. + if (mActivityRecord.isLetterboxedForFixedOrientationAndAspectRatio()) { + return true; + } + } + // Letterboxed for display cutout. + return isLetterboxedForDisplayCutout(); } /** Returns {@code true} if the window is letterboxed for the display cutout. */ diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 524892b2ec4b..28e9acf8d883 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -715,6 +715,9 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Nullable private DevicePolicySafetyChecker mSafetyChecker; + @GuardedBy("getLockObject()") + private final ArrayList<Object> mPendingUserCreatedCallbackTokens = new ArrayList<>(); + public static final class Lifecycle extends SystemService { private BaseIDevicePolicyManager mService; @@ -753,21 +756,25 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override public void onUserStarting(@NonNull TargetUser user) { + if (user.isPreCreated()) return; mService.handleStartUser(user.getUserIdentifier()); } @Override public void onUserUnlocking(@NonNull TargetUser user) { + if (user.isPreCreated()) return; mService.handleUnlockUser(user.getUserIdentifier()); } @Override public void onUserStopping(@NonNull TargetUser user) { + if (user.isPreCreated()) return; mService.handleStopUser(user.getUserIdentifier()); } @Override public void onUserUnlocked(@NonNull TargetUser user) { + if (user.isPreCreated()) return; mService.handleOnUserUnlocked(user.getUserIdentifier()); } } @@ -965,8 +972,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { private final class UserLifecycleListener implements UserManagerInternal.UserLifecycleListener { @Override - public void onUserCreated(UserInfo user) { - mHandler.post(() -> handleNewUserCreated(user)); + public void onUserCreated(UserInfo user, Object token) { + mHandler.post(() -> handleNewUserCreated(user, token)); } } @@ -3151,11 +3158,6 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { if (!mHasFeature) { return; } - setActiveAdmin(adminReceiver, refreshing, userHandle, null); - } - - private void setActiveAdmin(ComponentName adminReceiver, boolean refreshing, int userHandle, - Bundle onEnableData) { Preconditions.checkArgumentNonnegative(userHandle, "Invalid userId"); final CallerIdentity caller = getCallerIdentity(); @@ -3198,7 +3200,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } saveSettingsLocked(userHandle); sendAdminCommandLocked(newAdmin, DeviceAdminReceiver.ACTION_DEVICE_ADMIN_ENABLED, - onEnableData, null); + /* adminExtras= */ null, /* result= */ null); }); } } @@ -9187,13 +9189,24 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { pw.println(); mStatLogger.dump(pw); pw.println(); - pw.println("Encryption Status: " + getEncryptionStatusName(getEncryptionStatus())); pw.println(); + + if (mPendingUserCreatedCallbackTokens.isEmpty()) { + pw.println("no pending user created callback tokens"); + } else { + int size = mPendingUserCreatedCallbackTokens.size(); + pw.printf("%d pending user created callback token%s\n", size, + (size == 1 ? "" : "s")); + } + pw.println(); + mPolicyCache.dump(pw); pw.println(); mStateCache.dump(pw); + pw.println(); } + dumpResources(pw); } } @@ -9208,6 +9221,32 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { pw.decreaseIndent(); } + private void dumpResources(IndentingPrintWriter pw) { + mOverlayPackagesProvider.dump(pw); + pw.println(); + + pw.println("Other overlayable app resources"); + pw.increaseIndent(); + dumpResources(pw, mContext, "cross_profile_apps", R.array.cross_profile_apps); + dumpResources(pw, mContext, "vendor_cross_profile_apps", R.array.vendor_cross_profile_apps); + pw.decreaseIndent(); + pw.println(); + } + + static void dumpResources(IndentingPrintWriter pw, Context context, String resName, int resId) { + String[] apps = context.getResources().getStringArray(resId); + if (apps == null || apps.length == 0) { + pw.printf("%s: empty\n", resName); + return; + } + pw.printf("%s: %d app%s\n", resName, apps.length, apps.length == 1 ? "" : "s"); + pw.increaseIndent(); + for (int i = 0; i < apps.length; i++) { + pw.printf("%d: %s\n", i, apps[i]); + } + pw.decreaseIndent(); + } + @Override public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err, String[] args, ShellCallback callback, ResultReceiver resultReceiver) { @@ -9946,8 +9985,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { clearInitBundle = sendAdminCommandLocked(admin, DeviceAdminReceiver.ACTION_DEVICE_ADMIN_ENABLED, initBundle == null ? null : new Bundle(initBundle), - null /* result receiver */, - true /* send in foreground */); + /* result= */ null , + /* inForeground= */ true); } if (clearInitBundle) { // If there's no admin or we've successfully called the admin, clear the init bundle @@ -10020,9 +10059,13 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { UserHandle.myUserId(), ACTION_PROVISION_MANAGED_USER).toArray( new String[0]); } + + Object token = new Object(); + Slog.d(LOG_TAG, "Adding new pending token: " + token); + mPendingUserCreatedCallbackTokens.add(token); try { UserInfo userInfo = mUserManagerInternal.createUserEvenWhenDisallowed(name, - userType, userInfoFlags, disallowedPackages); + userType, userInfoFlags, disallowedPackages, token); if (userInfo != null) { user = userInfo.getUserHandle(); } @@ -10032,7 +10075,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } finally { mInjector.binderRestoreCallingIdentity(id); } - } + } // synchronized + if (user == null) { if (targetSdkVersion >= Build.VERSION_CODES.P) { throw new ServiceSpecificException(UserManager.USER_OPERATION_ERROR_UNKNOWN, @@ -10054,14 +10098,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { final long id = mInjector.binderClearCallingIdentity(); try { - if (!mInjector.userManagerIsHeadlessSystemUserMode()) { - manageUserUnchecked(admin, profileOwner, userHandle, adminExtras, - /* showDisclaimer= */ true); - } else if (VERBOSE_LOG) { - Slog.v(LOG_TAG, "createAndManageUser(): skipping manageUserUnchecked() on user " - + userHandle + " on headless system user as it will be called by " - + "handleNewUserCreated()"); - } + manageUserUnchecked(admin, profileOwner, userHandle, adminExtras, + /* showDisclaimer= */ true); if ((flags & DevicePolicyManager.SKIP_SETUP_WIZARD) != 0) { Settings.Secure.putIntForUser(mContext.getContentResolver(), @@ -10083,7 +10121,15 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } private void manageUserUnchecked(ComponentName admin, ComponentName profileOwner, - @UserIdInt int userId, PersistableBundle adminExtras, boolean showDisclaimer) { + @UserIdInt int userId, @Nullable PersistableBundle adminExtras, + boolean showDisclaimer) { + synchronized (getLockObject()) { + if (VERBOSE_LOG) { + Slog.v(LOG_TAG, "manageUserUnchecked(): admin=" + admin + ", po=" + profileOwner + + ", userId=" + userId + ", hasAdminExtras=" + (adminExtras != null) + + ", showDisclaimer=" + showDisclaimer); + } + } final String adminPkg = admin.getPackageName(); try { // Install the profile owner if not present. @@ -10113,23 +10159,37 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { ? DevicePolicyData.NEW_USER_DISCLAIMER_NEEDED : DevicePolicyData.NEW_USER_DISCLAIMER_NOT_NEEDED; saveSettingsLocked(userId); + } } - private void handleNewUserCreated(UserInfo user) { - if (VERBOSE_LOG) Slog.v(LOG_TAG, "handleNewUserCreated(): " + user.toFullString()); - - if (!mOwners.hasDeviceOwner() || !user.isFull() || user.isManagedProfile()) return; + private void handleNewUserCreated(UserInfo user, @Nullable Object token) { + if (VERBOSE_LOG) { + Slog.v(LOG_TAG, "handleNewUserCreated(): user=" + user.toFullString() + + ", token=" + token); + } final int userId = user.id; + if (token != null) { + synchronized (getLockObject()) { + if (mPendingUserCreatedCallbackTokens.contains(token)) { + // Ignore because it was triggered by createAndManageUser() + Slog.d(LOG_TAG, "handleNewUserCreated(): ignoring for user " + userId + + " due to token" + token); + mPendingUserCreatedCallbackTokens.remove(token); + return; + } + } + } + + if (!mOwners.hasDeviceOwner() || !user.isFull() || user.isManagedProfile()) return; if (mInjector.userManagerIsHeadlessSystemUserMode()) { ComponentName admin = mOwners.getDeviceOwnerComponent(); Slog.i(LOG_TAG, "Automatically setting profile owner (" + admin + ") on new user " + userId); manageUserUnchecked(/* deviceOwner= */ admin, /* profileOwner= */ admin, - /* managedUser= */ userId, /* adminExtras= */ null, - /* showDisclaimer= */ true); + /* managedUser= */ userId, /* adminExtras= */ null, /* showDisclaimer= */ true); } else { Log.i(LOG_TAG, "User " + userId + " added on DO mode; setting ShowNewUserDisclaimer"); setShowNewUserDisclaimer(userId, DevicePolicyData.NEW_USER_DISCLAIMER_NEEDED); @@ -10250,11 +10310,12 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { final long id = mInjector.binderClearCallingIdentity(); try { if (!mInjector.getActivityManagerInternal().canStartMoreUsers()) { - Log.w(LOG_TAG, "Cannot start more users in background"); + Log.w(LOG_TAG, "Cannot start user " + userId + ", too many users in background"); return UserManager.USER_OPERATION_ERROR_MAX_RUNNING_USERS; } if (mInjector.getIActivityManager().startUserInBackground(userId)) { + Log.i(LOG_TAG, "Started used " + userId + " in background"); return UserManager.USER_OPERATION_SUCCESS; } else { return UserManager.USER_OPERATION_ERROR_UNKNOWN; diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/OverlayPackagesProvider.java b/services/devicepolicy/java/com/android/server/devicepolicy/OverlayPackagesProvider.java index 261a83c4f67a..280f12f6a60e 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/OverlayPackagesProvider.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/OverlayPackagesProvider.java @@ -21,6 +21,7 @@ import static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_PRO import static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_USER; import static com.android.internal.util.Preconditions.checkNotNull; +import static com.android.server.devicepolicy.DevicePolicyManagerService.dumpResources; import android.annotation.NonNull; import android.annotation.UserIdInt; @@ -32,6 +33,7 @@ import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.util.ArraySet; +import android.util.IndentingPrintWriter; import android.view.inputmethod.InputMethodInfo; import com.android.internal.R; @@ -224,4 +226,39 @@ public class OverlayPackagesProvider { } return new ArraySet<>(Arrays.asList(mContext.getResources().getStringArray(resId))); } + + void dump(IndentingPrintWriter pw) { + pw.println("OverlayPackagesProvider"); + pw.increaseIndent(); + + dumpResources(pw, mContext, "required_apps_managed_device", + R.array.required_apps_managed_device); + dumpResources(pw, mContext, "required_apps_managed_user", + R.array.required_apps_managed_user); + dumpResources(pw, mContext, "required_apps_managed_profile", + R.array.required_apps_managed_profile); + + dumpResources(pw, mContext, "disallowed_apps_managed_device", + R.array.disallowed_apps_managed_device); + dumpResources(pw, mContext, "disallowed_apps_managed_user", + R.array.disallowed_apps_managed_user); + dumpResources(pw, mContext, "disallowed_apps_managed_device", + R.array.disallowed_apps_managed_device); + + dumpResources(pw, mContext, "vendor_required_apps_managed_device", + R.array.vendor_required_apps_managed_device); + dumpResources(pw, mContext, "vendor_required_apps_managed_user", + R.array.vendor_required_apps_managed_user); + dumpResources(pw, mContext, "vendor_required_apps_managed_profile", + R.array.vendor_required_apps_managed_profile); + + dumpResources(pw, mContext, "vendor_disallowed_apps_managed_user", + R.array.vendor_disallowed_apps_managed_user); + dumpResources(pw, mContext, "vendor_disallowed_apps_managed_device", + R.array.vendor_disallowed_apps_managed_device); + dumpResources(pw, mContext, "vendor_disallowed_apps_managed_profile", + R.array.vendor_disallowed_apps_managed_profile); + + pw.decreaseIndent(); + } } diff --git a/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationCoreApiTest.kt b/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationCoreApiTest.kt index deb314764404..9447f390ada0 100644 --- a/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationCoreApiTest.kt +++ b/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationCoreApiTest.kt @@ -16,8 +16,9 @@ package com.android.server.pm.test.verify.domain -import android.content.pm.verify.domain.DomainVerificationRequest +import android.content.pm.verify.domain.DomainSet import android.content.pm.verify.domain.DomainVerificationInfo +import android.content.pm.verify.domain.DomainVerificationRequest import android.content.pm.verify.domain.DomainVerificationUserSelection import android.os.Parcel import android.os.Parcelable @@ -27,6 +28,7 @@ import org.junit.Test import org.junit.runner.RunWith import org.junit.runners.Parameterized import java.util.UUID +import kotlin.random.Random @RunWith(Parameterized::class) class DomainVerificationCoreApiTest { @@ -40,18 +42,25 @@ class DomainVerificationCoreApiTest { assertThat(value).containsExactlyEntriesIn(other) } + private val massiveSet by lazy { + val fragmentOf21 = ".com.example.test.app" + val list = mutableListOf("prefix$fragmentOf21") + var totalSize = 0 + // Slightly overshoot a size of 1MB + while (totalSize < (1024 * 512)) { + val nextValue = "${list.last()}$fragmentOf21" + totalSize += nextValue.length + list += nextValue + } + list.toSet() + } + @JvmStatic - @Parameterized.Parameters + @Parameterized.Parameters(name = "{0}") fun parameters() = arrayOf( Parameter( - initial = { - DomainVerificationRequest( - setOf( - "com.test.pkg.one", - "com.test.pkg.two" - ) - ) - }, + testName = "DomainVerificationRequest", + initial = { DomainVerificationRequest(massiveSet) }, unparcel = { DomainVerificationRequest.CREATOR.createFromParcel(it) }, assertion = { first, second -> assertAll<DomainVerificationRequest, Set<String>>(first, second, @@ -61,15 +70,12 @@ class DomainVerificationCoreApiTest { } ), Parameter( + testName = "DomainVerificationInfo", initial = { DomainVerificationInfo( UUID.fromString("703f6d34-6241-4cfd-8176-2e1d23355811"), "com.test.pkg", - mapOf( - "example.com" to 0, - "example.org" to 1, - "example.new" to 1000 - ) + massiveSet.withIndex().associate { it.value to it.index } ) }, unparcel = { DomainVerificationInfo.CREATOR.createFromParcel(it) }, @@ -86,17 +92,15 @@ class DomainVerificationCoreApiTest { } ), Parameter( + testName = "DomainVerificationUserSelection", initial = { DomainVerificationUserSelection( UUID.fromString("703f6d34-6241-4cfd-8176-2e1d23355811"), "com.test.pkg", UserHandle.of(10), true, - mapOf( - "example.com" to true, - "example.org" to false, - "example.new" to true - ) + massiveSet.withIndex() + .associate { it.value to (it.index % 3) } ) }, unparcel = { DomainVerificationUserSelection.CREATOR.createFromParcel(it) }, @@ -114,21 +118,35 @@ class DomainVerificationCoreApiTest { first, second, { it.isLinkHandlingAllowed }, { it.component4() }, IS_EQUAL_TO ) - assertAll<DomainVerificationUserSelection, Map<String, Boolean>>( - first, second, { it.hostToUserSelectionMap }, + assertAll<DomainVerificationUserSelection, Map<String, Int>>( + first, second, { it.hostToStateMap }, { it.component5() }, IS_MAP_EQUAL_TO ) } + ), + Parameter( + testName = "DomainSet", + initial = { DomainSet(massiveSet) }, + unparcel = { DomainSet.CREATOR.createFromParcel(it) }, + assertion = { first, second -> + assertAll<DomainSet, Set<String>>( + first, second, + { it.domains }, assertion = IS_EQUAL_TO + ) + } ) ) class Parameter<T : Parcelable>( + val testName: String, val initial: () -> T, val unparcel: (Parcel) -> T, private val assertion: (first: T, second: T) -> Unit ) { @Suppress("UNCHECKED_CAST") fun assert(first: Any, second: Any) = assertion(first as T, second as T) + + override fun toString() = testName } private fun <T> assertAll(vararg values: T, block: (value: T, other: T) -> Unit) { @@ -141,11 +159,17 @@ class DomainVerificationCoreApiTest { first: T, second: T, fieldValue: (T) -> V, - componentValue: (T) -> V, + componentValue: ((T) -> V)? = null, assertion: (value: V, other: V) -> Unit ) { - val values = arrayOf<Any>(fieldValue(first), fieldValue(second), - componentValue(first), componentValue(second)) + val values = mutableListOf<Any>(fieldValue(first), fieldValue(second)) + .apply { + componentValue?.let { + add(it(first)) + add(it(second)) + } + } + .toTypedArray() values.indices.drop(1).forEach { @Suppress("UNCHECKED_CAST") assertion(values[0] as V, values[it] as V) diff --git a/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationEnforcerTest.kt b/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationEnforcerTest.kt index 2d23fb4990bf..89394837655a 100644 --- a/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationEnforcerTest.kt +++ b/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationEnforcerTest.kt @@ -244,6 +244,14 @@ class DomainVerificationEnforcerTest { service(Type.LEGACY_QUERENT, "getLegacyUserState") { getLegacyState(it.targetPackageName, it.userId) }, + service(Type.OWNER_QUERENT, "getOwnersForDomain") { + // Re-use package name, since the result itself isn't relevant + getOwnersForDomain(it.targetPackageName) + }, + service(Type.OWNER_QUERENT_USER, "getOwnersForDomainUserId") { + // Re-use package name, since the result itself isn't relevant + getOwnersForDomain(it.targetPackageName, it.userId) + }, ) } @@ -327,6 +335,7 @@ class DomainVerificationEnforcerTest { domainSetId ) ) { + whenever(getName()) { packageName } whenever(getPkg()) { mockPkg(packageName) } whenever(this.domainSetId) { domainSetId } whenever(userState) { @@ -357,6 +366,8 @@ class DomainVerificationEnforcerTest { Type.SELECTOR_USER -> approvedUserSelector(verifyCrossUser = true) Type.LEGACY_QUERENT -> legacyQuerent() Type.LEGACY_SELECTOR -> legacyUserSelector() + Type.OWNER_QUERENT -> ownerQuerent(verifyCrossUser = false) + Type.OWNER_QUERENT_USER -> ownerQuerent(verifyCrossUser = true) }.run { /*exhaust*/ } } @@ -628,6 +639,80 @@ class DomainVerificationEnforcerTest { runTestCases(callingUserId, notCallingUserId, throws = false) } + private fun ownerQuerent(verifyCrossUser: Boolean) { + val allowQueryAll = AtomicBoolean(false) + val allowUserSelection = AtomicBoolean(false) + val allowInteractAcrossUsers = AtomicBoolean(false) + val context: Context = mockThrowOnUnmocked { + initPermission( + allowQueryAll, + android.Manifest.permission.QUERY_ALL_PACKAGES + ) + initPermission( + allowUserSelection, + android.Manifest.permission.UPDATE_DOMAIN_VERIFICATION_USER_SELECTION + ) + initPermission( + allowInteractAcrossUsers, + android.Manifest.permission.INTERACT_ACROSS_USERS + ) + } + val target = params.construct(context) + + fun runTestCases(callingUserId: Int, targetUserId: Int, throws: Boolean) { + // Owner querent makes no distinction by UID + val allUids = INTERNAL_UIDS + VERIFIER_UID + NON_VERIFIER_UID + if (throws) { + allUids.forEach { + assertFails { + runMethod(target, it, visible = true, callingUserId, targetUserId) + } + } + } else { + allUids.forEach { + runMethod(target, it, visible = true, callingUserId, targetUserId) + } + } + } + + val callingUserId = 0 + val notCallingUserId = 1 + + runTestCases(callingUserId, callingUserId, throws = true) + if (verifyCrossUser) { + runTestCases(callingUserId, notCallingUserId, throws = true) + } + + allowQueryAll.set(true) + + runTestCases(callingUserId, callingUserId, throws = true) + if (verifyCrossUser) { + runTestCases(callingUserId, notCallingUserId, throws = true) + } + + allowUserSelection.set(true) + + runTestCases(callingUserId, callingUserId, throws = false) + if (verifyCrossUser) { + runTestCases(callingUserId, notCallingUserId, throws = true) + } + + allowQueryAll.set(false) + + runTestCases(callingUserId, callingUserId, throws = true) + if (verifyCrossUser) { + runTestCases(callingUserId, notCallingUserId, throws = true) + } + + allowQueryAll.set(true) + allowInteractAcrossUsers.set(true) + + runTestCases(callingUserId, callingUserId, throws = false) + if (verifyCrossUser) { + runTestCases(callingUserId, notCallingUserId, throws = false) + } + } + private fun Context.initPermission(boolean: AtomicBoolean, permission: String) { whenever(enforcePermission(eq(permission), anyInt(), anyInt(), anyString())) { if (!boolean.get()) { @@ -694,6 +779,12 @@ class DomainVerificationEnforcerTest { LEGACY_QUERENT, // Holding the legacy preferred apps permission - LEGACY_SELECTOR + LEGACY_SELECTOR, + + // Holding user setting permission, but not targeting a package + OWNER_QUERENT, + + // Holding user setting permission, but not targeting a package, but targeting cross user + OWNER_QUERENT_USER, } } diff --git a/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationManagerUserSelectionOverrideTest.kt b/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationManagerUserSelectionOverrideTest.kt new file mode 100644 index 000000000000..48056a2b54d1 --- /dev/null +++ b/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationManagerUserSelectionOverrideTest.kt @@ -0,0 +1,174 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.pm.test.verify.domain + +import android.content.Context +import android.content.Intent +import android.content.pm.PackageManager +import android.content.pm.parsing.component.ParsedActivity +import android.content.pm.parsing.component.ParsedIntentInfo +import android.content.pm.verify.domain.DomainVerificationManager +import android.content.pm.verify.domain.DomainVerificationUserSelection +import android.os.Build +import android.os.PatternMatcher +import android.os.Process +import android.util.ArraySet +import androidx.test.InstrumentationRegistry +import com.android.server.pm.PackageSetting +import com.android.server.pm.parsing.pkg.AndroidPackage +import com.android.server.pm.verify.domain.DomainVerificationService +import com.android.server.testutils.mockThrowOnUnmocked +import com.android.server.testutils.whenever +import com.google.common.truth.Truth.assertThat +import org.junit.Test +import org.mockito.ArgumentMatchers.any +import org.mockito.ArgumentMatchers.anyInt +import org.mockito.ArgumentMatchers.anyLong +import org.mockito.ArgumentMatchers.anyString +import java.util.UUID + +class DomainVerificationManagerUserSelectionOverrideTest { + + companion object { + private const val PKG_ONE = "com.test.one" + private const val PKG_TWO = "com.test.two" + private val UUID_ONE = UUID.fromString("1b041c96-8d37-4932-a858-561bfac5947c") + private val UUID_TWO = UUID.fromString("a3389c16-7f9f-4e86-85e3-500d1249c74c") + + private val DOMAIN_ONE = + DomainVerificationManagerUserSelectionOverrideTest::class.java.packageName + + private const val STATE_NONE = DomainVerificationUserSelection.DOMAIN_STATE_NONE + private const val STATE_SELECTED = DomainVerificationUserSelection.DOMAIN_STATE_SELECTED + private const val STATE_VERIFIED = DomainVerificationUserSelection.DOMAIN_STATE_VERIFIED + } + + private val pkg1 = mockPkgSetting(PKG_ONE, UUID_ONE) + private val pkg2 = mockPkgSetting(PKG_TWO, UUID_TWO) + + fun makeManager(): DomainVerificationManager = + DomainVerificationService(mockThrowOnUnmocked { + // Assume the test has every permission necessary + whenever(enforcePermission(anyString(), anyInt(), anyInt(), anyString())) + whenever(checkPermission(anyString(), anyInt(), anyInt())) { + PackageManager.PERMISSION_GRANTED + } + }, mockThrowOnUnmocked { + whenever(linkedApps) { ArraySet<String>() } + }, mockThrowOnUnmocked { + whenever(isChangeEnabled(anyLong(), any())) { true } + }).apply { + setConnection(mockThrowOnUnmocked { + whenever(filterAppAccess(anyString(), anyInt(), anyInt())) { false } + whenever(scheduleWriteSettings()) + + // Need to provide an internal UID so some permission checks are ignored + whenever(callingUid) { Process.ROOT_UID } + whenever(callingUserId) { 0 } + whenever(getPackageSettingLocked(PKG_ONE)) { pkg1 } + whenever(getPackageSettingLocked(PKG_TWO)) { pkg2 } + whenever(getPackageLocked(PKG_ONE)) { pkg1.getPkg() } + whenever(getPackageLocked(PKG_TWO)) { pkg2.getPkg() } + }) + addPackage(pkg1) + addPackage(pkg2) + + // Starting state for all tests is to have domain 1 enabled for the first package + setDomainVerificationUserSelection(UUID_ONE, setOf(DOMAIN_ONE), true) + + assertThat(stateFor(PKG_ONE, DOMAIN_ONE)).isEqualTo(STATE_SELECTED) + } + + fun mockPkgSetting(pkgName: String, domainSetId: UUID) = mockThrowOnUnmocked<PackageSetting> { + val pkg = mockThrowOnUnmocked<AndroidPackage> { + whenever(packageName) { pkgName } + whenever(targetSdkVersion) { Build.VERSION_CODES.S } + + val activityList = listOf( + ParsedActivity().apply { + addIntent( + ParsedIntentInfo().apply { + autoVerify = true + addAction(Intent.ACTION_VIEW) + addCategory(Intent.CATEGORY_BROWSABLE) + addCategory(Intent.CATEGORY_DEFAULT) + addDataScheme("http") + addDataScheme("https") + addDataPath("/sub", PatternMatcher.PATTERN_LITERAL) + addDataAuthority(DOMAIN_ONE, null) + } + ) + addIntent( + ParsedIntentInfo().apply { + autoVerify = true + addAction(Intent.ACTION_VIEW) + addCategory(Intent.CATEGORY_BROWSABLE) + addCategory(Intent.CATEGORY_DEFAULT) + addDataScheme("http") + addDataPath("/sub2", PatternMatcher.PATTERN_LITERAL) + addDataAuthority("example2.com", null) + } + ) + }, + ) + + whenever(activities) { activityList } + } + + whenever(getPkg()) { pkg } + whenever(getName()) { pkgName } + whenever(this.domainSetId) { domainSetId } + whenever(getInstantApp(anyInt())) { false } + whenever(firstInstallTime) { 0L } + } + + @Test + fun anotherPackageTakeoverSuccess() { + val manager = makeManager() + + // Attempt override by package 2 + manager.setDomainVerificationUserSelection(UUID_TWO, setOf(DOMAIN_ONE), true) + + // 1 loses approval + assertThat(manager.stateFor(PKG_ONE, DOMAIN_ONE)).isEqualTo(STATE_NONE) + + // 2 gains approval + assertThat(manager.stateFor(PKG_TWO, DOMAIN_ONE)).isEqualTo(STATE_SELECTED) + + // 2 is the only owner + assertThat(manager.getOwnersForDomain(DOMAIN_ONE).map { it.packageName }) + .containsExactly(PKG_TWO) + } + + @Test(expected = IllegalArgumentException::class) + fun anotherPackageTakeoverFailure() { + val manager = makeManager() + + // Verify 1 to give it a higher approval level + manager.setDomainVerificationStatus(UUID_ONE, setOf(DOMAIN_ONE), + DomainVerificationManager.STATE_SUCCESS) + assertThat(manager.stateFor(PKG_ONE, DOMAIN_ONE)).isEqualTo(STATE_VERIFIED) + assertThat(manager.getOwnersForDomain(DOMAIN_ONE).map { it.packageName }) + .containsExactly(PKG_ONE) + + // Attempt override by package 2 + manager.setDomainVerificationUserSelection(UUID_TWO, setOf(DOMAIN_ONE), true) + } + + private fun DomainVerificationManager.stateFor(pkgName: String, host: String) = + getDomainVerificationUserSelection(pkgName)!!.hostToStateMap[host] +} diff --git a/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationModelExtensions.kt b/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationModelExtensions.kt index a76d8cee582c..439048ce51bb 100644 --- a/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationModelExtensions.kt +++ b/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationModelExtensions.kt @@ -34,7 +34,7 @@ operator fun DomainVerificationUserSelection.component1() = identifier operator fun DomainVerificationUserSelection.component2() = packageName operator fun DomainVerificationUserSelection.component3() = user operator fun DomainVerificationUserSelection.component4() = isLinkHandlingAllowed -operator fun DomainVerificationUserSelection.component5() = hostToUserSelectionMap +operator fun DomainVerificationUserSelection.component5() = hostToStateMap operator fun DomainVerificationPersistence.ReadResult.component1() = active operator fun DomainVerificationPersistence.ReadResult.component2() = restored diff --git a/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationSettingsMutationTest.kt b/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationSettingsMutationTest.kt index 48518f4693dd..010eacf3f51f 100644 --- a/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationSettingsMutationTest.kt +++ b/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/verify/domain/DomainVerificationSettingsMutationTest.kt @@ -237,6 +237,7 @@ class DomainVerificationSettingsMutationTest { TEST_UUID ) ) { + whenever(getName()) { TEST_PKG } whenever(getPkg()) { mockPkg() } whenever(domainSetId) { TEST_UUID } whenever(userState) { diff --git a/services/tests/mockingservicestests/src/com/android/server/job/controllers/ConnectivityControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/job/controllers/ConnectivityControllerTest.java index 775276bd03f6..f7f592886473 100644 --- a/services/tests/mockingservicestests/src/com/android/server/job/controllers/ConnectivityControllerTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/job/controllers/ConnectivityControllerTest.java @@ -19,6 +19,7 @@ package com.android.server.job.controllers; import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED; +import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED; import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED; import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; @@ -611,6 +612,7 @@ public class ConnectivityControllerTest { private static NetworkCapabilities createCapabilities() { return new NetworkCapabilities().addCapability(NET_CAPABILITY_INTERNET) + .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED) .addCapability(NET_CAPABILITY_VALIDATED); } diff --git a/services/tests/mockingservicestests/src/com/android/server/location/gnss/hal/FakeGnssHal.java b/services/tests/mockingservicestests/src/com/android/server/location/gnss/hal/FakeGnssHal.java index 69fe140a7863..e0c8b09aae88 100644 --- a/services/tests/mockingservicestests/src/com/android/server/location/gnss/hal/FakeGnssHal.java +++ b/services/tests/mockingservicestests/src/com/android/server/location/gnss/hal/FakeGnssHal.java @@ -500,7 +500,7 @@ public final class FakeGnssHal extends GnssNative.GnssHal { } @Override - protected boolean isAntennaInfoListeningSupported() { + protected boolean isAntennaInfoSupported() { return mIsAntennaInfoListeningSupported; } diff --git a/services/tests/mockingservicestests/src/com/android/server/location/provider/LocationProviderManagerTest.java b/services/tests/mockingservicestests/src/com/android/server/location/provider/LocationProviderManagerTest.java index c4c9ad088e45..1b58e924dd6a 100644 --- a/services/tests/mockingservicestests/src/com/android/server/location/provider/LocationProviderManagerTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/location/provider/LocationProviderManagerTest.java @@ -353,7 +353,7 @@ public class LocationProviderManagerTest { @Test public void testGetLastLocation_ClearOnMockRemoval() { MockLocationProvider mockProvider = new MockLocationProvider(PROPERTIES, PROVIDER_IDENTITY, - null); + Collections.emptySet()); mockProvider.setAllowed(true); mManager.setMockProvider(mockProvider); @@ -1049,7 +1049,7 @@ public class LocationProviderManagerTest { private final ArrayList<Runnable> mFlushCallbacks = new ArrayList<>(); TestProvider(ProviderProperties properties, CallerIdentity identity) { - super(DIRECT_EXECUTOR, identity, properties, null); + super(DIRECT_EXECUTOR, identity, properties, Collections.emptySet()); } public void setProviderAllowed(boolean allowed) { diff --git a/services/tests/mockingservicestests/src/com/android/server/location/provider/MockableLocationProviderTest.java b/services/tests/mockingservicestests/src/com/android/server/location/provider/MockableLocationProviderTest.java index e8a0bb51e20f..cf5db2e0db98 100644 --- a/services/tests/mockingservicestests/src/com/android/server/location/provider/MockableLocationProviderTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/location/provider/MockableLocationProviderTest.java @@ -43,6 +43,8 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import java.util.Collections; + @Presubmit @SmallTest @RunWith(AndroidJUnit4.class) @@ -72,7 +74,7 @@ public class MockableLocationProviderTest { .setAccuracy(ACCURACY_FINE) .build(), CallerIdentity.forTest(0, 1, "testpackage", "test"), - null); + Collections.emptySet()); mProvider = new MockableLocationProvider(lock); mProvider.getController().setListener(mListener); diff --git a/services/tests/mockingservicestests/src/com/android/server/location/test/FakeProvider.java b/services/tests/mockingservicestests/src/com/android/server/location/test/FakeProvider.java index a1eadbe4a64f..2bc1268f1b85 100644 --- a/services/tests/mockingservicestests/src/com/android/server/location/test/FakeProvider.java +++ b/services/tests/mockingservicestests/src/com/android/server/location/test/FakeProvider.java @@ -23,6 +23,7 @@ import com.android.server.location.provider.AbstractLocationProvider; import java.io.FileDescriptor; import java.io.PrintWriter; +import java.util.Collections; public class FakeProvider extends AbstractLocationProvider { @@ -40,7 +41,7 @@ public class FakeProvider extends AbstractLocationProvider { private final FakeProviderInterface mFakeInterface; public FakeProvider(FakeProviderInterface fakeInterface) { - super(Runnable::run, null, null, null); + super(Runnable::run, null, null, Collections.emptySet()); mFakeInterface = fakeInterface; } diff --git a/services/tests/servicestests/Android.bp b/services/tests/servicestests/Android.bp index bea4ae3af1fd..68f547979ce0 100644 --- a/services/tests/servicestests/Android.bp +++ b/services/tests/servicestests/Android.bp @@ -181,9 +181,12 @@ java_genrule { ":FrameworksServicesTests_install_split_feature_a", ":FrameworksServicesTests_install_uses_sdk_0", ":FrameworksServicesTests_install_uses_sdk_q0", - ":FrameworksServicesTests_install_uses_sdk_r", + ":FrameworksServicesTests_install_uses_sdk_q0_r0", + ":FrameworksServicesTests_install_uses_sdk_r_none", ":FrameworksServicesTests_install_uses_sdk_r0", ":FrameworksServicesTests_install_uses_sdk_r5", + ":FrameworksServicesTests_install_uses_sdk_r0_s0", + ":FrameworksServicesTests_install_uses_sdk_r0_s5", ], out: ["FrameworkServicesTests_apks_as_resources.res.zip"], tools: ["soong_zip"], diff --git a/services/tests/servicestests/apks/install_uses_sdk/Android.bp b/services/tests/servicestests/apks/install_uses_sdk/Android.bp index feb152c49eb3..a51293dc1997 100644 --- a/services/tests/servicestests/apks/install_uses_sdk/Android.bp +++ b/services/tests/servicestests/apks/install_uses_sdk/Android.bp @@ -8,41 +8,49 @@ package { } android_test_helper_app { + name: "FrameworksServicesTests_install_uses_sdk_q0", + defaults: ["FrameworksServicesTests_apks_defaults"], + manifest: "AndroidManifest-q0.xml", +} + +android_test_helper_app { + name: "FrameworksServicesTests_install_uses_sdk_q0_r0", + defaults: ["FrameworksServicesTests_apks_defaults"], + manifest: "AndroidManifest-q0-r0.xml", +} + +android_test_helper_app { + name: "FrameworksServicesTests_install_uses_sdk_r_none", + defaults: ["FrameworksServicesTests_apks_defaults"], + manifest: "AndroidManifest-r-none.xml", +} + +android_test_helper_app { name: "FrameworksServicesTests_install_uses_sdk_r0", defaults: ["FrameworksServicesTests_apks_defaults"], manifest: "AndroidManifest-r0.xml", - - srcs: ["**/*.java"], } android_test_helper_app { name: "FrameworksServicesTests_install_uses_sdk_r5", defaults: ["FrameworksServicesTests_apks_defaults"], manifest: "AndroidManifest-r5.xml", - - srcs: ["**/*.java"], } android_test_helper_app { - name: "FrameworksServicesTests_install_uses_sdk_q0", + name: "FrameworksServicesTests_install_uses_sdk_r0_s0", defaults: ["FrameworksServicesTests_apks_defaults"], - manifest: "AndroidManifest-q0.xml", - - srcs: ["**/*.java"], + manifest: "AndroidManifest-r0-s0.xml", } android_test_helper_app { - name: "FrameworksServicesTests_install_uses_sdk_r", + name: "FrameworksServicesTests_install_uses_sdk_r0_s5", defaults: ["FrameworksServicesTests_apks_defaults"], - manifest: "AndroidManifest-r.xml", - - srcs: ["**/*.java"], + manifest: "AndroidManifest-r0-s5.xml", } android_test_helper_app { name: "FrameworksServicesTests_install_uses_sdk_0", defaults: ["FrameworksServicesTests_apks_defaults"], manifest: "AndroidManifest-0.xml", - - srcs: ["**/*.java"], } diff --git a/services/tests/servicestests/apks/install_uses_sdk/AndroidManifest-0.xml b/services/tests/servicestests/apks/install_uses_sdk/AndroidManifest-0.xml index 215384b2831c..90b13d45fc05 100644 --- a/services/tests/servicestests/apks/install_uses_sdk/AndroidManifest-0.xml +++ b/services/tests/servicestests/apks/install_uses_sdk/AndroidManifest-0.xml @@ -18,7 +18,7 @@ <uses-sdk android:minSdkVersion="4" android:targetSdkVersion="29"> <!-- This is invalid, because there is no sdk version specified --> - <extension-sdk android:minExtensionVersion="5" /> + <extension-sdk android:minExtensionVersion="0" /> </uses-sdk> <application> diff --git a/services/tests/servicestests/apks/install_uses_sdk/AndroidManifest-q0-r0.xml b/services/tests/servicestests/apks/install_uses_sdk/AndroidManifest-q0-r0.xml new file mode 100644 index 000000000000..2a3227660686 --- /dev/null +++ b/services/tests/servicestests/apks/install_uses_sdk/AndroidManifest-q0-r0.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- 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. +--> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.frameworks.servicestests.install_uses_sdk"> + + <uses-sdk android:minSdkVersion="4" android:targetSdkVersion="29"> + <!-- This fails because 29 doesn't have an extension sdk --> + <extension-sdk android:sdkVersion="29" android:minExtensionVersion="0" /> + <extension-sdk android:sdkVersion="30" android:minExtensionVersion="0" /> + </uses-sdk> + + <application> + </application> +</manifest> diff --git a/services/tests/servicestests/apks/install_uses_sdk/AndroidManifest-r.xml b/services/tests/servicestests/apks/install_uses_sdk/AndroidManifest-r-none.xml index 5d22577d118a..c79c61c3dc32 100644 --- a/services/tests/servicestests/apks/install_uses_sdk/AndroidManifest-r.xml +++ b/services/tests/servicestests/apks/install_uses_sdk/AndroidManifest-r-none.xml @@ -18,7 +18,7 @@ <uses-sdk android:minSdkVersion="4" android:targetSdkVersion="29"> <!-- This is invalid, because there is no minimum extension version specified --> - <extension-sdk android:sdkVersion="10000" /> + <extension-sdk android:sdkVersion="30" /> </uses-sdk> <application> diff --git a/services/tests/servicestests/apks/install_uses_sdk/AndroidManifest-r0-s0.xml b/services/tests/servicestests/apks/install_uses_sdk/AndroidManifest-r0-s0.xml new file mode 100644 index 000000000000..af30915b4f0b --- /dev/null +++ b/services/tests/servicestests/apks/install_uses_sdk/AndroidManifest-r0-s0.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- 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. +--> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.frameworks.servicestests.install_uses_sdk"> + + <uses-sdk android:minSdkVersion="4" android:targetSdkVersion="29"> + <extension-sdk android:sdkVersion="30" android:minExtensionVersion="0" /> + <extension-sdk android:sdkVersion="31" android:minExtensionVersion="0" /> + </uses-sdk> + + <application> + </application> +</manifest> diff --git a/services/tests/servicestests/apks/install_uses_sdk/AndroidManifest-r0-s5.xml b/services/tests/servicestests/apks/install_uses_sdk/AndroidManifest-r0-s5.xml new file mode 100644 index 000000000000..bafe4c4faa3f --- /dev/null +++ b/services/tests/servicestests/apks/install_uses_sdk/AndroidManifest-r0-s5.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- 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. +--> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.frameworks.servicestests.install_uses_sdk"> + + <uses-sdk android:minSdkVersion="4" android:targetSdkVersion="29"> + <!-- This fails because 31 is not version 5 --> + <extension-sdk android:sdkVersion="30" android:minExtensionVersion="0" /> + <extension-sdk android:sdkVersion="31" android:minExtensionVersion="5" /> + </uses-sdk> + + <application> + </application> +</manifest> diff --git a/services/tests/servicestests/apks/install_uses_sdk/AndroidManifest-r0.xml b/services/tests/servicestests/apks/install_uses_sdk/AndroidManifest-r0.xml index c1244f246355..2920b8641586 100644 --- a/services/tests/servicestests/apks/install_uses_sdk/AndroidManifest-r0.xml +++ b/services/tests/servicestests/apks/install_uses_sdk/AndroidManifest-r0.xml @@ -17,7 +17,7 @@ package="com.android.frameworks.servicestests.install_uses_sdk"> <uses-sdk android:minSdkVersion="4" android:targetSdkVersion="29"> - <extension-sdk android:sdkVersion="10000" android:minExtensionVersion="0" /> + <extension-sdk android:sdkVersion="30" android:minExtensionVersion="0" /> </uses-sdk> <application> diff --git a/services/tests/servicestests/apks/install_uses_sdk/AndroidManifest-r5.xml b/services/tests/servicestests/apks/install_uses_sdk/AndroidManifest-r5.xml index 3410938b3c2d..7723d051a041 100644 --- a/services/tests/servicestests/apks/install_uses_sdk/AndroidManifest-r5.xml +++ b/services/tests/servicestests/apks/install_uses_sdk/AndroidManifest-r5.xml @@ -18,7 +18,7 @@ <uses-sdk android:minSdkVersion="4" android:targetSdkVersion="29"> <!-- This will fail to install, because minExtensionVersion is not met --> - <extension-sdk android:sdkVersion="10000" android:minExtensionVersion="5" /> + <extension-sdk android:sdkVersion="30" android:minExtensionVersion="5" /> </uses-sdk> <application> diff --git a/services/tests/servicestests/src/com/android/server/am/BatteryStatsServiceTest.java b/services/tests/servicestests/src/com/android/server/am/BatteryStatsServiceTest.java index 488e5cdf33b9..1870df9ecf17 100644 --- a/services/tests/servicestests/src/com/android/server/am/BatteryStatsServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/am/BatteryStatsServiceTest.java @@ -30,6 +30,7 @@ import com.android.internal.os.BatteryStatsImpl; import org.junit.After; import org.junit.Before; +import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; @@ -59,6 +60,7 @@ public final class BatteryStatsServiceTest { } @Test + @Ignore("b/180015146") public void testAwaitCompletion() throws Exception { final CountDownLatch readyLatch = new CountDownLatch(2); final CountDownLatch startLatch = new CountDownLatch(1); diff --git a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java index 73191dca6093..4a42940832c4 100644 --- a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java +++ b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java @@ -150,7 +150,7 @@ public class LockSettingsServiceTestable extends LockSettingsService { } @Override - public RecoverableKeyStoreManager getRecoverableKeyStoreManager(KeyStore keyStore) { + public RecoverableKeyStoreManager getRecoverableKeyStoreManager() { return mRecoverableKeyStoreManager; } diff --git a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java index e46ab6b01f0a..029e9a39ea4b 100644 --- a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java @@ -45,6 +45,13 @@ import android.app.ActivityManagerInternal; import android.app.IUidObserver; import android.app.Person; import android.app.admin.DevicePolicyManager; +import android.app.appsearch.AppSearchBatchResult; +import android.app.appsearch.AppSearchManager; +import android.app.appsearch.AppSearchResult; +import android.app.appsearch.IAppSearchBatchResultCallback; +import android.app.appsearch.IAppSearchManager; +import android.app.appsearch.IAppSearchResultCallback; +import android.app.appsearch.PackageIdentifier; import android.app.role.OnRoleHoldersChangedListener; import android.app.usage.UsageStatsManagerInternal; import android.content.ActivityNotFoundException; @@ -78,6 +85,7 @@ import android.net.Uri; import android.os.Bundle; import android.os.FileUtils; import android.os.Handler; +import android.os.IBinder; import android.os.Looper; import android.os.PersistableBundle; import android.os.Process; @@ -150,6 +158,8 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase { return mMockUserManager; case Context.DEVICE_POLICY_SERVICE: return mMockDevicePolicyManager; + case Context.APP_SEARCH_SERVICE: + return new AppSearchManager(getTestContext(), mMockAppSearchManager); case Context.ROLE_SERVICE: // RoleManager is final and cannot be mocked, so we only override the inject // accessor methods in ShortcutService. @@ -159,6 +169,11 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase { } @Override + public String getOpPackageName() { + return getTestContext().getOpPackageName(); + } + + @Override public String getSystemServiceName(Class<?> serviceClass) { return getTestContext().getSystemServiceName(serviceClass); } @@ -601,6 +616,123 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase { } } + protected class MockAppSearchManager implements IAppSearchManager { + + protected Map<String, List<PackageIdentifier>> mSchemasPackageAccessible = + new ArrayMap<>(1); + + @Override + public void setSchema(String packageName, String databaseName, List<Bundle> schemaBundles, + List<String> schemasNotPlatformSurfaceable, + Map<String, List<Bundle>> schemasPackageAccessibleBundles, boolean forceOverride, + int userId, IAppSearchResultCallback callback) throws RemoteException { + for (Map.Entry<String, List<Bundle>> entry : + schemasPackageAccessibleBundles.entrySet()) { + final String key = entry.getKey(); + final List<PackageIdentifier> packageIdentifiers; + if (!mSchemasPackageAccessible.containsKey(key)) { + packageIdentifiers = new ArrayList<>(entry.getValue().size()); + mSchemasPackageAccessible.put(key, packageIdentifiers); + } else { + packageIdentifiers = mSchemasPackageAccessible.get(key); + } + for (int i = 0; i < entry.getValue().size(); i++) { + packageIdentifiers.add(new PackageIdentifier(entry.getValue().get(i))); + } + } + callback.onResult(AppSearchResult.newSuccessfulResult(null)); + } + + @Override + public void getSchema(String packageName, String databaseName, int userId, + IAppSearchResultCallback callback) throws RemoteException { + ignore(callback); + } + + @Override + public void putDocuments(String packageName, String databaseName, + List<Bundle> documentBundles, int userId, IAppSearchBatchResultCallback callback) + throws RemoteException { + ignore(callback); + } + + @Override + public void getDocuments(String packageName, String databaseName, String namespace, + List<String> uris, Map<String, List<String>> typePropertyPaths, int userId, + IAppSearchBatchResultCallback callback) throws RemoteException { + ignore(callback); + } + + @Override + public void query(String packageName, String databaseName, String queryExpression, + Bundle searchSpecBundle, int userId, IAppSearchResultCallback callback) + throws RemoteException { + ignore(callback); + } + + @Override + public void globalQuery(String packageName, String queryExpression, Bundle searchSpecBundle, + int userId, IAppSearchResultCallback callback) throws RemoteException { + ignore(callback); + } + + @Override + public void getNextPage(long nextPageToken, int userId, IAppSearchResultCallback callback) + throws RemoteException { + ignore(callback); + } + + @Override + public void invalidateNextPageToken(long nextPageToken, int userId) throws RemoteException { + + } + + @Override + public void reportUsage(String packageName, String databaseName, String namespace, + String uri, long usageTimeMillis, int userId, IAppSearchResultCallback callback) + throws RemoteException { + ignore(callback); + } + + @Override + public void removeByUri(String packageName, String databaseName, String namespace, + List<String> uris, int userId, IAppSearchBatchResultCallback callback) + throws RemoteException { + ignore(callback); + } + + @Override + public void removeByQuery(String packageName, String databaseName, String queryExpression, + Bundle searchSpecBundle, int userId, IAppSearchResultCallback callback) + throws RemoteException { + ignore(callback); + } + + @Override + public void persistToDisk(int userId) throws RemoteException { + + } + + @Override + public void initialize(int userId, IAppSearchResultCallback callback) + throws RemoteException { + ignore(callback); + } + + @Override + public IBinder asBinder() { + return null; + } + + private void ignore(IAppSearchResultCallback callback) throws RemoteException { + callback.onResult(AppSearchResult.newSuccessfulResult(null)); + } + + private void ignore(IAppSearchBatchResultCallback callback) throws RemoteException { + callback.onResult(new AppSearchBatchResult.Builder().build()); + } + } + public static class ShortcutActivity extends Activity { } @@ -652,6 +784,7 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase { protected PackageManagerInternal mMockPackageManagerInternal; protected UserManager mMockUserManager; protected DevicePolicyManager mMockDevicePolicyManager; + protected MockAppSearchManager mMockAppSearchManager; protected UserManagerInternal mMockUserManagerInternal; protected UsageStatsManagerInternal mMockUsageStatsManagerInternal; protected ActivityManagerInternal mMockActivityManagerInternal; @@ -801,6 +934,7 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase { mMockPackageManagerInternal = mock(PackageManagerInternal.class); mMockUserManager = mock(UserManager.class); mMockDevicePolicyManager = mock(DevicePolicyManager.class); + mMockAppSearchManager = new MockAppSearchManager(); mMockUserManagerInternal = mock(UserManagerInternal.class); mMockUsageStatsManagerInternal = mock(UsageStatsManagerInternal.class); mMockActivityManagerInternal = mock(ActivityManagerInternal.class); diff --git a/services/tests/servicestests/src/com/android/server/pm/OWNERS b/services/tests/servicestests/src/com/android/server/pm/OWNERS index d825dfd7cf00..e15b5f57069c 100644 --- a/services/tests/servicestests/src/com/android/server/pm/OWNERS +++ b/services/tests/servicestests/src/com/android/server/pm/OWNERS @@ -1 +1,3 @@ include /services/core/java/com/android/server/pm/OWNERS + +per-file *Shortcut* = file:/core/java/android/content/pm/SHORTCUT_OWNERS diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest12.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest12.java new file mode 100644 index 000000000000..b17085ee0317 --- /dev/null +++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest12.java @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.server.pm; + +import android.app.appsearch.PackageIdentifier; +import android.content.pm.AppSearchShortcutInfo; + +import java.util.Random; + +/** + * Tests for {@link android.app.appsearch.AppSearchManager} and relevant APIs in ShortcutManager. + * + atest -c com.android.server.pm.ShortcutManagerTest12 + */ +public class ShortcutManagerTest12 extends BaseShortcutManagerTest { + + public void testUpdateShortcutVisibility_updatesShortcutSchema() { + + final byte[] cert = new byte[20]; + new Random().nextBytes(cert); + + runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { + mManager.updateShortcutVisibility(CALLING_PACKAGE_2, cert, true); + assertTrue(mMockAppSearchManager.mSchemasPackageAccessible.containsKey( + AppSearchShortcutInfo.SCHEMA_TYPE)); + assertTrue(mMockAppSearchManager.mSchemasPackageAccessible.get( + AppSearchShortcutInfo.SCHEMA_TYPE).get(0).equals( + new PackageIdentifier(CALLING_PACKAGE_2, cert))); + }); + } +} diff --git a/services/tests/servicestests/src/com/android/server/pm/parsing/PackageParserLegacyCoreTest.java b/services/tests/servicestests/src/com/android/server/pm/parsing/PackageParserLegacyCoreTest.java index fb13d8707a44..c2b385889802 100644 --- a/services/tests/servicestests/src/com/android/server/pm/parsing/PackageParserLegacyCoreTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/parsing/PackageParserLegacyCoreTest.java @@ -17,10 +17,10 @@ package com.android.server.pm.parsing; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; import android.apex.ApexInfo; import android.content.Context; @@ -39,6 +39,7 @@ import android.os.Build; import android.os.Bundle; import android.os.FileUtils; import android.platform.test.annotations.Presubmit; +import android.util.Pair; import android.util.SparseIntArray; import androidx.test.InstrumentationRegistry; @@ -50,12 +51,17 @@ import com.android.internal.util.ArrayUtils; import com.android.server.pm.parsing.pkg.AndroidPackage; import com.android.server.pm.parsing.pkg.ParsedPackage; +import com.google.common.truth.Expect; + +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import java.io.File; import java.io.InputStream; import java.util.Collections; +import java.util.HashMap; +import java.util.Map; import java.util.function.Function; /** @@ -89,6 +95,8 @@ public class PackageParserLegacyCoreTest { private static final int PLATFORM_VERSION = 20; private static final int NEWER_VERSION = 30; + @Rule public final Expect expect = Expect.create(); + private void verifyComputeMinSdkVersion(int minSdkVersion, String minSdkCodename, boolean isPlatformReleased, int expectedMinSdk) { final String[] outError = new String[1]; @@ -553,36 +561,44 @@ public class PackageParserLegacyCoreTest { @Test public void testUsesSdk() throws Exception { - ParsedPackage pkg = - parsePackage("install_uses_sdk.apk_r0", R.raw.install_uses_sdk_r0, x -> x); - SparseIntArray minExtVers = pkg.getMinExtensionVersions(); + ParsedPackage pkg; + SparseIntArray minExtVers; + pkg = parsePackage("install_uses_sdk.apk_r0", R.raw.install_uses_sdk_r0, x -> x); + minExtVers = pkg.getMinExtensionVersions(); assertEquals(1, minExtVers.size()); - assertEquals(0, minExtVers.get(10000, -1)); - - try { - parsePackage("install_uses_sdk.apk_r5", R.raw.install_uses_sdk_r5, x -> x); - fail("Expected parsing exception due to incompatible extension SDK version"); - } catch (PackageParser.PackageParserException expected) { - assertEquals(PackageManager.INSTALL_FAILED_OLDER_SDK, expected.error); - } - try { - parsePackage("install_uses_sdk.apk_q0", R.raw.install_uses_sdk_q0, x -> x); - fail("Expected parsing exception due to non-existent extension SDK"); - } catch (PackageParser.PackageParserException expected) { - assertEquals(PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED, expected.error); - } - try { - parsePackage("install_uses_sdk.apk_r", R.raw.install_uses_sdk_r, x -> x); - fail("Expected parsing exception due to unspecified extension SDK version"); - } catch (PackageParser.PackageParserException expected) { - assertEquals(PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED, expected.error); - } - try { - parsePackage("install_uses_sdk.apk_0", R.raw.install_uses_sdk_0, x -> x); - fail("Expected parsing exception due to unspecified extension SDK"); - } catch (PackageParser.PackageParserException expected) { - assertEquals(PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED, expected.error); + assertEquals(0, minExtVers.get(30, -1)); + + pkg = parsePackage("install_uses_sdk.apk_r0_s0", R.raw.install_uses_sdk_r0_s0, x -> x); + minExtVers = pkg.getMinExtensionVersions(); + assertEquals(2, minExtVers.size()); + assertEquals(0, minExtVers.get(30, -1)); + assertEquals(0, minExtVers.get(31, -1)); + + Map<Pair<String, Integer>, Integer> appToError = new HashMap<>(); + appToError.put(Pair.create("install_uses_sdk.apk_r5", R.raw.install_uses_sdk_r5), + PackageManager.INSTALL_FAILED_OLDER_SDK); + appToError.put(Pair.create("install_uses_sdk.apk_r0_s5", R.raw.install_uses_sdk_r0_s5), + PackageManager.INSTALL_FAILED_OLDER_SDK); + + appToError.put(Pair.create("install_uses_sdk.apk_q0", R.raw.install_uses_sdk_q0), + PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED); + appToError.put(Pair.create("install_uses_sdk.apk_q0_r0", R.raw.install_uses_sdk_q0_r0), + PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED); + appToError.put(Pair.create("install_uses_sdk.apk_r_none", R.raw.install_uses_sdk_r_none), + PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED); + appToError.put(Pair.create("install_uses_sdk.apk_0", R.raw.install_uses_sdk_0), + PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED); + + for (Map.Entry<Pair<String, Integer>, Integer> entry : appToError.entrySet()) { + String filename = entry.getKey().first; + int resId = entry.getKey().second; + int result = entry.getValue(); + try { + parsePackage(filename, resId, x -> x); + expect.withMessage("Expected parsing error %d from %s", result, filename).fail(); + } catch (PackageParser.PackageParserException expected) { + expect.that(expected.error).isEqualTo(result); + } } - } } diff --git a/services/tests/servicestests/src/com/android/server/soundtrigger_middleware/OWNERS b/services/tests/servicestests/src/com/android/server/soundtrigger_middleware/OWNERS index 816bc6bba639..33385afbdfd6 100644 --- a/services/tests/servicestests/src/com/android/server/soundtrigger_middleware/OWNERS +++ b/services/tests/servicestests/src/com/android/server/soundtrigger_middleware/OWNERS @@ -1 +1 @@ -include /core/java/android/media/soundtrigger/OWNERS +include /media/aidl/android/media/soundtrigger_middleware/OWNERS diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenersTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenersTest.java index 80a046a1e8bb..9ac755f78a06 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenersTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenersTest.java @@ -17,6 +17,8 @@ package com.android.server.notification; import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_ALERTING; import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_CONVERSATIONS; +import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_ONGOING; +import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_SILENT; import static com.android.server.notification.NotificationManagerService.NotificationListeners.TAG_REQUESTED_LISTENERS; @@ -205,6 +207,52 @@ public class NotificationListenersTest extends UiServiceTestCase { } @Test + public void testEnsureFilters_newServiceWithMetadata_onlyOneListed() { + ServiceInfo si = new ServiceInfo(); + si.packageName = "new"; + si.name = "comp"; + si.metaData = new Bundle(); + si.metaData.putInt(NotificationListenerService.META_DATA_DEFAULT_FILTER_TYPES, 2); + + mListeners.ensureFilters(si, 0); + + assertThat(mListeners.getNotificationListenerFilter( + Pair.create(si.getComponentName(), 0)).getTypes()) + .isEqualTo(FLAG_FILTER_TYPE_ALERTING); + } + + @Test + public void testEnsureFilters_newServiceWithMetadata_disabledTypes() { + ServiceInfo si = new ServiceInfo(); + si.packageName = "new"; + si.name = "comp"; + si.metaData = new Bundle(); + si.metaData.putString(NotificationListenerService.META_DATA_DISABLED_FILTER_TYPES, "1,2"); + + mListeners.ensureFilters(si, 0); + + assertThat(mListeners.getNotificationListenerFilter( + Pair.create(si.getComponentName(), 0)).getTypes()) + .isEqualTo(FLAG_FILTER_TYPE_SILENT | FLAG_FILTER_TYPE_ONGOING); + } + + @Test + public void testEnsureFilters_newServiceWithMetadata_metaDataDisagrees() { + ServiceInfo si = new ServiceInfo(); + si.packageName = "new"; + si.name = "comp"; + si.metaData = new Bundle(); + si.metaData.putString(NotificationListenerService.META_DATA_DEFAULT_FILTER_TYPES, "1,2"); + si.metaData.putInt(NotificationListenerService.META_DATA_DISABLED_FILTER_TYPES, 1); + + mListeners.ensureFilters(si, 0); + + assertThat(mListeners.getNotificationListenerFilter( + Pair.create(si.getComponentName(), 0)).getTypes()) + .isEqualTo(FLAG_FILTER_TYPE_ALERTING); + } + + @Test public void testEnsureFilters_newServiceWithEmptyMetadata() { ServiceInfo si = new ServiceInfo(); si.packageName = "new"; diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java index 488e629f5790..990927b704fa 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java @@ -555,9 +555,10 @@ public class ActivityRecordTests extends WindowTestsBase { activity.setRequestedOrientation( isScreenPortrait ? SCREEN_ORIENTATION_PORTRAIT : SCREEN_ORIENTATION_LANDSCAPE); - // Asserts it has orientation derived from bounds. - assertEquals(isScreenPortrait ? ORIENTATION_LANDSCAPE : ORIENTATION_PORTRAIT, + // Asserts it has orientation derived requested orientation (fixed orientation letterbox). + assertEquals(isScreenPortrait ? ORIENTATION_PORTRAIT : ORIENTATION_LANDSCAPE, activity.getConfiguration().orientation); + assertTrue(activity.isLetterboxedForFixedOrientationAndAspectRatio()); } @Test diff --git a/services/tests/wmtests/src/com/android/server/wm/DualDisplayAreaGroupPolicyTest.java b/services/tests/wmtests/src/com/android/server/wm/DualDisplayAreaGroupPolicyTest.java index f91c9d0e9853..e9c356d6c6c4 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DualDisplayAreaGroupPolicyTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/DualDisplayAreaGroupPolicyTest.java @@ -171,7 +171,7 @@ public class DualDisplayAreaGroupPolicyTest extends WindowTestsBase { final Rect activityBounds = new Rect(mFirstActivity.getBounds()); // DAG is portrait (860x1200), so Task and Activity fill DAG. - assertThat(mFirstTask.isTaskLetterboxed()).isFalse(); + assertThat(mFirstActivity.isLetterboxedForFixedOrientationAndAspectRatio()).isFalse(); assertThat(mFirstActivity.inSizeCompatMode()).isFalse(); assertThat(taskBounds).isEqualTo(dagBounds); assertThat(activityBounds).isEqualTo(taskBounds); @@ -194,8 +194,8 @@ public class DualDisplayAreaGroupPolicyTest extends WindowTestsBase { final Rect activityConfigBounds = new Rect(mFirstActivity.getConfiguration().windowConfiguration.getBounds()); - // DAG is landscape (1200x860), Task fills parent - assertThat(mFirstTask.isTaskLetterboxed()).isFalse(); + // DAG is landscape (1200x860), no fixed orientation letterbox + assertThat(mFirstActivity.isLetterboxedForFixedOrientationAndAspectRatio()).isFalse(); assertThat(mFirstActivity.inSizeCompatMode()).isTrue(); assertThat(newDagBounds.width()).isEqualTo(dagBounds.height()); assertThat(newDagBounds.height()).isEqualTo(dagBounds.width()); @@ -211,7 +211,7 @@ public class DualDisplayAreaGroupPolicyTest extends WindowTestsBase { } @Test - public void testLaunchLandscapeApp_taskIsLetterboxInDisplayAreaGroup() { + public void testLaunchLandscapeApp_activityIsLetterboxForFixedOrientationInDisplayAreaGroup() { mFirstRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */); mSecondRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */); mDisplay.onLastFocusedTaskDisplayAreaChanged(mFirstTda); @@ -221,17 +221,18 @@ public class DualDisplayAreaGroupPolicyTest extends WindowTestsBase { final Rect taskBounds = new Rect(mFirstTask.getBounds()); final Rect activityBounds = new Rect(mFirstActivity.getBounds()); - // DAG is portrait (860x1200), so Task is letterbox (860x[860x860/1200=616]) - assertThat(mFirstTask.isTaskLetterboxed()).isTrue(); + // DAG is portrait (860x1200), and activity is letterboxed for fixed orientation + // (860x[860x860/1200=616]). Task fills DAG. + assertThat(mFirstActivity.isLetterboxedForFixedOrientationAndAspectRatio()).isTrue(); assertThat(mFirstActivity.inSizeCompatMode()).isFalse(); - assertThat(taskBounds.width()).isEqualTo(dagBounds.width()); - assertThat(taskBounds.height()) + assertThat(taskBounds).isEqualTo(dagBounds); + assertThat(activityBounds.width()).isEqualTo(dagBounds.width()); + assertThat(activityBounds.height()) .isEqualTo(dagBounds.width() * dagBounds.width() / dagBounds.height()); - assertThat(activityBounds).isEqualTo(taskBounds); } @Test - public void testLaunchLandscapeApp_taskLetterboxBecomesActivityLetterboxAfterRotation() { + public void testLaunchLandscapeApp_fixedOrientationLetterboxBecomesSizeCompatAfterRotation() { mFirstRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */); mSecondRoot.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */); mDisplay.onLastFocusedTaskDisplayAreaChanged(mFirstTda); @@ -245,9 +246,8 @@ public class DualDisplayAreaGroupPolicyTest extends WindowTestsBase { final Rect newTaskBounds = new Rect(mFirstTask.getBounds()); final Rect newActivityBounds = new Rect(mFirstActivity.getBounds()); - // DAG is landscape (1200x860), Task fills parent - // Task letterbox size - assertThat(mFirstTask.isTaskLetterboxed()).isFalse(); + // DAG is landscape (1200x860), no fixed orientation letterbox + assertThat(mFirstActivity.isLetterboxedForFixedOrientationAndAspectRatio()).isFalse(); assertThat(mFirstActivity.inSizeCompatMode()).isTrue(); assertThat(newDagBounds.width()).isEqualTo(dagBounds.height()); assertThat(newDagBounds.height()).isEqualTo(dagBounds.width()); @@ -311,7 +311,7 @@ public class DualDisplayAreaGroupPolicyTest extends WindowTestsBase { } @Test - public void testResizableFixedOrientationApp_taskLevelLetterboxing() { + public void testResizableFixedOrientationApp_fixedOrientationLetterboxing() { mFirstRoot.setIgnoreOrientationRequest(false /* ignoreOrientationRequest */); mSecondRoot.setIgnoreOrientationRequest(false /* ignoreOrientationRequest */); @@ -324,7 +324,7 @@ public class DualDisplayAreaGroupPolicyTest extends WindowTestsBase { assertThat(mDisplay.getLastOrientation()).isEqualTo(SCREEN_ORIENTATION_LANDSCAPE); assertThat(mFirstRoot.getConfiguration().orientation).isEqualTo(ORIENTATION_PORTRAIT); assertThat(mFirstActivity.getConfiguration().orientation).isEqualTo(ORIENTATION_PORTRAIT); - assertThat(mFirstTask.isTaskLetterboxed()).isFalse(); + assertThat(mFirstActivity.isLetterboxedForFixedOrientationAndAspectRatio()).isFalse(); assertThat(mFirstActivity.inSizeCompatMode()).isFalse(); // Launch portrait on second DAG @@ -336,13 +336,13 @@ public class DualDisplayAreaGroupPolicyTest extends WindowTestsBase { assertThat(mDisplay.getLastOrientation()).isEqualTo(SCREEN_ORIENTATION_PORTRAIT); assertThat(mSecondRoot.getConfiguration().orientation).isEqualTo(ORIENTATION_LANDSCAPE); assertThat(mSecondActivity.getConfiguration().orientation).isEqualTo(ORIENTATION_LANDSCAPE); - assertThat(mSecondTask.isTaskLetterboxed()).isFalse(); + assertThat(mSecondActivity.isLetterboxedForFixedOrientationAndAspectRatio()).isFalse(); assertThat(mSecondActivity.inSizeCompatMode()).isFalse(); // First activity is letterboxed in portrait as requested. assertThat(mFirstRoot.getConfiguration().orientation).isEqualTo(ORIENTATION_LANDSCAPE); assertThat(mFirstActivity.getConfiguration().orientation).isEqualTo(ORIENTATION_PORTRAIT); - assertThat(mFirstTask.isTaskLetterboxed()).isTrue(); + assertThat(mFirstActivity.isLetterboxedForFixedOrientationAndAspectRatio()).isTrue(); assertThat(mFirstActivity.inSizeCompatMode()).isFalse(); } diff --git a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java index e843dd71381f..b73c66407874 100644 --- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java @@ -23,6 +23,7 @@ import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; import static android.content.res.Configuration.ORIENTATION_LANDSCAPE; +import static android.content.res.Configuration.ORIENTATION_PORTRAIT; import static android.view.Surface.ROTATION_180; import static android.view.Surface.ROTATION_270; import static android.view.Surface.ROTATION_90; @@ -43,7 +44,6 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertTrue; -import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.same; @@ -126,6 +126,7 @@ public class SizeCompatTests extends WindowTestsBase { // Put app window into freeform and then make it a compat app. final Rect bounds = new Rect(100, 100, 400, 600); mTask.setBounds(bounds); + prepareUnresizable(mActivity, -1.f /* maxAspect */, SCREEN_ORIENTATION_PORTRAIT); assertEquals(bounds, mActivity.getBounds()); @@ -194,12 +195,7 @@ public class SizeCompatTests extends WindowTestsBase { new TestDisplayContent.Builder(mAtm, 1000, 2000) .setDensityDpi(200).build(); - mActivity = new ActivityBuilder(mAtm) - .setTask(mTask) - .setResizeMode(RESIZE_MODE_UNRESIZEABLE) - .setMaxAspectRatio(1.5f) - .build(); - mActivity.mVisibleRequested = true; + prepareUnresizable(mActivity, 1.5f /* maxAspect */, SCREEN_ORIENTATION_UNSPECIFIED); final Rect originalBounds = new Rect(mActivity.getBounds()); final int originalDpi = mActivity.getConfiguration().densityDpi; @@ -566,18 +562,18 @@ public class SizeCompatTests extends WindowTestsBase { .setResizeMode(ActivityInfo.RESIZE_MODE_UNRESIZEABLE) .setScreenOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) .build(); - assertTrue(activity.shouldUseSizeCompatMode()); + assertTrue(activity.shouldCreateCompatDisplayInsets()); // The non-resizable activity should not be size compat because it is on a resizable task // in multi-window mode. mTask.setWindowingMode(WindowConfiguration.WINDOWING_MODE_FREEFORM); - assertFalse(activity.shouldUseSizeCompatMode()); + assertFalse(activity.shouldCreateCompatDisplayInsets()); // The non-resizable activity should not be size compat because the display support // changing windowing mode from fullscreen to freeform. mTask.mDisplayContent.setDisplayWindowingMode(WindowConfiguration.WINDOWING_MODE_FREEFORM); mTask.setWindowingMode(WindowConfiguration.WINDOWING_MODE_FULLSCREEN); - assertFalse(activity.shouldUseSizeCompatMode()); + assertFalse(activity.shouldCreateCompatDisplayInsets()); } @Test @@ -597,7 +593,7 @@ public class SizeCompatTests extends WindowTestsBase { SizeCompatTests.class.getName())) .setUid(android.os.Process.myUid()) .build(); - assertFalse(activity.shouldUseSizeCompatMode()); + assertFalse(activity.shouldCreateCompatDisplayInsets()); } @Test @@ -653,7 +649,7 @@ public class SizeCompatTests extends WindowTestsBase { } @Test - public void testDisplayIgnoreOrientationRequest_fixedOrientationAppLaunchedInTaskLetterbox() { + public void testDisplayIgnoreOrientationRequest_fixedOrientationAppLaunchedLetterbox() { // Set up a display in landscape and ignoring orientation request. setUpDisplaySizeWithApp(2800, 1400); mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */); @@ -662,7 +658,6 @@ public class SizeCompatTests extends WindowTestsBase { prepareUnresizable(mActivity, 0, SCREEN_ORIENTATION_PORTRAIT); final Rect displayBounds = new Rect(mActivity.mDisplayContent.getBounds()); - final Rect taskBounds = new Rect(mTask.getBounds()); final Rect activityBounds = new Rect(mActivity.getBounds()); // Display shouldn't be rotated. @@ -670,19 +665,19 @@ public class SizeCompatTests extends WindowTestsBase { mActivity.mDisplayContent.getLastOrientation()); assertTrue(displayBounds.width() > displayBounds.height()); - // App should launch in task level letterboxing. - assertTrue(mTask.isTaskLetterboxed()); + // App should launch in fixed orientation letterbox. + assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio()); assertFalse(mActivity.inSizeCompatMode()); - assertEquals(taskBounds, activityBounds); - // Task bounds should be 700x1400 with the ratio as the display. - assertEquals(displayBounds.height(), taskBounds.height()); + // Activity bounds should be 700x1400 with the ratio as the display. + assertEquals(displayBounds.height(), activityBounds.height()); assertEquals(displayBounds.height() * displayBounds.height() / displayBounds.width(), - taskBounds.width()); + activityBounds.width()); } @Test - public void testDisplayIgnoreOrientationRequest_taskLetterboxBecameSizeCompatAfterRotate() { + public void + testDisplayIgnoreOrientationRequest_orientationLetterboxBecameSizeCompatAfterRotate() { // Set up a display in landscape and ignoring orientation request. setUpDisplaySizeWithApp(2800, 1400); mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */); @@ -700,7 +695,7 @@ public class SizeCompatTests extends WindowTestsBase { assertTrue(displayBounds.width() < displayBounds.height()); // App should be in size compat. - assertFalse(mTask.isTaskLetterboxed()); + assertFalse(mActivity.isLetterboxedForFixedOrientationAndAspectRatio()); assertScaled(); assertEquals(activityBounds.width(), newActivityBounds.width()); assertEquals(activityBounds.height(), newActivityBounds.height()); @@ -719,7 +714,7 @@ public class SizeCompatTests extends WindowTestsBase { Rect activityBounds = new Rect(mActivity.getBounds()); // App should launch in fullscreen. - assertFalse(mTask.isTaskLetterboxed()); + assertFalse(mActivity.isLetterboxedForFixedOrientationAndAspectRatio()); assertFalse(mActivity.inSizeCompatMode()); assertEquals(displayBounds, activityBounds); @@ -731,7 +726,7 @@ public class SizeCompatTests extends WindowTestsBase { assertTrue(displayBounds.width() > displayBounds.height()); // App should be in size compat. - assertFalse(mTask.isTaskLetterboxed()); + assertFalse(mActivity.isLetterboxedForFixedOrientationAndAspectRatio()); assertScaled(); // App bounds should be 700x1400 with the ratio as the display. @@ -741,7 +736,7 @@ public class SizeCompatTests extends WindowTestsBase { } @Test - public void testDisplayIgnoreOrientationRequest_newLaunchedOrientationAppInTaskLetterbox() { + public void testDisplayIgnoreOrientationRequest_newLaunchedOrientationAppInLetterbox() { // Set up a display in landscape and ignoring orientation request. setUpDisplaySizeWithApp(2800, 1400); final DisplayContent display = mActivity.mDisplayContent; @@ -750,7 +745,7 @@ public class SizeCompatTests extends WindowTestsBase { // Portrait fixed app without max aspect. prepareUnresizable(mActivity, 0, SCREEN_ORIENTATION_PORTRAIT); - assertTrue(mTask.isTaskLetterboxed()); + assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio()); assertFalse(mActivity.inSizeCompatMode()); // Launch another portrait fixed app. @@ -765,19 +760,19 @@ public class SizeCompatTests extends WindowTestsBase { // Update with new activity requested orientation and recompute bounds with no previous // size compat cache. verify(mTask).onDescendantOrientationChanged(same(newActivity)); - verify(mTask).computeFullscreenBounds(any(), any()); final Rect displayBounds = new Rect(display.getBounds()); final Rect taskBounds = new Rect(mTask.getBounds()); final Rect newActivityBounds = new Rect(newActivity.getBounds()); - // Task and app bounds should be 700x1400 with the ratio as the display. - assertTrue(mTask.isTaskLetterboxed()); + // Task and display bounds should be equal while activity should be letterboxed and + // has 700x1400 bounds with the ratio as the display. + assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio()); assertFalse(newActivity.inSizeCompatMode()); - assertEquals(taskBounds, newActivityBounds); - assertEquals(displayBounds.height(), taskBounds.height()); + assertEquals(taskBounds, displayBounds); + assertEquals(displayBounds.height(), newActivityBounds.height()); assertEquals(displayBounds.height() * displayBounds.height() / displayBounds.width(), - taskBounds.width()); + newActivityBounds.width()); } @Test @@ -790,7 +785,7 @@ public class SizeCompatTests extends WindowTestsBase { // Portrait fixed app without max aspect. prepareUnresizable(mActivity, 0, SCREEN_ORIENTATION_PORTRAIT); - assertTrue(mTask.isTaskLetterboxed()); + assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio()); assertFalse(mActivity.inSizeCompatMode()); // Launch another portrait fixed app with max aspect ratio as 1.3. @@ -806,21 +801,20 @@ public class SizeCompatTests extends WindowTestsBase { // Update with new activity requested orientation and recompute bounds with no previous // size compat cache. verify(mTask).onDescendantOrientationChanged(same(newActivity)); - verify(mTask).computeFullscreenBounds(any(), any()); final Rect displayBounds = new Rect(display.getBounds()); final Rect taskBounds = new Rect(mTask.getBounds()); final Rect newActivityBounds = new Rect(newActivity.getBounds()); - // Task bounds should be (1400 / 1.3 = 1076)x1400 with the app requested ratio. - assertTrue(mTask.isTaskLetterboxed()); - assertEquals(displayBounds.height(), taskBounds.height()); - assertEquals((long) Math.rint(taskBounds.height() / newActivity.info.maxAspectRatio), - taskBounds.width()); + // Task bounds should fill parent bounds. + assertEquals(displayBounds, taskBounds); - // App bounds should be fullscreen in Task bounds. + // Activity bounds should be (1400 / 1.3 = 1076)x1400 with the app requested ratio. + assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio()); assertFalse(newActivity.inSizeCompatMode()); - assertEquals(taskBounds, newActivityBounds); + assertEquals(displayBounds.height(), newActivityBounds.height()); + assertEquals((long) Math.rint(newActivityBounds.height() / newActivity.info.maxAspectRatio), + newActivityBounds.width()); } @Test @@ -834,26 +828,23 @@ public class SizeCompatTests extends WindowTestsBase { prepareUnresizable(mActivity, 0, SCREEN_ORIENTATION_PORTRAIT); clearInvocations(mActivity); - assertTrue(mTask.isTaskLetterboxed()); + assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio()); assertFalse(mActivity.inSizeCompatMode()); - assertEquals(mTask.getLastTaskBoundsComputeActivity(), mActivity); // Rotate display to portrait. rotateDisplay(mActivity.mDisplayContent, ROTATION_90); // App should be in size compat. - assertFalse(mTask.isTaskLetterboxed()); + assertFalse(mActivity.isLetterboxedForFixedOrientationAndAspectRatio()); assertScaled(); - assertEquals(mTask.getLastTaskBoundsComputeActivity(), mActivity); final Rect activityBounds = new Rect(mActivity.getBounds()); mTask.resumeTopActivityUncheckedLocked(null /* prev */, null /* options */); // App still in size compat, and the bounds don't change. verify(mActivity, never()).clearSizeCompatMode(); - assertFalse(mTask.isTaskLetterboxed()); + assertFalse(mActivity.isLetterboxedForFixedOrientationAndAspectRatio()); assertScaled(); - assertEquals(mTask.getLastTaskBoundsComputeActivity(), mActivity); assertEquals(activityBounds, mActivity.getBounds()); } @@ -867,22 +858,22 @@ public class SizeCompatTests extends WindowTestsBase { // Portrait fixed app. prepareUnresizable(mActivity, 0, SCREEN_ORIENTATION_PORTRAIT); - // In Task letterbox - assertTrue(mTask.isTaskLetterboxed()); + // In fixed orientation letterbox + assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio()); assertFalse(mActivity.inSizeCompatMode()); // Rotate display to portrait. rotateDisplay(display, ROTATION_90); // App should be in size compat. - assertFalse(mTask.isTaskLetterboxed()); + assertFalse(mActivity.isLetterboxedForFixedOrientationAndAspectRatio()); assertScaled(); // Rotate display to landscape. rotateDisplay(display, ROTATION_180); // In Task letterbox - assertTrue(mTask.isTaskLetterboxed()); + assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio()); assertFalse(mActivity.inSizeCompatMode()); } @@ -898,22 +889,22 @@ public class SizeCompatTests extends WindowTestsBase { // Landscape fixed app. prepareUnresizable(mActivity, 0, SCREEN_ORIENTATION_LANDSCAPE); - // In Task letterbox - assertTrue(mTask.isTaskLetterboxed()); + // In fixed orientation letterbox + assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio()); assertFalse(mActivity.inSizeCompatMode()); // Rotate display to portrait. rotateDisplay(display, ROTATION_90); // App should be in size compat. - assertFalse(mTask.isTaskLetterboxed()); + assertFalse(mActivity.isLetterboxedForFixedOrientationAndAspectRatio()); assertScaled(); // Rotate display to landscape. rotateDisplay(display, ROTATION_180); - // In Task letterbox - assertTrue(mTask.isTaskLetterboxed()); + // In fixed orientation letterbox + assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio()); assertFalse(mActivity.inSizeCompatMode()); } @@ -972,21 +963,21 @@ public class SizeCompatTests extends WindowTestsBase { addWindowToActivity(mActivity); mActivity.mRootWindowContainer.performSurfacePlacement(); - // Split screen is also in portrait [1000,1400], so Task should be in letterbox, and - // activity fills task. - assertEquals(ORIENTATION_LANDSCAPE, mTask.getConfiguration().orientation); + // Split screen is also in portrait [1000,1400], so activty should be in fixed orientation + // letterbox. + assertEquals(ORIENTATION_PORTRAIT, mTask.getConfiguration().orientation); assertEquals(ORIENTATION_LANDSCAPE, mActivity.getConfiguration().orientation); assertFitted(); - assertTrue(mTask.isTaskLetterboxed()); + assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio()); - // Letterbox should fill the gap between the split screen and the letterboxed task. + // Letterbox should fill the gap between the split screen and the letterboxed activity. final Rect primarySplitBounds = new Rect(organizer.mPrimary.getBounds()); - final Rect letterboxedTaskBounds = new Rect(mTask.getBounds()); - assertTrue(primarySplitBounds.contains(letterboxedTaskBounds)); - assertEquals(new Rect(letterboxedTaskBounds.left - primarySplitBounds.left, - letterboxedTaskBounds.top - primarySplitBounds.top, - primarySplitBounds.right - letterboxedTaskBounds.right, - primarySplitBounds.bottom - letterboxedTaskBounds.bottom), + final Rect letterboxedBounds = new Rect(mActivity.getBounds()); + assertTrue(primarySplitBounds.contains(letterboxedBounds)); + assertEquals(new Rect(letterboxedBounds.left - primarySplitBounds.left, + letterboxedBounds.top - primarySplitBounds.top, + primarySplitBounds.right - letterboxedBounds.right, + primarySplitBounds.bottom - letterboxedBounds.bottom), mActivity.getLetterboxInsets()); } diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java index 49847992125e..f8346efba06d 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java @@ -683,12 +683,12 @@ public class TaskLaunchParamsModifierTests extends WindowTestsBase { } @Test - public void testLaunchesAppInWindowOnFreeformDisplay() { + public void testLaunchesPortraitSizeCompatOnFreeformLandscapeDisplayWithFreeformSizeCompat() { mAtm.mSizeCompatFreeform = true; final TestDisplayContent freeformDisplay = createNewDisplayContent( WINDOWING_MODE_FREEFORM); - Rect expectedLaunchBounds = new Rect(0, 0, 200, 100); + Rect expectedLaunchBounds = new Rect(0, 0, 100, 200); final ActivityOptions options = ActivityOptions.makeBasic(); options.setLaunchWindowingMode(WINDOWING_MODE_FREEFORM); @@ -699,6 +699,7 @@ public class TaskLaunchParamsModifierTests extends WindowTestsBase { mCurrent.mBounds.set(expectedLaunchBounds); mActivity.info.resizeMode = RESIZE_MODE_UNRESIZEABLE; + mActivity.info.screenOrientation = SCREEN_ORIENTATION_PORTRAIT; assertEquals(RESULT_CONTINUE, new CalculateRequestBuilder().setOptions(options).calculate()); @@ -710,6 +711,38 @@ public class TaskLaunchParamsModifierTests extends WindowTestsBase { } @Test + public void testLaunchesLandscapeSizeCompatOnFreeformLandscapeDisplayWithFreeformSizeCompat() { + mAtm.mSizeCompatFreeform = true; + final TestDisplayContent freeformDisplay = createNewDisplayContent( + WINDOWING_MODE_FREEFORM); + final ActivityOptions options = ActivityOptions.makeBasic(); + mCurrent.mPreferredTaskDisplayArea = freeformDisplay.getDefaultTaskDisplayArea(); + mActivity.info.resizeMode = RESIZE_MODE_UNRESIZEABLE; + mActivity.info.screenOrientation = SCREEN_ORIENTATION_LANDSCAPE; + assertEquals(RESULT_CONTINUE, + new CalculateRequestBuilder().setOptions(options).calculate()); + + assertEquivalentWindowingMode(WINDOWING_MODE_FULLSCREEN, mResult.mWindowingMode, + WINDOWING_MODE_FREEFORM); + } + + @Test + public void testLaunchesPortraitUnresizableOnFreeformDisplayWithFreeformSizeCompat() { + mAtm.mSizeCompatFreeform = true; + final TestDisplayContent freeformDisplay = createNewDisplayContent( + WINDOWING_MODE_FREEFORM); + final ActivityOptions options = ActivityOptions.makeBasic(); + mCurrent.mPreferredTaskDisplayArea = freeformDisplay.getDefaultTaskDisplayArea(); + mActivity.info.resizeMode = RESIZE_MODE_UNRESIZEABLE; + mActivity.info.screenOrientation = SCREEN_ORIENTATION_PORTRAIT; + assertEquals(RESULT_CONTINUE, + new CalculateRequestBuilder().setOptions(options).calculate()); + + assertEquivalentWindowingMode(WINDOWING_MODE_FREEFORM, mResult.mWindowingMode, + WINDOWING_MODE_FREEFORM); + } + + @Test public void testSkipsForceMaximizingAppsOnNonFreeformDisplay() { final ActivityOptions options = ActivityOptions.makeBasic(); options.setLaunchWindowingMode(WINDOWING_MODE_FREEFORM); diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java index 0eb8c8d2e58a..d853b930af11 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java @@ -266,8 +266,9 @@ public class TaskRecordTests extends WindowTestsBase { root.setRequestedOrientation(SCREEN_ORIENTATION_PORTRAIT); assertEquals(root, task.getRootActivity()); assertEquals(SCREEN_ORIENTATION_PORTRAIT, task.getRootActivity().getOrientation()); - assertThat(task.getBounds().width()).isLessThan(task.getBounds().height()); - assertEquals(fullScreenBounds.height(), task.getBounds().height()); + // Portrait orientation is enforced on activity level. Task should fill fullscreen bounds. + assertThat(task.getBounds().height()).isLessThan(task.getBounds().width()); + assertEquals(fullScreenBounds, task.getBounds()); // Top activity gets used final ActivityRecord top = new ActivityBuilder(mAtm).setTask(task).setParentTask(stack) @@ -286,8 +287,11 @@ public class TaskRecordTests extends WindowTestsBase { // Fix the display orientation to portrait which is 90 degrees for the test display. dr.setUserRotation(USER_ROTATION_FREE, ROTATION_90); - assertThat(task.getBounds().width()).isGreaterThan(task.getBounds().height()); - assertEquals(fullScreenBoundsPort.width(), task.getBounds().width()); + // Fixed orientation request should be resolved on activity level. Task fills display + // bounds. + assertThat(task.getBounds().height()).isGreaterThan(task.getBounds().width()); + assertThat(top.getBounds().width()).isGreaterThan(top.getBounds().height()); + assertEquals(fullScreenBoundsPort, task.getBounds()); // in FREEFORM, no constraint final Rect freeformBounds = new Rect(display.getBounds()); @@ -297,10 +301,11 @@ public class TaskRecordTests extends WindowTestsBase { task.setBounds(freeformBounds); assertEquals(freeformBounds, task.getBounds()); - // FULLSCREEN letterboxes bounds + // FULLSCREEN letterboxes bounds on activity level, no constraint on task level. stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN); - assertThat(task.getBounds().width()).isGreaterThan(task.getBounds().height()); - assertEquals(fullScreenBoundsPort.width(), task.getBounds().width()); + assertThat(task.getBounds().height()).isGreaterThan(task.getBounds().width()); + assertThat(top.getBounds().width()).isGreaterThan(top.getBounds().height()); + assertEquals(fullScreenBoundsPort, task.getBounds()); // FREEFORM restores bounds as before stack.setWindowingMode(WINDOWING_MODE_FREEFORM); @@ -327,9 +332,10 @@ public class TaskRecordTests extends WindowTestsBase { assertEquals(fullScreenBounds, task.getBounds()); - // Setting app to fixed portrait fits within parent + // Setting app to fixed portrait fits within parent on activity level. Task fills parent. root.setRequestedOrientation(SCREEN_ORIENTATION_PORTRAIT); - assertThat(task.getBounds().width()).isLessThan(task.getBounds().height()); + assertThat(root.getBounds().width()).isLessThan(root.getBounds().height()); + assertEquals(task.getBounds(), fullScreenBounds); assertEquals(SCREEN_ORIENTATION_PORTRAIT, task.getOrientation()); } @@ -424,7 +430,8 @@ public class TaskRecordTests extends WindowTestsBase { // to the input bounds. final ActivityRecord activity = new ActivityBuilder(mAtm).setTask(task).build(); final ActivityRecord.CompatDisplayInsets compatIntsets = - new ActivityRecord.CompatDisplayInsets(display, activity); + new ActivityRecord.CompatDisplayInsets( + display, activity, /* fixedOrientationBounds= */ null); task.computeConfigResourceOverrides(inOutConfig, parentConfig, compatIntsets); assertEquals(largerLandscapeBounds, inOutConfig.windowConfiguration.getAppBounds()); diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskTests.java index 1c0f640e1a9c..c3eb5c49cea0 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TaskTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/TaskTests.java @@ -257,24 +257,4 @@ public class TaskTests extends WindowTestsBase { task.resolveOverrideConfiguration(parentConfig); assertThat(resolvedOverride.getWindowingMode()).isEqualTo(WINDOWING_MODE_UNDEFINED); } - - @Test - public void testCleanUpActivityReferences_clearLastTaskBoundsComputeActivity() { - final Task rootTask = createTaskStackOnDisplay(mDisplayContent); - final Task leafTask = createTaskInStack(rootTask, 0 /* userId */); - final ActivityRecord activity2 = createActivityRecord(mDisplayContent, leafTask); - final ActivityRecord activity1 = createActivityRecord(mDisplayContent, leafTask); - activity1.finishing = false; - leafTask.resolveOverrideConfiguration(rootTask.getConfiguration()); - - assertEquals(activity1, leafTask.getLastTaskBoundsComputeActivity()); - - leafTask.cleanUpActivityReferences(activity2); - - assertNotNull(leafTask.getLastTaskBoundsComputeActivity()); - - leafTask.cleanUpActivityReferences(activity1); - - assertNull(leafTask.getLastTaskBoundsComputeActivity()); - } } diff --git a/telecomm/java/android/telecom/InCallService.java b/telecomm/java/android/telecom/InCallService.java index 5cf8de8f9078..f20ee7e56d05 100644 --- a/telecomm/java/android/telecom/InCallService.java +++ b/telecomm/java/android/telecom/InCallService.java @@ -138,6 +138,24 @@ import java.util.List; * } * } * } + * + * </pre> + * <p id="companionInCallService"> + * <h3>Access to InCallService for Wearable Devices</h3> + * <ol> + * If your app is a third-party companion app and wants to access InCallService APIs, what your + * app could do are: + * <p> + * <ol> + * <li> Declare MANAGE_ONGOING_CALLS permission in your manifest + * <li> Associate with a physical wearable device via the + * {@link android.companion.CompanionDeviceManager} API as a companion app. See: + * https://developer.android.com/guide/topics/connectivity/companion-device-pairing + * <li> Implement this InCallService with BIND_INCALL_SERVICE permission + * </ol> + * </ol> + * <p> + * * </pre> * <p id="incomingCallNotification"> * <h3>Showing the Incoming Call Notification</h3> diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java index 472d63946ebc..17749e8b0a8f 100644 --- a/telecomm/java/android/telecom/TelecomManager.java +++ b/telecomm/java/android/telecom/TelecomManager.java @@ -1702,22 +1702,22 @@ public class TelecomManager { } /** - * Returns whether the caller has {@link InCallService} access for companion apps. - * - * A companion app is an app associated with a physical wearable device via the - * {@link android.companion.CompanionDeviceManager} API. + * Returns whether the caller has {@link android.Manifest.permission#MANAGE_ONGOING_CALLS} + * permission. The permission can be obtained by associating with a physical wearable device + * via the {@link android.companion.CompanionDeviceManager} API as a companion app. If the + * caller app has the permission, it has {@link InCallService} access to manage ongoing calls. * * @return {@code true} if the caller has {@link InCallService} access for * companion app; {@code false} otherwise. */ - public boolean hasCompanionInCallServiceAccess() { + public boolean hasManageOngoingCallsPermission() { ITelecomService service = getTelecomService(); if (service != null) { try { - return service.hasCompanionInCallServiceAccess( + return service.hasManageOngoingCallsPermission( mContext.getOpPackageName()); } catch (RemoteException e) { - Log.e(TAG, "RemoteException calling hasCompanionInCallServiceAccess().", e); + Log.e(TAG, "RemoteException calling hasManageOngoingCallsPermission().", e); if (!isSystemProcess()) { e.rethrowAsRuntimeException(); } diff --git a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl index 88ef1b09f6b1..eb106b50f69d 100644 --- a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl +++ b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl @@ -179,9 +179,9 @@ interface ITelecomService { boolean isInCall(String callingPackage, String callingFeatureId); /** - * @see TelecomServiceImpl#hasCompanionInCallServiceAccess + * @see TelecomServiceImpl#hasManageOngoingCallsPermission */ - boolean hasCompanionInCallServiceAccess(String callingPackage); + boolean hasManageOngoingCallsPermission(String callingPackage); /** * @see TelecomServiceImpl#isInManagedCall diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java index 4b57fcbf0ad3..b52f49190679 100644 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -33,7 +33,11 @@ import android.os.RemoteException; import android.service.carrier.CarrierService; import android.telecom.TelecomManager; import android.telephony.ims.ImsReasonInfo; +import android.telephony.ims.ImsRegistrationAttributes; import android.telephony.ims.ImsSsData; +import android.telephony.ims.SipDelegateManager; +import android.telephony.ims.feature.MmTelFeature; +import android.telephony.ims.feature.RcsFeature; import com.android.internal.telephony.ICarrierConfigLoader; import com.android.telephony.Rlog; @@ -3672,14 +3676,13 @@ public class CarrierConfigManager { /** Prefix of all ImsServiceEntitlement.KEY_* constants. */ public static final String KEY_PREFIX = "imsserviceentitlement."; - /** The address of the entitlement configuration server. */ - public static final String KEY_AES_URL_STRING = KEY_PREFIX + "aes_url_string"; - + public static final String KEY_ENTITLEMENT_SERVER_URL_STRING = + KEY_PREFIX + "entitlement_server_url_string"; private static PersistableBundle getDefaults() { PersistableBundle defaults = new PersistableBundle(); - defaults.putString(KEY_AES_URL_STRING, ""); + defaults.putString(KEY_ENTITLEMENT_SERVER_URL_STRING, ""); return defaults; } } @@ -4007,6 +4010,43 @@ public class CarrierConfigManager { KEY_PREFIX + "enable_presence_publish_bool"; /** + * Each string in this array contains a mapping between the service-id and version portion + * of the service-description element and the associated IMS feature tag(s) that are + * associated with each element (see RCC.07 Table 7). + * <p> + * Each string contains 3 parts, which define the mapping between service-description and + * feature tag(s) that must be present in the IMS REGISTER for the RCS service to be + * published as part of the RCS PUBLISH procedure: + * [service-id]|[version]|[desc]|[feature_tag];[feature_tag];... + * <ul> + * <li>[service-id]: the service-id element associated with the RCS capability.</li> + * <li>[version]: The version element associated with that service-id</li> + * <li>[desc]: The optional desecription element associated with that service-id</li> + * <li>[feature_tag];[feature_tag]: The list of all feature tags associated with this + * capability that MUST ALL be present in the IMS registration for this this + * capability to be published to the network.</li> + * </ul> + * <p> + * Features managed by the framework will be considered capable when the ImsService reports + * that those services are capable via the + * {@link MmTelFeature#notifyCapabilitiesStatusChanged(MmTelFeature.MmTelCapabilities)} or + * {@link RcsFeature#notifyCapabilitiesStatusChanged(RcsFeature.RcsImsCapabilities)} APIs. + * For RCS services not managed by the framework, the capability of these services are + * determined by looking at the feature tags associated with the IMS registration using the + * {@link ImsRegistrationAttributes} API and mapping them to the service-description map. + * <p> + * The framework contains a default value of this key, which is based off of RCC.07 + * specification. Capabilities based of carrier extensions may be added to this list on a + * carrier-by-carrier basis as required in order to support additional services in the + * PUBLISH. If this list contains a service-id and version that overlaps with the default, + * it will override the framework default. + * @hide + */ + @SystemApi + public static final String KEY_PUBLISH_SERVICE_DESC_FEATURE_TAG_MAP_OVERRIDE_STRING_ARRAY = + KEY_PREFIX + "publish_service_desc_feature_tag_map_override_string_array"; + + /** * Flag indicating whether or not this carrier supports the exchange of phone numbers with * the carrier's RCS presence server in order to retrieve the RCS capabilities of requested * contacts used in the RCS User Capability Exchange (UCE) procedure. See RCC.71, section 3 @@ -4065,6 +4105,8 @@ public class CarrierConfigManager { defaults.putInt(KEY_WIFI_OFF_DEFERRING_TIME_MILLIS_INT, 4000); defaults.putBoolean(KEY_IMS_SINGLE_REGISTRATION_REQUIRED_BOOL, false); defaults.putBoolean(KEY_ENABLE_PRESENCE_PUBLISH_BOOL, false); + defaults.putStringArray(KEY_PUBLISH_SERVICE_DESC_FEATURE_TAG_MAP_OVERRIDE_STRING_ARRAY, + new String[] {}); defaults.putBoolean(KEY_ENABLE_PRESENCE_CAPABILITY_EXCHANGE_BOOL, false); defaults.putBoolean(KEY_RCS_BULK_CAPABILITY_EXCHANGE_BOOL, false); defaults.putBoolean(KEY_ENABLE_PRESENCE_GROUP_SUBSCRIBE_BOOL, true); diff --git a/telephony/java/android/telephony/SignalStrengthUpdateRequest.java b/telephony/java/android/telephony/SignalStrengthUpdateRequest.java index af67ed279fab..fe7e5976b132 100644 --- a/telephony/java/android/telephony/SignalStrengthUpdateRequest.java +++ b/telephony/java/android/telephony/SignalStrengthUpdateRequest.java @@ -187,7 +187,7 @@ public final class SignalStrengthUpdateRequest implements Parcelable { return mIsSystemThresholdReportingRequestedWhileIdle; } - /* + /** * @return the live token of the request * * @hide diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index f64f4283b66a..61e809b55031 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -29,6 +29,7 @@ import android.annotation.IntDef; import android.annotation.LongDef; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.RequiresFeature; import android.annotation.RequiresPermission; import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; @@ -8579,6 +8580,9 @@ public class TelephonyManager { */ @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) + @RequiresFeature( + enforcement = "android.telephony.TelephonyManager#isRadioInterfaceCapabilitySupported", + value = TelephonyManager.CAPABILITY_ALLOWED_NETWORK_TYPES_USED) @SystemApi public boolean setAllowedNetworkTypes(@NetworkTypeBitMask long allowedNetworkTypes) { try { @@ -8670,6 +8674,9 @@ public class TelephonyManager { */ @SystemApi @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) + @RequiresFeature( + enforcement = "android.telephony.TelephonyManager#isRadioInterfaceCapabilitySupported", + value = TelephonyManager.CAPABILITY_ALLOWED_NETWORK_TYPES_USED) public void setAllowedNetworkTypesForReason(@AllowedNetworkTypesReason int reason, @NetworkTypeBitMask long allowedNetworkTypes) { if (!isValidAllowedNetworkTypesReason(reason)) { @@ -8708,6 +8715,9 @@ public class TelephonyManager { */ @SystemApi @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) + @RequiresFeature( + enforcement = "android.telephony.TelephonyManager#isRadioInterfaceCapabilitySupported", + value = TelephonyManager.CAPABILITY_ALLOWED_NETWORK_TYPES_USED) public @NetworkTypeBitMask long getAllowedNetworkTypesForReason( @AllowedNetworkTypesReason int reason) { if (!isValidAllowedNetworkTypesReason(reason)) { diff --git a/telephony/java/android/telephony/ims/RcsContactPresenceTuple.java b/telephony/java/android/telephony/ims/RcsContactPresenceTuple.java index 5eb75e762fc9..bdf628b4d339 100644 --- a/telephony/java/android/telephony/ims/RcsContactPresenceTuple.java +++ b/telephony/java/android/telephony/ims/RcsContactPresenceTuple.java @@ -21,6 +21,7 @@ import android.annotation.Nullable; import android.annotation.StringDef; import android.annotation.SystemApi; import android.net.Uri; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -39,6 +40,15 @@ import java.util.List; public final class RcsContactPresenceTuple implements Parcelable { /** + * The service ID used to indicate that service discovery via presence is available. + * <p> + * See RCC.07 v5.0 specification for more information. + * @hide + */ + public static final String SERVICE_ID_PRESENCE = + "org.3gpp.urn:urn-7:3gpp-application.ims.iari.rcse.dp"; + + /** * The service ID used to indicate that MMTEL service is available. * <p> * See the GSMA RCC.07 specification for more information. @@ -329,6 +339,13 @@ public final class RcsContactPresenceTuple implements Parcelable { public @NonNull @DuplexMode List<String> getUnsupportedDuplexModes() { return Collections.unmodifiableList(mUnsupportedDuplexModeList); } + + @Override + public String toString() { + return "servCaps{" + "a=" + mIsAudioCapable + ", v=" + mIsVideoCapable + + ", supported=" + mSupportedDuplexModeList + ", unsupported=" + + mUnsupportedDuplexModeList + '}'; + } } /** @@ -487,4 +504,36 @@ public final class RcsContactPresenceTuple implements Parcelable { public @Nullable ServiceCapabilities getServiceCapabilities() { return mServiceCapabilities; } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder("{"); + if (Build.IS_ENG) { + builder.append("u="); + builder.append(mContactUri); + } else { + builder.append("u="); + builder.append(mContactUri != null ? "XXX" : "null"); + } + builder.append(", id="); + builder.append(mServiceId); + builder.append(", v="); + builder.append(mServiceVersion); + builder.append(", s="); + builder.append(mStatus); + if (mTimestamp != null) { + builder.append(", timestamp="); + builder.append(mTimestamp); + } + if (mServiceDescription != null) { + builder.append(", servDesc="); + builder.append(mServiceDescription); + } + if (mServiceCapabilities != null) { + builder.append(", servCaps="); + builder.append(mServiceCapabilities); + } + builder.append("}"); + return builder.toString(); + } } diff --git a/telephony/java/android/telephony/ims/RcsContactUceCapability.java b/telephony/java/android/telephony/ims/RcsContactUceCapability.java index fe855023f5d0..9299fed1e27d 100644 --- a/telephony/java/android/telephony/ims/RcsContactUceCapability.java +++ b/telephony/java/android/telephony/ims/RcsContactUceCapability.java @@ -21,6 +21,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; import android.net.Uri; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -344,4 +345,39 @@ public final class RcsContactUceCapability implements Parcelable { public @NonNull Uri getContactUri() { return mContactUri; } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder("RcsContactUceCapability"); + if (mCapabilityMechanism == CAPABILITY_MECHANISM_PRESENCE) { + builder.append("(presence) {"); + } else if (mCapabilityMechanism == CAPABILITY_MECHANISM_OPTIONS) { + builder.append("(options) {"); + } else { + builder.append("(?) {"); + } + if (Build.IS_ENG) { + builder.append("uri="); + builder.append(mContactUri); + } else { + builder.append("uri (isNull)="); + builder.append(mContactUri != null ? "XXX" : "null"); + } + builder.append(", sourceType="); + builder.append(mSourceType); + builder.append(", requestResult="); + builder.append(mRequestResult); + + if (mCapabilityMechanism == CAPABILITY_MECHANISM_PRESENCE) { + builder.append(", presenceTuples={"); + builder.append(mPresenceTuples); + builder.append("}"); + } else if (mCapabilityMechanism == CAPABILITY_MECHANISM_OPTIONS) { + builder.append(", featureTags={"); + builder.append(mFeatureTags); + builder.append("}"); + } + + return builder.toString(); + } } diff --git a/telephony/java/android/telephony/ims/stub/CapabilityExchangeEventListener.java b/telephony/java/android/telephony/ims/stub/CapabilityExchangeEventListener.java index 4967e5da7c9a..62955487897f 100644 --- a/telephony/java/android/telephony/ims/stub/CapabilityExchangeEventListener.java +++ b/telephony/java/android/telephony/ims/stub/CapabilityExchangeEventListener.java @@ -25,7 +25,6 @@ import android.telephony.ims.RcsContactUceCapability; import android.telephony.ims.RcsUceAdapter; import android.telephony.ims.feature.ImsFeature; import android.telephony.ims.feature.RcsFeature; -import android.util.Log; import java.util.List; @@ -44,30 +43,12 @@ public interface CapabilityExchangeEventListener { * Respond to a remote capability request from the contact specified with the * capabilities of this device. * @param ownCapabilities The capabilities of this device. - * @hide - */ - default void onRespondToCapabilityRequest( - @NonNull RcsContactUceCapability ownCapabilities) {} - - /** - * Respond to a remote capability request from the contact specified with the - * capabilities of this device. - * @param ownCapabilities The capabilities of this device. * @param isBlocked Whether or not the user has blocked the number requesting the * capabilities of this device. If true, the device should respond to the OPTIONS * request with a 200 OK response and no capabilities. */ - default void onRespondToCapabilityRequest(@NonNull RcsContactUceCapability ownCapabilities, - boolean isBlocked) { - Log.w("CapabilityExchangeEventListener", "implement " - + "onRespondToCapabilityRequest(RcsContactUceCapability, boolean) instead!"); - // Fall back to old implementation - if (isBlocked) { - onRespondToCapabilityRequestWithError(200, "OK"); - } else { - onRespondToCapabilityRequest(ownCapabilities); - } - } + void onRespondToCapabilityRequest(@NonNull RcsContactUceCapability ownCapabilities, + boolean isBlocked); /** * Respond to a remote capability request from the contact specified with the diff --git a/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java b/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java index cc050becfb25..34984e05e181 100644 --- a/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java +++ b/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java @@ -37,6 +37,7 @@ import com.android.internal.telephony.util.RemoteCallbackListExt; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.ref.WeakReference; +import java.util.Arrays; import java.util.HashMap; /** @@ -368,7 +369,13 @@ public class ImsConfigImplBase { } private void onNotifyRcsAutoConfigurationReceived(byte[] config, boolean isCompressed) { - mRcsConfigData = isCompressed ? RcsConfig.decompressGzip(config) : config; + // cache uncompressed config + config = isCompressed ? RcsConfig.decompressGzip(config) : config; + if (Arrays.equals(mRcsConfigData, config)) { + return; + } + mRcsConfigData = config; + // can be null in testing if (mRcsCallbacks != null) { mRcsCallbacks.broadcastAction(c -> { diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl index 0048d53f9172..e87f3d9aec76 100644 --- a/telephony/java/com/android/internal/telephony/ITelephony.aidl +++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl @@ -2325,6 +2325,16 @@ interface ITelephony { void triggerRcsReconfiguration(int subId); /** + * Enables or disables the test mode for RCS VoLTE single registration. + */ + void setRcsSingleRegistrationTestModeEnabled(boolean enabled); + + /** + * Gets the test mode for RCS VoLTE single registration. + */ + boolean getRcsSingleRegistrationTestModeEnabled(); + + /** * Overrides the config of RCS VoLTE single registration enabled for the device. */ void setDeviceSingleRegistrationEnabledOverride(String enabled); diff --git a/tests/net/common/java/android/net/CaptivePortalDataTest.kt b/tests/net/common/java/android/net/CaptivePortalDataTest.kt index ad5bbf220d57..18a93319b271 100644 --- a/tests/net/common/java/android/net/CaptivePortalDataTest.kt +++ b/tests/net/common/java/android/net/CaptivePortalDataTest.kt @@ -55,14 +55,14 @@ class CaptivePortalDataTest { .build() private val dataFromPasspoint = CaptivePortalData.Builder() - .setUserPortalUrl(Uri.parse("https://tc.example.com/passpoint"), - CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT) - .setVenueInfoUrl(Uri.parse("https://venue.example.com/passpoint"), - CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT) .setCaptive(true) .apply { if (SdkLevel.isAtLeastS()) { setVenueFriendlyName("venue friendly name") + setUserPortalUrl(Uri.parse("https://tc.example.com/passpoint"), + CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT) + setVenueInfoUrl(Uri.parse("https://venue.example.com/passpoint"), + CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT) } } .build() @@ -96,28 +96,28 @@ class CaptivePortalDataTest { if (SdkLevel.isAtLeastS()) { assertNotEqualsAfterChange { it.setVenueFriendlyName("another friendly name") } assertNotEqualsAfterChange { it.setVenueFriendlyName(null) } - } - assertEquals(dataFromPasspoint, CaptivePortalData.Builder(dataFromPasspoint).build()) - assertNotEqualsAfterChange { it.setUserPortalUrl( - Uri.parse("https://tc.example.com/passpoint")) } - assertNotEqualsAfterChange { it.setUserPortalUrl( - Uri.parse("https://tc.example.com/passpoint"), - CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_OTHER) } - assertNotEqualsAfterChange { it.setUserPortalUrl( - Uri.parse("https://tc.example.com/other"), - CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT) } - assertNotEqualsAfterChange { it.setUserPortalUrl( - Uri.parse("https://tc.example.com/passpoint"), - CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_OTHER) } - assertNotEqualsAfterChange { it.setVenueInfoUrl( - Uri.parse("https://venue.example.com/passpoint")) } - assertNotEqualsAfterChange { it.setVenueInfoUrl( - Uri.parse("https://venue.example.com/other"), - CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT) } - assertNotEqualsAfterChange { it.setVenueInfoUrl( - Uri.parse("https://venue.example.com/passpoint"), - CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_OTHER) } + assertEquals(dataFromPasspoint, CaptivePortalData.Builder(dataFromPasspoint).build()) + assertNotEqualsAfterChange { it.setUserPortalUrl( + Uri.parse("https://tc.example.com/passpoint")) } + assertNotEqualsAfterChange { it.setUserPortalUrl( + Uri.parse("https://tc.example.com/passpoint"), + CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_OTHER) } + assertNotEqualsAfterChange { it.setUserPortalUrl( + Uri.parse("https://tc.example.com/other"), + CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT) } + assertNotEqualsAfterChange { it.setUserPortalUrl( + Uri.parse("https://tc.example.com/passpoint"), + CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_OTHER) } + assertNotEqualsAfterChange { it.setVenueInfoUrl( + Uri.parse("https://venue.example.com/passpoint")) } + assertNotEqualsAfterChange { it.setVenueInfoUrl( + Uri.parse("https://venue.example.com/other"), + CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT) } + assertNotEqualsAfterChange { it.setVenueInfoUrl( + Uri.parse("https://venue.example.com/passpoint"), + CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_OTHER) } + } } @Test diff --git a/tests/net/common/java/android/net/NetworkStateSnapshotTest.kt b/tests/net/common/java/android/net/NetworkStateSnapshotTest.kt new file mode 100644 index 000000000000..56b56efd501b --- /dev/null +++ b/tests/net/common/java/android/net/NetworkStateSnapshotTest.kt @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net + +import android.net.ConnectivityManager.TYPE_NONE +import android.net.ConnectivityManager.TYPE_WIFI +import android.net.InetAddresses.parseNumericAddress +import android.net.NetworkCapabilities.TRANSPORT_WIFI +import android.os.Build +import androidx.test.filters.SmallTest +import com.android.testutils.DevSdkIgnoreRule +import com.android.testutils.DevSdkIgnoreRunner +import com.android.testutils.assertParcelSane +import org.junit.Test +import org.junit.runner.RunWith +import java.net.Inet4Address +import java.net.Inet6Address + +private const val TEST_IMSI = "imsi1" +private const val TEST_SSID = "SSID1" +private const val TEST_NETID = 123 + +private val TEST_IPV4_GATEWAY = parseNumericAddress("192.168.222.3") as Inet4Address +private val TEST_IPV6_GATEWAY = parseNumericAddress("2001:db8::1") as Inet6Address +private val TEST_IPV4_LINKADDR = LinkAddress("192.168.222.123/24") +private val TEST_IPV6_LINKADDR = LinkAddress("2001:db8::123/64") +private val TEST_IFACE = "fake0" +private val TEST_LINK_PROPERTIES = LinkProperties().apply { + interfaceName = TEST_IFACE + addLinkAddress(TEST_IPV4_LINKADDR) + addLinkAddress(TEST_IPV6_LINKADDR) + + // Add default routes + addRoute(RouteInfo(IpPrefix(parseNumericAddress("0.0.0.0"), 0), TEST_IPV4_GATEWAY)) + addRoute(RouteInfo(IpPrefix(parseNumericAddress("::"), 0), TEST_IPV6_GATEWAY)) +} + +private val TEST_CAPABILITIES = NetworkCapabilities().apply { + addTransportType(TRANSPORT_WIFI) + setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED, false) + setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING, true) + setSSID(TEST_SSID) +} + +@SmallTest +@RunWith(DevSdkIgnoreRunner::class) +@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.R) +class NetworkStateSnapshotTest { + + @Test + fun testParcelUnparcel() { + val emptySnapshot = NetworkStateSnapshot(LinkProperties(), NetworkCapabilities(), + Network(TEST_NETID), null, TYPE_NONE) + val snapshot = NetworkStateSnapshot( + TEST_LINK_PROPERTIES, TEST_CAPABILITIES, Network(TEST_NETID), TEST_IMSI, TYPE_WIFI) + assertParcelSane(emptySnapshot, 5) + assertParcelSane(snapshot, 5) + } +} diff --git a/tests/net/integration/Android.bp b/tests/net/integration/Android.bp index 4d1e3371e0a7..56f9df78c83e 100644 --- a/tests/net/integration/Android.bp +++ b/tests/net/integration/Android.bp @@ -35,7 +35,7 @@ android_test { "android.test.mock", ], static_libs: [ - "TestNetworkStackLib", + "NetworkStackApiStableLib", "androidx.test.ext.junit", "frameworks-net-integration-testutils", "kotlin-reflect", diff --git a/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java b/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java index dc9e587332cb..e1da3d0ae2b3 100644 --- a/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java +++ b/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java @@ -17,6 +17,7 @@ package com.android.server; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED; +import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN; import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; import static android.net.NetworkCapabilities.TRANSPORT_ETHERNET; @@ -84,6 +85,7 @@ public class NetworkAgentWrapper implements TestableNetworkCallback.HasNetwork { final String typeName = ConnectivityManager.getNetworkTypeName(type); mNetworkCapabilities = (ncTemplate != null) ? ncTemplate : new NetworkCapabilities(); mNetworkCapabilities.addCapability(NET_CAPABILITY_NOT_SUSPENDED); + mNetworkCapabilities.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED); mNetworkCapabilities.addTransportType(transport); switch (transport) { case TRANSPORT_ETHERNET: diff --git a/tests/net/java/android/net/NetworkIdentityTest.kt b/tests/net/java/android/net/NetworkIdentityTest.kt new file mode 100644 index 000000000000..eb2b85c14578 --- /dev/null +++ b/tests/net/java/android/net/NetworkIdentityTest.kt @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net + +import android.net.NetworkIdentity.OEM_NONE +import android.net.NetworkIdentity.OEM_PAID +import android.net.NetworkIdentity.OEM_PRIVATE +import android.net.NetworkIdentity.getOemBitfield +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.JUnit4 +import kotlin.test.assertEquals + +@RunWith(JUnit4::class) +class NetworkIdentityTest { + @Test + fun testGetOemBitfield() { + val oemNone = NetworkCapabilities().apply { + setCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PAID, false) + setCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE, false) + } + val oemPaid = NetworkCapabilities().apply { + setCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PAID, true) + setCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE, false) + } + val oemPrivate = NetworkCapabilities().apply { + setCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PAID, false) + setCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE, true) + } + val oemAll = NetworkCapabilities().apply { + setCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PAID, true) + setCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE, true) + } + + assertEquals(getOemBitfield(oemNone), OEM_NONE) + assertEquals(getOemBitfield(oemPaid), OEM_PAID) + assertEquals(getOemBitfield(oemPrivate), OEM_PRIVATE) + assertEquals(getOemBitfield(oemAll), OEM_PAID or OEM_PRIVATE) + } +} diff --git a/tests/net/java/android/net/NetworkTemplateTest.kt b/tests/net/java/android/net/NetworkTemplateTest.kt index b39555d15dcb..27224c216db3 100644 --- a/tests/net/java/android/net/NetworkTemplateTest.kt +++ b/tests/net/java/android/net/NetworkTemplateTest.kt @@ -20,14 +20,23 @@ import android.content.Context import android.net.ConnectivityManager.TYPE_MOBILE import android.net.ConnectivityManager.TYPE_WIFI import android.net.NetworkIdentity.SUBTYPE_COMBINED +import android.net.NetworkIdentity.OEM_NONE; +import android.net.NetworkIdentity.OEM_PAID; +import android.net.NetworkIdentity.OEM_PRIVATE; import android.net.NetworkIdentity.buildNetworkIdentity import android.net.NetworkStats.DEFAULT_NETWORK_ALL import android.net.NetworkStats.METERED_ALL import android.net.NetworkStats.ROAMING_ALL +import android.net.NetworkTemplate.MATCH_ETHERNET import android.net.NetworkTemplate.MATCH_MOBILE +import android.net.NetworkTemplate.MATCH_MOBILE_WILDCARD import android.net.NetworkTemplate.MATCH_WIFI +import android.net.NetworkTemplate.MATCH_WIFI_WILDCARD import android.net.NetworkTemplate.NETWORK_TYPE_5G_NSA import android.net.NetworkTemplate.NETWORK_TYPE_ALL +import android.net.NetworkTemplate.OEM_MANAGED_ALL +import android.net.NetworkTemplate.OEM_MANAGED_NO +import android.net.NetworkTemplate.OEM_MANAGED_YES import android.net.NetworkTemplate.buildTemplateMobileWithRatType import android.telephony.TelephonyManager import com.android.testutils.assertParcelSane @@ -37,9 +46,11 @@ import org.junit.runner.RunWith import org.junit.runners.JUnit4 import org.mockito.Mockito.mock import org.mockito.MockitoAnnotations +import kotlin.test.assertEquals import kotlin.test.assertFalse import kotlin.test.assertNotEquals import kotlin.test.assertTrue +import kotlin.test.fail private const val TEST_IMSI1 = "imsi1" private const val TEST_IMSI2 = "imsi2" @@ -57,13 +68,18 @@ class NetworkTemplateTest { private fun buildNetworkState( type: Int, subscriberId: String? = null, - ssid: String? = null + ssid: String? = null, + oemManaged: Int = OEM_NONE, ): NetworkState { val lp = LinkProperties() val caps = NetworkCapabilities().apply { setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED, false) setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING, true) setSSID(ssid) + setCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PAID, + (oemManaged and OEM_PAID) == OEM_PAID) + setCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE, + (oemManaged and OEM_PRIVATE) == OEM_PRIVATE) } return NetworkState(type, lp, caps, mock(Network::class.java), subscriberId) } @@ -136,11 +152,15 @@ class NetworkTemplateTest { @Test fun testParcelUnparcel() { val templateMobile = NetworkTemplate(MATCH_MOBILE, TEST_IMSI1, null, null, METERED_ALL, - ROAMING_ALL, DEFAULT_NETWORK_ALL, TelephonyManager.NETWORK_TYPE_LTE) + ROAMING_ALL, DEFAULT_NETWORK_ALL, TelephonyManager.NETWORK_TYPE_LTE, + OEM_MANAGED_ALL) val templateWifi = NetworkTemplate(MATCH_WIFI, null, null, TEST_SSID1, METERED_ALL, - ROAMING_ALL, DEFAULT_NETWORK_ALL, 0) - assertParcelSane(templateMobile, 8) - assertParcelSane(templateWifi, 8) + ROAMING_ALL, DEFAULT_NETWORK_ALL, 0, OEM_MANAGED_ALL) + val templateOem = NetworkTemplate(MATCH_MOBILE, null, null, null, METERED_ALL, + ROAMING_ALL, DEFAULT_NETWORK_ALL, 0, OEM_MANAGED_YES) + assertParcelSane(templateMobile, 9) + assertParcelSane(templateWifi, 9) + assertParcelSane(templateOem, 9) } // Verify NETWORK_TYPE_* constants in NetworkTemplate do not conflict with @@ -152,4 +172,81 @@ class NetworkTemplateTest { assertNotEquals(NETWORK_TYPE_5G_NSA, ratType) } } + + @Test + fun testOemNetworkConstants() { + val constantValues = arrayOf(OEM_MANAGED_YES, OEM_MANAGED_ALL, OEM_MANAGED_NO, + OEM_PAID, OEM_PRIVATE, OEM_PAID or OEM_PRIVATE) + + // Verify that "not OEM managed network" constants are equal. + assertEquals(OEM_MANAGED_NO, OEM_NONE); + + // Verify the constants don't conflict. + assertEquals(constantValues.size, constantValues.distinct().count()) + } + + /** + * Helper to enumerate and assert OEM managed wifi and mobile {@code NetworkTemplate}s match + * their the appropriate OEM managed {@code NetworkIdentity}s. + * + * @param networkType {@code TYPE_MOBILE} or {@code TYPE_WIFI} + * @param matchType A match rule from {@code NetworkTemplate.MATCH_*} corresponding to the + * networkType. + * @param subscriberId To be populated with {@code TEST_IMSI*} only if networkType is + * {@code TYPE_MOBILE}. May be left as null when matchType is + * {@link NetworkTemplate.MATCH_MOBILE_WILDCARD}. + * @param templateSsid Top be populated with {@code TEST_SSID*} only if networkType is + * {@code TYPE_WIFI}. May be left as null when matchType is + * {@link NetworkTemplate.MATCH_WIFI_WILDCARD}. + * @param identSsid If networkType is {@code TYPE_WIFI}, this value must *NOT* be null. Provide + * one of {@code TEST_SSID*}. + */ + private fun matchOemManagedIdent(networkType: Int, matchType:Int, subscriberId: String? = null, + templateSsid: String? = null, identSsid: String? = null) { + val oemManagedStates = arrayOf(OEM_NONE, OEM_PAID, OEM_PRIVATE, OEM_PAID or OEM_PRIVATE) + // A null subscriberId needs a null matchSubscriberIds argument as well. + val matchSubscriberIds = if (subscriberId == null) null else arrayOf(subscriberId) + + val templateOemYes = NetworkTemplate(matchType, subscriberId, matchSubscriberIds, + templateSsid, METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, + OEM_MANAGED_YES) + val templateOemAll = NetworkTemplate(matchType, subscriberId, matchSubscriberIds, + templateSsid, METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, + OEM_MANAGED_ALL) + + for (identityOemManagedState in oemManagedStates) { + val ident = buildNetworkIdentity(mockContext, buildNetworkState(networkType, + subscriberId, identSsid, identityOemManagedState), /*defaultNetwork=*/false, + /*subType=*/0) + + // Create a template with each OEM managed type and match it against the NetworkIdentity + for (templateOemManagedState in oemManagedStates) { + val template = NetworkTemplate(matchType, subscriberId, matchSubscriberIds, + templateSsid, METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, + NETWORK_TYPE_ALL, templateOemManagedState) + if (identityOemManagedState == templateOemManagedState) { + template.assertMatches(ident) + } else { + template.assertDoesNotMatch(ident) + } + } + // OEM_MANAGED_ALL ignores OEM state. + templateOemAll.assertMatches(ident) + if (identityOemManagedState == OEM_NONE) { + // OEM_MANAGED_YES matches everything except OEM_NONE. + templateOemYes.assertDoesNotMatch(ident) + } else { + templateOemYes.assertMatches(ident) + } + } + } + + @Test + fun testOemManagedMatchesIdent() { + matchOemManagedIdent(TYPE_MOBILE, MATCH_MOBILE, subscriberId = TEST_IMSI1) + matchOemManagedIdent(TYPE_MOBILE, MATCH_MOBILE_WILDCARD) + matchOemManagedIdent(TYPE_WIFI, MATCH_WIFI, templateSsid = TEST_SSID1, + identSsid = TEST_SSID1) + matchOemManagedIdent(TYPE_WIFI, MATCH_WIFI_WILDCARD, identSsid = TEST_SSID1) + } } diff --git a/tests/net/java/android/net/VpnTransportInfoTest.java b/tests/net/java/android/net/VpnTransportInfoTest.java index 866f38c84333..d04c87b29c25 100644 --- a/tests/net/java/android/net/VpnTransportInfoTest.java +++ b/tests/net/java/android/net/VpnTransportInfoTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 The Android Open Source Project + * Copyright (C) 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/tests/net/java/android/net/util/MultinetworkPolicyTrackerTest.kt b/tests/net/java/android/net/util/MultinetworkPolicyTrackerTest.kt new file mode 100644 index 000000000000..9b0cfa9db30f --- /dev/null +++ b/tests/net/java/android/net/util/MultinetworkPolicyTrackerTest.kt @@ -0,0 +1,137 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net.util + +import android.content.Context +import android.content.res.Resources +import android.net.ConnectivityManager.MULTIPATH_PREFERENCE_HANDOVER +import android.net.ConnectivityManager.MULTIPATH_PREFERENCE_PERFORMANCE +import android.net.ConnectivityManager.MULTIPATH_PREFERENCE_RELIABILITY +import android.net.util.MultinetworkPolicyTracker.ActiveDataSubscriptionIdChangedListener +import android.provider.Settings +import android.provider.Settings.Global.NETWORK_AVOID_BAD_WIFI +import android.provider.Settings.Global.NETWORK_METERED_MULTIPATH_PREFERENCE +import android.telephony.SubscriptionInfo +import android.telephony.SubscriptionManager +import android.telephony.TelephonyManager +import android.test.mock.MockContentResolver +import androidx.test.filters.SmallTest +import androidx.test.runner.AndroidJUnit4 +import com.android.internal.R +import com.android.internal.util.test.FakeSettingsProvider +import org.junit.Assert.assertEquals +import org.junit.Assert.assertFalse +import org.junit.Assert.assertTrue +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.ArgumentCaptor +import org.mockito.ArgumentMatchers.anyInt +import org.mockito.ArgumentMatchers.argThat +import org.mockito.Mockito.any +import org.mockito.Mockito.doReturn +import org.mockito.Mockito.mock +import org.mockito.Mockito.times +import org.mockito.Mockito.verify + +/** + * Tests for [MultinetworkPolicyTracker]. + * + * Build, install and run with: + * atest android.net.util.MultinetworkPolicyTrackerTest + */ +@RunWith(AndroidJUnit4::class) +@SmallTest +class MultinetworkPolicyTrackerTest { + private val resources = mock(Resources::class.java).also { + doReturn(0).`when`(it).getInteger(R.integer.config_networkAvoidBadWifi) + } + private val telephonyManager = mock(TelephonyManager::class.java) + private val subscriptionManager = mock(SubscriptionManager::class.java).also { + doReturn(null).`when`(it).getActiveSubscriptionInfo(anyInt()) + } + private val resolver = MockContentResolver().apply { + addProvider(Settings.AUTHORITY, FakeSettingsProvider()) } + private val context = mock(Context::class.java).also { + doReturn(Context.TELEPHONY_SERVICE).`when`(it) + .getSystemServiceName(TelephonyManager::class.java) + doReturn(telephonyManager).`when`(it).getSystemService(Context.TELEPHONY_SERVICE) + doReturn(subscriptionManager).`when`(it) + .getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE) + doReturn(resolver).`when`(it).contentResolver + doReturn(resources).`when`(it).resources + doReturn(it).`when`(it).createConfigurationContext(any()) + Settings.Global.putString(resolver, NETWORK_AVOID_BAD_WIFI, "1") + } + private val tracker = MultinetworkPolicyTracker(context, null /* handler */) + + private fun assertMultipathPreference(preference: Int) { + Settings.Global.putString(resolver, NETWORK_METERED_MULTIPATH_PREFERENCE, + preference.toString()) + tracker.updateMeteredMultipathPreference() + assertEquals(preference, tracker.meteredMultipathPreference) + } + + @Test + fun testUpdateMeteredMultipathPreference() { + assertMultipathPreference(MULTIPATH_PREFERENCE_HANDOVER) + assertMultipathPreference(MULTIPATH_PREFERENCE_RELIABILITY) + assertMultipathPreference(MULTIPATH_PREFERENCE_PERFORMANCE) + } + + @Test + fun testUpdateAvoidBadWifi() { + Settings.Global.putString(resolver, NETWORK_AVOID_BAD_WIFI, "0") + assertTrue(tracker.updateAvoidBadWifi()) + assertFalse(tracker.avoidBadWifi) + + doReturn(1).`when`(resources).getInteger(R.integer.config_networkAvoidBadWifi) + assertTrue(tracker.updateAvoidBadWifi()) + assertTrue(tracker.avoidBadWifi) + } + + @Test + fun testOnActiveDataSubscriptionIdChanged() { + val testSubId = 1000 + val subscriptionInfo = SubscriptionInfo(testSubId, ""/* iccId */, 1/* iccId */, + "TMO"/* displayName */, "TMO"/* carrierName */, 1/* nameSource */, 1/* iconTint */, + "123"/* number */, 1/* roaming */, null/* icon */, "310"/* mcc */, "210"/* mnc */, + ""/* countryIso */, false/* isEmbedded */, null/* nativeAccessRules */, + "1"/* cardString */) + doReturn(subscriptionInfo).`when`(subscriptionManager).getActiveSubscriptionInfo(testSubId) + + // Modify avoidBadWifi and meteredMultipathPreference settings value and local variables in + // MultinetworkPolicyTracker should be also updated after subId changed. + Settings.Global.putString(resolver, NETWORK_AVOID_BAD_WIFI, "0") + Settings.Global.putString(resolver, NETWORK_METERED_MULTIPATH_PREFERENCE, + MULTIPATH_PREFERENCE_PERFORMANCE.toString()) + + val listenerCaptor = ArgumentCaptor.forClass( + ActiveDataSubscriptionIdChangedListener::class.java) + verify(telephonyManager, times(1)) + .registerPhoneStateListener(any(), listenerCaptor.capture()) + val listener = listenerCaptor.value + listener.onActiveDataSubscriptionIdChanged(testSubId) + + // Check it get resource value with test sub id. + verify(subscriptionManager, times(1)).getActiveSubscriptionInfo(testSubId) + verify(context).createConfigurationContext(argThat { it.mcc == 310 && it.mnc == 210 }) + + // Check if avoidBadWifi and meteredMultipathPreference values have been updated. + assertFalse(tracker.avoidBadWifi) + assertEquals(MULTIPATH_PREFERENCE_PERFORMANCE, tracker.meteredMultipathPreference) + } +} diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java index 11c10fa44101..1cfc3f9f9e5c 100644 --- a/tests/net/java/com/android/server/ConnectivityServiceTest.java +++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java @@ -407,8 +407,6 @@ public class ConnectivityServiceTest { private QosCallbackMockHelper mQosCallbackMockHelper; private QosCallbackTracker mQosCallbackTracker; private VpnManagerService mVpnManagerService; - private TestNetworkCallback mDefaultNetworkCallback; - private TestNetworkCallback mSystemDefaultNetworkCallback; // State variables required to emulate NetworkPolicyManagerService behaviour. private int mUidRules = RULE_NONE; @@ -1549,7 +1547,6 @@ public class ConnectivityServiceTest { @After public void tearDown() throws Exception { - unregisterDefaultNetworkCallbacks(); setAlwaysOnNetworks(false); if (mCellNetworkAgent != null) { mCellNetworkAgent.disconnect(); @@ -2800,6 +2797,10 @@ public class ConnectivityServiceTest { NetworkCapabilities filter = new NetworkCapabilities(); filter.addCapability(capability); + // Add NOT_VCN_MANAGED capability into filter unconditionally since some request will add + // NOT_VCN_MANAGED automatically but not for NetworkCapabilities, + // see {@code NetworkCapabilities#deduceNotVcnManagedCapability} for more details. + filter.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED); final HandlerThread handlerThread = new HandlerThread("testNetworkFactoryRequests"); handlerThread.start(); final MockNetworkFactory testFactory = new MockNetworkFactory(handlerThread.getLooper(), @@ -4147,6 +4148,7 @@ public class ConnectivityServiceTest { handlerThread.start(); NetworkCapabilities filter = new NetworkCapabilities() .addTransportType(TRANSPORT_CELLULAR) + .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED) .addCapability(NET_CAPABILITY_INTERNET); final MockNetworkFactory testFactory = new MockNetworkFactory(handlerThread.getLooper(), mServiceContext, "testFactory", filter, mCsHandlerThread); @@ -6051,6 +6053,7 @@ public class ConnectivityServiceTest { .addTransportType(TRANSPORT_CELLULAR) .addCapability(NET_CAPABILITY_INTERNET) .addCapability(NET_CAPABILITY_NOT_CONGESTED) + .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED) .setLinkDownstreamBandwidthKbps(10); final NetworkCapabilities wifiNc = new NetworkCapabilities() .addTransportType(TRANSPORT_WIFI) @@ -6059,6 +6062,7 @@ public class ConnectivityServiceTest { .addCapability(NET_CAPABILITY_NOT_ROAMING) .addCapability(NET_CAPABILITY_NOT_CONGESTED) .addCapability(NET_CAPABILITY_NOT_SUSPENDED) + .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED) .setLinkUpstreamBandwidthKbps(20); mCellNetworkAgent.setNetworkCapabilities(cellNc, true /* sendToConnectivityService */); mWiFiNetworkAgent.setNetworkCapabilities(wifiNc, true /* sendToConnectivityService */); @@ -7751,19 +7755,13 @@ public class ConnectivityServiceTest { mWiFiNetworkAgent.removeCapability(testCap); callbackWithCap.expectAvailableCallbacksValidated(mCellNetworkAgent); callbackWithoutCap.expectCapabilitiesWithout(testCap, mWiFiNetworkAgent); - // TODO: Test default network changes for NOT_VCN_MANAGED once the default request has - // it. - if (testCap == NET_CAPABILITY_TRUSTED) { - verify(mMockNetd).networkSetDefault(eq(mCellNetworkAgent.getNetwork().netId)); - reset(mMockNetd); - } + verify(mMockNetd).networkSetDefault(eq(mCellNetworkAgent.getNetwork().netId)); + reset(mMockNetd); mCellNetworkAgent.removeCapability(testCap); callbackWithCap.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); callbackWithoutCap.assertNoCallback(); - if (testCap == NET_CAPABILITY_TRUSTED) { - verify(mMockNetd).networkClearDefault(); - } + verify(mMockNetd).networkClearDefault(); mCm.unregisterNetworkCallback(callbackWithCap); mCm.unregisterNetworkCallback(callbackWithoutCap); @@ -9469,10 +9467,6 @@ public class ConnectivityServiceTest { fail("TOO_MANY_REQUESTS never thrown"); } - private UidRange createUidRange(int userId) { - return UidRange.createForUser(UserHandle.of(userId)); - } - private void mockGetApplicationInfo(@NonNull final String packageName, @NonNull final int uid) throws Exception { final ApplicationInfo applicationInfo = new ApplicationInfo(); @@ -9807,54 +9801,6 @@ public class ConnectivityServiceTest { assertEquals(expectedPerAppNetwork, defaultNetwork); assertEquals(expectedOemRequestsSize, defaultRequest.mRequests.size()); } - verifyMultipleDefaultCallbacks(expectedDefaultNetwork, expectedPerAppNetwork); - } - - /** - * Verify default callbacks for 'available' fire as expected. This will only run if - * registerDefaultNetworkCallbacks() was executed prior and will only be different if the - * setOemNetworkPreference() per-app API was used for the current process. - * @param expectedSystemDefault the expected network for the system default. - * @param expectedPerAppDefault the expected network for the current process's default. - */ - private void verifyMultipleDefaultCallbacks( - @NonNull final Network expectedSystemDefault, - @NonNull final Network expectedPerAppDefault) { - if (null != mSystemDefaultNetworkCallback && null != expectedSystemDefault - && mService.mNoServiceNetwork.network() != expectedSystemDefault) { - // getLastAvailableNetwork() is used as this method can be called successively with - // the same network to validate therefore expectAvailableThenValidatedCallbacks - // can't be used. - assertEquals(mSystemDefaultNetworkCallback.getLastAvailableNetwork(), - expectedSystemDefault); - } - if (null != mDefaultNetworkCallback && null != expectedPerAppDefault - && mService.mNoServiceNetwork.network() != expectedPerAppDefault) { - assertEquals(mDefaultNetworkCallback.getLastAvailableNetwork(), - expectedPerAppDefault); - } - } - - private void registerDefaultNetworkCallbacks() { - // Using Manifest.permission.NETWORK_SETTINGS for registerSystemDefaultNetworkCallback() - mServiceContext.setPermission( - Manifest.permission.NETWORK_SETTINGS, PERMISSION_GRANTED); - mSystemDefaultNetworkCallback = new TestNetworkCallback(); - mDefaultNetworkCallback = new TestNetworkCallback(); - mCm.registerSystemDefaultNetworkCallback(mSystemDefaultNetworkCallback, - new Handler(ConnectivityThread.getInstanceLooper())); - mCm.registerDefaultNetworkCallback(mDefaultNetworkCallback); - mServiceContext.setPermission( - Manifest.permission.NETWORK_SETTINGS, PERMISSION_DENIED); - } - - private void unregisterDefaultNetworkCallbacks() { - if (null != mDefaultNetworkCallback) { - mCm.unregisterNetworkCallback(mDefaultNetworkCallback); - } - if (null != mSystemDefaultNetworkCallback) { - mCm.unregisterNetworkCallback(mSystemDefaultNetworkCallback); - } } private void setupMultipleDefaultNetworksForOemNetworkPreferenceNotCurrentUidTest( @@ -9938,7 +9884,6 @@ public class ConnectivityServiceTest { @OemNetworkPreferences.OemNetworkPreference final int networkPref = OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY; final int expectedOemPrefRequestSize = 1; - registerDefaultNetworkCallbacks(); // Setup the test process to use networkPref for their default network. setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest(networkPref); @@ -9953,7 +9898,6 @@ public class ConnectivityServiceTest { // Verify that the active network is correct verifyActiveNetwork(TRANSPORT_ETHERNET); - // default NCs will be unregistered in tearDown } @Test @@ -9961,7 +9905,6 @@ public class ConnectivityServiceTest { @OemNetworkPreferences.OemNetworkPreference final int networkPref = OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY; final int expectedOemPrefRequestSize = 1; - registerDefaultNetworkCallbacks(); // Setup the test process to use networkPref for their default network. setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest(networkPref); @@ -9982,7 +9925,6 @@ public class ConnectivityServiceTest { mEthernetNetworkAgent.getNetwork()); assertFalse(mCm.isActiveNetworkMetered()); - // default NCs will be unregistered in tearDown } @Test @@ -10139,6 +10081,7 @@ public class ConnectivityServiceTest { /** * Test the tracked default requests clear previous OEM requests on setOemNetworkPreference(). + * @throws Exception */ @Test public void testSetOemNetworkPreferenceClearPreviousOemValues() throws Exception { @@ -10166,8 +10109,9 @@ public class ConnectivityServiceTest { } /** - * Test network priority for preference OEM_NETWORK_PREFERENCE_OEM_PAID in the following order: + * Test network priority for preference OEM_NETWORK_PREFERENCE_OEM_PAID following in order: * NET_CAPABILITY_NOT_METERED -> NET_CAPABILITY_OEM_PAID -> fallback + * @throws Exception */ @Test public void testMultilayerForPreferenceOemPaidEvaluatesCorrectly() @@ -10233,8 +10177,9 @@ public class ConnectivityServiceTest { } /** - * Test network priority for OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK in the following order: + * Test network priority for OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK following in order: * NET_CAPABILITY_NOT_METERED -> NET_CAPABILITY_OEM_PAID + * @throws Exception */ @Test public void testMultilayerForPreferenceOemPaidNoFallbackEvaluatesCorrectly() @@ -10295,9 +10240,10 @@ public class ConnectivityServiceTest { } /** - * Test network priority for OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY in the following order: + * Test network priority for OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY following in order: * NET_CAPABILITY_OEM_PAID * This preference should only apply to OEM_PAID networks. + * @throws Exception */ @Test public void testMultilayerForPreferenceOemPaidOnlyEvaluatesCorrectly() @@ -10348,9 +10294,10 @@ public class ConnectivityServiceTest { } /** - * Test network priority for OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY in the following order: + * Test network priority for OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY following in order: * NET_CAPABILITY_OEM_PRIVATE * This preference should only apply to OEM_PRIVATE networks. + * @throws Exception */ @Test public void testMultilayerForPreferenceOemPrivateOnlyEvaluatesCorrectly() @@ -10400,235 +10347,7 @@ public class ConnectivityServiceTest { true /* shouldDestroyNetwork */); } - /** - * Test network priority for preference OEM_NETWORK_PREFERENCE_OEM_PAID in the following order: - * NET_CAPABILITY_NOT_METERED -> NET_CAPABILITY_OEM_PAID -> fallback - */ - @Test - public void testMultipleDefaultNetworksTracksOemNetworkPreferenceOemPaidCorrectly() - throws Exception { - @OemNetworkPreferences.OemNetworkPreference final int networkPref = - OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID; - setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest(networkPref); - final int expectedDefaultRequestSize = 2; - final int expectedOemPrefRequestSize = 3; - registerDefaultNetworkCallbacks(); - - // The fallback as well as the OEM preference should now be tracked. - assertEquals(expectedDefaultRequestSize, mService.mDefaultNetworkRequests.size()); - - // Test lowest to highest priority requests. - // Bring up metered cellular. This will satisfy the fallback network. - setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); - verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, - mCellNetworkAgent.getNetwork(), - mCellNetworkAgent.getNetwork()); - - // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID. - setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true); - verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, - mCellNetworkAgent.getNetwork(), - mEthernetNetworkAgent.getNetwork()); - - // Bring up unmetered Wi-Fi. This will satisfy NET_CAPABILITY_NOT_METERED. - setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, true); - verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, - mWiFiNetworkAgent.getNetwork(), - mWiFiNetworkAgent.getNetwork()); - - // Disconnecting unmetered Wi-Fi will put the pref on OEM_PAID and fallback on cellular. - setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, false); - verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, - mCellNetworkAgent.getNetwork(), - mEthernetNetworkAgent.getNetwork()); - - // Disconnecting cellular should keep OEM network on OEM_PAID and fallback will be null. - setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, false); - verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, - null, - mEthernetNetworkAgent.getNetwork()); - - // Disconnecting OEM_PAID will put both on null as it is the last network. - setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, false); - verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, - null, - null); - - // default NCs will be unregistered in tearDown - } - - /** - * Test network priority for OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK in the following order: - * NET_CAPABILITY_NOT_METERED -> NET_CAPABILITY_OEM_PAID - */ - @Test - public void testMultipleDefaultNetworksTracksOemNetworkPreferenceOemPaidNoFallbackCorrectly() - throws Exception { - @OemNetworkPreferences.OemNetworkPreference final int networkPref = - OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK; - setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest(networkPref); - final int expectedDefaultRequestSize = 2; - final int expectedOemPrefRequestSize = 2; - registerDefaultNetworkCallbacks(); - - // The fallback as well as the OEM preference should now be tracked. - assertEquals(expectedDefaultRequestSize, mService.mDefaultNetworkRequests.size()); - - // Test lowest to highest priority requests. - // Bring up metered cellular. This will satisfy the fallback network but not the pref. - setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); - verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, - mCellNetworkAgent.getNetwork(), - mService.mNoServiceNetwork.network()); - - // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID. - setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true); - verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, - mCellNetworkAgent.getNetwork(), - mEthernetNetworkAgent.getNetwork()); - - // Bring up unmetered Wi-Fi. This will satisfy NET_CAPABILITY_NOT_METERED. - setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, true); - verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, - mWiFiNetworkAgent.getNetwork(), - mWiFiNetworkAgent.getNetwork()); - - // Disconnecting unmetered Wi-Fi will put the OEM pref on OEM_PAID and fallback on cellular. - setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, false); - verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, - mCellNetworkAgent.getNetwork(), - mEthernetNetworkAgent.getNetwork()); - - // Disconnecting cellular should keep OEM network on OEM_PAID and fallback will be null. - setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, false); - verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, - null, - mEthernetNetworkAgent.getNetwork()); - - // Disconnecting OEM_PAID puts the fallback on null and the pref on the disconnected net. - setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, false); - verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, - null, - mService.mNoServiceNetwork.network()); - - // default NCs will be unregistered in tearDown - } - - /** - * Test network priority for OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY in the following order: - * NET_CAPABILITY_OEM_PAID - * This preference should only apply to OEM_PAID networks. - */ - @Test - public void testMultipleDefaultNetworksTracksOemNetworkPreferenceOemPaidOnlyCorrectly() - throws Exception { - @OemNetworkPreferences.OemNetworkPreference final int networkPref = - OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY; - setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest(networkPref); - final int expectedDefaultRequestSize = 2; - final int expectedOemPrefRequestSize = 1; - registerDefaultNetworkCallbacks(); - - // The fallback as well as the OEM preference should now be tracked. - assertEquals(expectedDefaultRequestSize, mService.mDefaultNetworkRequests.size()); - - // Test lowest to highest priority requests. - // Bring up metered cellular. This will satisfy the fallback network. - setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); - verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, - mCellNetworkAgent.getNetwork(), - mService.mNoServiceNetwork.network()); - - // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID. - setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true); - verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, - mCellNetworkAgent.getNetwork(), - mEthernetNetworkAgent.getNetwork()); - - // Bring up unmetered Wi-Fi. The OEM network shouldn't change, the fallback will take Wi-Fi. - setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, true); - verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, - mWiFiNetworkAgent.getNetwork(), - mEthernetNetworkAgent.getNetwork()); - - // Disconnecting unmetered Wi-Fi shouldn't change the OEM network with fallback on cellular. - setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, false); - verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, - mCellNetworkAgent.getNetwork(), - mEthernetNetworkAgent.getNetwork()); - - // Disconnecting OEM_PAID will keep the fallback on cellular and nothing for OEM_PAID. - // OEM_PAID_ONLY not supporting a fallback now uses the disconnected network. - setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, false); - verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, - mCellNetworkAgent.getNetwork(), - mService.mNoServiceNetwork.network()); - - // Disconnecting cellular will put the fallback on null and the pref on disconnected. - setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, false); - verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, - null, - mService.mNoServiceNetwork.network()); - - // default NCs will be unregistered in tearDown - } - - /** - * Test network priority for OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY in the following order: - * NET_CAPABILITY_OEM_PRIVATE - * This preference should only apply to OEM_PRIVATE networks. - */ - @Test - public void testMultipleDefaultNetworksTracksOemNetworkPreferenceOemPrivateOnlyCorrectly() - throws Exception { - @OemNetworkPreferences.OemNetworkPreference final int networkPref = - OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY; - setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest(networkPref); - final int expectedDefaultRequestSize = 2; - final int expectedOemPrefRequestSize = 1; - registerDefaultNetworkCallbacks(); - - // The fallback as well as the OEM preference should now be tracked. - assertEquals(expectedDefaultRequestSize, mService.mDefaultNetworkRequests.size()); - - // Test lowest to highest priority requests. - // Bring up metered cellular. This will satisfy the fallback network. - setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true); - verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, - mCellNetworkAgent.getNetwork(), - mService.mNoServiceNetwork.network()); - - // Bring up ethernet with OEM_PRIVATE. This will satisfy NET_CAPABILITY_OEM_PRIVATE. - startOemManagedNetwork(false); - verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, - mCellNetworkAgent.getNetwork(), - mEthernetNetworkAgent.getNetwork()); - - // Bring up unmetered Wi-Fi. The OEM network shouldn't change, the fallback will take Wi-Fi. - setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, true); - verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, - mWiFiNetworkAgent.getNetwork(), - mEthernetNetworkAgent.getNetwork()); - - // Disconnecting unmetered Wi-Fi shouldn't change the OEM network with fallback on cellular. - setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, false); - verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, - mCellNetworkAgent.getNetwork(), - mEthernetNetworkAgent.getNetwork()); - - // Disconnecting OEM_PRIVATE will keep the fallback on cellular. - // OEM_PRIVATE_ONLY not supporting a fallback now uses to the disconnected network. - stopOemManagedNetwork(); - verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, - mCellNetworkAgent.getNetwork(), - mService.mNoServiceNetwork.network()); - - // Disconnecting cellular will put the fallback on null and pref on disconnected. - setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, false); - verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize, - null, - mService.mNoServiceNetwork.network()); - - // default NCs will be unregistered in tearDown + private UidRange createUidRange(int userId) { + return UidRange.createForUser(UserHandle.of(userId)); } } diff --git a/tests/net/java/com/android/server/net/NetworkStatsCollectionTest.java b/tests/net/java/com/android/server/net/NetworkStatsCollectionTest.java index 435c3c0af817..505ff9b6a34b 100644 --- a/tests/net/java/com/android/server/net/NetworkStatsCollectionTest.java +++ b/tests/net/java/com/android/server/net/NetworkStatsCollectionTest.java @@ -17,6 +17,7 @@ package com.android.server.net; import static android.net.ConnectivityManager.TYPE_MOBILE; +import static android.net.NetworkIdentity.OEM_NONE; import static android.net.NetworkStats.SET_ALL; import static android.net.NetworkStats.SET_DEFAULT; import static android.net.NetworkStats.TAG_NONE; @@ -213,7 +214,7 @@ public class NetworkStatsCollectionTest { final NetworkStats.Entry entry = new NetworkStats.Entry(); final NetworkIdentitySet identSet = new NetworkIdentitySet(); identSet.add(new NetworkIdentity(TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_UNKNOWN, - TEST_IMSI, null, false, true, true)); + TEST_IMSI, null, false, true, true, OEM_NONE)); int myUid = Process.myUid(); int otherUidInSameUser = Process.myUid() + 1; @@ -468,7 +469,7 @@ public class NetworkStatsCollectionTest { final NetworkStatsCollection large = new NetworkStatsCollection(HOUR_IN_MILLIS); final NetworkIdentitySet ident = new NetworkIdentitySet(); ident.add(new NetworkIdentity(ConnectivityManager.TYPE_MOBILE, -1, TEST_IMSI, null, - false, true, true)); + false, true, true, OEM_NONE)); large.recordData(ident, UID_ALL, SET_ALL, TAG_NONE, TIME_A, TIME_B, new NetworkStats.Entry(12_730_893_164L, 1, 0, 0, 0)); diff --git a/tests/net/java/com/android/server/net/NetworkStatsObserversTest.java b/tests/net/java/com/android/server/net/NetworkStatsObserversTest.java index 291efc74aa47..9fa1c50423d9 100644 --- a/tests/net/java/com/android/server/net/NetworkStatsObserversTest.java +++ b/tests/net/java/com/android/server/net/NetworkStatsObserversTest.java @@ -17,6 +17,7 @@ package com.android.server.net; import static android.net.ConnectivityManager.TYPE_MOBILE; +import static android.net.NetworkIdentity.OEM_NONE; import static android.net.NetworkStats.DEFAULT_NETWORK_NO; import static android.net.NetworkStats.DEFAULT_NETWORK_YES; import static android.net.NetworkStats.METERED_NO; @@ -220,7 +221,7 @@ public class NetworkStatsObserversTest { identSet.add(new NetworkIdentity( TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_UNKNOWN, IMSI_1, null /* networkId */, false /* roaming */, true /* metered */, - true /* defaultNetwork */)); + true /* defaultNetwork */, OEM_NONE)); return identSet; } diff --git a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java index d644739ea25e..54d6fb9f2c12 100644 --- a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java +++ b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java @@ -21,6 +21,9 @@ import static android.content.Intent.EXTRA_UID; import static android.net.ConnectivityManager.TYPE_MOBILE; import static android.net.ConnectivityManager.TYPE_VPN; import static android.net.ConnectivityManager.TYPE_WIFI; +import static android.net.NetworkIdentity.OEM_NONE; +import static android.net.NetworkIdentity.OEM_PAID; +import static android.net.NetworkIdentity.OEM_PRIVATE; import static android.net.NetworkStats.DEFAULT_NETWORK_ALL; import static android.net.NetworkStats.DEFAULT_NETWORK_NO; import static android.net.NetworkStats.DEFAULT_NETWORK_YES; @@ -40,7 +43,10 @@ import static android.net.NetworkStats.TAG_ALL; import static android.net.NetworkStats.TAG_NONE; import static android.net.NetworkStats.UID_ALL; import static android.net.NetworkStatsHistory.FIELD_ALL; +import static android.net.NetworkTemplate.MATCH_MOBILE_WILDCARD; import static android.net.NetworkTemplate.NETWORK_TYPE_ALL; +import static android.net.NetworkTemplate.OEM_MANAGED_NO; +import static android.net.NetworkTemplate.OEM_MANAGED_YES; import static android.net.NetworkTemplate.buildTemplateMobileAll; import static android.net.NetworkTemplate.buildTemplateMobileWithRatType; import static android.net.NetworkTemplate.buildTemplateWifi; @@ -643,6 +649,116 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { assertUidTotal(template5g, UID_RED, 5L, 13L, 31L, 9L, 2); } + @Test + public void testMobileStatsOemManaged() throws Exception { + final NetworkTemplate templateOemPaid = new NetworkTemplate(MATCH_MOBILE_WILDCARD, + /*subscriberId=*/null, /*matchSubscriberIds=*/null, /*networkId=*/null, + METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, OEM_PAID); + + final NetworkTemplate templateOemPrivate = new NetworkTemplate(MATCH_MOBILE_WILDCARD, + /*subscriberId=*/null, /*matchSubscriberIds=*/null, /*networkId=*/null, + METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, OEM_PRIVATE); + + final NetworkTemplate templateOemAll = new NetworkTemplate(MATCH_MOBILE_WILDCARD, + /*subscriberId=*/null, /*matchSubscriberIds=*/null, /*networkId=*/null, + METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, + OEM_PAID | OEM_PRIVATE); + + final NetworkTemplate templateOemYes = new NetworkTemplate(MATCH_MOBILE_WILDCARD, + /*subscriberId=*/null, /*matchSubscriberIds=*/null, /*networkId=*/null, + METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, OEM_MANAGED_YES); + + final NetworkTemplate templateOemNone = new NetworkTemplate(MATCH_MOBILE_WILDCARD, + /*subscriberId=*/null, /*matchSubscriberIds=*/null, /*networkId=*/null, + METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, OEM_MANAGED_NO); + + // OEM_PAID network comes online. + NetworkState[] states = new NetworkState[]{buildOemManagedMobileState(IMSI_1, false, + new int[]{NetworkCapabilities.NET_CAPABILITY_OEM_PAID})}; + expectNetworkStatsSummary(buildEmptyStats()); + expectNetworkStatsUidDetail(buildEmptyStats()); + mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states), + new UnderlyingNetworkInfo[0]); + + // Create some traffic. + incrementCurrentTime(MINUTE_IN_MILLIS); + expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1) + .addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, + 36L, 41L, 24L, 96L, 0L))); + forcePollAndWaitForIdle(); + + // OEM_PRIVATE network comes online. + states = new NetworkState[]{buildOemManagedMobileState(IMSI_1, false, + new int[]{NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE})}; + expectNetworkStatsSummary(buildEmptyStats()); + expectNetworkStatsUidDetail(buildEmptyStats()); + mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states), + new UnderlyingNetworkInfo[0]); + + // Create some traffic. + incrementCurrentTime(MINUTE_IN_MILLIS); + expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1) + .addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, + 49L, 71L, 72L, 48L, 0L))); + forcePollAndWaitForIdle(); + + // OEM_PAID + OEM_PRIVATE network comes online. + states = new NetworkState[]{buildOemManagedMobileState(IMSI_1, false, + new int[]{NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE, + NetworkCapabilities.NET_CAPABILITY_OEM_PAID})}; + expectNetworkStatsSummary(buildEmptyStats()); + expectNetworkStatsUidDetail(buildEmptyStats()); + mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states), + new UnderlyingNetworkInfo[0]); + + // Create some traffic. + incrementCurrentTime(MINUTE_IN_MILLIS); + expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1) + .addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, + 57L, 86L, 83L, 93L, 0L))); + forcePollAndWaitForIdle(); + + // OEM_NONE network comes online. + states = new NetworkState[]{buildOemManagedMobileState(IMSI_1, false, new int[]{})}; + expectNetworkStatsSummary(buildEmptyStats()); + expectNetworkStatsUidDetail(buildEmptyStats()); + mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states), + new UnderlyingNetworkInfo[0]); + + // Create some traffic. + incrementCurrentTime(MINUTE_IN_MILLIS); + expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1) + .addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, + 29L, 73L, 34L, 31L, 0L))); + forcePollAndWaitForIdle(); + + // Verify OEM_PAID template gets only relevant stats. + assertUidTotal(templateOemPaid, UID_RED, 36L, 41L, 24L, 96L, 0); + + // Verify OEM_PRIVATE template gets only relevant stats. + assertUidTotal(templateOemPrivate, UID_RED, 49L, 71L, 72L, 48L, 0); + + // Verify OEM_PAID + OEM_PRIVATE template gets only relevant stats. + assertUidTotal(templateOemAll, UID_RED, 57L, 86L, 83L, 93L, 0); + + // Verify OEM_NONE sees only non-OEM managed stats. + assertUidTotal(templateOemNone, UID_RED, 29L, 73L, 34L, 31L, 0); + + // Verify OEM_MANAGED_YES sees all OEM managed stats. + assertUidTotal(templateOemYes, UID_RED, + 36L + 49L + 57L, + 41L + 71L + 86L, + 24L + 72L + 83L, + 96L + 48L + 93L, 0); + + // Verify ALL_MOBILE template gets both OEM managed and non-OEM managed stats. + assertUidTotal(sTemplateImsi1, UID_RED, + 36L + 49L + 57L + 29L, + 41L + 71L + 86L + 73L, + 24L + 72L + 83L + 34L, + 96L + 48L + 93L + 31L, 0); + } + // TODO: support per IMSI state private void setMobileRatTypeAndWaitForIdle(int ratType) { when(mNetworkStatsSubscriptionsMonitor.getRatTypeForSubscriberId(anyString())) @@ -1488,6 +1604,20 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { return new NetworkState(TYPE_VPN, prop, new NetworkCapabilities(), VPN_NETWORK, null); } + private static NetworkState buildOemManagedMobileState(String subscriberId, boolean isRoaming, + int[] oemNetCapabilities) { + final LinkProperties prop = new LinkProperties(); + prop.setInterfaceName(TEST_IFACE); + final NetworkCapabilities capabilities = new NetworkCapabilities(); + capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED, false); + capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING, !isRoaming); + for (int nc : oemNetCapabilities) { + capabilities.setCapability(nc, true); + } + capabilities.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR); + return new NetworkState(TYPE_MOBILE, prop, capabilities, MOBILE_NETWORK, subscriberId); + } + private long getElapsedRealtime() { return mElapsedRealtime; } diff --git a/tools/protologtool/Android.bp b/tools/protologtool/Android.bp index 4342d4eef8ee..039bb4e2788c 100644 --- a/tools/protologtool/Android.bp +++ b/tools/protologtool/Android.bp @@ -34,9 +34,13 @@ java_test_host { srcs: [ "tests/**/*.kt", ], + test_options: { + unit_test: true, + }, static_libs: [ "protologtool-lib", "junit", "mockito", + "objenesis", ], } |