diff options
379 files changed, 8400 insertions, 2430 deletions
diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/BackgroundJobsController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/BackgroundJobsController.java index d7b1e0793f67..1645bcb928c1 100644 --- a/apex/jobscheduler/service/java/com/android/server/job/controllers/BackgroundJobsController.java +++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/BackgroundJobsController.java @@ -184,7 +184,6 @@ public final class BackgroundJobsController extends StateController { } boolean updateSingleJobRestrictionLocked(JobStatus jobStatus, int activeState) { - final int uid = jobStatus.getSourceUid(); final String packageName = jobStatus.getSourcePackageName(); @@ -199,7 +198,7 @@ public final class BackgroundJobsController extends StateController { isActive = (activeState == KNOWN_ACTIVE); } if (isActive && jobStatus.getStandbyBucket() == NEVER_INDEX) { - Slog.wtf(TAG, "App became active but still in NEVER bucket"); + Slog.wtf(TAG, "App " + packageName + " became active but still in NEVER bucket"); } boolean didChange = jobStatus.setBackgroundNotRestrictedConstraintSatisfied(canRun); didChange |= jobStatus.setUidActive(isActive); diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/idle/DeviceIdlenessTracker.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/idle/DeviceIdlenessTracker.java index f74eb3b9a45f..e2c8f649fdb7 100644 --- a/apex/jobscheduler/service/java/com/android/server/job/controllers/idle/DeviceIdlenessTracker.java +++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/idle/DeviceIdlenessTracker.java @@ -19,10 +19,12 @@ package com.android.server.job.controllers.idle; import static com.android.server.job.JobSchedulerService.sElapsedRealtimeClock; import android.app.AlarmManager; +import android.app.UiModeManager; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.os.PowerManager; import android.util.Log; import android.util.Slog; import android.util.proto.ProtoOutputStream; @@ -39,6 +41,7 @@ public final class DeviceIdlenessTracker extends BroadcastReceiver implements Id || Log.isLoggable(TAG, Log.DEBUG); private AlarmManager mAlarm; + private PowerManager mPowerManager; // After construction, mutations of idle/screen-on state will only happen // on the main looper thread, either in onReceive() or in an alarm callback. @@ -47,6 +50,7 @@ public final class DeviceIdlenessTracker extends BroadcastReceiver implements Id private boolean mIdle; private boolean mScreenOn; private boolean mDockIdle; + private boolean mInCarMode; private IdlenessListener mIdleListener; private AlarmManager.OnAlarmListener mIdleAlarmListener = () -> { @@ -59,6 +63,7 @@ public final class DeviceIdlenessTracker extends BroadcastReceiver implements Id mIdle = false; mScreenOn = true; mDockIdle = false; + mInCarMode = false; } @Override @@ -74,6 +79,7 @@ public final class DeviceIdlenessTracker extends BroadcastReceiver implements Id mIdleWindowSlop = context.getResources().getInteger( com.android.internal.R.integer.config_jobSchedulerIdleWindowSlop); mAlarm = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); + mPowerManager = context.getSystemService(PowerManager.class); IntentFilter filter = new IntentFilter(); @@ -92,6 +98,10 @@ public final class DeviceIdlenessTracker extends BroadcastReceiver implements Id filter.addAction(Intent.ACTION_DOCK_IDLE); filter.addAction(Intent.ACTION_DOCK_ACTIVE); + // Car mode + filter.addAction(UiModeManager.ACTION_ENTER_CAR_MODE_PRIORITIZED); + filter.addAction(UiModeManager.ACTION_EXIT_CAR_MODE_PRIORITIZED); + context.registerReceiver(this, filter); } @@ -100,6 +110,8 @@ public final class DeviceIdlenessTracker extends BroadcastReceiver implements Id pw.print(" mIdle: "); pw.println(mIdle); pw.print(" mScreenOn: "); pw.println(mScreenOn); pw.print(" mDockIdle: "); pw.println(mDockIdle); + pw.print(" mInCarMode: "); + pw.println(mInCarMode); } @Override @@ -116,6 +128,9 @@ public final class DeviceIdlenessTracker extends BroadcastReceiver implements Id proto.write( StateControllerProto.IdleController.IdlenessTracker.DeviceIdlenessTracker.IS_DOCK_IDLE, mDockIdle); + proto.write( + StateControllerProto.IdleController.IdlenessTracker.DeviceIdlenessTracker.IN_CAR_MODE, + mInCarMode); proto.end(diToken); proto.end(token); @@ -124,63 +139,90 @@ public final class DeviceIdlenessTracker extends BroadcastReceiver implements Id @Override public void onReceive(Context context, Intent intent) { final String action = intent.getAction(); - if (action.equals(Intent.ACTION_SCREEN_ON) - || action.equals(Intent.ACTION_DREAMING_STOPPED) - || action.equals(Intent.ACTION_DOCK_ACTIVE)) { - if (action.equals(Intent.ACTION_DOCK_ACTIVE)) { + if (DEBUG) { + Slog.v(TAG, "Received action: " + action); + } + switch (action) { + case Intent.ACTION_DOCK_ACTIVE: if (!mScreenOn) { // Ignore this intent during screen off return; - } else { - mDockIdle = false; } - } else { + // Intentional fallthrough + case Intent.ACTION_DREAMING_STOPPED: + if (!mPowerManager.isInteractive()) { + // Ignore this intent if the device isn't interactive. + return; + } + // Intentional fallthrough + case Intent.ACTION_SCREEN_ON: mScreenOn = true; mDockIdle = false; - } - if (DEBUG) { - Slog.v(TAG,"exiting idle : " + action); - } - //cancel the alarm - mAlarm.cancel(mIdleAlarmListener); - if (mIdle) { - // possible transition to not-idle - mIdle = false; - mIdleListener.reportNewIdleState(mIdle); - } - } else if (action.equals(Intent.ACTION_SCREEN_OFF) - || action.equals(Intent.ACTION_DREAMING_STARTED) - || action.equals(Intent.ACTION_DOCK_IDLE)) { - // when the screen goes off or dreaming starts or wireless charging dock in idle, - // we schedule the alarm that will tell us when we have decided the device is - // truly idle. - if (action.equals(Intent.ACTION_DOCK_IDLE)) { - if (!mScreenOn) { - // Ignore this intent during screen off - return; + if (DEBUG) { + Slog.v(TAG, "exiting idle"); + } + cancelIdlenessCheck(); + if (mIdle) { + mIdle = false; + mIdleListener.reportNewIdleState(mIdle); + } + break; + case Intent.ACTION_SCREEN_OFF: + case Intent.ACTION_DREAMING_STARTED: + case Intent.ACTION_DOCK_IDLE: + // when the screen goes off or dreaming starts or wireless charging dock in idle, + // we schedule the alarm that will tell us when we have decided the device is + // truly idle. + if (action.equals(Intent.ACTION_DOCK_IDLE)) { + if (!mScreenOn) { + // Ignore this intent during screen off + return; + } else { + mDockIdle = true; + } } else { - mDockIdle = true; + mScreenOn = false; + mDockIdle = false; } - } else { - mScreenOn = false; - mDockIdle = false; - } + maybeScheduleIdlenessCheck(action); + break; + case UiModeManager.ACTION_ENTER_CAR_MODE_PRIORITIZED: + mInCarMode = true; + cancelIdlenessCheck(); + if (mIdle) { + mIdle = false; + mIdleListener.reportNewIdleState(mIdle); + } + break; + case UiModeManager.ACTION_EXIT_CAR_MODE_PRIORITIZED: + mInCarMode = false; + maybeScheduleIdlenessCheck(action); + break; + case ActivityManagerService.ACTION_TRIGGER_IDLE: + handleIdleTrigger(); + break; + } + } + + private void maybeScheduleIdlenessCheck(String reason) { + if ((!mScreenOn || mDockIdle) && !mInCarMode) { final long nowElapsed = sElapsedRealtimeClock.millis(); final long when = nowElapsed + mInactivityIdleThreshold; if (DEBUG) { - Slog.v(TAG, "Scheduling idle : " + action + " now:" + nowElapsed + " when=" - + when); + Slog.v(TAG, "Scheduling idle : " + reason + " now:" + nowElapsed + " when=" + when); } mAlarm.setWindow(AlarmManager.ELAPSED_REALTIME_WAKEUP, when, mIdleWindowSlop, "JS idleness", mIdleAlarmListener, null); - } else if (action.equals(ActivityManagerService.ACTION_TRIGGER_IDLE)) { - handleIdleTrigger(); } } + private void cancelIdlenessCheck() { + mAlarm.cancel(mIdleAlarmListener); + } + private void handleIdleTrigger() { // idle time starts now. Do not set mIdle if screen is on. - if (!mIdle && (!mScreenOn || mDockIdle)) { + if (!mIdle && (!mScreenOn || mDockIdle) && !mInCarMode) { if (DEBUG) { Slog.v(TAG, "Idle trigger fired @ " + sElapsedRealtimeClock.millis()); } @@ -189,7 +231,7 @@ public final class DeviceIdlenessTracker extends BroadcastReceiver implements Id } else { if (DEBUG) { Slog.v(TAG, "TRIGGER_IDLE received but not changing state; idle=" - + mIdle + " screen=" + mScreenOn); + + mIdle + " screen=" + mScreenOn + " car=" + mInCarMode); } } } diff --git a/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java index 1ab79380fb0d..3c1fafbc1495 100644 --- a/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java +++ b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java @@ -172,8 +172,7 @@ public class AppStandbyController implements AppStandbyInternal { COMPRESS_TIME ? 1 * ONE_MINUTE : 12 * ONE_HOUR, COMPRESS_TIME ? 4 * ONE_MINUTE : 24 * ONE_HOUR, COMPRESS_TIME ? 16 * ONE_MINUTE : 48 * ONE_HOUR, - // TODO(149050681): increase timeout to 30+ days - COMPRESS_TIME ? 32 * ONE_MINUTE : 4 * ONE_DAY + COMPRESS_TIME ? 32 * ONE_MINUTE : 30 * ONE_DAY }; /** The minimum allowed values for each index in {@link #ELAPSED_TIME_THRESHOLDS}. */ diff --git a/apex/media/framework/java/android/media/MediaParser.java b/apex/media/framework/java/android/media/MediaParser.java index e533b7a7d6f3..073fddf8f615 100644 --- a/apex/media/framework/java/android/media/MediaParser.java +++ b/apex/media/framework/java/android/media/MediaParser.java @@ -51,6 +51,7 @@ import com.google.android.exoplayer2.extractor.ts.DefaultTsPayloadReaderFactory; import com.google.android.exoplayer2.extractor.ts.PsExtractor; import com.google.android.exoplayer2.extractor.ts.TsExtractor; import com.google.android.exoplayer2.extractor.wav.WavExtractor; +import com.google.android.exoplayer2.upstream.DataReader; import com.google.android.exoplayer2.upstream.DataSource; import com.google.android.exoplayer2.upstream.DataSpec; import com.google.android.exoplayer2.upstream.TransferListener; @@ -60,7 +61,6 @@ import com.google.android.exoplayer2.video.ColorInfo; import java.io.EOFException; import java.io.IOException; -import java.io.InterruptedIOException; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.nio.ByteBuffer; @@ -848,9 +848,9 @@ public final class MediaParser { private final String[] mParserNamesPool; private final PositionHolder mPositionHolder; private final InputReadingDataSource mDataSource; - private final ExtractorInputAdapter mScratchExtractorInputAdapter; + private final DataReaderAdapter mScratchDataReaderAdapter; private final ParsableByteArrayAdapter mScratchParsableByteArrayAdapter; - private String mExtractorName; + private String mParserName; private Extractor mExtractor; private ExtractorInput mExtractorInput; private long mPendingSeekPosition; @@ -924,7 +924,7 @@ public final class MediaParser { @NonNull @ParserName public String getParserName() { - return mExtractorName; + return mParserName; } /** @@ -958,25 +958,21 @@ public final class MediaParser { // TODO: Apply parameters when creating extractor instances. if (mExtractor == null) { - if (!mExtractorName.equals(PARSER_NAME_UNKNOWN)) { - mExtractor = EXTRACTOR_FACTORIES_BY_NAME.get(mExtractorName).createInstance(); + if (!mParserName.equals(PARSER_NAME_UNKNOWN)) { + mExtractor = createExtractor(mParserName); mExtractor.init(new ExtractorOutputAdapter()); } else { for (String parserName : mParserNamesPool) { Extractor extractor = createExtractor(parserName); try { if (extractor.sniff(mExtractorInput)) { - mExtractorName = parserName; + mParserName = parserName; mExtractor = extractor; mExtractor.init(new ExtractorOutputAdapter()); break; } } catch (EOFException e) { // Do nothing. - } catch (InterruptedException e) { - // TODO: Remove this exception replacement once we update the ExoPlayer - // version. - throw new InterruptedIOException(); } finally { mExtractorInput.resetPeekPosition(); } @@ -999,9 +995,6 @@ public final class MediaParser { result = mExtractor.read(mExtractorInput, mPositionHolder); } catch (ParserException e) { throw new ParsingException(e); - } catch (InterruptedException e) { - // TODO: Remove this exception replacement once we update the ExoPlayer version. - throw new InterruptedIOException(); } if (result == Extractor.RESULT_END_OF_INPUT) { return false; @@ -1051,11 +1044,11 @@ public final class MediaParser { mParserParameters = new HashMap<>(); mOutputConsumer = outputConsumer; mParserNamesPool = parserNamesPool; - mExtractorName = sniff ? PARSER_NAME_UNKNOWN : parserNamesPool[0]; + mParserName = sniff ? PARSER_NAME_UNKNOWN : parserNamesPool[0]; mPositionHolder = new PositionHolder(); mDataSource = new InputReadingDataSource(); removePendingSeek(); - mScratchExtractorInputAdapter = new ExtractorInputAdapter(); + mScratchDataReaderAdapter = new DataReaderAdapter(); mScratchParsableByteArrayAdapter = new ParsableByteArrayAdapter(); } @@ -1097,7 +1090,7 @@ public final class MediaParser { getBooleanParameter(PARAMETER_MP4_IGNORE_EDIT_LISTS) ? Mp4Extractor.FLAG_WORKAROUND_IGNORE_EDIT_LISTS : 0; - return new Mp4Extractor(); + return new Mp4Extractor(flags); case PARSER_NAME_MP3: flags |= getBooleanParameter(PARAMETER_MP3_DISABLE_ID3) @@ -1270,12 +1263,12 @@ public final class MediaParser { } @Override - public int sampleData(ExtractorInput input, int length, boolean allowEndOfInput) + public int sampleData(DataReader input, int length, boolean allowEndOfInput) throws IOException { - mScratchExtractorInputAdapter.setExtractorInput(input, length); - long positionBeforeReading = mScratchExtractorInputAdapter.getPosition(); - mOutputConsumer.onSampleDataFound(mTrackIndex, mScratchExtractorInputAdapter); - return (int) (mScratchExtractorInputAdapter.getPosition() - positionBeforeReading); + mScratchDataReaderAdapter.setDataReader(input, length); + long positionBeforeReading = mScratchDataReaderAdapter.getPosition(); + mOutputConsumer.onSampleDataFound(mTrackIndex, mScratchDataReaderAdapter); + return (int) (mScratchDataReaderAdapter.getPosition() - positionBeforeReading); } @Override @@ -1297,14 +1290,14 @@ public final class MediaParser { } } - private static final class ExtractorInputAdapter implements InputReader { + private static final class DataReaderAdapter implements InputReader { - private ExtractorInput mExtractorInput; + private DataReader mDataReader; private int mCurrentPosition; private long mLength; - public void setExtractorInput(ExtractorInput extractorInput, long length) { - mExtractorInput = extractorInput; + public void setDataReader(DataReader dataReader, long length) { + mDataReader = dataReader; mCurrentPosition = 0; mLength = length; } @@ -1314,12 +1307,7 @@ public final class MediaParser { @Override public int read(byte[] buffer, int offset, int readLength) throws IOException { int readBytes = 0; - try { - readBytes = mExtractorInput.read(buffer, offset, readLength); - } catch (InterruptedException e) { - // TODO: Remove this exception replacement once we update the ExoPlayer version. - throw new InterruptedIOException(); - } + readBytes = mDataReader.read(buffer, offset, readLength); mCurrentPosition += readBytes; return readBytes; } diff --git a/apex/statsd/service/java/com/android/server/stats/StatsCompanionService.java b/apex/statsd/service/java/com/android/server/stats/StatsCompanionService.java index ce5309e4df52..93e6c108a289 100644 --- a/apex/statsd/service/java/com/android/server/stats/StatsCompanionService.java +++ b/apex/statsd/service/java/com/android/server/stats/StatsCompanionService.java @@ -166,13 +166,6 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { } private static void informAllUids(Context context) { - UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE); - PackageManager pm = context.getPackageManager(); - final List<UserHandle> users = um.getUserHandles(true); - if (DEBUG) { - Log.d(TAG, "Iterating over " + users.size() + " userHandles."); - } - ParcelFileDescriptor[] fds; try { fds = ParcelFileDescriptor.createPipe(); @@ -185,6 +178,12 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { backgroundThread.start(); Handler handler = new Handler(backgroundThread.getLooper()); handler.post(() -> { + UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE); + PackageManager pm = context.getPackageManager(); + final List<UserHandle> users = um.getUserHandles(true); + if (DEBUG) { + Log.d(TAG, "Iterating over " + users.size() + " userHandles."); + } IStatsd statsd = getStatsdNonblocking(); if (statsd == null) { return; @@ -699,8 +698,6 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { deathRecipient.addRegisteredBroadcastReceivers( List.of(appUpdateReceiver, userUpdateReceiver, shutdownEventReceiver)); - final long token = Binder.clearCallingIdentity(); - // Used so we can call statsd.bootComplete() outside of the lock. boolean shouldSendBootComplete = false; synchronized (sStatsdLock) { @@ -713,13 +710,10 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { statsd.bootCompleted(); } - try { - // Pull the latest state of UID->app name, version mapping when - // statsd starts. - informAllUids(mContext); - } finally { - Binder.restoreCallingIdentity(token); - } + // Pull the latest state of UID->app name, version mapping when + // statsd starts. + informAllUids(mContext); + Log.i(TAG, "Told statsd that StatsCompanionService is alive."); } catch (RemoteException e) { Log.e(TAG, "Failed to inform statsd that statscompanion is ready", e); diff --git a/cmds/statsd/Android.bp b/cmds/statsd/Android.bp index b3579045b6a5..6e8ceb7cb367 100644 --- a/cmds/statsd/Android.bp +++ b/cmds/statsd/Android.bp @@ -104,6 +104,7 @@ cc_defaults { "src/subscriber/IncidentdReporter.cpp", "src/subscriber/SubscriberReporter.cpp", "src/uid_data.proto", + "src/utils/NamedLatch.cpp", ], local_include_dirs: [ @@ -361,6 +362,7 @@ cc_test { "tests/StatsService_test.cpp", "tests/storage/StorageManager_test.cpp", "tests/UidMap_test.cpp", + "tests/utils/NamedLatch_test.cpp", ], static_libs: [ diff --git a/cmds/statsd/src/StatsService.cpp b/cmds/statsd/src/StatsService.cpp index dd1d40083a6b..ae7a8d0d30cc 100644 --- a/cmds/statsd/src/StatsService.cpp +++ b/cmds/statsd/src/StatsService.cpp @@ -118,8 +118,9 @@ StatsService::StatsService(const sp<Looper>& handlerLooper, shared_ptr<LogEventQ } })), mEventQueue(queue), - mStatsCompanionServiceDeathRecipient(AIBinder_DeathRecipient_new( - StatsService::statsCompanionServiceDied)) { + mBootCompleteLatch({kBootCompleteTag, kUidMapReceivedTag, kAllPullersRegisteredTag}), + mStatsCompanionServiceDeathRecipient( + AIBinder_DeathRecipient_new(StatsService::statsCompanionServiceDied)) { mUidMap = UidMap::getInstance(); mPullerManager = new StatsPullerManager(); StatsPuller::SetUidMap(mUidMap); @@ -164,6 +165,12 @@ StatsService::StatsService(const sp<Looper>& handlerLooper, shared_ptr<LogEventQ std::thread pushedEventThread([this] { readLogs(); }); pushedEventThread.detach(); } + + std::thread bootCompletedThread([this] { + mBootCompleteLatch.wait(); + VLOG("In the boot completed thread"); + }); + bootCompletedThread.detach(); } StatsService::~StatsService() { @@ -939,6 +946,7 @@ Status StatsService::informAllUidData(const ScopedFileDescriptor& fd) { packageNames, installers); + mBootCompleteLatch.countDown(kUidMapReceivedTag); VLOG("StatsService::informAllUidData UidData proto parsed successfully."); return Status::ok(); } @@ -1058,7 +1066,7 @@ Status StatsService::bootCompleted() { ENFORCE_UID(AID_SYSTEM); VLOG("StatsService::bootCompleted was called"); - + mBootCompleteLatch.countDown(kBootCompleteTag); return Status::ok(); } @@ -1227,7 +1235,7 @@ Status StatsService::allPullersFromBootRegistered() { ENFORCE_UID(AID_SYSTEM); VLOG("StatsService::allPullersFromBootRegistered was called"); - + mBootCompleteLatch.countDown(kAllPullersRegisteredTag); return Status::ok(); } diff --git a/cmds/statsd/src/StatsService.h b/cmds/statsd/src/StatsService.h index 23d4c1bd199d..79324d89d8e8 100644 --- a/cmds/statsd/src/StatsService.h +++ b/cmds/statsd/src/StatsService.h @@ -17,7 +17,14 @@ #ifndef STATS_SERVICE_H #define STATS_SERVICE_H +#include <aidl/android/os/BnStatsd.h> +#include <aidl/android/os/IPendingIntentRef.h> +#include <aidl/android/os/IPullAtomCallback.h> #include <gtest/gtest_prod.h> +#include <utils/Looper.h> + +#include <mutex> + #include "StatsLogProcessor.h" #include "anomaly/AlarmMonitor.h" #include "config/ConfigManager.h" @@ -26,13 +33,7 @@ #include "packages/UidMap.h" #include "shell/ShellSubscriber.h" #include "statscompanion_util.h" - -#include <aidl/android/os/BnStatsd.h> -#include <aidl/android/os/IPendingIntentRef.h> -#include <aidl/android/os/IPullAtomCallback.h> -#include <utils/Looper.h> - -#include <mutex> +#include "utils/NamedLatch.h" using namespace android; using namespace android::os; @@ -385,6 +386,11 @@ private: mutable mutex mShellSubscriberMutex; std::shared_ptr<LogEventQueue> mEventQueue; + NamedLatch mBootCompleteLatch; + static const inline string kBootCompleteTag = "BOOT_COMPLETE"; + static const inline string kUidMapReceivedTag = "UID_MAP"; + static const inline string kAllPullersRegisteredTag = "PULLERS_REGISTERED"; + ScopedAIBinder_DeathRecipient mStatsCompanionServiceDeathRecipient; FRIEND_TEST(StatsLogProcessorTest, TestActivationsPersistAcrossSystemServerRestart); diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto index 453ddeb332af..b7ed6eb16013 100644 --- a/cmds/statsd/src/atoms.proto +++ b/cmds/statsd/src/atoms.proto @@ -421,6 +421,8 @@ message Atom { TvSettingsUIInteracted tvsettings_ui_interacted = 261 [(module) = "tv_settings"]; LauncherStaticLayout launcher_snapshot = 262 [(module) = "sysui"]; PackageInstallerV2Reported package_installer_v2_reported = 263 [(module) = "framework"]; + UserLifecycleJourneyReported user_lifecycle_journey_reported = 264 [(module) = "framework"]; + UserLifecycleEventOccurred user_lifecycle_event_occurred = 265 [(module) = "framework"]; SdkExtensionStatus sdk_extension_status = 354; } @@ -9249,12 +9251,13 @@ message SharesheetStarted { optional bool is_workprofile = 7; enum SharesheetPreviewType { // Constants from ChooserActivity.java + CONTENT_PREVIEW_TYPE_UNKNOWN = 0; // Default for proto 2 / 3 compatibility. CONTENT_PREVIEW_IMAGE = 1; // The preview shown in the sharesheet is an image. CONTENT_PREVIEW_FILE = 2; // The preview shown in the sharesheet is a file. CONTENT_PREVIEW_TEXT = 3; // The preview shown in the sharesheet is text. } // How the sharesheet preview is presented. - optional SharesheetPreviewType previewType = 8; + optional SharesheetPreviewType preview_type = 8; enum ResolverActivityIntent { // Intents handled by ResolverActivity.java INTENT_DEFAULT = 0; @@ -9267,7 +9270,7 @@ message SharesheetStarted { INTENT_ACTION_MAIN = 7; } // The intent being processed (only SEND and SEND_MULTIPLE are system sharesheet) - optional ResolverActivityIntent intentType = 9; + optional ResolverActivityIntent intent_type = 9; } /** @@ -9356,3 +9359,82 @@ message SettingSnapshot { // Android user index. 0 for primary user, 10, 11 for secondary or profile user optional int32 user_id = 7; } + +/** + * An event logged to indicate that a user journey is about to be performed. This atom includes + * relevant information about the users involved in the journey. A UserLifecycleEventOccurred event + * will immediately follow this atom which will describe the event(s) and its state. + * + * Logged from: + * frameworks/base/services/core/java/com/android/server/am/UserController.java + * frameworks/base/services/core/java/com/android/server/pm/UserManagerService.java + */ +message UserLifecycleJourneyReported { + // An identifier to track a chain of user lifecycle events occurring (referenced in the + // UserLifecycleEventOccurred atom) + optional int64 session_id = 1; + + // Indicates what type of user journey this session is related to + enum Journey { + UNKNOWN = 0; // Undefined user lifecycle journey + USER_SWITCH_UI = 1; // A user switch journey where a UI is shown + USER_SWITCH_FG = 2; // A user switch journey without a UI shown + USER_START = 3; // A user start journey + USER_CREATE = 4; // A user creation journey + } + optional Journey journey = 2; + // Which user the journey is originating from - could be -1 for certain phases (eg USER_CREATE) + // This integer is a UserIdInt (eg 0 for the system user, 10 for secondary/guest) + optional int32 origin_user = 3; + // Which user the journey is targeting + // This integer is a UserIdInt (eg 0 for the system user, 10 for secondary/guest) + optional int32 target_user = 4; + + // What is the user type of the target user + // These should be in sync with USER_TYPE_* flags defined in UserManager.java + enum UserType { + TYPE_UNKNOWN = 0; + FULL_SYSTEM = 1; + FULL_SECONDARY = 2; + FULL_GUEST = 3; + FULL_DEMO = 4; + FULL_RESTRICTED = 5; + PROFILE_MANAGED = 6; + SYSTEM_HEADLESS = 7; + } + optional UserType user_type = 5; + // What are the flags attached to the target user + optional int32 user_flags = 6; +} + +/** + * An event logged when a specific user lifecycle event is performed. These events should be + * correlated with a UserLifecycleJourneyReported atom via the session_id. + * Note: journeys can span over multiple events, hence some events may share a single session id. + * + * Logged from: + * frameworks/base/services/core/java/com/android/server/am/UserController.java + * frameworks/base/services/core/java/com/android/server/pm/UserManagerService.java + */ +message UserLifecycleEventOccurred { + // An id which links back to user details (reported in the UserLifecycleJourneyReported atom) + optional int64 session_id = 1; + // The target user for this event (same as target_user in the UserLifecycleJourneyReported atom) + // This integer is a UserIdInt (eg 0 for the system user, 10 for secondary/guest) + optional int32 user_id = 2; + + enum Event { + UNKNOWN = 0; // Indicates that the associated user journey timed-out or resulted in an error + SWITCH_USER = 1; // Indicates that this is a user switch event + START_USER = 2; // Indicates that this is a user start event + CREATE_USER = 3; // Indicates that this is a user create event + } + optional Event event = 3; + + enum State { + NONE = 0; // Indicates the associated event has no start/end defined + BEGIN = 1; + FINISH = 2; + } + optional State state = 4; // Represents the state of an event (beginning/ending) +} diff --git a/cmds/statsd/src/utils/NamedLatch.cpp b/cmds/statsd/src/utils/NamedLatch.cpp new file mode 100644 index 000000000000..6e77977857cc --- /dev/null +++ b/cmds/statsd/src/utils/NamedLatch.cpp @@ -0,0 +1,48 @@ +/* + * 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. + */ +#define DEBUG false // STOPSHIP if true + +#include "NamedLatch.h" + +using namespace std; + +namespace android { +namespace os { +namespace statsd { + +NamedLatch::NamedLatch(const set<string>& eventNames) : mRemainingEventNames(eventNames) { +} + +void NamedLatch::countDown(const string& eventName) { + bool notify = false; + { + lock_guard<mutex> lg(mMutex); + mRemainingEventNames.erase(eventName); + notify = mRemainingEventNames.empty(); + } + if (notify) { + mConditionVariable.notify_all(); + } +} + +void NamedLatch::wait() const { + unique_lock<mutex> unique_lk(mMutex); + mConditionVariable.wait(unique_lk, [this] { return mRemainingEventNames.empty(); }); +} + +} // namespace statsd +} // namespace os +} // namespace android diff --git a/cmds/statsd/src/utils/NamedLatch.h b/cmds/statsd/src/utils/NamedLatch.h new file mode 100644 index 000000000000..70238370f647 --- /dev/null +++ b/cmds/statsd/src/utils/NamedLatch.h @@ -0,0 +1,58 @@ +/* + * 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. + */ +#pragma once + +#include <gtest/gtest_prod.h> + +#include <condition_variable> +#include <mutex> +#include <set> + +namespace android { +namespace os { +namespace statsd { + +/** + * This class provides a threading primitive similar to a latch. + * The primary difference is that it waits for named events to occur instead of waiting for + * N threads to reach a certain point. + * + * It uses a condition variable under the hood. + */ +class NamedLatch { +public: + explicit NamedLatch(const std::set<std::string>& eventNames); + + NamedLatch(const NamedLatch&) = delete; + NamedLatch& operator=(const NamedLatch&) = delete; + + // Mark a specific event as completed. If this event has called countDown already or if the + // event was not specified in the constructor, the function is a no-op. + void countDown(const std::string& eventName); + + // Blocks the calling thread until all events in eventNames have called countDown. + void wait() const; + +private: + mutable std::mutex mMutex; + mutable std::condition_variable mConditionVariable; + std::set<std::string> mRemainingEventNames; + + FRIEND_TEST(NamedLatchTest, TestCountDownCalledBySameEventName); +}; +} // namespace statsd +} // namespace os +} // namespace android diff --git a/cmds/statsd/tests/utils/NamedLatch_test.cpp b/cmds/statsd/tests/utils/NamedLatch_test.cpp new file mode 100644 index 000000000000..de48a133823e --- /dev/null +++ b/cmds/statsd/tests/utils/NamedLatch_test.cpp @@ -0,0 +1,96 @@ +/* + * 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 "utils/NamedLatch.h" + +#include <gtest/gtest.h> + +#include <chrono> +#include <set> +#include <thread> +#include <vector> + +#ifdef __ANDROID__ + +using namespace std; +using std::this_thread::sleep_for; + +namespace android { +namespace os { +namespace statsd { + +TEST(NamedLatchTest, TestWait) { + int numEvents = 5; + string t1 = "t1", t2 = "t2", t3 = "t3", t4 = "t4", t5 = "t5"; + set<string> eventNames = {t1, t2, t3, t4, t5}; + + NamedLatch latch(eventNames); + vector<thread> threads; + vector<bool> done(numEvents, false); + + int i = 0; + for (const string& eventName : eventNames) { + threads.emplace_back([&done, &eventName, &latch, i] { + sleep_for(chrono::milliseconds(3)); + done[i] = true; + latch.countDown(eventName); + }); + i++; + } + + latch.wait(); + + for (i = 0; i < numEvents; i++) { + EXPECT_EQ(done[i], 1); + } + + for (i = 0; i < numEvents; i++) { + threads[i].join(); + } +} + +TEST(NamedLatchTest, TestNoWorkers) { + NamedLatch latch({}); + latch.wait(); + // Ensure that latch does not wait if no events need to countDown. +} + +TEST(NamedLatchTest, TestCountDownCalledBySameEventName) { + string t1 = "t1", t2 = "t2"; + set<string> eventNames = {t1, t2}; + + NamedLatch latch(eventNames); + + thread waiterThread([&latch] { latch.wait(); }); + + latch.countDown(t1); + latch.countDown(t1); + + // Ensure that the latch's remaining threads still has t2. + latch.mMutex.lock(); + ASSERT_EQ(latch.mRemainingEventNames.size(), 1); + EXPECT_NE(latch.mRemainingEventNames.find(t2), latch.mRemainingEventNames.end()); + latch.mMutex.unlock(); + + latch.countDown(t2); + waiterThread.join(); +} + +} // namespace statsd +} // namespace os +} // namespace android +#else +GTEST_LOG_(INFO) << "This test does nothing.\n"; +#endif diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java index 3a708a6f699b..8e0d939487e3 100644 --- a/core/java/android/app/AppOpsManager.java +++ b/core/java/android/app/AppOpsManager.java @@ -2586,6 +2586,44 @@ public class AppOpsManager { } /** + * Returns a listenerId suitable for use with {@link #noteOp(int, int, String, String, String)}. + * + * This is intended for use client side, when the receiver id must be created before the + * associated call is made to the system server. If using {@link PendingIntent} as the receiver, + * avoid using this method as it will include a pointless additional x-process call. Instead to + * prefer passing the PendingIntent to the system server, and then invoking + * {@link #toReceiverId(PendingIntent)} instead. + * + * @param obj the receiver in use + * @return a string representation of the receiver suitable for app ops use + * @hide + */ + // TODO: this should probably be @SystemApi as well + public static @NonNull String toReceiverId(@NonNull Object obj) { + if (obj instanceof PendingIntent) { + return toReceiverId((PendingIntent) obj); + } else { + return obj.getClass().getName() + "@" + System.identityHashCode(obj); + } + } + + /** + * Returns a listenerId suitable for use with {@link #noteOp(int, int, String, String, String)}. + * + * This is intended for use server side, where ActivityManagerService can be referenced without + * an additional x-process call. + * + * @param pendingIntent the pendingIntent in use + * @return a string representation of the pending intent suitable for app ops use + * @see #toReceiverId(Object) + * @hide + */ + // TODO: this should probably be @SystemApi as well + public static @NonNull String toReceiverId(@NonNull PendingIntent pendingIntent) { + return pendingIntent.getTag(""); + } + + /** * When to not enforce {@link #setUserRestriction restrictions}. * * @hide diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl index 78d3581a7012..9d0364eba39f 100644 --- a/core/java/android/app/INotificationManager.aidl +++ b/core/java/android/app/INotificationManager.aidl @@ -78,10 +78,9 @@ interface INotificationManager boolean shouldHideSilentStatusIcons(String callingPkg); void setHideSilentStatusIcons(boolean hide); - void setBubblesAllowed(String pkg, int uid, boolean allowed); + void setBubblesAllowed(String pkg, int uid, int bubblePreference); boolean areBubblesAllowed(String pkg); - boolean areBubblesAllowedForPackage(String pkg, int uid); - boolean hasUserApprovedBubblesForPackage(String pkg, int uid); + int getBubblePreferenceForPackage(String pkg, int uid); void createNotificationChannelGroups(String pkg, in ParceledListSlice channelGroupList); void createNotificationChannels(String pkg, in ParceledListSlice channelsList); diff --git a/core/java/android/app/NotificationChannel.java b/core/java/android/app/NotificationChannel.java index d1d67f0d81d8..2feb9277775c 100644 --- a/core/java/android/app/NotificationChannel.java +++ b/core/java/android/app/NotificationChannel.java @@ -102,7 +102,7 @@ public final class NotificationChannel implements Parcelable { private static final String ATT_FG_SERVICE_SHOWN = "fgservice"; private static final String ATT_GROUP = "group"; private static final String ATT_BLOCKABLE_SYSTEM = "blockable_system"; - private static final String ATT_ALLOW_BUBBLE = "can_bubble"; + private static final String ATT_ALLOW_BUBBLE = "allow_bubble"; private static final String ATT_ORIG_IMP = "orig_imp"; private static final String ATT_PARENT_CHANNEL = "parent"; private static final String ATT_CONVERSATION_ID = "conv_id"; @@ -168,7 +168,7 @@ public final class NotificationChannel implements Parcelable { NotificationManager.IMPORTANCE_UNSPECIFIED; private static final boolean DEFAULT_DELETED = false; private static final boolean DEFAULT_SHOW_BADGE = true; - private static final boolean DEFAULT_ALLOW_BUBBLE = true; + private static final boolean DEFAULT_ALLOW_BUBBLE = false; @UnsupportedAppUsage private String mId; @@ -545,15 +545,8 @@ public final class NotificationChannel implements Parcelable { } /** - * Sets whether notifications posted to this channel can appear outside of the notification - * shade, floating over other apps' content as a bubble. - * - * <p>This value will be ignored for channels that aren't allowed to pop on screen (that is, - * channels whose {@link #getImportance() importance} is < - * {@link NotificationManager#IMPORTANCE_HIGH}.</p> - * - * <p>Only modifiable before the channel is submitted to - * * {@link NotificationManager#createNotificationChannel(NotificationChannel)}.</p> + * As of Android 11 this value is no longer respected. + * @see #canBubble() * @see Notification#getBubbleMetadata() */ public void setAllowBubbles(boolean allowBubbles) { @@ -702,8 +695,10 @@ public final class NotificationChannel implements Parcelable { } /** - * Returns whether notifications posted to this channel can display outside of the notification - * shade, in a floating window on top of other apps. + * Returns whether notifications posted to this channel are allowed to display outside of the + * notification shade, in a floating window on top of other apps. + * + * @see Notification#getBubbleMetadata() */ public boolean canBubble() { return mAllowBubbles; diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java index 0e97e3fe06ce..d6df400f86b6 100644 --- a/core/java/android/app/NotificationManager.java +++ b/core/java/android/app/NotificationManager.java @@ -452,6 +452,19 @@ public class NotificationManager { */ public static final int IMPORTANCE_MAX = 5; + /** + * @hide + */ + public static final int BUBBLE_PREFERENCE_NONE = 0; + /** + * @hide + */ + public static final int BUBBLE_PREFERENCE_ALL = 1; + /** + * @hide + */ + public static final int BUBBLE_PREFERENCE_SELECTED = 2; + @UnsupportedAppUsage private static INotificationManager sService; @@ -1213,7 +1226,7 @@ public class NotificationManager { /** - * Sets whether notifications posted by this app can appear outside of the + * Gets whether all notifications posted by this app can appear outside of the * notification shade, floating over other apps' content. * * <p>This value will be ignored for notifications that are posted to channels that do not diff --git a/core/java/android/app/TEST_MAPPING b/core/java/android/app/TEST_MAPPING index ab868604dfde..344a4d79b766 100644 --- a/core/java/android/app/TEST_MAPPING +++ b/core/java/android/app/TEST_MAPPING @@ -20,6 +20,10 @@ }, { "file_patterns": ["(/|^)AppOpsManager.java"], + "name": "UidAtomTests:testAppOps" + }, + { + "file_patterns": ["(/|^)AppOpsManager.java"], "name": "FrameworksServicesTests", "options": [ { diff --git a/core/java/android/app/WindowTokenClient.java b/core/java/android/app/WindowTokenClient.java index 301960ec53f9..b5d103959818 100644 --- a/core/java/android/app/WindowTokenClient.java +++ b/core/java/android/app/WindowTokenClient.java @@ -67,13 +67,11 @@ public class WindowTokenClient extends IWindowToken.Stub { } final int currentDisplayId = context.getDisplayId(); final boolean displayChanged = newDisplayId != currentDisplayId; - final Configuration config = new Configuration(context.getResources() - .getConfiguration()); - final boolean configChanged = config.isOtherSeqNewer(newConfig) - && config.updateFrom(newConfig) != 0; + final Configuration config = context.getResources().getConfiguration(); + final boolean configChanged = config.diff(newConfig) != 0; if (displayChanged || configChanged) { // TODO(ag/9789103): update resource manager logic to track non-activity tokens - mResourcesManager.updateResourcesForActivity(this, config, newDisplayId, + mResourcesManager.updateResourcesForActivity(this, newConfig, newDisplayId, displayChanged); } if (displayChanged) { diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index fb9adb730314..41e2dc0de4d6 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -3666,6 +3666,28 @@ public class DevicePolicyManager { } /** + * Returns whether the given user's credential will be sufficient for all password policy + * requirement, once the user's profile has switched to unified challenge. + * + * <p>This is different from {@link #isActivePasswordSufficient()} since once the profile + * switches to unified challenge, policies set explicitly on the profile will start to affect + * the parent user. + * @param userHandle the user whose password requirement will be checked + * @param profileUser the profile user whose lockscreen challenge will be unified. + * @hide + */ + public boolean isPasswordSufficientAfterProfileUnification(int userHandle, int profileUser) { + if (mService != null) { + try { + return mService.isPasswordSufficientAfterProfileUnification(userHandle, + profileUser); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + return false; + } + /** * Retrieve the number of times the user has failed at entering a password since that last * successful password entry. * <p> diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl index 591a3f68eed0..d10153c11723 100644 --- a/core/java/android/app/admin/IDevicePolicyManager.aidl +++ b/core/java/android/app/admin/IDevicePolicyManager.aidl @@ -85,6 +85,7 @@ interface IDevicePolicyManager { boolean isActivePasswordSufficient(int userHandle, boolean parent); boolean isProfileActivePasswordSufficientForParent(int userHandle); + boolean isPasswordSufficientAfterProfileUnification(int userHandle, int profileUser); int getPasswordComplexity(boolean parent); boolean isUsingUnifiedPassword(in ComponentName admin); int getCurrentFailedPasswordAttempts(int userHandle, boolean parent); diff --git a/core/java/android/app/admin/PasswordMetrics.java b/core/java/android/app/admin/PasswordMetrics.java index 86ebb47400c7..39e1f0dc2d2c 100644 --- a/core/java/android/app/admin/PasswordMetrics.java +++ b/core/java/android/app/admin/PasswordMetrics.java @@ -350,7 +350,7 @@ public final class PasswordMetrics implements Parcelable { * * TODO: move to PasswordPolicy */ - private void maxWith(PasswordMetrics other) { + public void maxWith(PasswordMetrics other) { credType = Math.max(credType, other.credType); if (credType != CREDENTIAL_TYPE_PASSWORD) { return; diff --git a/core/java/android/content/pm/IPackageInstaller.aidl b/core/java/android/content/pm/IPackageInstaller.aidl index b0b2c33e0ddd..37baae35734b 100644 --- a/core/java/android/content/pm/IPackageInstaller.aidl +++ b/core/java/android/content/pm/IPackageInstaller.aidl @@ -55,4 +55,6 @@ interface IPackageInstaller { in IntentSender statusReceiver, int userId, in List<String> whiteListedPermissions); void setPermissionsResult(int sessionId, boolean accepted); + + void bypassNextStagedInstallerCheck(boolean value); } diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index 9ca2db970eb7..d36d583559a0 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -3158,6 +3158,23 @@ public abstract class PackageManager { "android.content.pm.extra.VERIFICATION_LONG_VERSION_CODE"; /** + * Extra field name for the Merkle tree root hash of a package. + * <p>Passed to a package verifier both prior to verification and as a result + * of verification. + * <p>The value of the extra is a specially formatted list: + * {@code filename1:HASH_1;filename2:HASH_2;...;filenameN:HASH_N} + * <p>The extra must include an entry for every APK within an installation. If + * a hash is not physically present, a hash value of {@code 0} will be used. + * <p>The root hash is generated using SHA-256, no salt with a 4096 byte block + * size. See the description of the + * <a href="https://www.kernel.org/doc/html/latest/filesystems/fsverity.html#merkle-tree">fs-verity merkle-tree</a> + * for more details. + * @hide + */ + public static final String EXTRA_VERIFICATION_ROOT_HASH = + "android.content.pm.extra.EXTRA_VERIFICATION_ROOT_HASH"; + + /** * Extra field name for the ID of a intent filter pending verification. * Passed to an intent filter verifier and is used to call back to * {@link #verifyIntentFilter} diff --git a/core/java/android/hardware/display/DeviceProductInfo.java b/core/java/android/hardware/display/DeviceProductInfo.java index ed50d7cae8cc..94c5dd884eab 100644 --- a/core/java/android/hardware/display/DeviceProductInfo.java +++ b/core/java/android/hardware/display/DeviceProductInfo.java @@ -19,6 +19,7 @@ package android.hardware.display; import android.os.Parcel; import android.os.Parcelable; +import java.util.Arrays; import java.util.Objects; /** @@ -33,18 +34,21 @@ public final class DeviceProductInfo implements Parcelable { private final String mProductId; private final Integer mModelYear; private final ManufactureDate mManufactureDate; + private final int[] mRelativeAddress; public DeviceProductInfo( String name, String manufacturerPnpId, String productId, Integer modelYear, - ManufactureDate manufactureDate) { + ManufactureDate manufactureDate, + int[] relativeAddress) { this.mName = name; this.mManufacturerPnpId = manufacturerPnpId; this.mProductId = productId; this.mModelYear = modelYear; this.mManufactureDate = manufactureDate; + this.mRelativeAddress = relativeAddress; } private DeviceProductInfo(Parcel in) { @@ -53,6 +57,7 @@ public final class DeviceProductInfo implements Parcelable { mProductId = (String) in.readValue(null); mModelYear = (Integer) in.readValue(null); mManufactureDate = (ManufactureDate) in.readValue(null); + mRelativeAddress = in.createIntArray(); } /** @@ -92,6 +97,14 @@ public final class DeviceProductInfo implements Parcelable { return mManufactureDate; } + /** + * @return Relative address in the display network. For example, for HDMI connected devices this + * can be its physical address. Each component of the address is in the range [0, 255]. + */ + public int[] getRelativeAddress() { + return mRelativeAddress; + } + @Override public String toString() { return "DeviceProductInfo{" @@ -105,6 +118,8 @@ public final class DeviceProductInfo implements Parcelable { + mModelYear + ", manufactureDate=" + mManufactureDate + + ", relativeAddress=" + + Arrays.toString(mRelativeAddress) + '}'; } @@ -117,12 +132,14 @@ public final class DeviceProductInfo implements Parcelable { && Objects.equals(mManufacturerPnpId, that.mManufacturerPnpId) && Objects.equals(mProductId, that.mProductId) && Objects.equals(mModelYear, that.mModelYear) - && Objects.equals(mManufactureDate, that.mManufactureDate); + && Objects.equals(mManufactureDate, that.mManufactureDate) + && Arrays.equals(mRelativeAddress, that.mRelativeAddress); } @Override public int hashCode() { - return Objects.hash(mName, mManufacturerPnpId, mProductId, mModelYear, mManufactureDate); + return Objects.hash(mName, mManufacturerPnpId, mProductId, mModelYear, mManufactureDate, + mRelativeAddress); } public static final Creator<DeviceProductInfo> CREATOR = @@ -150,6 +167,7 @@ public final class DeviceProductInfo implements Parcelable { dest.writeValue(mProductId); dest.writeValue(mModelYear); dest.writeValue(mManufactureDate); + dest.writeIntArray(mRelativeAddress); } /** diff --git a/core/java/android/net/NetworkAgent.java b/core/java/android/net/NetworkAgent.java index 31d7d0820996..65e772cb5ebb 100644 --- a/core/java/android/net/NetworkAgent.java +++ b/core/java/android/net/NetworkAgent.java @@ -25,12 +25,14 @@ import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.os.Build; import android.os.Bundle; +import android.os.ConditionVariable; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.os.Messenger; import android.util.Log; +import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.AsyncChannel; import com.android.internal.util.Protocol; @@ -572,6 +574,37 @@ public abstract class NetworkAgent { } /** + * Register this network agent with a testing harness. + * + * The returned Messenger sends messages to the Handler. This allows a test to send + * this object {@code CMD_*} messages as if they came from ConnectivityService, which + * is useful for testing the behavior. + * + * @hide + */ + public Messenger registerForTest(final Network network) { + log("Registering NetworkAgent for test"); + synchronized (mRegisterLock) { + mNetwork = network; + mInitialConfiguration = null; + } + return new Messenger(mHandler); + } + + /** + * Waits for the handler to be idle. + * This is useful for testing, and has smaller scope than an accessor to mHandler. + * TODO : move the implementation in common library with the tests + * @hide + */ + @VisibleForTesting + public boolean waitForIdle(final long timeoutMs) { + final ConditionVariable cv = new ConditionVariable(false); + mHandler.post(cv::open); + return cv.block(timeoutMs); + } + + /** * @return The Network associated with this agent, or null if it's not registered yet. */ @Nullable diff --git a/core/java/android/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java index 73c6b3daf2ec..52d6fdfbd529 100644 --- a/core/java/android/net/NetworkCapabilities.java +++ b/core/java/android/net/NetworkCapabilities.java @@ -680,11 +680,13 @@ public final class NetworkCapabilities implements Parcelable { public void restrictCapabilitesForTestNetwork() { final long originalCapabilities = mNetworkCapabilities; final NetworkSpecifier originalSpecifier = mNetworkSpecifier; + final int originalSignalStrength = mSignalStrength; clearAll(); // Reset the transports to only contain TRANSPORT_TEST. mTransportTypes = (1 << TRANSPORT_TEST); mNetworkCapabilities = originalCapabilities & TEST_NETWORKS_ALLOWED_CAPABILITIES; mNetworkSpecifier = originalSpecifier; + mSignalStrength = originalSignalStrength; } /** diff --git a/core/java/android/net/UrlQuerySanitizer.java b/core/java/android/net/UrlQuerySanitizer.java index cf08b653d0f4..b1cf044e8173 100644 --- a/core/java/android/net/UrlQuerySanitizer.java +++ b/core/java/android/net/UrlQuerySanitizer.java @@ -306,7 +306,7 @@ public class UrlQuerySanitizer { return null; } int length = value.length(); - if ((mFlags & SCRIPT_URL_OK) != 0) { + if ((mFlags & SCRIPT_URL_OK) == 0) { if (length >= MIN_SCRIPT_PREFIX_LENGTH) { String asLower = value.toLowerCase(Locale.ROOT); if (asLower.startsWith(JAVASCRIPT_PREFIX) || diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java index 0f2060a36ac9..187274a837a0 100644 --- a/core/java/android/os/UserManager.java +++ b/core/java/android/os/UserManager.java @@ -57,6 +57,7 @@ import android.view.WindowManager.LayoutParams; import com.android.internal.R; import com.android.internal.os.RoSystemProperties; +import com.android.internal.util.FrameworkStatsLog; import java.io.IOException; import java.lang.annotation.Retention; @@ -1841,6 +1842,35 @@ public class UserManager { } /** + * Returns the enum defined in the statsd UserLifecycleJourneyReported atom corresponding to the + * user type. + * @hide + */ + public static int getUserTypeForStatsd(@NonNull String userType) { + switch (userType) { + case USER_TYPE_FULL_SYSTEM: + return FrameworkStatsLog.USER_LIFECYCLE_JOURNEY_REPORTED__USER_TYPE__FULL_SYSTEM; + case USER_TYPE_FULL_SECONDARY: + return FrameworkStatsLog.USER_LIFECYCLE_JOURNEY_REPORTED__USER_TYPE__FULL_SECONDARY; + case USER_TYPE_FULL_GUEST: + return FrameworkStatsLog.USER_LIFECYCLE_JOURNEY_REPORTED__USER_TYPE__FULL_GUEST; + case USER_TYPE_FULL_DEMO: + return FrameworkStatsLog.USER_LIFECYCLE_JOURNEY_REPORTED__USER_TYPE__FULL_DEMO; + case USER_TYPE_FULL_RESTRICTED: + return FrameworkStatsLog + .USER_LIFECYCLE_JOURNEY_REPORTED__USER_TYPE__FULL_RESTRICTED; + case USER_TYPE_PROFILE_MANAGED: + return FrameworkStatsLog + .USER_LIFECYCLE_JOURNEY_REPORTED__USER_TYPE__PROFILE_MANAGED; + case USER_TYPE_SYSTEM_HEADLESS: + return FrameworkStatsLog + .USER_LIFECYCLE_JOURNEY_REPORTED__USER_TYPE__SYSTEM_HEADLESS; + default: + return FrameworkStatsLog.USER_LIFECYCLE_JOURNEY_REPORTED__USER_TYPE__TYPE_UNKNOWN; + } + } + + /** * @hide * @deprecated Use {@link #isRestrictedProfile()} */ diff --git a/core/java/android/os/incremental/V4Signature.java b/core/java/android/os/incremental/V4Signature.java index 5cc73caa4f60..d35ce5b2c3f8 100644 --- a/core/java/android/os/incremental/V4Signature.java +++ b/core/java/android/os/incremental/V4Signature.java @@ -16,6 +16,8 @@ package android.os.incremental; +import android.annotation.NonNull; +import android.annotation.Nullable; import android.os.ParcelFileDescriptor; import java.io.ByteArrayInputStream; @@ -45,8 +47,8 @@ public class V4Signature { public static class HashingInfo { public final int hashAlgorithm; // only 1 == SHA256 supported public final byte log2BlockSize; // only 12 (block size 4096) supported now - public final byte[] salt; // used exactly as in fs-verity, 32 bytes max - public final byte[] rawRootHash; // salted digest of the first Merkle tree page + @Nullable public final byte[] salt; // used exactly as in fs-verity, 32 bytes max + @Nullable public final byte[] rawRootHash; // salted digest of the first Merkle tree page HashingInfo(int hashAlgorithm, byte log2BlockSize, byte[] salt, byte[] rawRootHash) { this.hashAlgorithm = hashAlgorithm; @@ -58,7 +60,8 @@ public class V4Signature { /** * Constructs HashingInfo from byte array. */ - public static HashingInfo fromByteArray(byte[] bytes) throws IOException { + @NonNull + public static HashingInfo fromByteArray(@NonNull byte[] bytes) throws IOException { ByteBuffer buffer = ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN); final int hashAlgorithm = buffer.getInt(); final byte log2BlockSize = buffer.get(); @@ -106,8 +109,18 @@ public class V4Signature { } public final int version; // Always 2 for now. - public final byte[] hashingInfo; - public final byte[] signingInfo; // Passed as-is to the kernel. Can be retrieved later. + /** + * Raw byte array containing the IncFS hashing data. + * @see HashingInfo#fromByteArray(byte[]) + */ + @Nullable public final byte[] hashingInfo; + + /** + * Raw byte array containing the V4 signature data. + * <p>Passed as-is to the kernel. Can be retrieved later. + * @see SigningInfo#fromByteArray(byte[]) + */ + @Nullable public final byte[] signingInfo; /** * Construct a V4Signature from .idsig file. @@ -121,7 +134,8 @@ public class V4Signature { /** * Construct a V4Signature from a byte array. */ - public static V4Signature readFrom(byte[] bytes) throws IOException { + @NonNull + public static V4Signature readFrom(@NonNull byte[] bytes) throws IOException { try (InputStream stream = new ByteArrayInputStream(bytes)) { return readFrom(stream); } @@ -169,7 +183,7 @@ public class V4Signature { return this.version == SUPPORTED_VERSION; } - private V4Signature(int version, byte[] hashingInfo, byte[] signingInfo) { + private V4Signature(int version, @Nullable byte[] hashingInfo, @Nullable byte[] signingInfo) { this.version = version; this.hashingInfo = hashingInfo; this.signingInfo = signingInfo; diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 541883346e23..fe340c46e3c4 100644..100755 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -4748,6 +4748,14 @@ public final class Settings { public static final String SHOW_BATTERY_PERCENT = "status_bar_show_battery_percent"; /** + * Whether or not to enable multiple audio focus. + * When enabled, requires more management by user over application playback activity, + * for instance pausing media apps when another starts. + * @hide + */ + public static final String MULTI_AUDIO_FOCUS_ENABLED = "multi_audio_focus_enabled"; + + /** * IMPORTANT: If you add a new public settings you also have to add it to * PUBLIC_SETTINGS below. If the new setting is hidden you have to add * it to PRIVATE_SETTINGS below. Also add a validator that can validate diff --git a/core/java/android/service/autofill/augmented/AugmentedAutofillService.java b/core/java/android/service/autofill/augmented/AugmentedAutofillService.java index 1efa3dd0c865..b47b2b41bdd9 100644 --- a/core/java/android/service/autofill/augmented/AugmentedAutofillService.java +++ b/core/java/android/service/autofill/augmented/AugmentedAutofillService.java @@ -31,6 +31,7 @@ import android.content.ComponentName; import android.content.Intent; import android.graphics.Rect; import android.os.Build; +import android.os.Bundle; import android.os.CancellationSignal; import android.os.Handler; import android.os.IBinder; @@ -558,9 +559,10 @@ public abstract class AugmentedAutofillService extends Service { } } - void reportResult(@Nullable List<Dataset> inlineSuggestionsData) { + void reportResult(@Nullable List<Dataset> inlineSuggestionsData, + @Nullable Bundle clientState) { try { - mCallback.onSuccess(inlineSuggestionsData); + mCallback.onSuccess(inlineSuggestionsData, clientState); } catch (RemoteException e) { Log.e(TAG, "Error calling back with the inline suggestions data: " + e); } diff --git a/core/java/android/service/autofill/augmented/FillCallback.java b/core/java/android/service/autofill/augmented/FillCallback.java index 526a749c95a1..21738d80f2d3 100644 --- a/core/java/android/service/autofill/augmented/FillCallback.java +++ b/core/java/android/service/autofill/augmented/FillCallback.java @@ -21,6 +21,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; import android.annotation.TestApi; +import android.os.Bundle; import android.service.autofill.Dataset; import android.service.autofill.augmented.AugmentedAutofillService.AutofillProxy; import android.util.Log; @@ -55,14 +56,15 @@ public final class FillCallback { if (response == null) { mProxy.logEvent(AutofillProxy.REPORT_EVENT_NO_RESPONSE); - mProxy.reportResult(/* inlineSuggestionsData */ null); + mProxy.reportResult(/* inlineSuggestionsData */ null, /* clientState */ null); return; } List<Dataset> inlineSuggestions = response.getInlineSuggestions(); + Bundle clientState = response.getClientState(); if (inlineSuggestions != null && !inlineSuggestions.isEmpty()) { mProxy.logEvent(AutofillProxy.REPORT_EVENT_INLINE_RESPONSE); - mProxy.reportResult(inlineSuggestions); + mProxy.reportResult(inlineSuggestions, clientState); return; } diff --git a/core/java/android/service/autofill/augmented/IFillCallback.aidl b/core/java/android/service/autofill/augmented/IFillCallback.aidl index 24af1e51dd56..609e382e2b96 100644 --- a/core/java/android/service/autofill/augmented/IFillCallback.aidl +++ b/core/java/android/service/autofill/augmented/IFillCallback.aidl @@ -30,7 +30,7 @@ import java.util.List; */ interface IFillCallback { void onCancellable(in ICancellationSignal cancellation); - void onSuccess(in @nullable List<Dataset> inlineSuggestionsData); + void onSuccess(in @nullable List<Dataset> inlineSuggestionsData, in @nullable Bundle clientState); boolean isCompleted(); void cancel(); } diff --git a/core/java/android/service/dreams/DreamService.java b/core/java/android/service/dreams/DreamService.java index 0db97718b693..337027ef5bc9 100644 --- a/core/java/android/service/dreams/DreamService.java +++ b/core/java/android/service/dreams/DreamService.java @@ -182,7 +182,6 @@ public class DreamService extends Service implements Window.Callback { private Window mWindow; private Activity mActivity; private boolean mInteractive; - private boolean mLowProfile = true; private boolean mFullscreen; private boolean mScreenBright = true; private boolean mStarted; @@ -530,32 +529,6 @@ public class DreamService extends Service implements Window.Callback { } /** - * Sets View.SYSTEM_UI_FLAG_LOW_PROFILE on the content view. - * - * @param lowProfile True to set View.SYSTEM_UI_FLAG_LOW_PROFILE - * @hide There is no reason to have this -- dreams can set this flag - * on their own content view, and from there can actually do the - * correct interactions with it (seeing when it is cleared etc). - */ - public void setLowProfile(boolean lowProfile) { - if (mLowProfile != lowProfile) { - mLowProfile = lowProfile; - int flag = View.SYSTEM_UI_FLAG_LOW_PROFILE; - applySystemUiVisibilityFlags(mLowProfile ? flag : 0, flag); - } - } - - /** - * Returns whether or not this dream is in low profile mode. Defaults to true. - * - * @see #setLowProfile(boolean) - * @hide - */ - public boolean isLowProfile() { - return getSystemUiVisibilityFlagValue(View.SYSTEM_UI_FLAG_LOW_PROFILE, mLowProfile); - } - - /** * Controls {@link android.view.WindowManager.LayoutParams#FLAG_FULLSCREEN} * on the dream's window. * @@ -900,10 +873,11 @@ public class DreamService extends Service implements Window.Callback { public final void finish() { if (mDebug) Slog.v(TAG, "finish(): mFinished=" + mFinished); - if (mActivity != null) { - if (!mActivity.isFinishing()) { + Activity activity = mActivity; + if (activity != null) { + if (!activity.isFinishing()) { // In case the activity is not finished yet, do it now. - mActivity.finishAndRemoveTask(); + activity.finishAndRemoveTask(); } return; } @@ -1093,10 +1067,6 @@ public class DreamService extends Service implements Window.Callback { // along well. Dreams usually don't need such bars anyways, so disable them by default. mWindow.clearFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); - applySystemUiVisibilityFlags( - (mLowProfile ? View.SYSTEM_UI_FLAG_LOW_PROFILE : 0), - View.SYSTEM_UI_FLAG_LOW_PROFILE); - mWindow.getDecorView().addOnAttachStateChangeListener( new View.OnAttachStateChangeListener() { @Override @@ -1106,6 +1076,7 @@ public class DreamService extends Service implements Window.Callback { @Override public void onViewDetachedFromWindow(View v) { + mActivity = null; finish(); } }); @@ -1124,18 +1095,6 @@ public class DreamService extends Service implements Window.Callback { } } - private boolean getSystemUiVisibilityFlagValue(int flag, boolean defaultValue) { - View v = mWindow == null ? null : mWindow.getDecorView(); - return v == null ? defaultValue : (v.getSystemUiVisibility() & flag) != 0; - } - - private void applySystemUiVisibilityFlags(int flags, int mask) { - View v = mWindow == null ? null : mWindow.getDecorView(); - if (v != null) { - v.setSystemUiVisibility(applyFlags(v.getSystemUiVisibility(), flags, mask)); - } - } - private int applyFlags(int oldFlags, int flags, int mask) { return (oldFlags&~mask) | (flags&mask); } @@ -1161,7 +1120,6 @@ public class DreamService extends Service implements Window.Callback { pw.println(" window: " + mWindow); pw.print(" flags:"); if (isInteractive()) pw.print(" interactive"); - if (isLowProfile()) pw.print(" lowprofile"); if (isFullscreen()) pw.print(" fullscreen"); if (isScreenBright()) pw.print(" bright"); if (isWindowless()) pw.print(" windowless"); diff --git a/core/java/android/service/notification/StatusBarNotification.java b/core/java/android/service/notification/StatusBarNotification.java index 21b83c660446..5c43f8f829b0 100644 --- a/core/java/android/service/notification/StatusBarNotification.java +++ b/core/java/android/service/notification/StatusBarNotification.java @@ -292,6 +292,18 @@ public class StatusBarNotification implements Parcelable { return this.user.getIdentifier(); } + /** + * Like {@link #getUserId()} but handles special users. + * @hide + */ + public int getNormalizedUserId() { + int userId = getUserId(); + if (userId == UserHandle.USER_ALL) { + userId = UserHandle.USER_SYSTEM; + } + return userId; + } + /** The package that the notification belongs to. */ public String getPackageName() { return pkg; diff --git a/core/java/android/speech/RecognizerIntent.java b/core/java/android/speech/RecognizerIntent.java index 362b94b83c3f..3b5a6d59e7e6 100644 --- a/core/java/android/speech/RecognizerIntent.java +++ b/core/java/android/speech/RecognizerIntent.java @@ -413,6 +413,10 @@ public class RecognizerIntent { * {@link #ACTION_VOICE_SEARCH_HANDS_FREE}, {@link #ACTION_WEB_SEARCH} to indicate whether to * only use an offline speech recognition engine. The default is false, meaning that either * network or offline recognition engines may be used. + * + * <p>Depending on the recognizer implementation, these values may have + * no effect.</p> + * */ public static final String EXTRA_PREFER_OFFLINE = "android.speech.extra.PREFER_OFFLINE"; } diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java index 1086774fc8ff..76ed37c51bfe 100644 --- a/core/java/android/view/SurfaceControl.java +++ b/core/java/android/view/SurfaceControl.java @@ -228,6 +228,7 @@ public final class SurfaceControl implements Parcelable { */ public long mNativeObject; private long mNativeHandle; + private Throwable mReleaseStack = null; // TODO: Move this to native. private final Object mSizeLock = new Object(); @@ -426,11 +427,18 @@ public final class SurfaceControl implements Parcelable { if (mNativeObject != 0) { release(); } - if (nativeObject != 0) { + if (nativeObject != 0) { mCloseGuard.open("release"); } mNativeObject = nativeObject; mNativeHandle = mNativeObject != 0 ? nativeGetHandle(nativeObject) : 0; + if (mNativeObject == 0) { + if (Build.IS_DEBUGGABLE) { + mReleaseStack = new Throwable("assigned zero nativeObject here"); + } + } else { + mReleaseStack = null; + } } /** @@ -989,11 +997,22 @@ public final class SurfaceControl implements Parcelable { nativeRelease(mNativeObject); mNativeObject = 0; mNativeHandle = 0; + if (Build.IS_DEBUGGABLE) { + mReleaseStack = new Throwable("released here"); + } mCloseGuard.close(); } } /** + * Returns the call stack that assigned mNativeObject to zero. + * @hide + */ + public Throwable getReleaseStack() { + return mReleaseStack; + } + + /** * Disconnect any client still connected to the surface. * @hide */ @@ -1004,8 +1023,11 @@ public final class SurfaceControl implements Parcelable { } private void checkNotReleased() { - if (mNativeObject == 0) throw new NullPointerException( - "mNativeObject is null. Have you called release() already?"); + if (mNativeObject == 0) { + Log.wtf(TAG, "Invalid " + this + " caused by:", mReleaseStack); + throw new NullPointerException( + "mNativeObject of " + this + " is null. Have you called release() already?"); + } } /** diff --git a/core/java/android/view/WindowInsets.java b/core/java/android/view/WindowInsets.java index ca3dd04fd756..aad1c60d7b7e 100644 --- a/core/java/android/view/WindowInsets.java +++ b/core/java/android/view/WindowInsets.java @@ -473,6 +473,12 @@ public final class WindowInsets { /** * Returns the display cutout if there is one. * + * <p>Note: the display cutout will already be {@link #consumeDisplayCutout consumed} during + * dispatch to {@link View#onApplyWindowInsets}, unless the window has requested a + * {@link WindowManager.LayoutParams#layoutInDisplayCutoutMode} other than + * {@link WindowManager.LayoutParams#LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER never} or + * {@link WindowManager.LayoutParams#LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT default}. + * * @return the display cutout or null if there is none * @see DisplayCutout */ @@ -1424,7 +1430,13 @@ public final class WindowInsets { /** * Returns an insets type representing the area that used by {@link DisplayCutout}. * - * <p>This is equivalent to the safe insets on {@link #getDisplayCutout()}.</p> + * <p>This is equivalent to the safe insets on {@link #getDisplayCutout()}. + * + * <p>Note: During dispatch to {@link View#onApplyWindowInsets}, if the window is using + * the {@link WindowManager.LayoutParams#LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT default} + * {@link WindowManager.LayoutParams#layoutInDisplayCutoutMode}, {@link #getDisplayCutout()} + * will return {@code null} even if the window overlaps a display cutout area, in which case + * the {@link #displayCutout() displayCutout() inset} will still report the accurate value. * * @see DisplayCutout#getSafeInsetLeft() * @see DisplayCutout#getSafeInsetTop() diff --git a/core/java/android/view/WindowInsetsAnimationController.java b/core/java/android/view/WindowInsetsAnimationController.java index c191a54283fb..fb9d05e2d730 100644 --- a/core/java/android/view/WindowInsetsAnimationController.java +++ b/core/java/android/view/WindowInsetsAnimationController.java @@ -141,7 +141,10 @@ public interface WindowInsetsAnimationController { /** * Finishes the animation, and leaves the windows shown or hidden. * <p> - * After invoking {@link #finish(boolean)}, this instance is no longer {@link #isReady ready}. + * After invoking {@link #finish}, this instance is no longer {@link #isReady ready}. + * <p> + * Note: Finishing an animation implicitly {@link #setInsetsAndAlpha sets insets and alpha} + * according to the requested end state without any further animation. * * @param shown if {@code true}, the windows will be shown after finishing the * animation. Otherwise they will be hidden. diff --git a/core/java/com/android/internal/app/AccessibilityButtonChooserActivity.java b/core/java/com/android/internal/accessibility/dialog/AccessibilityShortcutChooserActivity.java index 4f98a6354ea3..9338c3c87217 100644 --- a/core/java/com/android/internal/app/AccessibilityButtonChooserActivity.java +++ b/core/java/com/android/internal/accessibility/dialog/AccessibilityShortcutChooserActivity.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 The Android Open Source Project + * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.android.internal.app; +package com.android.internal.accessibility.dialog; import static android.view.accessibility.AccessibilityManager.ACCESSIBILITY_BUTTON; import static android.view.accessibility.AccessibilityManager.ACCESSIBILITY_SHORTCUT_KEY; @@ -79,9 +79,10 @@ import java.util.List; import java.util.Locale; /** - * Activity used to display and persist a service or feature target for the Accessibility button. + * Activity used to display various targets related to accessibility service, accessibility + * activity or white listing feature for volume key shortcut. */ -public class AccessibilityButtonChooserActivity extends Activity { +public class AccessibilityShortcutChooserActivity extends Activity { @ShortcutType private static int sShortcutType; @UserShortcutType @@ -355,17 +356,18 @@ public class AccessibilityButtonChooserActivity extends Activity { ViewHolder holder; if (convertView == null) { convertView = LayoutInflater.from(context).inflate( - R.layout.accessibility_button_chooser_item, parent, /* attachToRoot= */ + R.layout.accessibility_shortcut_chooser_item, parent, /* attachToRoot= */ false); holder = new ViewHolder(); holder.mItemView = convertView; holder.mCheckBox = convertView.findViewById( - R.id.accessibility_button_target_checkbox); - holder.mIconView = convertView.findViewById(R.id.accessibility_button_target_icon); + R.id.accessibility_shortcut_target_checkbox); + holder.mIconView = convertView.findViewById( + R.id.accessibility_shortcut_target_icon); holder.mLabelView = convertView.findViewById( - R.id.accessibility_button_target_label); + R.id.accessibility_shortcut_target_label); holder.mSwitchItem = convertView.findViewById( - R.id.accessibility_button_target_switch_item); + R.id.accessibility_shortcut_target_switch_item); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); diff --git a/core/java/com/android/internal/accessibility/util/AccessibilityUtils.java b/core/java/com/android/internal/accessibility/util/AccessibilityUtils.java index bcbd6abc252c..a92a50d4d832 100644 --- a/core/java/com/android/internal/accessibility/util/AccessibilityUtils.java +++ b/core/java/com/android/internal/accessibility/util/AccessibilityUtils.java @@ -19,6 +19,7 @@ import static com.android.internal.accessibility.common.ShortcutConstants.Access import static com.android.internal.accessibility.common.ShortcutConstants.SERVICES_SEPARATOR; import android.accessibilityservice.AccessibilityServiceInfo; +import android.annotation.NonNull; import android.content.ComponentName; import android.content.Context; import android.os.Build; @@ -115,7 +116,7 @@ public final class AccessibilityUtils { * @return int from {@link AccessibilityFragmentType}. */ public static @AccessibilityFragmentType int getAccessibilityServiceFragmentType( - AccessibilityServiceInfo accessibilityServiceInfo) { + @NonNull AccessibilityServiceInfo accessibilityServiceInfo) { final int targetSdk = accessibilityServiceInfo.getResolveInfo() .serviceInfo.applicationInfo.targetSdkVersion; final boolean requestA11yButton = (accessibilityServiceInfo.flags diff --git a/core/java/com/android/internal/accessibility/util/ShortcutUtils.java b/core/java/com/android/internal/accessibility/util/ShortcutUtils.java index 717e78078b1c..7ec80ecdb2a9 100644 --- a/core/java/com/android/internal/accessibility/util/ShortcutUtils.java +++ b/core/java/com/android/internal/accessibility/util/ShortcutUtils.java @@ -39,21 +39,21 @@ public final class ShortcutUtils { new TextUtils.SimpleStringSplitter(SERVICES_SEPARATOR); /** - * Opts in component name into colon-separated {@link UserShortcutType} - * key's string in Settings. + * Opts in component id into colon-separated {@link UserShortcutType} + * key's string from Settings. * * @param context The current context. * @param shortcutType The preferred shortcut type user selected. - * @param componentId The component id that need to be opted out from Settings. + * @param componentId The component id that need to be opted in Settings. */ public static void optInValueToSettings(Context context, @UserShortcutType int shortcutType, - String componentId) { + @NonNull String componentId) { final StringJoiner joiner = new StringJoiner(String.valueOf(SERVICES_SEPARATOR)); final String targetKey = convertToKey(shortcutType); final String targetString = Settings.Secure.getString(context.getContentResolver(), targetKey); - if (hasValueInSettings(context, shortcutType, componentId)) { + if (isComponentIdExistingInSettings(context, shortcutType, componentId)) { return; } @@ -66,14 +66,15 @@ public final class ShortcutUtils { } /** - * Opts out component name into colon-separated {@code shortcutType} key's string in Settings. + * Opts out of component id into colon-separated {@link UserShortcutType} key's string from + * Settings. * * @param context The current context. * @param shortcutType The preferred shortcut type user selected. - * @param componentId The component id that need to be opted out from Settings. + * @param componentId The component id that need to be opted out of Settings. */ public static void optOutValueFromSettings( - Context context, @UserShortcutType int shortcutType, String componentId) { + Context context, @UserShortcutType int shortcutType, @NonNull String componentId) { final StringJoiner joiner = new StringJoiner(String.valueOf(SERVICES_SEPARATOR)); final String targetsKey = convertToKey(shortcutType); final String targetsValue = Settings.Secure.getString(context.getContentResolver(), @@ -96,36 +97,38 @@ public final class ShortcutUtils { } /** - * Returns if component name existed in one of {@code shortcutTypes} string in Settings. + * Returns if component id existed in one of {@link UserShortcutType} string from Settings. * * @param context The current context. * @param shortcutTypes A combination of {@link UserShortcutType}. - * @param componentId The component name that need to be checked existed in Settings. - * @return {@code true} if componentName existed in Settings. + * @param componentId The component id that need to be checked existed in Settings. + * @return {@code true} if component id existed in Settings. */ - public static boolean hasValuesInSettings(Context context, int shortcutTypes, + public static boolean hasValuesInSettings(Context context, @UserShortcutType int shortcutTypes, @NonNull String componentId) { boolean exist = false; if ((shortcutTypes & UserShortcutType.SOFTWARE) == UserShortcutType.SOFTWARE) { - exist = hasValueInSettings(context, UserShortcutType.SOFTWARE, componentId); + exist = isComponentIdExistingInSettings(context, UserShortcutType.SOFTWARE, + componentId); } if (((shortcutTypes & UserShortcutType.HARDWARE) == UserShortcutType.HARDWARE)) { - exist |= hasValueInSettings(context, UserShortcutType.HARDWARE, componentId); + exist |= isComponentIdExistingInSettings(context, UserShortcutType.HARDWARE, + componentId); } return exist; } /** - * Returns if component name existed in Settings. + * Returns if component id existed in Settings. * * @param context The current context. * @param shortcutType The preferred shortcut type user selected. * @param componentId The component id that need to be checked existed in Settings. - * @return {@code true} if componentName existed in Settings. + * @return {@code true} if component id existed in Settings. */ - public static boolean hasValueInSettings(Context context, @UserShortcutType int shortcutType, - @NonNull String componentId) { + public static boolean isComponentIdExistingInSettings(Context context, + @UserShortcutType int shortcutType, @NonNull String componentId) { final String targetKey = convertToKey(shortcutType); final String targetString = Settings.Secure.getString(context.getContentResolver(), targetKey); @@ -146,7 +149,7 @@ public final class ShortcutUtils { } /** - * Converts {@link UserShortcutType} to key in Settings. + * Converts {@link UserShortcutType} to {@link Settings.Secure} key. * * @param type The shortcut type. * @return Mapping key in Settings. @@ -169,7 +172,7 @@ public final class ShortcutUtils { * Converts {@link ShortcutType} to {@link UserShortcutType}. * * @param type The shortcut type. - * @return {@link UserShortcutType}. + * @return Mapping type from {@link UserShortcutType}. */ public static @UserShortcutType int convertToUserType(@ShortcutType int type) { switch (type) { diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java index c82ab6c79e9d..3e7f24b034ac 100644 --- a/core/java/com/android/internal/app/ChooserActivity.java +++ b/core/java/com/android/internal/app/ChooserActivity.java @@ -169,6 +169,17 @@ public class ChooserActivity extends ResolverActivity implements public static final String EXTRA_PRIVATE_RETAIN_IN_ON_STOP = "com.android.internal.app.ChooserActivity.EXTRA_PRIVATE_RETAIN_IN_ON_STOP"; + /** + * Integer extra to indicate which profile should be automatically selected. + * <p>Can only be used if there is a work profile. + * <p>Possible values can be either {@link #PROFILE_PERSONAL} or {@link #PROFILE_WORK}. + */ + static final String EXTRA_SELECTED_PROFILE = + "com.android.internal.app.ChooserActivity.EXTRA_SELECTED_PROFILE"; + + static final int PROFILE_PERSONAL = AbstractMultiProfilePagerAdapter.PROFILE_PERSONAL; + static final int PROFILE_WORK = AbstractMultiProfilePagerAdapter.PROFILE_WORK; + private static final String PREF_NUM_SHEET_EXPANSIONS = "pref_num_sheet_expansions"; private static final String CHIP_LABEL_METADATA_KEY = "android.service.chooser.chip_label"; @@ -860,15 +871,31 @@ public class ChooserActivity extends ResolverActivity implements filterLastUsed, mUseLayoutForBrowsables, /* userHandle */ getWorkProfileUserHandle()); + int selectedProfile = findSelectedProfile(); return new ChooserMultiProfilePagerAdapter( /* context */ this, personalAdapter, workAdapter, - /* defaultProfile */ getCurrentProfile(), + selectedProfile, getPersonalProfileUserHandle(), getWorkProfileUserHandle()); } + private int findSelectedProfile() { + int selectedProfile; + if (getIntent().hasExtra(EXTRA_SELECTED_PROFILE)) { + selectedProfile = getIntent().getIntExtra(EXTRA_SELECTED_PROFILE, /* defValue = */ -1); + if (selectedProfile != PROFILE_PERSONAL && selectedProfile != PROFILE_WORK) { + throw new IllegalArgumentException(EXTRA_SELECTED_PROFILE + " has invalid value " + + selectedProfile + ". Must be either ChooserActivity.PROFILE_PERSONAL or " + + "ChooserActivity.PROFILE_WORK."); + } + } else { + selectedProfile = getProfileForUser(getUser()); + } + return selectedProfile; + } + @Override protected boolean postRebuildList(boolean rebuildCompleted) { updateStickyContentPreview(); @@ -2479,7 +2506,10 @@ public class ChooserActivity extends ResolverActivity implements gridAdapter.getMaxTargetsPerRow()); } - if (mChooserMultiProfilePagerAdapter.getCurrentUserHandle() != getUser()) { + UserHandle currentUserHandle = mChooserMultiProfilePagerAdapter.getCurrentUserHandle(); + int currentProfile = getProfileForUser(currentUserHandle); + int initialProfile = findSelectedProfile(); + if (currentProfile != initialProfile) { return; } @@ -2576,6 +2606,19 @@ public class ChooserActivity extends ResolverActivity implements } } + /** + * Returns {@link #PROFILE_PERSONAL}, {@link #PROFILE_WORK}, or -1 if the given user handle + * does not match either the personal or work user handle. + **/ + private int getProfileForUser(UserHandle currentUserHandle) { + if (currentUserHandle == getPersonalProfileUserHandle()) { + return PROFILE_PERSONAL; + } else if (currentUserHandle == getWorkProfileUserHandle()) { + return PROFILE_WORK; + } + return -1; + } + private ViewGroup getCurrentEmptyStateView() { int currentPage = mChooserMultiProfilePagerAdapter.getCurrentPage(); return mChooserMultiProfilePagerAdapter.getItem(currentPage).getEmptyStateView(); diff --git a/core/java/com/android/internal/app/ChooserActivityLogger.java b/core/java/com/android/internal/app/ChooserActivityLogger.java index 088973cde3e9..c26bac437915 100644 --- a/core/java/com/android/internal/app/ChooserActivityLogger.java +++ b/core/java/com/android/internal/app/ChooserActivityLogger.java @@ -182,7 +182,8 @@ public interface ChooserActivityLogger { return FrameworkStatsLog.SHARESHEET_STARTED__PREVIEW_TYPE__CONTENT_PREVIEW_FILE; case ChooserActivity.CONTENT_PREVIEW_TEXT: default: - return FrameworkStatsLog.SHARESHEET_STARTED__PREVIEW_TYPE__CONTENT_PREVIEW_TEXT; + return FrameworkStatsLog + .SHARESHEET_STARTED__PREVIEW_TYPE__CONTENT_PREVIEW_TYPE_UNKNOWN; } } diff --git a/core/java/com/android/internal/app/IntentForwarderActivity.java b/core/java/com/android/internal/app/IntentForwarderActivity.java index 9bdfa4ad4e43..36eecfb685e8 100644 --- a/core/java/com/android/internal/app/IntentForwarderActivity.java +++ b/core/java/com/android/internal/app/IntentForwarderActivity.java @@ -108,20 +108,16 @@ public class IntentForwarderActivity extends Activity { finish(); return; } + if (Intent.ACTION_CHOOSER.equals(intentReceived.getAction())) { + launchChooserActivityWithCorrectTab(intentReceived, className); + return; + } final int callingUserId = getUserId(); final Intent newIntent = canForward(intentReceived, getUserId(), targetUserId, mInjector.getIPackageManager(), getContentResolver()); if (newIntent != null) { - if (Intent.ACTION_CHOOSER.equals(newIntent.getAction())) { - Intent innerIntent = newIntent.getParcelableExtra(Intent.EXTRA_INTENT); - // At this point, innerIntent is not null. Otherwise, canForward would have returned - // false. - innerIntent.prepareToLeaveUser(callingUserId); - innerIntent.fixUris(callingUserId); - } else { - newIntent.prepareToLeaveUser(callingUserId); - } + newIntent.prepareToLeaveUser(callingUserId); final ResolveInfo ri = mInjector.resolveActivityAsUser(newIntent, MATCH_DEFAULT_ONLY, targetUserId); @@ -153,6 +149,33 @@ public class IntentForwarderActivity extends Activity { finish(); } + private void launchChooserActivityWithCorrectTab(Intent intentReceived, String className) { + // When showing the sharesheet, instead of forwarding to the other profile, + // we launch the sharesheet in the current user and select the other tab. + // This fixes b/152866292 where the user can not go back to the original profile + // when cross-profile intents are disabled. + int selectedProfile = findSelectedProfile(className); + sanitizeIntent(intentReceived); + intentReceived.putExtra(ChooserActivity.EXTRA_SELECTED_PROFILE, selectedProfile); + Intent innerIntent = intentReceived.getParcelableExtra(Intent.EXTRA_INTENT); + if (innerIntent == null) { + Slog.wtf(TAG, "Cannot start a chooser intent with no extra " + Intent.EXTRA_INTENT); + return; + } + sanitizeIntent(innerIntent); + startActivity(intentReceived); + finish(); + } + + private int findSelectedProfile(String className) { + if (className.equals(FORWARD_INTENT_TO_PARENT)) { + return ChooserActivity.PROFILE_PERSONAL; + } else if (className.equals(FORWARD_INTENT_TO_MANAGED_PROFILE)) { + return ChooserActivity.PROFILE_WORK; + } + return -1; + } + private boolean shouldShowDisclosure(@Nullable ResolveInfo ri, Intent intent) { if (!isDeviceProvisioned()) { return false; diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java index fc3f20f7a556..dd3a6603f46a 100644 --- a/core/java/com/android/internal/app/ResolverActivity.java +++ b/core/java/com/android/internal/app/ResolverActivity.java @@ -398,11 +398,6 @@ public class ResolverActivity extends Activity implements | View.SYSTEM_UI_FLAG_LAYOUT_STABLE); rdl.setOnApplyWindowInsetsListener(this::onApplyWindowInsets); - if (shouldShowTabs() && isIntentPicker()) { - rdl.setMaxCollapsedHeight(getResources() - .getDimensionPixelSize(R.dimen.resolver_max_collapsed_height_with_tabs)); - } - mResolverDrawerLayout = rdl; } @@ -1012,6 +1007,15 @@ public class ResolverActivity extends Activity implements protected void onListRebuilt(ResolverListAdapter listAdapter) { final ItemClickListener listener = new ItemClickListener(); setupAdapterListView((ListView) mMultiProfilePagerAdapter.getActiveAdapterView(), listener); + if (shouldShowTabs() && isIntentPicker()) { + final ResolverDrawerLayout rdl = findViewById(R.id.contentPanel); + if (rdl != null) { + rdl.setMaxCollapsedHeight(getResources() + .getDimensionPixelSize(useLayoutWithDefault() + ? R.dimen.resolver_max_collapsed_height_with_default_with_tabs + : R.dimen.resolver_max_collapsed_height_with_tabs)); + } + } } protected boolean onTargetSelected(TargetInfo target, boolean alwaysCheck) { diff --git a/core/java/com/android/internal/app/SystemUserHomeActivity.java b/core/java/com/android/internal/app/SystemUserHomeActivity.java index 26fbf6f826a8..ee936a3f9abc 100644 --- a/core/java/com/android/internal/app/SystemUserHomeActivity.java +++ b/core/java/com/android/internal/app/SystemUserHomeActivity.java @@ -17,10 +17,27 @@ package com.android.internal.app; import android.app.Activity; +import android.os.Bundle; +import android.util.Log; + +import com.android.internal.R; /** * Placeholder home activity, which is always installed on the system user. At least one home * activity must be present and enabled in order for the system to boot. */ public class SystemUserHomeActivity extends Activity { + private static final String TAG = "SystemUserHome"; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + Log.i(TAG, "onCreate"); + setContentView(R.layout.system_user_home); + } + + protected void onDestroy() { + super.onDestroy(); + Log.i(TAG, "onDestroy"); + } } diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java index b6c58e16b51c..f5d38ca37bb7 100644 --- a/core/java/com/android/internal/policy/DecorView.java +++ b/core/java/com/android/internal/policy/DecorView.java @@ -1631,9 +1631,7 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind int opacity = PixelFormat.OPAQUE; final WindowConfiguration winConfig = getResources().getConfiguration().windowConfiguration; - // TODO(b/149585281) remove when root task has the correct bounds for freeform - final boolean renderShadowsInCompositor = mWindow.mRenderShadowsInCompositor - && winConfig.getWindowingMode() != WINDOWING_MODE_FREEFORM; + final boolean renderShadowsInCompositor = mWindow.mRenderShadowsInCompositor; // If we draw shadows in the compositor we don't need to force the surface to be // translucent. if (winConfig.hasWindowShadow() && !renderShadowsInCompositor) { @@ -2427,8 +2425,7 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind private void updateElevation() { final int windowingMode = getResources().getConfiguration().windowConfiguration.getWindowingMode(); - final boolean renderShadowsInCompositor = mWindow.mRenderShadowsInCompositor - && windowingMode != WINDOWING_MODE_FREEFORM; + final boolean renderShadowsInCompositor = mWindow.mRenderShadowsInCompositor; // If rendering shadows in the compositor, don't set an elevation on the view if (renderShadowsInCompositor) { return; diff --git a/core/java/com/android/internal/statusbar/IStatusBarService.aidl b/core/java/com/android/internal/statusbar/IStatusBarService.aidl index 1dbd69c67831..24fe0638b091 100644 --- a/core/java/com/android/internal/statusbar/IStatusBarService.aidl +++ b/core/java/com/android/internal/statusbar/IStatusBarService.aidl @@ -77,7 +77,7 @@ interface IStatusBarService void onNotificationSmartReplySent(in String key, in int replyIndex, in CharSequence reply, in int notificationLocation, boolean modifiedBeforeSending); void onNotificationSettingsViewed(String key); - void onNotificationBubbleChanged(String key, boolean isBubble); + void onNotificationBubbleChanged(String key, boolean isBubble, int flags); void onBubbleNotificationSuppressionChanged(String key, boolean isSuppressed); void grantInlineReplyUriPermission(String key, in Uri uri, in UserHandle user, String packageName); void clearInlineReplyUriPermissions(String key); diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp index 1cfa12df32ab..58697875b2c3 100644 --- a/core/jni/android_view_SurfaceControl.cpp +++ b/core/jni/android_view_SurfaceControl.cpp @@ -848,8 +848,18 @@ static jobject convertDeviceProductInfoToJavaObject( LOG_FATAL("Unknown alternative for variant DeviceProductInfo::ManufactureOrModelDate"); } + jintArray relativeAddress = nullptr; + if (info->relativeAddress != DeviceProductInfo::NO_RELATIVE_ADDRESS) { + relativeAddress = env->NewIntArray(info->relativeAddress.size()); + jint* relativeAddressData = env->GetIntArrayElements(relativeAddress, nullptr); + for (size_t i = 0; i < info->relativeAddress.size(); i++) { + relativeAddressData[i] = static_cast<jint>(info->relativeAddress[i]); + } + env->ReleaseIntArrayElements(relativeAddress, relativeAddressData, 0); + } return env->NewObject(gDeviceProductInfoClassInfo.clazz, gDeviceProductInfoClassInfo.ctor, name, - manufacturerPnpId, productId, modelYear, manufactureDate); + manufacturerPnpId, productId, modelYear, manufactureDate, + relativeAddress); } static jobject nativeGetDisplayInfo(JNIEnv* env, jclass clazz, jobject tokenObj) { @@ -1684,7 +1694,8 @@ int register_android_view_SurfaceControl(JNIEnv* env) "Ljava/lang/String;" "Ljava/lang/String;" "Ljava/lang/Integer;" - "Landroid/hardware/display/DeviceProductInfo$ManufactureDate;)V"); + "Landroid/hardware/display/DeviceProductInfo$ManufactureDate;" + "[I)V"); jclass deviceProductInfoManufactureDateClazz = FindClassOrDie(env, "android/hardware/display/DeviceProductInfo$ManufactureDate"); diff --git a/core/proto/android/server/jobscheduler.proto b/core/proto/android/server/jobscheduler.proto index bd1bae6d83fb..b678d627d48c 100644 --- a/core/proto/android/server/jobscheduler.proto +++ b/core/proto/android/server/jobscheduler.proto @@ -523,6 +523,7 @@ message StateControllerProto { optional bool is_idle = 1; optional bool is_screen_on = 2; optional bool is_dock_idle = 3; + optional bool in_car_mode = 4; } oneof active_tracker { diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 32a79f3ab8ae..5d6fc766676b 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -5060,7 +5060,7 @@ <category android:name="android.intent.category.VOICE" /> </intent-filter> </activity> - <activity android:name="com.android.internal.app.AccessibilityButtonChooserActivity" + <activity android:name="com.android.internal.accessibility.dialog.AccessibilityShortcutChooserActivity" android:exported="false" android:theme="@style/Theme.DeviceDefault.Dialog.Alert.DayNight" android:finishOnCloseSystemDialogs="true" diff --git a/core/res/res/layout/accessibility_button_chooser_item.xml b/core/res/res/layout/accessibility_shortcut_chooser_item.xml index b7dd892fd161..fff22d916b15 100644 --- a/core/res/res/layout/accessibility_button_chooser_item.xml +++ b/core/res/res/layout/accessibility_shortcut_chooser_item.xml @@ -24,7 +24,7 @@ android:padding="16dp"> <CheckBox - android:id="@+id/accessibility_button_target_checkbox" + android:id="@+id/accessibility_shortcut_target_checkbox" android:layout_width="wrap_content" android:layout_height="wrap_content" android:paddingStart="16dp" @@ -34,13 +34,13 @@ android:visibility="gone"/> <ImageView - android:id="@+id/accessibility_button_target_icon" + android:id="@+id/accessibility_shortcut_target_icon" android:layout_width="48dp" android:layout_height="48dp" android:scaleType="fitCenter"/> <TextView - android:id="@+id/accessibility_button_target_label" + android:id="@+id/accessibility_shortcut_target_label" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginStart="16dp" @@ -50,7 +50,7 @@ android:fontFamily="sans-serif-medium"/> <Switch - android:id="@+id/accessibility_button_target_switch_item" + android:id="@+id/accessibility_shortcut_target_switch_item" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@null" diff --git a/core/res/res/layout/notification_material_action_list.xml b/core/res/res/layout/notification_material_action_list.xml index 425801991927..ec54091e5a20 100644 --- a/core/res/res/layout/notification_material_action_list.xml +++ b/core/res/res/layout/notification_material_action_list.xml @@ -20,16 +20,34 @@ android:layout_height="wrap_content" android:layout_marginTop="@dimen/notification_action_list_margin_top" android:layout_gravity="bottom"> - <com.android.internal.widget.NotificationActionListLayout - android:id="@+id/actions" + + <LinearLayout android:layout_width="match_parent" - android:layout_height="@dimen/notification_action_list_height" - android:paddingEnd="12dp" + android:layout_height="wrap_content" android:orientation="horizontal" - android:gravity="center_vertical" - android:visibility="gone" - android:background="@color/notification_action_list_background_color" + android:paddingEnd="12dp" > - <!-- actions will be added here --> - </com.android.internal.widget.NotificationActionListLayout> + + <com.android.internal.widget.NotificationActionListLayout + android:id="@+id/actions" + android:layout_width="0dp" + android:layout_weight="1" + android:layout_height="@dimen/notification_action_list_height" + android:orientation="horizontal" + android:gravity="center_vertical" + android:visibility="gone" + android:background="@color/notification_action_list_background_color" + > + <!-- actions will be added here --> + </com.android.internal.widget.NotificationActionListLayout> + + <ImageView + android:id="@+id/bubble_button" + android:layout_width="48dp" + android:layout_height="48dp" + android:layout_gravity="center_vertical|end" + android:visibility="gone" + android:scaleType="centerInside" + /> + </LinearLayout> </FrameLayout> diff --git a/core/res/res/layout/resolver_list_with_default.xml b/core/res/res/layout/resolver_list_with_default.xml index 06a7633ce3f5..4a5aa020fb9f 100644 --- a/core/res/res/layout/resolver_list_with_default.xml +++ b/core/res/res/layout/resolver_list_with_default.xml @@ -21,7 +21,7 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:maxWidth="@dimen/resolver_max_width" - android:maxCollapsedHeight="144dp" + android:maxCollapsedHeight="@dimen/resolver_max_collapsed_height_with_default" android:id="@id/contentPanel"> <LinearLayout diff --git a/core/res/res/layout/system_user_home.xml b/core/res/res/layout/system_user_home.xml new file mode 100644 index 000000000000..8afa42338e36 --- /dev/null +++ b/core/res/res/layout/system_user_home.xml @@ -0,0 +1,44 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ 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 + --> +<FrameLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:background="#80000000" + android:forceHasOverlappingRendering="false"> + <LinearLayout + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:orientation="vertical" + android:layout_gravity="center" + android:layout_marginStart="16dp" + android:layout_marginEnd="16dp"> + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:textSize="20sp" + android:textColor="?android:attr/textColorPrimary" + android:text="Framework Fallback Home"/> + <ProgressBar + style="@android:style/Widget.Material.ProgressBar.Horizontal" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="12.75dp" + android:colorControlActivated="?android:attr/textColorPrimary" + android:indeterminate="true"/> + </LinearLayout> +</FrameLayout> diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 340dd4d7d89a..fba237936f6e 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -3397,7 +3397,7 @@ <!-- Inactivity threshold (in milliseconds) used in JobScheduler. JobScheduler will consider the device to be "idle" after being inactive for this long. --> - <integer name="config_jobSchedulerInactivityIdleThreshold">4260000</integer> + <integer name="config_jobSchedulerInactivityIdleThreshold">1860000</integer> <!-- The alarm window (in milliseconds) that JobScheduler uses to enter the idle state --> <integer name="config_jobSchedulerIdleWindowSlop">300000</integer> diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml index 7edb86b2db18..e4aef861198a 100644 --- a/core/res/res/values/dimens.xml +++ b/core/res/res/values/dimens.xml @@ -820,7 +820,9 @@ <dimen name="resolver_empty_state_height">212dp</dimen> <dimen name="resolver_empty_state_height_with_tabs">268dp</dimen> <dimen name="resolver_max_collapsed_height">192dp</dimen> - <dimen name="resolver_max_collapsed_height_with_tabs">248dp</dimen> + <dimen name="resolver_max_collapsed_height_with_tabs">268dp</dimen> + <dimen name="resolver_max_collapsed_height_with_default">144dp</dimen> + <dimen name="resolver_max_collapsed_height_with_default_with_tabs">300dp</dimen> <dimen name="resolver_tab_text_size">14sp</dimen> <dimen name="chooser_action_button_icon_size">18dp</dimen> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index ef1e8b74b05f..717f326d0378 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -1468,6 +1468,7 @@ <java-symbol type="layout" name="select_dialog" /> <java-symbol type="layout" name="simple_dropdown_hint" /> <java-symbol type="layout" name="status_bar_latest_event_content" /> + <java-symbol type="layout" name="system_user_home" /> <java-symbol type="layout" name="text_edit_action_popup_text" /> <java-symbol type="layout" name="text_drag_thumbnail" /> <java-symbol type="layout" name="typing_filter" /> @@ -3232,12 +3233,13 @@ <java-symbol type="string" name="accessibility_enable_service_title" /> <java-symbol type="string" name="accessibility_enable_service_encryption_warning" /> + <java-symbol type="layout" name="accessibility_shortcut_chooser_item" /> + <java-symbol type="id" name="accessibility_shortcut_target_checkbox" /> + <java-symbol type="id" name="accessibility_shortcut_target_icon" /> + <java-symbol type="id" name="accessibility_shortcut_target_label" /> + <java-symbol type="id" name="accessibility_shortcut_target_switch_item" /> + <!-- Accessibility Button --> - <java-symbol type="layout" name="accessibility_button_chooser_item" /> - <java-symbol type="id" name="accessibility_button_target_checkbox" /> - <java-symbol type="id" name="accessibility_button_target_icon" /> - <java-symbol type="id" name="accessibility_button_target_label" /> - <java-symbol type="id" name="accessibility_button_target_switch_item" /> <java-symbol type="string" name="accessibility_magnification_chooser_text" /> <java-symbol type="string" name="edit_accessibility_shortcut_menu_button" /> <java-symbol type="string" name="done_accessibility_shortcut_menu_button" /> @@ -3495,6 +3497,7 @@ <java-symbol type="id" name="clip_children_set_tag" /> <java-symbol type="id" name="clip_to_padding_tag" /> <java-symbol type="id" name="clip_children_tag" /> + <java-symbol type="id" name="bubble_button" /> <java-symbol type="dimen" name="messaging_avatar_size" /> <java-symbol type="dimen" name="messaging_group_sending_progress_size" /> <java-symbol type="dimen" name="messaging_image_rounding" /> @@ -3936,6 +3939,7 @@ <java-symbol type="dimen" name="resolver_empty_state_height" /> <java-symbol type="dimen" name="resolver_empty_state_height_with_tabs" /> <java-symbol type="dimen" name="resolver_max_collapsed_height_with_tabs" /> + <java-symbol type="dimen" name="resolver_max_collapsed_height_with_default_with_tabs" /> <java-symbol type="bool" name="resolver_landscape_phone" /> <java-symbol type="dimen" name="resolver_tab_text_size" /> diff --git a/core/tests/coretests/src/com/android/internal/app/IntentForwarderActivityTest.java b/core/tests/coretests/src/com/android/internal/app/IntentForwarderActivityTest.java index 8cf146ea801d..769c57835662 100644 --- a/core/tests/coretests/src/com/android/internal/app/IntentForwarderActivityTest.java +++ b/core/tests/coretests/src/com/android/internal/app/IntentForwarderActivityTest.java @@ -213,13 +213,9 @@ public class IntentForwarderActivityTest { } @Test - public void forwardToManagedProfile_canForward_chooserIntent() throws Exception { + public void launchInSameProfile_chooserIntent() { sComponentName = FORWARD_TO_MANAGED_PROFILE_COMPONENT_NAME; - // Intent can be forwarded. - when(mIPm.canForwardTo( - any(Intent.class), nullable(String.class), anyInt(), anyInt())).thenReturn(true); - // Manage profile exists. List<UserInfo> profiles = new ArrayList<>(); profiles.add(CURRENT_USER_INFO); @@ -235,10 +231,6 @@ public class IntentForwarderActivityTest { intent.putExtra(Intent.EXTRA_INTENT, sendIntent); IntentForwarderWrapperActivity activity = mActivityRule.launchActivity(intent); - ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class); - verify(mIPm).canForwardTo(intentCaptor.capture(), eq(TYPE_PLAIN_TEXT), anyInt(), anyInt()); - assertEquals(Intent.ACTION_SEND, intentCaptor.getValue().getAction()); - assertNotNull(activity.mStartActivityIntent); assertEquals(Intent.ACTION_CHOOSER, activity.mStartActivityIntent.getAction()); assertNull(activity.mStartActivityIntent.getPackage()); @@ -249,9 +241,9 @@ public class IntentForwarderActivityTest { assertEquals(Intent.ACTION_SEND, innerIntent.getAction()); assertNull(innerIntent.getComponent()); assertNull(innerIntent.getPackage()); - assertEquals(CURRENT_USER_INFO.id, innerIntent.getContentUserHint()); + assertEquals(UserHandle.USER_CURRENT, innerIntent.getContentUserHint()); - assertEquals(MANAGED_PROFILE_INFO.id, activity.mUserIdActivityLaunchedIn); + assertEquals(CURRENT_USER_INFO.id, activity.mUserIdActivityLaunchedIn); } @Test @@ -656,6 +648,12 @@ public class IntentForwarderActivityTest { } @Override + public void startActivity(Intent intent) { + mStartActivityIntent = intent; + mUserIdActivityLaunchedIn = getUserId(); + } + + @Override protected MetricsLogger getMetricsLogger() { return mMetricsLogger; } diff --git a/graphics/java/android/graphics/ColorSpace.java b/graphics/java/android/graphics/ColorSpace.java index ce8ff7dc38ba..1aeafa391b41 100644 --- a/graphics/java/android/graphics/ColorSpace.java +++ b/graphics/java/android/graphics/ColorSpace.java @@ -199,6 +199,11 @@ public abstract class ColorSpace { private static final float[] SRGB_PRIMARIES = { 0.640f, 0.330f, 0.300f, 0.600f, 0.150f, 0.060f }; private static final float[] NTSC_1953_PRIMARIES = { 0.67f, 0.33f, 0.21f, 0.71f, 0.14f, 0.08f }; + /** + * A gray color space does not have meaningful primaries, so we use this arbitrary set. + */ + private static final float[] GRAY_PRIMARIES = { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f }; + private static final float[] ILLUMINANT_D50_XYZ = { 0.964212f, 1.0f, 0.825188f }; private static final Rgb.TransferParameters SRGB_TRANSFER_PARAMETERS = @@ -1457,6 +1462,7 @@ public abstract class ColorSpace { "sRGB IEC61966-2.1", SRGB_PRIMARIES, ILLUMINANT_D65, + null, SRGB_TRANSFER_PARAMETERS, Named.SRGB.ordinal() ); @@ -1491,6 +1497,7 @@ public abstract class ColorSpace { "Rec. ITU-R BT.709-5", new float[] { 0.640f, 0.330f, 0.300f, 0.600f, 0.150f, 0.060f }, ILLUMINANT_D65, + null, new Rgb.TransferParameters(1 / 1.099, 0.099 / 1.099, 1 / 4.5, 0.081, 1 / 0.45), Named.BT709.ordinal() ); @@ -1498,6 +1505,7 @@ public abstract class ColorSpace { "Rec. ITU-R BT.2020-1", new float[] { 0.708f, 0.292f, 0.170f, 0.797f, 0.131f, 0.046f }, ILLUMINANT_D65, + null, new Rgb.TransferParameters(1 / 1.0993, 0.0993 / 1.0993, 1 / 4.5, 0.08145, 1 / 0.45), Named.BT2020.ordinal() ); @@ -1513,6 +1521,7 @@ public abstract class ColorSpace { "Display P3", new float[] { 0.680f, 0.320f, 0.265f, 0.690f, 0.150f, 0.060f }, ILLUMINANT_D65, + null, SRGB_TRANSFER_PARAMETERS, Named.DISPLAY_P3.ordinal() ); @@ -1520,6 +1529,7 @@ public abstract class ColorSpace { "NTSC (1953)", NTSC_1953_PRIMARIES, ILLUMINANT_C, + null, new Rgb.TransferParameters(1 / 1.099, 0.099 / 1.099, 1 / 4.5, 0.081, 1 / 0.45), Named.NTSC_1953.ordinal() ); @@ -1527,6 +1537,7 @@ public abstract class ColorSpace { "SMPTE-C RGB", new float[] { 0.630f, 0.340f, 0.310f, 0.595f, 0.155f, 0.070f }, ILLUMINANT_D65, + null, new Rgb.TransferParameters(1 / 1.099, 0.099 / 1.099, 1 / 4.5, 0.081, 1 / 0.45), Named.SMPTE_C.ordinal() ); @@ -1542,6 +1553,7 @@ public abstract class ColorSpace { "ROMM RGB ISO 22028-2:2013", new float[] { 0.7347f, 0.2653f, 0.1596f, 0.8404f, 0.0366f, 0.0001f }, ILLUMINANT_D50, + null, new Rgb.TransferParameters(1.0, 0.0, 1 / 16.0, 0.031248, 1.8), Named.PRO_PHOTO_RGB.ordinal() ); @@ -2471,7 +2483,11 @@ public abstract class ColorSpace { @NonNull @Size(min = 1) String name, @NonNull @Size(9) float[] toXYZ, @NonNull TransferParameters function) { - this(name, computePrimaries(toXYZ), computeWhitePoint(toXYZ), function, MIN_ID); + // Note: when isGray() returns false, this passes null for the transform for + // consistency with other constructors, which compute the transform from the primaries + // and white point. + this(name, isGray(toXYZ) ? GRAY_PRIMARIES : computePrimaries(toXYZ), + computeWhitePoint(toXYZ), isGray(toXYZ) ? toXYZ : null, function, MIN_ID); } /** @@ -2511,7 +2527,7 @@ public abstract class ColorSpace { @NonNull @Size(min = 6, max = 9) float[] primaries, @NonNull @Size(min = 2, max = 3) float[] whitePoint, @NonNull TransferParameters function) { - this(name, primaries, whitePoint, function, MIN_ID); + this(name, primaries, whitePoint, null, function, MIN_ID); } /** @@ -2534,6 +2550,8 @@ public abstract class ColorSpace { * @param name Name of the color space, cannot be null, its length must be >= 1 * @param primaries RGB primaries as an array of 6 (xy) or 9 (XYZ) floats * @param whitePoint Reference white as an array of 2 (xy) or 3 (XYZ) floats + * @param transform Computed transform matrix that converts from RGB to XYZ, or + * {@code null} to compute it from {@code primaries} and {@code whitePoint}. * @param function Parameters for the transfer functions * @param id ID of this color space as an integer between {@link #MIN_ID} and {@link #MAX_ID} * @@ -2552,9 +2570,10 @@ public abstract class ColorSpace { @NonNull @Size(min = 1) String name, @NonNull @Size(min = 6, max = 9) float[] primaries, @NonNull @Size(min = 2, max = 3) float[] whitePoint, + @Nullable @Size(9) float[] transform, @NonNull TransferParameters function, @IntRange(from = MIN_ID, to = MAX_ID) int id) { - this(name, primaries, whitePoint, null, + this(name, primaries, whitePoint, transform, function.e == 0.0 && function.f == 0.0 ? x -> rcpResponse(x, function.a, function.b, function.c, function.d, function.g) : @@ -2846,7 +2865,7 @@ public abstract class ColorSpace { * * @return The destination array passed as a parameter * - * @see #getWhitePoint(float[]) + * @see #getWhitePoint() */ @NonNull @Size(min = 2) @@ -2864,7 +2883,7 @@ public abstract class ColorSpace { * * @return A new non-null array of 2 floats * - * @see #getWhitePoint() + * @see #getWhitePoint(float[]) */ @NonNull @Size(2) @@ -2878,12 +2897,16 @@ public abstract class ColorSpace { * destination. The x and y components of the first primary are written * in the array at positions 0 and 1 respectively. * + * <p>Note: Some ColorSpaces represent gray profiles. The concept of + * primaries for such a ColorSpace does not make sense, so we use a special + * set of primaries that are all 1s.</p> + * * @param primaries The destination array, cannot be null, its length * must be >= 6 * * @return The destination array passed as a parameter * - * @see #getPrimaries(float[]) + * @see #getPrimaries() */ @NonNull @Size(min = 6) @@ -2898,9 +2921,13 @@ public abstract class ColorSpace { * the destination. The x and y components of the first primary are * written in the array at positions 0 and 1 respectively. * + * <p>Note: Some ColorSpaces represent gray profiles. The concept of + * primaries for such a ColorSpace does not make sense, so we use a special + * set of primaries that are all 1s.</p> + * * @return A new non-null array of 2 floats * - * @see #getWhitePoint() + * @see #getPrimaries(float[]) */ @NonNull @Size(6) @@ -2922,7 +2949,7 @@ public abstract class ColorSpace { * * @return The destination array passed as a parameter * - * @see #getInverseTransform() + * @see #getTransform() */ @NonNull @Size(min = 9) @@ -2942,7 +2969,7 @@ public abstract class ColorSpace { * * @return A new array of 9 floats * - * @see #getInverseTransform(float[]) + * @see #getTransform(float[]) */ @NonNull @Size(9) @@ -2964,7 +2991,7 @@ public abstract class ColorSpace { * * @return The destination array passed as a parameter * - * @see #getTransform() + * @see #getInverseTransform() */ @NonNull @Size(min = 9) @@ -2984,7 +3011,7 @@ public abstract class ColorSpace { * * @return A new array of 9 floats * - * @see #getTransform(float[]) + * @see #getInverseTransform(float[]) */ @NonNull @Size(9) @@ -3287,6 +3314,16 @@ public abstract class ColorSpace { return true; } + /** + * Report whether this matrix is a special gray matrix. + * @param toXYZ A XYZD50 matrix. Skia uses a special form for a gray profile. + * @return true if this is a special gray matrix. + */ + private static boolean isGray(@NonNull @Size(9) float[] toXYZ) { + return toXYZ.length == 9 && toXYZ[1] == 0 && toXYZ[2] == 0 && toXYZ[3] == 0 + && toXYZ[5] == 0 && toXYZ[6] == 0 && toXYZ[7] == 0; + } + private static boolean compare(double point, @NonNull DoubleUnaryOperator a, @NonNull DoubleUnaryOperator b) { double rA = a.applyAsDouble(point); diff --git a/libs/hwui/jni/Bitmap.cpp b/libs/hwui/jni/Bitmap.cpp index ba669053ed63..c0663a9bc699 100755 --- a/libs/hwui/jni/Bitmap.cpp +++ b/libs/hwui/jni/Bitmap.cpp @@ -601,6 +601,7 @@ static jobject Bitmap_createFromParcel(JNIEnv* env, jobject, jobject parcel) { android::Parcel* p = parcelForJavaObject(env, parcel); + const bool isMutable = p->readInt32() != 0; const SkColorType colorType = (SkColorType)p->readInt32(); const SkAlphaType alphaType = (SkAlphaType)p->readInt32(); const uint32_t colorSpaceSize = p->readUint32(); @@ -649,7 +650,9 @@ static jobject Bitmap_createFromParcel(JNIEnv* env, jobject, jobject parcel) { // Map the bitmap in place from the ashmem region if possible otherwise copy. sk_sp<Bitmap> nativeBitmap; - if (blob.fd() >= 0 && !blob.isMutable()) { + // If the blob is mutable we have ownership of the region and can always use it + // If the blob is immutable _and_ we're immutable, we can then still use it + if (blob.fd() >= 0 && (blob.isMutable() || !isMutable)) { #if DEBUG_PARCEL ALOGD("Bitmap.createFromParcel: mapped contents of bitmap from %s blob " "(fds %s)", @@ -669,7 +672,7 @@ static jobject Bitmap_createFromParcel(JNIEnv* env, jobject, jobject parcel) { // Map the pixels in place and take ownership of the ashmem region. We must also respect the // rowBytes value already set on the bitmap instead of attempting to compute our own. nativeBitmap = Bitmap::createFrom(bitmap->info(), bitmap->rowBytes(), dupFd, - const_cast<void*>(blob.data()), size, true); + const_cast<void*>(blob.data()), size, !isMutable); if (!nativeBitmap) { close(dupFd); blob.release(); @@ -707,7 +710,7 @@ static jobject Bitmap_createFromParcel(JNIEnv* env, jobject, jobject parcel) { } return createBitmap(env, nativeBitmap.release(), - getPremulBitmapCreateFlags(false), NULL, NULL, density); + getPremulBitmapCreateFlags(isMutable), NULL, NULL, density); #else doThrowRE(env, "Cannot use parcels outside of Android"); return NULL; @@ -728,6 +731,7 @@ static jboolean Bitmap_writeToParcel(JNIEnv* env, jobject, auto bitmapWrapper = reinterpret_cast<BitmapWrapper*>(bitmapHandle); bitmapWrapper->getSkBitmap(&bitmap); + p->writeInt32(!bitmap.isImmutable()); p->writeInt32(bitmap.colorType()); p->writeInt32(bitmap.alphaType()); SkColorSpace* colorSpace = bitmap.colorSpace(); @@ -754,7 +758,7 @@ static jboolean Bitmap_writeToParcel(JNIEnv* env, jobject, // Transfer the underlying ashmem region if we have one and it's immutable. android::status_t status; int fd = bitmapWrapper->bitmap().getAshmemFd(); - if (fd >= 0 && p->allowFds()) { + if (fd >= 0 && bitmap.isImmutable() && p->allowFds()) { #if DEBUG_PARCEL ALOGD("Bitmap.writeToParcel: transferring immutable bitmap's ashmem fd as " "immutable blob (fds %s)", @@ -775,9 +779,10 @@ static jboolean Bitmap_writeToParcel(JNIEnv* env, jobject, p->allowFds() ? "allowed" : "forbidden"); #endif + const bool mutableCopy = !bitmap.isImmutable(); size_t size = bitmap.computeByteSize(); android::Parcel::WritableBlob blob; - status = p->writeBlob(size, false, &blob); + status = p->writeBlob(size, mutableCopy, &blob); if (status) { doThrowRE(env, "Could not copy bitmap to parcel blob."); return JNI_FALSE; diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java index d1b41dfccf63..9b4aebcd8aff 100644 --- a/location/java/android/location/LocationManager.java +++ b/location/java/android/location/LocationManager.java @@ -34,6 +34,7 @@ import android.annotation.SystemApi; import android.annotation.SystemService; import android.annotation.TestApi; import android.app.AlarmManager; +import android.app.AppOpsManager; import android.app.PendingIntent; import android.app.PropertyInvalidatedCache; import android.compat.Compatibility; @@ -2561,7 +2562,7 @@ public class LocationManager { } public String getListenerId() { - return mConsumer.getClass().getName() + "@" + System.identityHashCode(mConsumer); + return AppOpsManager.toReceiverId(mConsumer); } public synchronized void register(AlarmManager alarmManager, @@ -2690,7 +2691,7 @@ public class LocationManager { } public String getListenerId() { - return mListener.getClass().getName() + "@" + System.identityHashCode(mListener); + return AppOpsManager.toReceiverId(mListener); } public void register(@NonNull Executor executor) { diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java index 8477aa3ca26e..3e1f72da8731 100644..100755 --- a/media/java/android/media/AudioManager.java +++ b/media/java/android/media/AudioManager.java @@ -6145,6 +6145,17 @@ public class AudioManager { } } + /** @hide + * TODO: make this a @SystemApi */ + @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) + public void setMultiAudioFocusEnabled(boolean enabled) { + try { + getService().setMultiAudioFocusEnabled(enabled); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + //--------------------------------------------------------- // Inner classes //-------------------- diff --git a/media/java/android/media/ExifInterface.java b/media/java/android/media/ExifInterface.java index d2379757f226..ed566a50ec58 100644 --- a/media/java/android/media/ExifInterface.java +++ b/media/java/android/media/ExifInterface.java @@ -31,6 +31,7 @@ import android.system.OsConstants; import android.util.Log; import android.util.Pair; +import com.android.internal.annotations.GuardedBy; import com.android.internal.util.ArrayUtils; import libcore.io.IoUtils; @@ -586,7 +587,9 @@ public class ExifInterface { private static final int WEBP_CHUNK_SIZE_BYTE_LENGTH = 4; @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) + @GuardedBy("sFormatter") private static SimpleDateFormat sFormatter; + @GuardedBy("sFormatterTz") private static SimpleDateFormat sFormatterTz; // See Exchangeable image file format for digital still cameras: Exif version 2.2. @@ -2426,12 +2429,17 @@ public class ExifInterface { try { // The exif field is in local time. Parsing it as if it is UTC will yield time // since 1/1/1970 local time - Date datetime = sFormatter.parse(dateTimeString, pos); + Date datetime; + synchronized (sFormatter) { + datetime = sFormatter.parse(dateTimeString, pos); + } if (offsetString != null) { dateTimeString = dateTimeString + " " + offsetString; ParsePosition position = new ParsePosition(0); - datetime = sFormatterTz.parse(dateTimeString, position); + synchronized (sFormatterTz) { + datetime = sFormatterTz.parse(dateTimeString, position); + } } if (datetime == null) return -1; @@ -2473,7 +2481,10 @@ public class ExifInterface { ParsePosition pos = new ParsePosition(0); try { - Date datetime = sFormatter.parse(dateTimeString, pos); + final Date datetime; + synchronized (sFormatter) { + datetime = sFormatter.parse(dateTimeString, pos); + } if (datetime == null) return -1; return datetime.getTime(); } catch (IllegalArgumentException e) { diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl index bb10e1fe2f2c..e3b67f86a367 100644..100755 --- a/media/java/android/media/IAudioService.aidl +++ b/media/java/android/media/IAudioService.aidl @@ -301,4 +301,6 @@ interface IAudioService { // WARNING: read warning at top of file, new methods that need to be used by native // code via IAudioManager.h need to be added to the top section. + + oneway void setMultiAudioFocusEnabled(in boolean enabled); } diff --git a/media/java/android/media/MediaRouter2.java b/media/java/android/media/MediaRouter2.java index 25f6059c35de..bd8fb9602656 100644 --- a/media/java/android/media/MediaRouter2.java +++ b/media/java/android/media/MediaRouter2.java @@ -409,7 +409,7 @@ public final class MediaRouter2 { // TODO: Check thread-safety if (!mRoutes.containsKey(route.getId())) { - notifyTransferFailed(route); + notifyTransferFailure(route); return; } if (controller.getRoutingSessionInfo().getTransferableRoutes().contains(route.getId())) { @@ -588,14 +588,14 @@ public final class MediaRouter2 { if (sessionInfo == null) { // TODO: We may need to distinguish between failure and rejection. // One way can be introducing 'reason'. - notifyTransferFailed(requestedRoute); + notifyTransferFailure(requestedRoute); return; } else if (!sessionInfo.getSelectedRoutes().contains(requestedRoute.getId())) { Log.w(TAG, "The session does not contain the requested route. " + "(requestedRouteId=" + requestedRoute.getId() + ", actualRoutes=" + sessionInfo.getSelectedRoutes() + ")"); - notifyTransferFailed(requestedRoute); + notifyTransferFailure(requestedRoute); return; } else if (!TextUtils.equals(requestedRoute.getProviderId(), sessionInfo.getProviderId())) { @@ -603,7 +603,7 @@ public final class MediaRouter2 { + "(requested route's providerId=" + requestedRoute.getProviderId() + ", actual providerId=" + sessionInfo.getProviderId() + ")"); - notifyTransferFailed(requestedRoute); + notifyTransferFailure(requestedRoute); return; } } @@ -619,7 +619,7 @@ public final class MediaRouter2 { } } //TODO: Determine oldController properly when transfer is launched by Output Switcher. - notifyTransferred(matchingRequest != null ? matchingRequest.mController : + notifyTransfer(matchingRequest != null ? matchingRequest.mController : getSystemController(), newController); } } @@ -687,15 +687,7 @@ public final class MediaRouter2 { return; } - boolean removed; - synchronized (sRouterLock) { - removed = mRoutingControllers.remove(uniqueSessionId, matchingController); - } - - if (removed) { - matchingController.release(); - notifyStopped(matchingController); - } + matchingController.releaseInternal(/* shouldReleaseSession= */ false); } private List<MediaRoute2Info> filterRoutes(List<MediaRoute2Info> routes, @@ -736,22 +728,21 @@ public final class MediaRouter2 { } } - private void notifyTransferred(RoutingController oldController, - RoutingController newController) { + private void notifyTransfer(RoutingController oldController, RoutingController newController) { for (TransferCallbackRecord record: mTransferCallbackRecords) { record.mExecutor.execute( () -> record.mTransferCallback.onTransfer(oldController, newController)); } } - private void notifyTransferFailed(MediaRoute2Info route) { + private void notifyTransferFailure(MediaRoute2Info route) { for (TransferCallbackRecord record: mTransferCallbackRecords) { record.mExecutor.execute( () -> record.mTransferCallback.onTransferFailure(route)); } } - private void notifyStopped(RoutingController controller) { + private void notifyStop(RoutingController controller) { for (TransferCallbackRecord record: mTransferCallbackRecords) { record.mExecutor.execute( () -> record.mTransferCallback.onStop(controller)); @@ -1189,32 +1180,38 @@ public final class MediaRouter2 { */ // TODO: Add tests using {@link MediaRouter2Manager#getActiveSessions()}. public void release() { + releaseInternal(/* shouldReleaseSession= */ true); + } + + void releaseInternal(boolean shouldReleaseSession) { synchronized (mControllerLock) { if (mIsReleased) { - Log.w(TAG, "release() called on released controller. Ignoring."); + Log.w(TAG, "releaseInternal() called on released controller. Ignoring."); return; } mIsReleased = true; } MediaRouter2Stub stub; - boolean removed; synchronized (sRouterLock) { - removed = mRoutingControllers.remove(getId(), this); + mRoutingControllers.remove(getId(), this); stub = mStub; } - if (removed) { - mHandler.post(() -> notifyStopped(RoutingController.this)); - } - - if (stub != null) { + if (shouldReleaseSession && stub != null) { try { mMediaRouterService.releaseSessionWithRouter2(stub, getId()); } catch (RemoteException ex) { - Log.e(TAG, "Unable to notify of controller release", ex); + Log.e(TAG, "Unable to release session", ex); } } + + if (Thread.currentThread() == mHandler.getLooper().getThread()) { + notifyStop(this); + } else { + mHandler.sendMessage(obtainMessage(MediaRouter2::notifyStop, MediaRouter2.this, + RoutingController.this)); + } } @Override diff --git a/media/java/android/media/midi/MidiDeviceInfo.java b/media/java/android/media/midi/MidiDeviceInfo.java index c2229850b4ce..dd3b6dbd6a39 100644 --- a/media/java/android/media/midi/MidiDeviceInfo.java +++ b/media/java/android/media/midi/MidiDeviceInfo.java @@ -19,7 +19,6 @@ package android.media.midi; import android.os.Bundle; import android.os.Parcel; import android.os.Parcelable; - import android.util.Log; /** @@ -205,6 +204,20 @@ public final class MidiDeviceInfo implements Parcelable { public MidiDeviceInfo(int type, int id, int numInputPorts, int numOutputPorts, String[] inputPortNames, String[] outputPortNames, Bundle properties, boolean isPrivate) { + // Check num ports for out-of-range values. Typical values will be + // between zero and three. More than 16 would be very unlikely + // because the port index field in the USB packet is only 4 bits. + // This check is mainly just to prevent OutOfMemoryErrors when + // fuzz testing. + final int maxPorts = 256; // arbitrary and very high + if (numInputPorts < 0 || numInputPorts > maxPorts) { + throw new IllegalArgumentException("numInputPorts out of range = " + + numInputPorts); + } + if (numOutputPorts < 0 || numOutputPorts > maxPorts) { + throw new IllegalArgumentException("numOutputPorts out of range = " + + numOutputPorts); + } mType = type; mId = id; mInputPortCount = numInputPorts; diff --git a/media/tests/AudioPolicyTest/Android.bp b/media/tests/AudioPolicyTest/Android.bp new file mode 100644 index 000000000000..ed3383752695 --- /dev/null +++ b/media/tests/AudioPolicyTest/Android.bp @@ -0,0 +1,17 @@ +android_test { + name: "audiopolicytest", + srcs: ["**/*.java"], + libs: [ + "android.test.runner", + "android.test.base", + ], + static_libs: [ + "mockito-target-minus-junit4", + "androidx.test.rules", + "android-ex-camera2", + "testng", + ], + platform_apis: true, + certificate: "platform", + resource_dirs: ["res"], +} diff --git a/media/tests/AudioPolicyTest/AndroidManifest.xml b/media/tests/AudioPolicyTest/AndroidManifest.xml new file mode 100644 index 000000000000..adb058c82870 --- /dev/null +++ b/media/tests/AudioPolicyTest/AndroidManifest.xml @@ -0,0 +1,45 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- 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. +--> + +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.audiopolicytest"> + + <uses-permission android:name="android.permission.RECORD_AUDIO" /> + <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" /> + <uses-permission android:name="android.permission.MODIFY_AUDIO_ROUTING" /> + <uses-permission android:name="android.permission.CHANGE_ACCESSIBILITY_VOLUME" /> + + <application> + <uses-library android:name="android.test.runner" /> + <activity android:label="@string/app_name" android:name="AudioPolicyTest" + android:screenOrientation="landscape"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER"/> + </intent-filter> + </activity> + </application> + + <!--instrumentation android:name=".AudioPolicyTestRunner" + android:targetPackage="com.android.audiopolicytest" + android:label="AudioManager policy oriented integration tests InstrumentationRunner"> + </instrumentation--> + + <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner" + android:targetPackage="com.android.audiopolicytest" + android:label="AudioManager policy oriented integration tests InstrumentationRunner"> + </instrumentation> +</manifest> diff --git a/media/tests/AudioPolicyTest/AndroidTest.xml b/media/tests/AudioPolicyTest/AndroidTest.xml new file mode 100644 index 000000000000..f3ca9a165d1b --- /dev/null +++ b/media/tests/AudioPolicyTest/AndroidTest.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- 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. +--> +<configuration description="Runs Media Framework Tests"> + <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup"> + <option name="test-file-name" value="audiopolicytest.apk" /> + </target_preparer> + + <option name="test-tag" value="AudioPolicyTest" /> + <test class="com.android.tradefed.testtype.AndroidJUnitTest" > + <option name="package" value="com.android.audiopolicytest" /> + <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" /> + <option name="hidden-api-checks" value="false"/> + </test> +</configuration> diff --git a/media/tests/AudioPolicyTest/res/layout/audiopolicytest.xml b/media/tests/AudioPolicyTest/res/layout/audiopolicytest.xml new file mode 100644 index 000000000000..17fdba6f7c15 --- /dev/null +++ b/media/tests/AudioPolicyTest/res/layout/audiopolicytest.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- 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. +--> + +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="fill_parent" + android:layout_height="fill_parent" + android:orientation="vertical"> +</LinearLayout> diff --git a/media/tests/AudioPolicyTest/res/values/strings.xml b/media/tests/AudioPolicyTest/res/values/strings.xml new file mode 100644 index 000000000000..036592770450 --- /dev/null +++ b/media/tests/AudioPolicyTest/res/values/strings.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <!-- name of the app [CHAR LIMIT=25]--> + <string name="app_name">Audio Policy APIs Tests</string> +</resources> diff --git a/media/tests/AudioPolicyTest/src/com/android/audiopolicytest/AudioManagerTest.java b/media/tests/AudioPolicyTest/src/com/android/audiopolicytest/AudioManagerTest.java new file mode 100644 index 000000000000..1131c623e428 --- /dev/null +++ b/media/tests/AudioPolicyTest/src/com/android/audiopolicytest/AudioManagerTest.java @@ -0,0 +1,328 @@ +/* + * 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.audiopolicytest; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; +import static org.testng.Assert.assertThrows; + +import android.media.AudioAttributes; +import android.media.AudioManager; +import android.media.AudioSystem; +import android.media.audiopolicy.AudioProductStrategy; +import android.media.audiopolicy.AudioVolumeGroup; +import android.util.Log; + +import com.google.common.primitives.Ints; + +import java.util.List; + +public class AudioManagerTest extends AudioVolumesTestBase { + private static final String TAG = "AudioManagerTest"; + + //----------------------------------------------------------------- + // Test getAudioProductStrategies and validate strategies + //----------------------------------------------------------------- + public void testGetAndValidateProductStrategies() throws Exception { + List<AudioProductStrategy> audioProductStrategies = + mAudioManager.getAudioProductStrategies(); + assertTrue(audioProductStrategies.size() > 0); + + List<AudioVolumeGroup> audioVolumeGroups = mAudioManager.getAudioVolumeGroups(); + assertTrue(audioVolumeGroups.size() > 0); + + // Validate Audio Product Strategies + for (final AudioProductStrategy audioProductStrategy : audioProductStrategies) { + AudioAttributes attributes = audioProductStrategy.getAudioAttributes(); + int strategyStreamType = + audioProductStrategy.getLegacyStreamTypeForAudioAttributes(attributes); + + assertTrue("Strategy shall support the attributes retrieved from its getter API", + audioProductStrategy.supportsAudioAttributes(attributes)); + + int volumeGroupId = + audioProductStrategy.getVolumeGroupIdForAudioAttributes(attributes); + + // A strategy must be associated to a volume group + assertNotEquals("strategy not assigned to any volume group", + volumeGroupId, AudioVolumeGroup.DEFAULT_VOLUME_GROUP); + + // Valid Group ? + AudioVolumeGroup audioVolumeGroup = null; + for (final AudioVolumeGroup avg : audioVolumeGroups) { + if (avg.getId() == volumeGroupId) { + audioVolumeGroup = avg; + break; + } + } + assertNotNull("Volume Group not found", audioVolumeGroup); + + // Cross check: the group shall have at least one aa / stream types following the + // considered strategy + boolean strategyAttributesSupported = false; + for (final AudioAttributes aa : audioVolumeGroup.getAudioAttributes()) { + if (audioProductStrategy.supportsAudioAttributes(aa)) { + strategyAttributesSupported = true; + break; + } + } + assertTrue("Volume Group and Strategy mismatching", strategyAttributesSupported); + + // Some Product strategy may not have corresponding stream types as they intends + // to address volume setting per attributes to avoid adding new stream type + // and going on deprecating the stream type even for volume + if (strategyStreamType != AudioSystem.STREAM_DEFAULT) { + boolean strategStreamTypeSupported = false; + for (final int vgStreamType : audioVolumeGroup.getLegacyStreamTypes()) { + if (vgStreamType == strategyStreamType) { + strategStreamTypeSupported = true; + break; + } + } + assertTrue("Volume Group and Strategy mismatching", strategStreamTypeSupported); + } + } + } + + //----------------------------------------------------------------- + // Test getAudioVolumeGroups and validate volume groups + //----------------------------------------------------------------- + + public void testGetAndValidateVolumeGroups() throws Exception { + List<AudioVolumeGroup> audioVolumeGroups = mAudioManager.getAudioVolumeGroups(); + assertTrue(audioVolumeGroups.size() > 0); + + List<AudioProductStrategy> audioProductStrategies = + mAudioManager.getAudioProductStrategies(); + assertTrue(audioProductStrategies.size() > 0); + + // Validate Audio Volume Groups, check all + for (final AudioVolumeGroup audioVolumeGroup : audioVolumeGroups) { + List<AudioAttributes> avgAttributes = audioVolumeGroup.getAudioAttributes(); + int[] avgStreamTypes = audioVolumeGroup.getLegacyStreamTypes(); + + // for each volume group attributes, find the matching product strategy and ensure + // it is linked the considered volume group + for (final AudioAttributes aa : avgAttributes) { + if (aa.equals(sDefaultAttributes)) { + // Some volume groups may not have valid attributes, used for internal + // volume management like patch/rerouting + // so bailing out strategy retrieval from attributes + continue; + } + boolean isVolumeGroupAssociatedToStrategy = false; + for (final AudioProductStrategy strategy : audioProductStrategies) { + int groupId = strategy.getVolumeGroupIdForAudioAttributes(aa); + if (groupId != AudioVolumeGroup.DEFAULT_VOLUME_GROUP) { + + assertEquals("Volume Group ID (" + audioVolumeGroup.toString() + + "), and Volume group ID associated to Strategy (" + + strategy.toString() + ") both supporting attributes " + + aa.toString() + " are mismatching", + audioVolumeGroup.getId(), groupId); + isVolumeGroupAssociatedToStrategy = true; + break; + } + } + assertTrue("Volume Group (" + audioVolumeGroup.toString() + + ") has no associated strategy for attributes " + aa.toString(), + isVolumeGroupAssociatedToStrategy); + } + + // for each volume group stream type, find the matching product strategy and ensure + // it is linked the considered volume group + for (final int avgStreamType : avgStreamTypes) { + if (avgStreamType == AudioSystem.STREAM_DEFAULT) { + // Some Volume Groups may not have corresponding stream types as they + // intends to address volume setting per attributes to avoid adding new + // stream type and going on deprecating the stream type even for volume + // so bailing out strategy retrieval from stream type + continue; + } + boolean isVolumeGroupAssociatedToStrategy = false; + for (final AudioProductStrategy strategy : audioProductStrategies) { + Log.i(TAG, "strategy:" + strategy.toString()); + int groupId = strategy.getVolumeGroupIdForLegacyStreamType(avgStreamType); + if (groupId != AudioVolumeGroup.DEFAULT_VOLUME_GROUP) { + + assertEquals("Volume Group ID (" + audioVolumeGroup.toString() + + "), and Volume group ID associated to Strategy (" + + strategy.toString() + ") both supporting stream " + + AudioSystem.streamToString(avgStreamType) + "(" + + avgStreamType + ") are mismatching", + audioVolumeGroup.getId(), groupId); + isVolumeGroupAssociatedToStrategy = true; + break; + } + } + assertTrue("Volume Group (" + audioVolumeGroup.toString() + + ") has no associated strategy for stream " + + AudioSystem.streamToString(avgStreamType) + "(" + avgStreamType + ")", + isVolumeGroupAssociatedToStrategy); + } + } + } + + //----------------------------------------------------------------- + // Test Volume per Attributes setter/getters + //----------------------------------------------------------------- + public void testSetGetVolumePerAttributesWithInvalidAttributes() throws Exception { + AudioAttributes nullAttributes = null; + + assertThrows(NullPointerException.class, + () -> mAudioManager.getMaxVolumeIndexForAttributes(nullAttributes)); + + assertThrows(NullPointerException.class, + () -> mAudioManager.getMinVolumeIndexForAttributes(nullAttributes)); + + assertThrows(NullPointerException.class, + () -> mAudioManager.getVolumeIndexForAttributes(nullAttributes)); + + assertThrows(NullPointerException.class, + () -> mAudioManager.setVolumeIndexForAttributes( + nullAttributes, 0 /*index*/, 0/*flags*/)); + } + + public void testSetGetVolumePerAttributes() throws Exception { + for (int usage : AudioAttributes.SDK_USAGES) { + if (usage == AudioAttributes.USAGE_UNKNOWN) { + continue; + } + AudioAttributes aaForUsage = new AudioAttributes.Builder().setUsage(usage).build(); + int indexMin = 0; + int indexMax = 0; + int index = 0; + Exception ex = null; + + try { + indexMax = mAudioManager.getMaxVolumeIndexForAttributes(aaForUsage); + } catch (Exception e) { + ex = e; // unexpected + } + assertNull("Exception was thrown for valid attributes", ex); + ex = null; + try { + indexMin = mAudioManager.getMinVolumeIndexForAttributes(aaForUsage); + } catch (Exception e) { + ex = e; // unexpected + } + assertNull("Exception was thrown for valid attributes", ex); + ex = null; + try { + index = mAudioManager.getVolumeIndexForAttributes(aaForUsage); + } catch (Exception e) { + ex = e; // unexpected + } + assertNull("Exception was thrown for valid attributes", ex); + ex = null; + try { + mAudioManager.setVolumeIndexForAttributes(aaForUsage, indexMin, 0/*flags*/); + } catch (Exception e) { + ex = e; // unexpected + } + assertNull("Exception was thrown for valid attributes", ex); + + index = mAudioManager.getVolumeIndexForAttributes(aaForUsage); + assertEquals(index, indexMin); + + mAudioManager.setVolumeIndexForAttributes(aaForUsage, indexMax, 0/*flags*/); + index = mAudioManager.getVolumeIndexForAttributes(aaForUsage); + assertEquals(index, indexMax); + } + } + + //----------------------------------------------------------------- + // Test register/unregister VolumeGroupCallback + //----------------------------------------------------------------- + public void testVolumeGroupCallback() throws Exception { + List<AudioVolumeGroup> audioVolumeGroups = mAudioManager.getAudioVolumeGroups(); + assertTrue(audioVolumeGroups.size() > 0); + + AudioVolumeGroupCallbackHelper vgCbReceiver = new AudioVolumeGroupCallbackHelper(); + mAudioManager.registerVolumeGroupCallback(mContext.getMainExecutor(), vgCbReceiver); + + final List<Integer> publicStreams = Ints.asList(PUBLIC_STREAM_TYPES); + try { + // Validate Audio Volume Groups callback reception + for (final AudioVolumeGroup audioVolumeGroup : audioVolumeGroups) { + int volumeGroupId = audioVolumeGroup.getId(); + + // Set the receiver to filter only the current group callback + vgCbReceiver.setExpectedVolumeGroup(volumeGroupId); + + List<AudioAttributes> avgAttributes = audioVolumeGroup.getAudioAttributes(); + int[] avgStreamTypes = audioVolumeGroup.getLegacyStreamTypes(); + + int index = 0; + int indexMax = 0; + int indexMin = 0; + + // Set the volume per attributes (if valid) and wait the callback + for (final AudioAttributes aa : avgAttributes) { + if (aa.equals(sDefaultAttributes)) { + // Some volume groups may not have valid attributes, used for internal + // volume management like patch/rerouting + // so bailing out strategy retrieval from attributes + continue; + } + index = mAudioManager.getVolumeIndexForAttributes(aa); + indexMax = mAudioManager.getMaxVolumeIndexForAttributes(aa); + indexMin = mAudioManager.getMinVolumeIndexForAttributes(aa); + index = incrementVolumeIndex(index, indexMin, indexMax); + + vgCbReceiver.setExpectedVolumeGroup(volumeGroupId); + mAudioManager.setVolumeIndexForAttributes(aa, index, 0/*flags*/); + assertTrue(vgCbReceiver.waitForExpectedVolumeGroupChanged( + AudioVolumeGroupCallbackHelper.ASYNC_TIMEOUT_MS)); + + int readIndex = mAudioManager.getVolumeIndexForAttributes(aa); + assertEquals(readIndex, index); + } + // Set the volume per stream type (if valid) and wait the callback + for (final int avgStreamType : avgStreamTypes) { + if (avgStreamType == AudioSystem.STREAM_DEFAULT) { + // Some Volume Groups may not have corresponding stream types as they + // intends to address volume setting per attributes to avoid adding new + // stream type and going on deprecating the stream type even for volume + // so bailing out strategy retrieval from stream type + continue; + } + if (!publicStreams.contains(avgStreamType) + || avgStreamType == AudioManager.STREAM_ACCESSIBILITY) { + // Limit scope of test to public stream that do not require any + // permission (e.g. Changing ACCESSIBILITY is subject to permission). + continue; + } + index = mAudioManager.getStreamVolume(avgStreamType); + indexMax = mAudioManager.getStreamMaxVolume(avgStreamType); + indexMin = mAudioManager.getStreamMinVolumeInt(avgStreamType); + index = incrementVolumeIndex(index, indexMin, indexMax); + + vgCbReceiver.setExpectedVolumeGroup(volumeGroupId); + mAudioManager.setStreamVolume(avgStreamType, index, 0/*flags*/); + assertTrue(vgCbReceiver.waitForExpectedVolumeGroupChanged( + AudioVolumeGroupCallbackHelper.ASYNC_TIMEOUT_MS)); + + int readIndex = mAudioManager.getStreamVolume(avgStreamType); + assertEquals(index, readIndex); + } + } + } finally { + mAudioManager.unregisterVolumeGroupCallback(vgCbReceiver); + } + } +} diff --git a/media/tests/AudioPolicyTest/src/com/android/audiopolicytest/AudioPolicyTest.java b/media/tests/AudioPolicyTest/src/com/android/audiopolicytest/AudioPolicyTest.java new file mode 100644 index 000000000000..e0c7b223a2e4 --- /dev/null +++ b/media/tests/AudioPolicyTest/src/com/android/audiopolicytest/AudioPolicyTest.java @@ -0,0 +1,38 @@ +/* + * 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.audiopolicytest; + +import android.app.Activity; +import android.os.Bundle; + +public class AudioPolicyTest extends Activity { + + public AudioPolicyTest() { + } + + /** Called when the activity is first created. */ + @Override + public void onCreate(Bundle icicle) { + super.onCreate(icicle); + setContentView(R.layout.audiopolicytest); + } + + @Override + public void onDestroy() { + super.onDestroy(); + } +} diff --git a/media/tests/AudioPolicyTest/src/com/android/audiopolicytest/AudioProductStrategyTest.java b/media/tests/AudioPolicyTest/src/com/android/audiopolicytest/AudioProductStrategyTest.java new file mode 100644 index 000000000000..c0f596b974e1 --- /dev/null +++ b/media/tests/AudioPolicyTest/src/com/android/audiopolicytest/AudioProductStrategyTest.java @@ -0,0 +1,213 @@ +/* + * 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.audiopolicytest; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; + +import android.media.AudioAttributes; +import android.media.AudioSystem; +import android.media.audiopolicy.AudioProductStrategy; +import android.media.audiopolicy.AudioVolumeGroup; +import android.util.Log; + +import java.util.List; + +public class AudioProductStrategyTest extends AudioVolumesTestBase { + private static final String TAG = "AudioProductStrategyTest"; + + //----------------------------------------------------------------- + // Test getAudioProductStrategies and validate strategies + //----------------------------------------------------------------- + public void testGetProductStrategies() throws Exception { + List<AudioProductStrategy> audioProductStrategies = + AudioProductStrategy.getAudioProductStrategies(); + + assertNotNull(audioProductStrategies); + assertTrue(audioProductStrategies.size() > 0); + + for (final AudioProductStrategy aps : audioProductStrategies) { + assertTrue(aps.getId() >= 0); + + AudioAttributes aa = aps.getAudioAttributes(); + assertNotNull(aa); + + // Ensure API consistency + assertTrue(aps.supportsAudioAttributes(aa)); + + int streamType = aps.getLegacyStreamTypeForAudioAttributes(aa); + if (streamType == AudioSystem.STREAM_DEFAULT) { + // bailing out test for volume group APIs consistency + continue; + } + final int volumeGroupFromStream = aps.getVolumeGroupIdForLegacyStreamType(streamType); + final int volumeGroupFromAttributes = aps.getVolumeGroupIdForAudioAttributes(aa); + assertNotEquals(volumeGroupFromStream, AudioVolumeGroup.DEFAULT_VOLUME_GROUP); + assertEquals(volumeGroupFromStream, volumeGroupFromAttributes); + } + } + + //----------------------------------------------------------------- + // Test stream to/from attributes conversion + //----------------------------------------------------------------- + public void testAudioAttributesFromStreamTypes() throws Exception { + List<AudioProductStrategy> audioProductStrategies = + AudioProductStrategy.getAudioProductStrategies(); + + assertNotNull(audioProductStrategies); + assertTrue(audioProductStrategies.size() > 0); + + for (final int streamType : PUBLIC_STREAM_TYPES) { + AudioAttributes aaFromStreamType = + AudioProductStrategy.getAudioAttributesForStrategyWithLegacyStreamType( + streamType); + + // No strategy found for this stream type or no attributes defined for the strategy + // hosting this stream type; Bailing out the test, just ensure that any request + // for reciproque API with the unknown attributes would return default stream + // for volume control, aka STREAM_MUSIC. + if (aaFromStreamType.equals(sInvalidAttributes)) { + assertEquals(AudioSystem.STREAM_MUSIC, + AudioProductStrategy.getLegacyStreamTypeForStrategyWithAudioAttributes( + aaFromStreamType)); + } else { + // Attributes are valid, i.e. a strategy was found supporting this stream type + // with valid attributes. Ensure reciproque works fine + int streamTypeFromAttributes = + AudioProductStrategy.getLegacyStreamTypeForStrategyWithAudioAttributes( + aaFromStreamType); + assertEquals("stream " + AudioSystem.streamToString(streamType) + "(" + + streamType + ") expected to match attributes " + + aaFromStreamType.toString() + " got instead stream " + + AudioSystem.streamToString(streamTypeFromAttributes) + "(" + + streamTypeFromAttributes + ") expected to match attributes ", + streamType, streamTypeFromAttributes); + } + + // Now identify the strategy supporting this stream type, ensure uniqueness + boolean strategyFound = false; + for (final AudioProductStrategy aps : audioProductStrategies) { + AudioAttributes aaFromAps = + aps.getAudioAttributesForLegacyStreamType(streamType); + + if (aaFromAps == null) { + // not this one... + continue; + } + // Got it! + assertFalse("Unique ProductStrategy shall match for a given stream type", + strategyFound); + strategyFound = true; + + // Ensure getters aligned + assertEquals(aaFromStreamType, aaFromAps); + assertTrue(aps.supportsAudioAttributes(aaFromStreamType)); + + // Ensure reciproque works fine + assertEquals(streamType, + aps.getLegacyStreamTypeForAudioAttributes(aaFromStreamType)); + + // Ensure consistency of volume group getter API + final int volumeGroupFromStream = + aps.getVolumeGroupIdForLegacyStreamType(streamType); + final int volumeGroupFromAttributes = + aps.getVolumeGroupIdForAudioAttributes(aaFromStreamType); + assertNotEquals(volumeGroupFromStream, AudioVolumeGroup.DEFAULT_VOLUME_GROUP); + assertEquals(volumeGroupFromStream, volumeGroupFromAttributes); + } + if (!strategyFound) { + // No strategy found, ensure volume control is MUSIC + assertEquals(AudioSystem.STREAM_MUSIC, + AudioProductStrategy.getLegacyStreamTypeForStrategyWithAudioAttributes( + aaFromStreamType)); + } + } + } + + public void testAudioAttributesToStreamTypes() throws Exception { + List<AudioProductStrategy> audioProductStrategies = + AudioProductStrategy.getAudioProductStrategies(); + + assertNotNull(audioProductStrategies); + assertTrue(audioProductStrategies.size() > 0); + + for (int usage : AudioAttributes.SDK_USAGES) { + AudioAttributes aaForUsage = new AudioAttributes.Builder().setUsage(usage).build(); + + int streamTypeFromUsage = + AudioProductStrategy.getLegacyStreamTypeForStrategyWithAudioAttributes( + aaForUsage); + + // Cannot be undefined, always shall fall back on a valid stream type + // to be able to control the volume + assertNotEquals(streamTypeFromUsage, AudioSystem.STREAM_DEFAULT); + + Log.w(TAG, "GUSTAVE aaForUsage=" + aaForUsage.toString()); + + // Now identify the strategy hosting these Audio Attributes and ensure informations + // matches. + // Now identify the strategy supporting this stream type, ensure uniqueness + boolean strategyFound = false; + for (final AudioProductStrategy aps : audioProductStrategies) { + if (!aps.supportsAudioAttributes(aaForUsage)) { + // Not this one + continue; + } + // Got it! + String msg = "Unique ProductStrategy shall match for a given audio attributes " + + aaForUsage.toString() + " already associated also matches with" + + aps.toString(); + assertFalse(msg, strategyFound); + strategyFound = true; + + // It may not return the expected stream type if the strategy does not have + // associated stream type. + // Behavior of member function getLegacyStreamTypeForAudioAttributes is + // different than getLegacyStreamTypeForStrategyWithAudioAttributes since it + // does not fallback on MUSIC stream type for volume operation + int streamTypeFromAps = aps.getLegacyStreamTypeForAudioAttributes(aaForUsage); + if (streamTypeFromAps == AudioSystem.STREAM_DEFAULT) { + // No stream type assigned to this strategy + // Expect static API to return default stream type for volume (aka MUSIC) + assertEquals("Strategy (" + aps.toString() + ") has no associated stream " + + ", must fallback on MUSIC stream as default", + streamTypeFromUsage, AudioSystem.STREAM_MUSIC); + } else { + assertEquals("Attributes " + aaForUsage.toString() + " associated to stream " + + AudioSystem.streamToString(streamTypeFromUsage) + + " are supported by strategy (" + aps.toString() + ") which reports " + + " these attributes are associated to stream " + + AudioSystem.streamToString(streamTypeFromAps), + streamTypeFromUsage, streamTypeFromAps); + + // Ensure consistency of volume group getter API + int volumeGroupFromStream = + aps.getVolumeGroupIdForLegacyStreamType(streamTypeFromAps); + int volumeGroupFromAttributes = + aps.getVolumeGroupIdForAudioAttributes(aaForUsage); + assertNotEquals( + volumeGroupFromStream, AudioVolumeGroup.DEFAULT_VOLUME_GROUP); + assertEquals(volumeGroupFromStream, volumeGroupFromAttributes); + } + } + if (!strategyFound) { + // No strategy found for the given attributes, the expected stream must be MUSIC + assertEquals(streamTypeFromUsage, AudioSystem.STREAM_MUSIC); + } + } + } +} diff --git a/media/tests/AudioPolicyTest/src/com/android/audiopolicytest/AudioVolumeGroupCallbackHelper.java b/media/tests/AudioPolicyTest/src/com/android/audiopolicytest/AudioVolumeGroupCallbackHelper.java new file mode 100644 index 000000000000..0c1d52c57020 --- /dev/null +++ b/media/tests/AudioPolicyTest/src/com/android/audiopolicytest/AudioVolumeGroupCallbackHelper.java @@ -0,0 +1,69 @@ +/* + * 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.audiopolicytest; + +import static org.junit.Assert.assertNotNull; + +import android.media.AudioManager; +import android.util.Log; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + + +final class AudioVolumeGroupCallbackHelper extends AudioManager.VolumeGroupCallback { + private static final String TAG = "AudioVolumeGroupCallbackHelper"; + public static final long ASYNC_TIMEOUT_MS = 800; + + private int mExpectedVolumeGroupId; + + private CountDownLatch mVolumeGroupChanged = null; + + void setExpectedVolumeGroup(int group) { + mVolumeGroupChanged = new CountDownLatch(1); + mExpectedVolumeGroupId = group; + } + + @Override + public void onAudioVolumeGroupChanged(int group, int flags) { + if (group != mExpectedVolumeGroupId) { + return; + } + if (mVolumeGroupChanged == null) { + Log.wtf(TAG, "Received callback but object not initialized"); + return; + } + if (mVolumeGroupChanged.getCount() <= 0) { + Log.i(TAG, "callback for group: " + group + " already received"); + return; + } + mVolumeGroupChanged.countDown(); + } + + public boolean waitForExpectedVolumeGroupChanged(long timeOutMs) { + assertNotNull("Call first setExpectedVolumeGroup before waiting...", mVolumeGroupChanged); + boolean timeoutReached = false; + if (mVolumeGroupChanged.getCount() == 0) { + // done already... + return true; + } + try { + timeoutReached = !mVolumeGroupChanged.await(ASYNC_TIMEOUT_MS, TimeUnit.MILLISECONDS); + } catch (InterruptedException e) { } + return !timeoutReached; + } +} diff --git a/media/tests/AudioPolicyTest/src/com/android/audiopolicytest/AudioVolumeGroupChangeHandlerTest.java b/media/tests/AudioPolicyTest/src/com/android/audiopolicytest/AudioVolumeGroupChangeHandlerTest.java new file mode 100644 index 000000000000..221f1f7fef17 --- /dev/null +++ b/media/tests/AudioPolicyTest/src/com/android/audiopolicytest/AudioVolumeGroupChangeHandlerTest.java @@ -0,0 +1,180 @@ +/* + * 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.audiopolicytest; + +import static org.junit.Assert.assertEquals; +import static org.testng.Assert.assertThrows; + +import android.media.AudioAttributes; +import android.media.AudioManager; +import android.media.audiopolicy.AudioVolumeGroup; +import android.media.audiopolicy.AudioVolumeGroupChangeHandler; + +import java.util.ArrayList; +import java.util.List; + +public class AudioVolumeGroupChangeHandlerTest extends AudioVolumesTestBase { + private static final String TAG = "AudioVolumeGroupChangeHandlerTest"; + + public void testRegisterInvalidCallback() throws Exception { + final AudioVolumeGroupChangeHandler audioAudioVolumeGroupChangedHandler = + new AudioVolumeGroupChangeHandler(); + + audioAudioVolumeGroupChangedHandler.init(); + + assertThrows(NullPointerException.class, () -> { + AudioManager.VolumeGroupCallback nullCb = null; + audioAudioVolumeGroupChangedHandler.registerListener(nullCb); + }); + } + + public void testUnregisterInvalidCallback() throws Exception { + final AudioVolumeGroupChangeHandler audioAudioVolumeGroupChangedHandler = + new AudioVolumeGroupChangeHandler(); + + audioAudioVolumeGroupChangedHandler.init(); + + final AudioVolumeGroupCallbackHelper cb = new AudioVolumeGroupCallbackHelper(); + audioAudioVolumeGroupChangedHandler.registerListener(cb); + + assertThrows(NullPointerException.class, () -> { + AudioManager.VolumeGroupCallback nullCb = null; + audioAudioVolumeGroupChangedHandler.unregisterListener(nullCb); + }); + audioAudioVolumeGroupChangedHandler.unregisterListener(cb); + } + + public void testRegisterUnregisterCallback() throws Exception { + final AudioVolumeGroupChangeHandler audioAudioVolumeGroupChangedHandler = + new AudioVolumeGroupChangeHandler(); + + audioAudioVolumeGroupChangedHandler.init(); + final AudioVolumeGroupCallbackHelper validCb = new AudioVolumeGroupCallbackHelper(); + + // Should not assert, otherwise test will fail + audioAudioVolumeGroupChangedHandler.registerListener(validCb); + + // Should not assert, otherwise test will fail + audioAudioVolumeGroupChangedHandler.unregisterListener(validCb); + } + + public void testCallbackReceived() throws Exception { + final AudioVolumeGroupChangeHandler audioAudioVolumeGroupChangedHandler = + new AudioVolumeGroupChangeHandler(); + + audioAudioVolumeGroupChangedHandler.init(); + + final AudioVolumeGroupCallbackHelper validCb = new AudioVolumeGroupCallbackHelper(); + audioAudioVolumeGroupChangedHandler.registerListener(validCb); + + List<AudioVolumeGroup> audioVolumeGroups = mAudioManager.getAudioVolumeGroups(); + assertTrue(audioVolumeGroups.size() > 0); + + try { + for (final AudioVolumeGroup audioVolumeGroup : audioVolumeGroups) { + int volumeGroupId = audioVolumeGroup.getId(); + + List<AudioAttributes> avgAttributes = audioVolumeGroup.getAudioAttributes(); + // Set the volume per attributes (if valid) and wait the callback + if (avgAttributes.size() == 0 || avgAttributes.get(0).equals(sDefaultAttributes)) { + // Some volume groups may not have valid attributes, used for internal + // volume management like patch/rerouting + // so bailing out strategy retrieval from attributes + continue; + } + final AudioAttributes aa = avgAttributes.get(0); + + int index = mAudioManager.getVolumeIndexForAttributes(aa); + int indexMax = mAudioManager.getMaxVolumeIndexForAttributes(aa); + int indexMin = mAudioManager.getMinVolumeIndexForAttributes(aa); + + final int indexForAa = incrementVolumeIndex(index, indexMin, indexMax); + + // Set the receiver to filter only the current group callback + validCb.setExpectedVolumeGroup(volumeGroupId); + mAudioManager.setVolumeIndexForAttributes(aa, indexForAa, 0/*flags*/); + assertTrue(validCb.waitForExpectedVolumeGroupChanged( + AudioVolumeGroupCallbackHelper.ASYNC_TIMEOUT_MS)); + + final int readIndex = mAudioManager.getVolumeIndexForAttributes(aa); + assertEquals(readIndex, indexForAa); + } + } finally { + audioAudioVolumeGroupChangedHandler.unregisterListener(validCb); + } + } + + public void testMultipleCallbackReceived() throws Exception { + + final AudioVolumeGroupChangeHandler audioAudioVolumeGroupChangedHandler = + new AudioVolumeGroupChangeHandler(); + + audioAudioVolumeGroupChangedHandler.init(); + + final int callbackCount = 10; + final List<AudioVolumeGroupCallbackHelper> validCbs = + new ArrayList<AudioVolumeGroupCallbackHelper>(); + for (int i = 0; i < callbackCount; i++) { + validCbs.add(new AudioVolumeGroupCallbackHelper()); + } + for (final AudioVolumeGroupCallbackHelper cb : validCbs) { + audioAudioVolumeGroupChangedHandler.registerListener(cb); + } + + List<AudioVolumeGroup> audioVolumeGroups = mAudioManager.getAudioVolumeGroups(); + assertTrue(audioVolumeGroups.size() > 0); + + try { + for (final AudioVolumeGroup audioVolumeGroup : audioVolumeGroups) { + int volumeGroupId = audioVolumeGroup.getId(); + + List<AudioAttributes> avgAttributes = audioVolumeGroup.getAudioAttributes(); + // Set the volume per attributes (if valid) and wait the callback + if (avgAttributes.size() == 0 || avgAttributes.get(0).equals(sDefaultAttributes)) { + // Some volume groups may not have valid attributes, used for internal + // volume management like patch/rerouting + // so bailing out strategy retrieval from attributes + continue; + } + AudioAttributes aa = avgAttributes.get(0); + + int index = mAudioManager.getVolumeIndexForAttributes(aa); + int indexMax = mAudioManager.getMaxVolumeIndexForAttributes(aa); + int indexMin = mAudioManager.getMinVolumeIndexForAttributes(aa); + + final int indexForAa = incrementVolumeIndex(index, indexMin, indexMax); + + // Set the receiver to filter only the current group callback + for (final AudioVolumeGroupCallbackHelper cb : validCbs) { + cb.setExpectedVolumeGroup(volumeGroupId); + } + mAudioManager.setVolumeIndexForAttributes(aa, indexForAa, 0/*flags*/); + + for (final AudioVolumeGroupCallbackHelper cb : validCbs) { + assertTrue(cb.waitForExpectedVolumeGroupChanged( + AudioVolumeGroupCallbackHelper.ASYNC_TIMEOUT_MS)); + } + int readIndex = mAudioManager.getVolumeIndexForAttributes(aa); + assertEquals(readIndex, indexForAa); + } + } finally { + for (final AudioVolumeGroupCallbackHelper cb : validCbs) { + audioAudioVolumeGroupChangedHandler.unregisterListener(cb); + } + } + } +} diff --git a/media/tests/AudioPolicyTest/src/com/android/audiopolicytest/AudioVolumeGroupTest.java b/media/tests/AudioPolicyTest/src/com/android/audiopolicytest/AudioVolumeGroupTest.java new file mode 100644 index 000000000000..84b24b8fcab3 --- /dev/null +++ b/media/tests/AudioPolicyTest/src/com/android/audiopolicytest/AudioVolumeGroupTest.java @@ -0,0 +1,131 @@ +/* + * 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.audiopolicytest; + +import static org.junit.Assert.assertNotEquals; + +import android.media.AudioAttributes; +import android.media.AudioSystem; +import android.media.audiopolicy.AudioProductStrategy; +import android.media.audiopolicy.AudioVolumeGroup; + +import java.util.List; + +public class AudioVolumeGroupTest extends AudioVolumesTestBase { + private static final String TAG = "AudioVolumeGroupTest"; + + //----------------------------------------------------------------- + // Test getAudioVolumeGroups and validate groud id + //----------------------------------------------------------------- + public void testGetVolumeGroupsFromNonServiceCaller() throws Exception { + // The transaction behind getAudioVolumeGroups will fail. Check is done at binder level + // with policy service. Error is not reported, the list is just empty. + // Request must come from service components + List<AudioVolumeGroup> audioVolumeGroup = AudioVolumeGroup.getAudioVolumeGroups(); + + assertNotNull(audioVolumeGroup); + assertEquals(audioVolumeGroup.size(), 0); + } + + //----------------------------------------------------------------- + // Test getAudioVolumeGroups and validate groud id + //----------------------------------------------------------------- + public void testGetVolumeGroups() throws Exception { + // Through AudioManager, the transaction behind getAudioVolumeGroups will succeed + final List<AudioVolumeGroup> audioVolumeGroup = mAudioManager.getAudioVolumeGroups(); + assertNotNull(audioVolumeGroup); + assertTrue(audioVolumeGroup.size() > 0); + + final List<AudioProductStrategy> audioProductStrategies = + mAudioManager.getAudioProductStrategies(); + assertTrue(audioProductStrategies.size() > 0); + + for (final AudioVolumeGroup avg : audioVolumeGroup) { + int avgId = avg.getId(); + assertNotEquals(avgId, AudioVolumeGroup.DEFAULT_VOLUME_GROUP); + + List<AudioAttributes> avgAttributes = avg.getAudioAttributes(); + assertNotNull(avgAttributes); + + final int[] avgStreamTypes = avg.getLegacyStreamTypes(); + assertNotNull(avgStreamTypes); + + // for each volume group attributes, find the matching product strategy and ensure + // it is linked the considered volume group + for (final AudioAttributes aa : avgAttributes) { + if (aa.equals(sDefaultAttributes)) { + // Some volume groups may not have valid attributes, used for internal + // volume management like patch/rerouting + // so bailing out strategy retrieval from attributes + continue; + } + boolean isVolumeGroupAssociatedToStrategy = false; + for (final AudioProductStrategy aps : audioProductStrategies) { + int groupId = aps.getVolumeGroupIdForAudioAttributes(aa); + if (groupId != AudioVolumeGroup.DEFAULT_VOLUME_GROUP) { + // Note that Audio Product Strategies are priority ordered, and the + // the first one matching the AudioAttributes will be used to identify + // the volume group associated to the request. + assertTrue(aps.supportsAudioAttributes(aa)); + assertEquals("Volume Group ID (" + avg.toString() + + "), and Volume group ID associated to Strategy (" + + aps.toString() + ") both supporting attributes " + + aa.toString() + " are mismatching", + avgId, groupId); + isVolumeGroupAssociatedToStrategy = true; + break; + } + } + assertTrue("Volume Group (" + avg.toString() + + ") has no associated strategy for attributes " + aa.toString(), + isVolumeGroupAssociatedToStrategy); + } + + // for each volume group stream type, find the matching product strategy and ensure + // it is linked the considered volume group + for (final int avgStreamType : avgStreamTypes) { + if (avgStreamType == AudioSystem.STREAM_DEFAULT) { + // Some Volume Groups may not have corresponding stream types as they + // intends to address volume setting per attributes to avoid adding new + // stream type and going on deprecating the stream type even for volume + // so bailing out strategy retrieval from stream type + continue; + } + boolean isVolumeGroupAssociatedToStrategy = false; + for (final AudioProductStrategy aps : audioProductStrategies) { + int groupId = aps.getVolumeGroupIdForLegacyStreamType(avgStreamType); + if (groupId != AudioVolumeGroup.DEFAULT_VOLUME_GROUP) { + + assertEquals("Volume Group ID (" + avg.toString() + + "), and Volume group ID associated to Strategy (" + + aps.toString() + ") both supporting stream " + + AudioSystem.streamToString(avgStreamType) + "(" + + avgStreamType + ") are mismatching", + avgId, groupId); + + isVolumeGroupAssociatedToStrategy = true; + break; + } + } + assertTrue("Volume Group (" + avg.toString() + + ") has no associated strategy for stream " + + AudioSystem.streamToString(avgStreamType) + "(" + avgStreamType + ")", + isVolumeGroupAssociatedToStrategy); + } + } + } +} diff --git a/media/tests/AudioPolicyTest/src/com/android/audiopolicytest/AudioVolumesTestBase.java b/media/tests/AudioPolicyTest/src/com/android/audiopolicytest/AudioVolumesTestBase.java new file mode 100644 index 000000000000..a17d65cf7376 --- /dev/null +++ b/media/tests/AudioPolicyTest/src/com/android/audiopolicytest/AudioVolumesTestBase.java @@ -0,0 +1,146 @@ +/* + * 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.audiopolicytest; + +import android.content.Context; +import android.content.pm.PackageManager; +import android.media.AudioAttributes; +import android.media.AudioManager; +import android.media.audiopolicy.AudioProductStrategy; +import android.media.audiopolicy.AudioVolumeGroup; +import android.test.ActivityInstrumentationTestCase2; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class AudioVolumesTestBase extends ActivityInstrumentationTestCase2<AudioPolicyTest> { + public AudioManager mAudioManager; + Context mContext; + private Map<Integer, Integer> mOriginalStreamVolumes = new HashMap<>(); + private Map<Integer, Integer> mOriginalVolumeGroupVolumes = new HashMap<>(); + + // Default matches the invalid (empty) attributes from native. + // The difference is the input source default which is not aligned between native and java + public static final AudioAttributes sDefaultAttributes = + AudioProductStrategy.sDefaultAttributes; + + public static final AudioAttributes sInvalidAttributes = new AudioAttributes.Builder().build(); + + public final int[] PUBLIC_STREAM_TYPES = { AudioManager.STREAM_VOICE_CALL, + AudioManager.STREAM_SYSTEM, AudioManager.STREAM_RING, AudioManager.STREAM_MUSIC, + AudioManager.STREAM_ALARM, AudioManager.STREAM_NOTIFICATION, + AudioManager.STREAM_DTMF, AudioManager.STREAM_ACCESSIBILITY }; + + public AudioVolumesTestBase() { + super("com.android.audiopolicytest", AudioPolicyTest.class); + } + + /** + * <p>Note: must be called with shell permission (MODIFY_AUDIO_ROUTING) + */ + private void storeAllVolumes() { + List<AudioVolumeGroup> audioVolumeGroups = mAudioManager.getAudioVolumeGroups(); + for (final AudioVolumeGroup avg : audioVolumeGroups) { + if (avg.getAudioAttributes().isEmpty()) { + // some volume group may not supports volume control per attributes + // like rerouting/patch since these groups are internal to audio policy manager + continue; + } + AudioAttributes avgAttributes = sDefaultAttributes; + for (final AudioAttributes aa : avg.getAudioAttributes()) { + if (!aa.equals(AudioProductStrategy.sDefaultAttributes)) { + avgAttributes = aa; + break; + } + } + if (avgAttributes.equals(sDefaultAttributes)) { + // This shall not happen, however, not purpose of this base class. + // so bailing out. + continue; + } + mOriginalVolumeGroupVolumes.put( + avg.getId(), mAudioManager.getVolumeIndexForAttributes(avgAttributes)); + } + } + + /** + * <p>Note: must be called with shell permission (MODIFY_AUDIO_ROUTING) + */ + private void restoreAllVolumes() { + List<AudioVolumeGroup> audioVolumeGroups = mAudioManager.getAudioVolumeGroups(); + for (Map.Entry<Integer, Integer> e : mOriginalVolumeGroupVolumes.entrySet()) { + for (final AudioVolumeGroup avg : audioVolumeGroups) { + if (avg.getId() == e.getKey()) { + assertTrue(!avg.getAudioAttributes().isEmpty()); + AudioAttributes avgAttributes = sDefaultAttributes; + for (final AudioAttributes aa : avg.getAudioAttributes()) { + if (!aa.equals(AudioProductStrategy.sDefaultAttributes)) { + avgAttributes = aa; + break; + } + } + assertTrue(!avgAttributes.equals(sDefaultAttributes)); + mAudioManager.setVolumeIndexForAttributes( + avgAttributes, e.getValue(), AudioManager.FLAG_ALLOW_RINGER_MODES); + } + } + } + } + + @Override + protected void setUp() throws Exception { + super.setUp(); + + mContext = getActivity(); + mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE); + + assertEquals(PackageManager.PERMISSION_GRANTED, + mContext.checkSelfPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)); + + // Store the original volumes that that they can be recovered in tearDown(). + mOriginalStreamVolumes.clear(); + for (int streamType : PUBLIC_STREAM_TYPES) { + mOriginalStreamVolumes.put(streamType, mAudioManager.getStreamVolume(streamType)); + } + // Store the original volume per attributes so that they can be recovered in tearDown() + mOriginalVolumeGroupVolumes.clear(); + storeAllVolumes(); + } + + @Override + protected void tearDown() throws Exception { + super.tearDown(); + + // Recover the volume and the ringer mode that the test may have overwritten. + for (Map.Entry<Integer, Integer> e : mOriginalStreamVolumes.entrySet()) { + mAudioManager.setStreamVolume(e.getKey(), e.getValue(), + AudioManager.FLAG_ALLOW_RINGER_MODES); + } + + // Recover the original volume per attributes + restoreAllVolumes(); + } + + public static int resetVolumeIndex(int indexMin, int indexMax) { + return (indexMax + indexMin) / 2; + } + + public static int incrementVolumeIndex(int index, int indexMin, int indexMax) { + return (index + 1 > indexMax) ? resetVolumeIndex(indexMin, indexMax) : ++index; + } +} diff --git a/packages/CarSystemUI/src/com/android/systemui/car/keyguard/CarKeyguardViewController.java b/packages/CarSystemUI/src/com/android/systemui/car/keyguard/CarKeyguardViewController.java index 1814fd0403d0..a4bb916b16ea 100644 --- a/packages/CarSystemUI/src/com/android/systemui/car/keyguard/CarKeyguardViewController.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/keyguard/CarKeyguardViewController.java @@ -26,6 +26,8 @@ import android.view.View; import android.view.ViewGroup; import android.view.ViewRootImpl; +import androidx.annotation.VisibleForTesting; + import com.android.internal.widget.LockPatternUtils; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.keyguard.KeyguardViewController; @@ -332,6 +334,11 @@ public class CarKeyguardViewController extends OverlayViewController implements getLayout().setVisibility(View.INVISIBLE); } + @VisibleForTesting + void setKeyguardBouncer(KeyguardBouncer keyguardBouncer) { + mBouncer = keyguardBouncer; + } + private void revealKeyguardIfBouncerPrepared() { int reattemptDelayMillis = 50; Runnable revealKeyguard = () -> { diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/keyguard/CarKeyguardViewControllerTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/keyguard/CarKeyguardViewControllerTest.java new file mode 100644 index 000000000000..d4cf6ccf4b9e --- /dev/null +++ b/packages/CarSystemUI/tests/src/com/android/systemui/car/keyguard/CarKeyguardViewControllerTest.java @@ -0,0 +1,209 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.car.keyguard; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.content.Context; +import android.os.Handler; +import android.testing.AndroidTestingRunner; +import android.testing.TestableLooper; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import com.android.internal.widget.LockPatternUtils; +import com.android.keyguard.KeyguardUpdateMonitor; +import com.android.keyguard.ViewMediatorCallback; +import com.android.systemui.R; +import com.android.systemui.SysuiTestCase; +import com.android.systemui.car.CarServiceProvider; +import com.android.systemui.keyguard.DismissCallbackRegistry; +import com.android.systemui.navigationbar.car.CarNavigationBarController; +import com.android.systemui.plugins.FalsingManager; +import com.android.systemui.statusbar.phone.BiometricUnlockController; +import com.android.systemui.statusbar.phone.KeyguardBouncer; +import com.android.systemui.statusbar.phone.KeyguardBypassController; +import com.android.systemui.statusbar.policy.KeyguardStateController; +import com.android.systemui.window.OverlayViewGlobalStateController; +import com.android.systemui.window.SystemUIOverlayWindowController; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +@RunWith(AndroidTestingRunner.class) +@TestableLooper.RunWithLooper +public class CarKeyguardViewControllerTest extends SysuiTestCase { + + private TestableCarKeyguardViewController mCarKeyguardViewController; + private OverlayViewGlobalStateController mOverlayViewGlobalStateController; + private ViewGroup mBaseLayout; + + @Mock + private KeyguardBouncer mBouncer; + @Mock + private CarNavigationBarController mCarNavigationBarController; + @Mock + private SystemUIOverlayWindowController mSystemUIOverlayWindowController; + @Mock + private CarKeyguardViewController.OnKeyguardCancelClickedListener mCancelClickedListener; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + + mOverlayViewGlobalStateController = new OverlayViewGlobalStateController( + mCarNavigationBarController, mSystemUIOverlayWindowController); + mBaseLayout = (ViewGroup) LayoutInflater.from(mContext).inflate( + R.layout.sysui_overlay_window, /* root= */ null); + when(mSystemUIOverlayWindowController.getBaseLayout()).thenReturn(mBaseLayout); + + mCarKeyguardViewController = new TestableCarKeyguardViewController( + mContext, + Handler.getMain(), + mock(CarServiceProvider.class), + mOverlayViewGlobalStateController, + mock(KeyguardStateController.class), + mock(KeyguardUpdateMonitor.class), + mock(BiometricUnlockController.class), + mock(ViewMediatorCallback.class), + mock(CarNavigationBarController.class), + mock(LockPatternUtils.class), + mock(DismissCallbackRegistry.class), + mock(FalsingManager.class), + mock(KeyguardBypassController.class) + ); + } + + @Test + public void onShow_bouncerIsSecure_showsBouncerWithSecuritySelectionReset() { + when(mBouncer.isSecure()).thenReturn(true); + mCarKeyguardViewController.show(/* options= */ null); + + verify(mBouncer).show(/* resetSecuritySelection= */ true); + } + + @Test + public void onShow_bouncerIsSecure_keyguardIsVisible() { + when(mBouncer.isSecure()).thenReturn(true); + mCarKeyguardViewController.show(/* options= */ null); + + assertThat(mBaseLayout.findViewById(R.id.keyguard_container).getVisibility()).isEqualTo( + View.VISIBLE); + } + + @Test + public void onShow_bouncerNotSecure_hidesBouncerAndDestroysTheView() { + when(mBouncer.isSecure()).thenReturn(false); + mCarKeyguardViewController.show(/* options= */ null); + + verify(mBouncer).hide(/* destroyView= */ true); + } + + @Test + public void onShow_bouncerNotSecure_keyguardIsNotVisible() { + when(mBouncer.isSecure()).thenReturn(false); + mCarKeyguardViewController.show(/* options= */ null); + + assertThat(mBaseLayout.findViewById(R.id.keyguard_container).getVisibility()).isEqualTo( + View.GONE); + } + + @Test + public void onHide_keyguardShowing_hidesBouncerAndDestroysTheView() { + when(mBouncer.isSecure()).thenReturn(true); + mCarKeyguardViewController.show(/* options= */ null); + mCarKeyguardViewController.hide(/* startTime= */ 0, /* fadeoutDelay= */ 0); + + verify(mBouncer).hide(/* destroyView= */ true); + } + + @Test + public void onHide_keyguardNotShown_doesNotHideOrDestroyBouncer() { + mCarKeyguardViewController.hide(/* startTime= */ 0, /* fadeoutDelay= */ 0); + + verify(mBouncer, never()).hide(anyBoolean()); + } + + @Test + public void onHide_KeyguardNotVisible() { + when(mBouncer.isSecure()).thenReturn(true); + mCarKeyguardViewController.show(/* options= */ null); + mCarKeyguardViewController.hide(/* startTime= */ 0, /* fadeoutDelay= */ 0); + + assertThat(mBaseLayout.findViewById(R.id.keyguard_container).getVisibility()).isEqualTo( + View.GONE); + } + + @Test + public void onCancelClicked_callsCancelClickedListener() { + when(mBouncer.isSecure()).thenReturn(true); + mCarKeyguardViewController.show(/* options= */ null); + mCarKeyguardViewController.registerOnKeyguardCancelClickedListener(mCancelClickedListener); + mCarKeyguardViewController.onCancelClicked(); + + verify(mCancelClickedListener).onCancelClicked(); + } + + @Test + public void onCancelClicked_hidesBouncerAndDestroysTheView() { + when(mBouncer.isSecure()).thenReturn(true); + mCarKeyguardViewController.show(/* options= */ null); + mCarKeyguardViewController.registerOnKeyguardCancelClickedListener(mCancelClickedListener); + mCarKeyguardViewController.onCancelClicked(); + + verify(mBouncer).hide(/* destroyView= */ true); + } + + private class TestableCarKeyguardViewController extends CarKeyguardViewController { + + TestableCarKeyguardViewController(Context context, + Handler mainHandler, + CarServiceProvider carServiceProvider, + OverlayViewGlobalStateController overlayViewGlobalStateController, + KeyguardStateController keyguardStateController, + KeyguardUpdateMonitor keyguardUpdateMonitor, + BiometricUnlockController biometricUnlockController, + ViewMediatorCallback viewMediatorCallback, + CarNavigationBarController carNavigationBarController, + LockPatternUtils lockPatternUtils, + DismissCallbackRegistry dismissCallbackRegistry, + FalsingManager falsingManager, + KeyguardBypassController keyguardBypassController) { + super(context, mainHandler, carServiceProvider, overlayViewGlobalStateController, + keyguardStateController, keyguardUpdateMonitor, biometricUnlockController, + viewMediatorCallback, carNavigationBarController, lockPatternUtils, + dismissCallbackRegistry, falsingManager, keyguardBypassController); + } + + @Override + public void onFinishInflate() { + super.onFinishInflate(); + setKeyguardBouncer(CarKeyguardViewControllerTest.this.mBouncer); + } + } + +} diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/InstallStart.java b/packages/PackageInstaller/src/com/android/packageinstaller/InstallStart.java index c11e1a03cb00..6fbee16e3dae 100644 --- a/packages/PackageInstaller/src/com/android/packageinstaller/InstallStart.java +++ b/packages/PackageInstaller/src/com/android/packageinstaller/InstallStart.java @@ -30,13 +30,17 @@ import android.content.pm.IPackageManager; import android.content.pm.PackageInstaller; import android.content.pm.PackageManager; import android.content.pm.ProviderInfo; +import android.content.pm.UserInfo; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.os.RemoteException; +import android.os.UserManager; import android.permission.IPermissionManager; import android.util.Log; +import java.util.List; + /** * Select which activity is the first visible activity of the installation and forward the intent to * it. @@ -47,6 +51,7 @@ public class InstallStart extends Activity { private static final String DOWNLOADS_AUTHORITY = "downloads"; private IPackageManager mIPackageManager; private IPermissionManager mIPermissionManager; + private UserManager mUserManager; private boolean mAbortInstall = false; @Override @@ -54,6 +59,7 @@ public class InstallStart extends Activity { super.onCreate(savedInstanceState); mIPackageManager = AppGlobals.getPackageManager(); mIPermissionManager = AppGlobals.getPermissionManager(); + mUserManager = getSystemService(UserManager.class); Intent intent = getIntent(); String callingPackage = getCallingPackage(); @@ -144,13 +150,16 @@ public class InstallStart extends Activity { if (packages == null) { return false; } + final List<UserInfo> users = mUserManager.getUsers(); for (String packageName : packages) { - try { - if (uid == getPackageManager().getPackageUid(packageName, 0)) { - return true; + for (UserInfo user : users) { + try { + if (uid == getPackageManager().getPackageUidAsUser(packageName, user.id)) { + return true; + } + } catch (PackageManager.NameNotFoundException e) { + // Ignore and try the next package } - } catch (PackageManager.NameNotFoundException e) { - // Ignore and try the next package } } } catch (RemoteException rexc) { diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-or/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-or/strings.xml index 6b1f2590f8e2..1d23c31f493d 100644 --- a/packages/SettingsLib/RestrictedLockUtils/res/values-or/strings.xml +++ b/packages/SettingsLib/RestrictedLockUtils/res/values-or/strings.xml @@ -17,6 +17,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="enabled_by_admin" msgid="6630472777476410137">"ବ୍ୟବସ୍ଥାପକଙ୍କ ଦ୍ୱାରା ସକ୍ଷମ କରାଯାଇଛି"</string> + <string name="enabled_by_admin" msgid="6630472777476410137">"ଆଡମିନଙ୍କ ଦ୍ୱାରା ସକ୍ଷମ କରାଯାଇଛି"</string> <string name="disabled_by_admin" msgid="4023569940620832713">"ବ୍ୟବସ୍ଥାପକଙ୍କ ଦ୍ଵାରା ଅକ୍ଷମ କରାଯାଇଛି"</string> </resources> diff --git a/packages/SettingsLib/RestrictedLockUtils/src/com/android/settingslib/RestrictedLockUtils.java b/packages/SettingsLib/RestrictedLockUtils/src/com/android/settingslib/RestrictedLockUtils.java index fa2ec55bd81a..a77e34b4af1e 100644 --- a/packages/SettingsLib/RestrictedLockUtils/src/com/android/settingslib/RestrictedLockUtils.java +++ b/packages/SettingsLib/RestrictedLockUtils/src/com/android/settingslib/RestrictedLockUtils.java @@ -147,6 +147,28 @@ public class RestrictedLockUtils { public EnforcedAdmin() { } + /** + * Combines two {@link EnforcedAdmin} into one: if one of them is null, then just return + * the other. If both of them are the same, then return that. Otherwise return the symbolic + * {@link #MULTIPLE_ENFORCED_ADMIN} + */ + public static EnforcedAdmin combine(EnforcedAdmin admin1, EnforcedAdmin admin2) { + if (admin1 == null) { + return admin2; + } + if (admin2 == null) { + return admin1; + } + if (admin1.equals(admin2)) { + return admin1; + } + if (!admin1.enforcedRestriction.equals(admin2.enforcedRestriction)) { + throw new IllegalArgumentException( + "Admins with different restriction cannot be combined"); + } + return MULTIPLE_ENFORCED_ADMIN; + } + @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/packages/SettingsLib/SearchWidget/res/values-be/strings.xml b/packages/SettingsLib/SearchWidget/res/values-be/strings.xml index 4fc722faba52..c72f8199f12e 100644 --- a/packages/SettingsLib/SearchWidget/res/values-be/strings.xml +++ b/packages/SettingsLib/SearchWidget/res/values-be/strings.xml @@ -17,5 +17,5 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="search_menu" msgid="1914043873178389845">"Налады пошуку"</string> + <string name="search_menu" msgid="1914043873178389845">"Пошук налад"</string> </resources> diff --git a/packages/SettingsLib/SearchWidget/res/values-pa/strings.xml b/packages/SettingsLib/SearchWidget/res/values-pa/strings.xml index 8c7dd6fe3ec6..09a285b7452f 100644 --- a/packages/SettingsLib/SearchWidget/res/values-pa/strings.xml +++ b/packages/SettingsLib/SearchWidget/res/values-pa/strings.xml @@ -17,5 +17,5 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="search_menu" msgid="1914043873178389845">"ਖੋਜ ਸੈਟਿੰਗਾਂ"</string> + <string name="search_menu" msgid="1914043873178389845">"ਸੈਟਿੰਗਾਂ ਵਿੱਚ ਖੋਜੋ"</string> </resources> diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml index a5bac278e383..90526dbea0ea 100644 --- a/packages/SettingsLib/res/values-af/strings.xml +++ b/packages/SettingsLib/res/values-af/strings.xml @@ -212,7 +212,7 @@ <string name="adb_wireless_settings" msgid="2295017847215680229">"Draadlose ontfouting"</string> <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Skakel draadlose ontfouting aan om beskikbare toestelle te sien en te gebruik"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"Gebruik QR-kode om toestel saam te bind"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"Gebruik QR-kodeskandeerder om nuwe toestelle saam te bind"</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"Gebruik QR-kodeskandeerder om nuwe toestelle saam te bind"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"Gebruik saambindkode om toestel saam te bind"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"Gebruik \'n sessyferkode om nuwe toestelle saam te bind"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"Saamgebinde toestelle"</string> @@ -231,7 +231,7 @@ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"Kon nie die toestel saambind nie. Óf die QR-kode is verkeerd, óf die toestel is nie aan dieselfde netwerk gekoppel nie."</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP-adres en -poort"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"Skandeer QR-kode"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"Bind toestel oor Wi-Fi saam deur \'n QR-kode te skandeer"</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Bind toestel oor Wi-Fi saam deur \'n QR-kode te skandeer"</string> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Koppel asseblief aan \'n Wi-Fi-netwerk"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, debug, dev"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"Kortpad na foutverslag"</string> @@ -251,6 +251,7 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"Draadlose skermsertifisering"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"Aktiveer Wi-Fi-woordryke aanmelding"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"Regulering van Wi-Fi-opsporing"</string> + <string name="wifi_enhanced_mac_randomization" msgid="5437378364995776979">"Wi‑Fi‑verbeterde MAC-verewekansiging"</string> <string name="mobile_data_always_on" msgid="8275958101875563572">"Mobiele data is altyd aktief"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"Hardewareversnelling vir verbinding"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"Wys Bluetooth-toestelle sonder name"</string> @@ -283,6 +284,7 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"Wys opsies vir draadlose skermsertifisering"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Verhoog Wi-Fi-aantekeningvlak, wys per SSID RSSI in Wi‑Fi-kieser"</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"Verlaag batteryverbruik en verbeter netwerk se werkverrigting"</string> + <string name="wifi_enhanced_mac_randomization_summary" msgid="7925425746373704991">"Hierdie skakelaar beïnvloed MAC-verewekansiginggedrag net vir klantmodus.\nWanneer hierdie modus geaktiveer is, kan enige netwerke waarvoor MAC-verewekansiging geaktiveer is, se MAC-adresse tydens die assosiasie weer verewigkansig word, na gelang van wanneer die klant laas van die netwerk ontkoppel het. Herverewekansiging vind nie plaas as die toestel binne 4 uur of korter herkoppel nie."</string> <string name="wifi_metered_label" msgid="8737187690304098638">"Beperk"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"Onbeperk"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"Loggerbuffer se groottes"</string> @@ -371,6 +373,8 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"Wys Program Reageer Nie-dialoog vir agtergrondprogramme"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"Wys kennisgewingkanaalwaarskuwings"</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"Wys waarskuwing op skerm wanneer \'n program \'n kennisgewing sonder \'n geldige kanaal plaas"</string> + <string name="enforce_shortcuts_for_conversations" msgid="7040735163945040763">"Dwing kortpaaie vir gesprekkennisgewings af"</string> + <string name="enforce_shortcuts_for_conversations_summary" msgid="1860168037282467862">"Kennisgewings moet deur \'n langleef-delingkortpad gerugsteun word om in gesprekafdeling te kan verskyn"</string> <string name="force_allow_on_external" msgid="9187902444231637880">"Dwing toelating op eksterne berging"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Maak dat enige program na eksterne berging geskryf kan word, ongeag manifeswaardes"</string> <string name="force_resizable_activities" msgid="7143612144399959606">"Dwing aktiwiteite om verstelbaar te wees"</string> diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml index 126efcc9bbd4..d25ef9bb4149 100644 --- a/packages/SettingsLib/res/values-am/strings.xml +++ b/packages/SettingsLib/res/values-am/strings.xml @@ -212,7 +212,7 @@ <string name="adb_wireless_settings" msgid="2295017847215680229">"ገመድ-አልባ debugging"</string> <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"የሚገኙ መሣሪያዎችን ለመመልከትና ለመጠቀም ገመድ-አልባ debuggingን ያብሩ"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"የQR ኮድን በመጠቀም መሣሪያን ያጣምሩ"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"የQR ኮድ መቃኛን በመጠቀም አዲስ መሣሪያዎችን ያጣምሩ"</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"የQR ኮድ መቃኛን በመጠቀም አዲስ መሣሪያዎችን ያጣምሩ"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"የማጣመሪያ ኮድን በመጠቀም መሣሪያን ያጣምሩ"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"የስድስት አኃዝ ኮድ በመጠቀም አዲስ መሣሪያዎችን ያጣምሩ"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"የተጣመሩ መሣሪያዎች"</string> @@ -231,7 +231,7 @@ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"መሣሪያውን ማጣመር አልተሳካም። ወይም QR ኮዱ ትክክል አልነበረም፣ ወይም መሣሪያው ከተመሳሳዩ አውታረ መረብ ጋር አልተገናኘም።"</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"የአይፒ አድራሻ እና ወደብ"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"QR ኮድን ይቃኙ"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"የQR ኮድ በመጠቀም መሣሪያን በመቃኘት በWi-Fi ላይ ያጣምሩ"</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"የQR ኮድ በመጠቀም መሣሪያን በመቃኘት በWi-Fi ላይ ያጣምሩ"</string> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"እባክዎ ከWi-Fi አውታረ መረብ ጋር ያገናኙ"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb፣ ማረም፣ ግንባታ"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"የሳንካ ሪፖርት አቋራጭ"</string> @@ -251,6 +251,8 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"የገመድ አልባ ማሳያ እውቅና ማረጋገጫ"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"የWi‑Fi ተጨማሪ ቃላት ምዝግብ ማስታወሻ መያዝ"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"Wi‑Fi scan throttling"</string> + <!-- no translation found for wifi_enhanced_mac_randomization (5437378364995776979) --> + <skip /> <string name="mobile_data_always_on" msgid="8275958101875563572">"የተንቀሳቃሽ ስልክ ውሂብ ሁልጊዜ ገቢር ነው"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"የሃርድዌር ማቀላጠፊያን በማስተሳሰር ላይ"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"የብሉቱዝ መሣሪያዎችን ያለ ስሞች አሳይ"</string> @@ -283,6 +285,8 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"የገመድ አልባ ማሳያ እውቅና ማረጋገጫ አማራጮችን አሳይ"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"የWi‑Fi ምዝግብ ማስታወሻ አያያዝ ደረጃ ጨምር፣ በWi‑Fi መምረጫ ውስጥ በአንድ SSID RSSI አሳይ"</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"የባትሪ መላሸቅን ይቀንሳል እንዲሁም የአውታረ መረብ አፈጻጸም ብቃትን ያሻሽላል"</string> + <!-- no translation found for wifi_enhanced_mac_randomization_summary (7925425746373704991) --> + <skip /> <string name="wifi_metered_label" msgid="8737187690304098638">"የሚለካ"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"ያልተለካ"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"የምዝግብ ማስታወሻ ያዥ መጠኖች"</string> @@ -371,6 +375,8 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"ለጀርባ መተግበሪያዎች የመተግበሪያ ምላሽ አይሰጥም መገናኛን አሳይ"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"የማሳወቂያ ሰርጥ ማስጠንቀቂያዎችን አሳይ"</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"አንድ መተግበሪያ የሚሰራ ሰርጥ ሳይኖረው ማሳወቂያ ሲለጥፍ በማያ ገጽ-ላይ ማስጠንቀቂያን ያሳያል"</string> + <string name="enforce_shortcuts_for_conversations" msgid="7040735163945040763">"ለውይይት ማሳወቂያዎች አቋራጮች ተፈጻሚ ያድርጉ"</string> + <string name="enforce_shortcuts_for_conversations_summary" msgid="1860168037282467862">"በውይይት ክፍል ውስጥ እንዲታይ በረዥም ጊዜ የሚቆይ የማጋራት አቋርጭ እንዲደገፉ ማሳወቂያዎችን ይጠይቁ"</string> <string name="force_allow_on_external" msgid="9187902444231637880">"በውጫዊ ላይ ሃይል ይፈቀዳል"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"የዝርዝር ሰነዶች እሴቶች ግምት ውስጥ ሳያስገባ ማንኛውም መተግበሪያ ወደ ውጫዊ ማከማቻው ለመጻፍ ብቁ ያደርጋል"</string> <string name="force_resizable_activities" msgid="7143612144399959606">"እንቅስቃሴዎች ዳግመኛ እንዲመጣጠኑ አስገድድ"</string> diff --git a/packages/SettingsLib/res/values-ar/arrays.xml b/packages/SettingsLib/res/values-ar/arrays.xml index d65d821e71ab..bb976183776d 100644 --- a/packages/SettingsLib/res/values-ar/arrays.xml +++ b/packages/SettingsLib/res/values-ar/arrays.xml @@ -141,13 +141,13 @@ <item msgid="1241278021345116816">"تحسين جودة الصوت (٩٩٠ كيلوبت في الثانية / ٩٠٩ كيلوبت في الثانية)"</item> <item msgid="3523665555859696539">"جودة متوازنة للصوت والاتصال (660 كيلوبت في الثانية/606 كيلوبت في الثانية)"</item> <item msgid="886408010459747589">"تحسين جودة الاتصال (٣٣٠ كيلوبت في الثانية / ٣٠٣ كيلوبت في الثانية)"</item> - <item msgid="3808414041654351577">"أفضل جهد (معدل سرعة المعلومات التكيُّفي)"</item> + <item msgid="3808414041654351577">"أفضل جهد (معدل نقل البيانات التكيُّفي)"</item> </string-array> <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries"> <item msgid="804499336721569838">"تحسين جودة الصوت"</item> <item msgid="7451422070435297462">"جودة متوازنة للصوت والاتصال"</item> <item msgid="6173114545795428901">"تحسين جودة الاتصال"</item> - <item msgid="4349908264188040530">"أفضل جهد (معدل سرعة المعلومات التكيُّفي)"</item> + <item msgid="4349908264188040530">"أفضل جهد (معدل نقل البيانات التكيُّفي)"</item> </string-array> <string-array name="bluetooth_audio_active_device_summaries"> <item msgid="8019740759207729126"></item> diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml index 88d4c0304396..a7c66bd7733b 100644 --- a/packages/SettingsLib/res/values-ar/strings.xml +++ b/packages/SettingsLib/res/values-ar/strings.xml @@ -206,13 +206,13 @@ <string name="enable_adb" msgid="8072776357237289039">"تصحيح أخطاء USB"</string> <string name="enable_adb_summary" msgid="3711526030096574316">"وضع تصحيح الأخطاء عند توصيل USB"</string> <string name="clear_adb_keys" msgid="3010148733140369917">"إلغاء عمليات تفويض تصحيح أخطاء USB"</string> - <string name="enable_adb_wireless" msgid="6973226350963971018">"تصحيح الأخطاء عبر شبكة Wi-Fi"</string> + <string name="enable_adb_wireless" msgid="6973226350963971018">"تصحيح الأخطاء اللاسلكي"</string> <string name="enable_adb_wireless_summary" msgid="7344391423657093011">"وضع تصحيح الأخطاء عندما يتم الاتصال بشبكة Wi‑Fi"</string> <string name="adb_wireless_error" msgid="721958772149779856">"خطأ"</string> - <string name="adb_wireless_settings" msgid="2295017847215680229">"تصحيح الأخطاء عبر شبكة Wi-Fi"</string> - <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"لعرض الأجهزة المتاحة واستخدامها، فعِّل ميزة تصحيح الأخطاء لاسلكيًا."</string> + <string name="adb_wireless_settings" msgid="2295017847215680229">"تصحيح الأخطاء اللاسلكي"</string> + <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"لعرض الأجهزة المتاحة واستخدامها، فعِّل ميزة \"تصحيح الأخطاء اللاسلكي\"."</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"إقران الجهاز باستخدام رمز الاستجابة السريعة"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"إقران الأجهزة الجديدة باستخدام الماسح الضوئي لرموز الاستجابة السريعة"</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"إقران الأجهزة الجديدة باستخدام الماسح الضوئي لرموز الاستجابة السريعة"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"إقران الجهاز باستخدام رمز الإقران"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"إقران الأجهزة الجديدة باستخدام رمز مكوّن من 6 أعداد"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"الأجهزة المقترنة"</string> @@ -231,7 +231,7 @@ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"تعذّر إقران الجهاز. إما أن رمز الاستجابة السريعة غير صحيح أو أن الجهاز غير متصل بالشبكة نفسها."</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"عنوان IP والمنفذ"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"المسح الضوئي لرمز الاستجابة السريعة"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"إقران الجهاز من خلال شبكة Wi‑Fi عن طريق المسح الضوئي لرمز استجابة سريعة"</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"إقران الجهاز من خلال شبكة Wi‑Fi عن طريق المسح الضوئي لرمز استجابة سريعة"</string> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"يُرجى الاتصال بشبكة Wi-Fi."</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb، تصحيح الأخطاء، مطور برامج"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"اختصار تقرير الأخطاء"</string> @@ -251,6 +251,8 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"شهادة عرض شاشة لاسلكي"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"تفعيل تسجيل Wi‑Fi Verbose"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"تقييد البحث عن شبكات Wi-Fi"</string> + <!-- no translation found for wifi_enhanced_mac_randomization (5437378364995776979) --> + <skip /> <string name="mobile_data_always_on" msgid="8275958101875563572">"بيانات الجوّال نشطة دائمًا"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"تسريع الأجهزة للتوصيل"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"عرض أجهزة البلوتوث بدون أسماء"</string> @@ -283,6 +285,8 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"عرض خيارات شهادة عرض شاشة لاسلكي"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"زيادة مستوى تسجيل Wi-Fi، وعرض لكل SSID RSSI في منتقي Wi-Fi"</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"لتقليل استنفاد البطارية وتحسين أداء الشبكة."</string> + <!-- no translation found for wifi_enhanced_mac_randomization_summary (7925425746373704991) --> + <skip /> <string name="wifi_metered_label" msgid="8737187690304098638">"تفرض تكلفة استخدام"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"بدون قياس"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"أحجام ذاكرة التخزين المؤقت للتسجيل"</string> @@ -300,8 +304,8 @@ <string name="tethering_hardware_offload_summary" msgid="7801345335142803029">"استخدام إعداد تسريع الأجهزة للتوصيل إن كان متاحًا"</string> <string name="adb_warning_title" msgid="7708653449506485728">"هل تريد السماح بتصحيح أخطاء USB؟"</string> <string name="adb_warning_message" msgid="8145270656419669221">"تم تصميم تصحيح أخطاء USB لأغراض التطوير فقط. يمكن استخدامه لنسخ البيانات بين الكمبيوتر والجهاز، وتثبيت التطبيقات على جهازك بدون تنبيه، وقراءة بيانات السجل."</string> - <string name="adbwifi_warning_title" msgid="727104571653031865">"هل تريد السماح بتصحيح الأخطاء عبر شبكة Wi-Fi؟"</string> - <string name="adbwifi_warning_message" msgid="8005936574322702388">"تم تصميم ميزة \"تصحيح الأخطاء عبر شبكة Wi-Fi\" لأغراض التطوير فقط. يمكن استخدامها لنسخ البيانات بين الكمبيوتر والجهاز وتثبيت التطبيقات على جهازك بدون إرسال إشعار وقراءة بيانات السجلّ."</string> + <string name="adbwifi_warning_title" msgid="727104571653031865">"هل تريد السماح بتفعيل ميزة \"تصحيح الأخطاء اللاسلكي\"؟"</string> + <string name="adbwifi_warning_message" msgid="8005936574322702388">"تم تصميم ميزة \"تصحيح الأخطاء اللاسلكي\" لأغراض التطوير فقط. ويمكن استخدامها لنسخ البيانات بين الكمبيوتر والجهاز ، وتثبيت التطبيقات على جهازك بدون إرسال إشعار، وقراءة بيانات السجلّ."</string> <string name="adb_keys_warning_message" msgid="2968555274488101220">"هل تريد إلغاء إمكانية الدخول إلى تصحيح أخطاء USB من جميع أجهزة الكمبيوتر التي تم التصريح لها سابقًا؟"</string> <string name="dev_settings_warning_title" msgid="8251234890169074553">"هل تريد السماح لإعدادات التطوير؟"</string> <string name="dev_settings_warning_message" msgid="37741686486073668">"هذه الإعدادات مخصصة لاستخدام التطوير فقط. قد يتسبب هذا في حدوث أعطال أو خلل في أداء الجهاز والتطبيقات المثبتة عليه."</string> @@ -371,6 +375,8 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"عرض مربع الحوار \"التطبيق لا يستجيب\" مع تطبيقات الخلفية"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"عرض تحذيرات قناة الإشعار"</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"عرض تحذير على الشاشة عندما ينشر تطبيق إشعارًا بدون قناة صالحة"</string> + <string name="enforce_shortcuts_for_conversations" msgid="7040735163945040763">"فرض اختصارات لإشعارات المحادثات"</string> + <string name="enforce_shortcuts_for_conversations_summary" msgid="1860168037282467862">"يجب دعم الإشعارات باختصار مشاركة قديم لتظهر في قسم المحادثات."</string> <string name="force_allow_on_external" msgid="9187902444231637880">"السماح بإدراج التطبيقات في وحدة تخزين خارجية"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"تأهيل أي تطبيق بحيث تتم كتابته على وحدة تخزين خارجية، بغض النظر عن قيم البيان"</string> <string name="force_resizable_activities" msgid="7143612144399959606">"فرض إمكانية تغيير حجم الأنشطة"</string> diff --git a/packages/SettingsLib/res/values-as/strings.xml b/packages/SettingsLib/res/values-as/strings.xml index 73a5e7c031d7..9d96384beba0 100644 --- a/packages/SettingsLib/res/values-as/strings.xml +++ b/packages/SettingsLib/res/values-as/strings.xml @@ -206,13 +206,14 @@ <string name="enable_adb" msgid="8072776357237289039">"ইউএছবি ডিবাগিং"</string> <string name="enable_adb_summary" msgid="3711526030096574316">"ইউএছবি সংযোগ হৈ থকাৰ অৱস্থাত ডিবাগ ম\'ড"</string> <string name="clear_adb_keys" msgid="3010148733140369917">"ইউএছবি ডিবাগিং অনুমতিসমূহ প্ৰত্যাহাৰ কৰক"</string> - <string name="enable_adb_wireless" msgid="6973226350963971018">"ৱায়াৰলেছ ডিবাগিং"</string> + <string name="enable_adb_wireless" msgid="6973226350963971018">"ৱায়াৰলেচ ডি\'বাগিং"</string> <string name="enable_adb_wireless_summary" msgid="7344391423657093011">"ৱাই-ফাই সংযোজিত হৈ থকা সময়ত ডিবাগ ম’ড"</string> <string name="adb_wireless_error" msgid="721958772149779856">"আসোঁৱাহ"</string> - <string name="adb_wireless_settings" msgid="2295017847215680229">"ৱায়াৰলেছ ডিবাগিং"</string> - <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"উপলব্ধ ডিভাইচসমূহ চাবলৈ আৰু ব্যৱহাৰ কৰিবলৈ, ৱায়াৰলেছ ডিবাগিং অন কৰক"</string> + <string name="adb_wireless_settings" msgid="2295017847215680229">"ৱায়াৰলেচ ডি\'বাগিং"</string> + <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"উপলব্ধ ডিভাইচসমূহ চাবলৈ আৰু ব্যৱহাৰ কৰিবলৈ, ৱায়াৰলেচ ডি\'বাগিং অন কৰক"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"কিউআৰ ক’ডৰ জৰিয়তে ডিভাইচ পেয়াৰ কৰক"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"কিউআৰ ক’ড স্কেনাৰ ব্যৱহাৰ কৰি নতুন ডিভাইচসমূহ পেয়াৰ কৰক"</string> + <!-- no translation found for adb_pair_method_qrcode_summary (7130694277228970888) --> + <skip /> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"পেয়াৰ কৰা ক’ডৰ জৰিয়তে ডিভাইচ পেয়াৰ কৰক"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"ছটা অংকৰ ক’ড ব্যৱহাৰ কৰি নতুন ডিভাইচসমূহ পেয়াৰ কৰক"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"পেয়াৰ কৰি থোৱা ডিভাইচসমূহ"</string> @@ -231,7 +232,8 @@ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"ডিভাইচটো পেয়াৰ কৰিব পৰা নগ’ল। কিউআৰ ক’ডটো ভুল অথবা ডিভাইচটো একেটা নেটৱৰ্কৰ সৈতে সংযোগ কৰা হোৱা নাই।"</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"আইপি ঠিকনা & প’ৰ্ট"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"কিউআৰ ক’ড স্কেন কৰক"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"এটা কিউআৰ ক’ড স্কেন কৰি ৱাই-ফাইৰে ডিভাইচ পেয়াৰ কৰক"</string> + <!-- no translation found for adb_wireless_qrcode_pairing_description (6014121407143607851) --> + <skip /> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"অনুগ্ৰহ কৰি এটা ৱাই-ফাই নেটৱর্কলৈ সংযোগ কৰক"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, ডিবাগ, dev"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"বাগ ৰিপৰ্টৰ শ্ৱৰ্টকাট"</string> @@ -251,6 +253,8 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"বেতাঁৰ ডিছপ্লে’ প্ৰমাণীকৰণ"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"ৱাই-ফাই ভাৰ্ব\'ছ লগিং সক্ষম কৰক"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"ৱাই-ফাই স্কেনৰ নিয়ন্ত্ৰণ"</string> + <!-- no translation found for wifi_enhanced_mac_randomization (5437378364995776979) --> + <skip /> <string name="mobile_data_always_on" msgid="8275958101875563572">"ম’বাইল ডেটা সদা-সক্ৰিয়"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"টেডাৰিং হাৰ্ডৱেৰ ত্বৰণ"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"নামবিহীন ব্লুটুথ ডিভাইচসমূহ দেখুৱাওক"</string> @@ -283,6 +287,8 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"বেতাঁৰ ডিছপ্লে’ প্ৰমাণপত্ৰৰ বাবে বিকল্পসমূহ দেখুৱাওক"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"ৱাই-ফাই লগিঙৰ মাত্ৰা বঢ়াওক, Wi‑Fi পিকাৰত প্ৰতি SSID RSSI দেখুৱাওক"</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"বেটাৰীৰ খৰচ কমায় আৰু নেটৱৰ্কৰ কাৰ্যক্ষমতা বৃদ্ধি কৰে"</string> + <!-- no translation found for wifi_enhanced_mac_randomization_summary (7925425746373704991) --> + <skip /> <string name="wifi_metered_label" msgid="8737187690304098638">"নিৰিখ-নিৰ্দিষ্ট"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"নিৰিখ অনিৰ্দিষ্ট"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"লগাৰৰ বাফাৰৰ আকাৰ"</string> @@ -300,8 +306,8 @@ <string name="tethering_hardware_offload_summary" msgid="7801345335142803029">"যদিহে উপলব্ধ হয় তেন্তে টেডাৰিং হাৰ্ডৱেৰ ত্বৰণ ব্যৱহাৰ কৰক"</string> <string name="adb_warning_title" msgid="7708653449506485728">"ইউএছবি ডিবাগিঙৰ অনুমতি দিয়েনে?"</string> <string name="adb_warning_message" msgid="8145270656419669221">"ইউএছবি ডিবাগ কৰা কাৰ্য কেৱল বিকাশৰ উদ্দেশ্যৰেহে কৰা হৈছে৷ আপোনাৰ কম্পিউটাৰ আৰু আপোনাৰ ডিভাইচৰ মাজত ডেটা প্ৰতিলিপি কৰিবলৈ এইটো ব্যৱহাৰ কৰক, কোনো জাননী নিদিয়াকৈয়ে আপোনাৰ ডিভাইচত এপ্সমূহ ইনষ্টল কৰক আৰু লগ ডেটা পঢ়ক৷"</string> - <string name="adbwifi_warning_title" msgid="727104571653031865">"ৱায়াৰলেছ ডিবাগিঙৰ অনুমতি দিবনে?"</string> - <string name="adbwifi_warning_message" msgid="8005936574322702388">"ৱায়াৰলেছ ডিবাগিং কেৱল বিকাশৰ উদ্দেশ্যেৰে কৰা হয়। আপোনাৰ কম্পিউটাৰ আৰু আপোনাৰ ডিভাইচৰ মাজত ডেটা প্ৰতিলিপি কৰিবলৈ, কোনো জাননী নিদিয়াকৈয়ে আপোনাৰ ডিভাইচত এপ্সমূহ ইনষ্টল কৰিবলৈ আৰু লগ ডেটা পঢ়িবলৈ এইটো ব্যৱহাৰ কৰক।"</string> + <string name="adbwifi_warning_title" msgid="727104571653031865">"ৱায়াৰলেচ ডি\'বাগিংৰ অনুমতি দিবনে?"</string> + <string name="adbwifi_warning_message" msgid="8005936574322702388">"ৱায়াৰলেচ ডি\'বাগিং কেৱল বিকাশৰ উদ্দেশ্যেৰে কৰা হয়। আপোনাৰ কম্পিউটাৰ আৰু আপোনাৰ ডিভাইচৰ মাজত ডেটা প্ৰতিলিপি কৰিবলৈ, কোনো জাননী নিদিয়াকৈয়ে আপোনাৰ ডিভাইচত এপ্সমূহ ইনষ্টল কৰিবলৈ আৰু লগ ডেটা পঢ়িবলৈ এইটো ব্যৱহাৰ কৰক।"</string> <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> @@ -371,6 +377,10 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"নেপথ্য এপসমূহৰ বাবে এপে সঁহাৰি দিয়া নাই ডায়ল\'গ প্ৰদৰ্শন কৰক"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"জাননী চ্চেনেলৰ সকীয়নিসমূহ দেখুৱাওক"</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"কোনো এপে বৈধ চ্চেনেল নোহোৱাকৈ কোনো জাননী প\'ষ্ট কৰিলে স্ক্ৰীণত সকীয়নি প্ৰদৰ্শন হয়"</string> + <!-- no translation found for enforce_shortcuts_for_conversations (7040735163945040763) --> + <skip /> + <!-- no translation found for enforce_shortcuts_for_conversations_summary (1860168037282467862) --> + <skip /> <string name="force_allow_on_external" msgid="9187902444231637880">"বাহ্যিক সঞ্চয়াগাৰত এপক বলেৰে অনুমতি দিয়ক"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"মেনিফেষ্টৰ মান যিয়েই নহওক, বাহ্যিক সঞ্চয়াগাৰত লিখিবলৈ যিকোনো এপক উপযুক্ত কৰি তোলে"</string> <string name="force_resizable_activities" msgid="7143612144399959606">"বলেৰে কাৰ্যকলাপসমূহৰ আকাৰ সলনি কৰিব পৰা কৰক"</string> diff --git a/packages/SettingsLib/res/values-az/strings.xml b/packages/SettingsLib/res/values-az/strings.xml index 4cb4017fcc06..4ec5156023a5 100644 --- a/packages/SettingsLib/res/values-az/strings.xml +++ b/packages/SettingsLib/res/values-az/strings.xml @@ -206,13 +206,13 @@ <string name="enable_adb" msgid="8072776357237289039">"USB debaq prosesi"</string> <string name="enable_adb_summary" msgid="3711526030096574316">"USB qoşulu olan zaman debaq rejimi"</string> <string name="clear_adb_keys" msgid="3010148733140369917">"USB debaq avtorizasiyasını ləğv edin"</string> - <string name="enable_adb_wireless" msgid="6973226350963971018">"Simsiz sazlama"</string> + <string name="enable_adb_wireless" msgid="6973226350963971018">"WiFi sazlaması"</string> <string name="enable_adb_wireless_summary" msgid="7344391423657093011">"Wi‑Fi qoşulduqda sazlama rejimi"</string> <string name="adb_wireless_error" msgid="721958772149779856">"Xəta"</string> - <string name="adb_wireless_settings" msgid="2295017847215680229">"Simsiz sazlama"</string> - <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Əlçatan cihazları görmək və onlardan istifadə etmək üçün simsiz sazlamanı yandırın"</string> + <string name="adb_wireless_settings" msgid="2295017847215680229">"WiFi sazlaması"</string> + <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Əlçatan cihazları görmək və onlardan istifadə etmək üçün WiFi sazlamasını yandırın"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"QR kodu ilə cihazı cütləşdirin"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"QR kod Skanerindən istifadə etməklə yeni cihazları cütləşdirin"</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"QR kod skanerindən istifadə etməklə yeni cihazları birləşdirin"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"Cütləşdirmə kodu ilə cihazı cütləşdirin"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"Altı rəqəmli koddan istifadə etməklə yeni cihazları cütləşdirin"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"Cütləşdirilmiş cihazlar"</string> @@ -231,7 +231,7 @@ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"Cihazı cütləşdirmək alınmadı. Ya QR kodu yanlış idi, ya da cihaz eyni şəbəkəyə qoşulmayıb."</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP ünvanı və Port"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"QR kodu skanlayın"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"QR Kodu skanlamaqla cihazı Wi‑Fi vasitəsilə cütləşdirin"</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"QR kodu skanlamaqla cihazı Wi‑Fi vasitəsilə birləşdirin"</string> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Wi-Fi şəbəkəsinə qoşulun"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, debug, dev"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"Baq raportu qısa yolu"</string> @@ -251,6 +251,7 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"Simsiz displey sertifikatlaşması"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"Wi‑Fi Çoxsözlü Girişə icazə verin"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"Wi‑Fi skanlamasının tənzimlənməsi"</string> + <string name="wifi_enhanced_mac_randomization" msgid="5437378364995776979">"Wi‑Fi ilə qabaqcıl MAC randomizasiyası"</string> <string name="mobile_data_always_on" msgid="8275958101875563572">"Mobil data həmişə aktiv"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"Birləşmə üçün avadanlıq akselerasiyası"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"Bluetooth cihazlarını adsız göstərin"</string> @@ -283,6 +284,7 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"Simsiz displey sertifikatlaşması üçün seçimləri göstərir"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Wi‑Fi giriş səviyyəsini qaldırın, Wi‑Fi seçəndə hər SSID RSSI üzrə göstərin"</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"Batareya istifadəsini azaldır & şəbəkə performansını yaxşılaşdırır"</string> + <string name="wifi_enhanced_mac_randomization_summary" msgid="7925425746373704991">"Bu keçid yalnız müştəri rejimi üçün MAC randomizasiyasına təsir edir.\nBu rejim aktivləşdirildikdə müştərinin şəbəkədən sonuncu dəfə ayrıldığı vaxtdan asılı olaraq, əlaqələndirmə zamanı MAC randomizasiyası aktivləşdirilmiş istənilən şəbəkənin MAC ünvanı təkrar randomizasiya olunacaq. Cihaz 4 saat və ya daha qısa zaman sonra təkrar qoşularsa, təkrar randomizasiya baş vermir."</string> <string name="wifi_metered_label" msgid="8737187690304098638">"Ödənişli"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"Limitsiz"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"Logger bufer ölçüləri"</string> @@ -300,8 +302,8 @@ <string name="tethering_hardware_offload_summary" msgid="7801345335142803029">"Əlçatan oldarsa, birləşmə üçün avadanlıq akselerasiyasından istifadə edin"</string> <string name="adb_warning_title" msgid="7708653449506485728">"USB debaq funksiyasına icazə verilsin?"</string> <string name="adb_warning_message" msgid="8145270656419669221">"USB sazlanması yalnız inkişaf məqsədlidir. Kompüteriniz və cihazınız arasında datanı kopyalamaq üçün ondan istifadə edin, bildiriş olmadan tətbiqləri cihazınıza quraşdırın və qeydiyyat datasını oxuyun."</string> - <string name="adbwifi_warning_title" msgid="727104571653031865">"Simsiz sazlamaya icazə verilsin?"</string> - <string name="adbwifi_warning_message" msgid="8005936574322702388">"Simsiz sazlama yalnız inkişaf məqsədlidir. Ondan kompüteriniz və cihazınız arasında datanı kopyalamaq, cihazınızda bildiriş olmadan tətbiqləri quraşdırmaq və qeydiyyat datasını oxumaq üçün istifadə edin."</string> + <string name="adbwifi_warning_title" msgid="727104571653031865">"WiFi sazlamasına icazə verilsin?"</string> + <string name="adbwifi_warning_message" msgid="8005936574322702388">"WiFi sazlaması yalnız inkişaf məqsədlidir. Ondan kompüteriniz və cihazınız arasında datanı kopyalamaq, cihazınızda bildiriş olmadan tətbiqləri quraşdırmaq və qeydiyyat datasını oxumaq üçün istifadə edin."</string> <string name="adb_keys_warning_message" msgid="2968555274488101220">"Əvvəl icazə verdiyiniz kompüterlərdən USB debaq əməliyyatına giriş ləğv olunsun?"</string> <string name="dev_settings_warning_title" msgid="8251234890169074553">"İnkişaf ayarlarına icazə verilsin mi?"</string> <string name="dev_settings_warning_message" msgid="37741686486073668">"Bu parametrlər yalnız inkişafetdirici istifadə üçün nəzərdə tutulub. Onlar cihaz və tətbiqlərinizin sınması və ya pis işləməsinə səbəb ola bilər."</string> @@ -371,6 +373,8 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"Arxa fon tətbiqləri üçün Tətbiq Cavab Vermir dialoqunu göstərin"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"Xəbərdarlıqları göstərin"</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"Bildiriş paylaşıldıqda xəbərdarlıq göstərir"</string> + <string name="enforce_shortcuts_for_conversations" msgid="7040735163945040763">"Söhbət bildirişləri üçün qısayolları tətbiq edin"</string> + <string name="enforce_shortcuts_for_conversations_summary" msgid="1860168037282467862">"Söhbət bölməsində görünmək üçün bildirişlərin uzunmüddətli paylaşım qısayolu ilə dəstəklənməsini tələb edin"</string> <string name="force_allow_on_external" msgid="9187902444231637880">"Tətbiqlərə xaricdən məcburi icazə"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Seçilmiş hər hansı tətbiqi bəyannamə dəyərlərindən aslı olmayaraq xarici yaddaşa yazılabilən edir."</string> <string name="force_resizable_activities" msgid="7143612144399959606">"Ölçü dəyişdirmək üçün məcburi fəaliyyətlər"</string> diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml index 839b85aca0aa..a93b42297c2e 100644 --- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml +++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml @@ -212,7 +212,7 @@ <string name="adb_wireless_settings" msgid="2295017847215680229">"Bežično otklanjanje grešaka"</string> <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Da biste videli i koristili dostupne uređaje, uključite bežično otklanjanje grešaka"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"Uparite uređaj pomoću QR koda"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"Uparite nove uređaje pomoću čitača QR koda"</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"Uparite nove uređaje pomoću čitača QR koda"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"Uparite uređaj pomoću koda za uparivanje"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"Uparite nove uređaje pomoću šestocifrenog koda"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"Upareni uređaji"</string> @@ -231,7 +231,7 @@ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"Uparivanje uređaja nije uspelo. QR kôd je pogrešan ili uređaj nije povezan sa istom mrežom."</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP adresa i port"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"Skeniraj QR kôd"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"Uparite uređaj pomoću Wi‑Fi mreže ili tako što ćete skenirati QR kôd"</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Uparite uređaj pomoću Wi‑Fi mreže tako što ćete skenirati QR kôd"</string> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Povežite se na Wi-Fi mrežu"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, otklanjanje grešaka, programer"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"Prečica za izveštaj o greškama"</string> @@ -251,6 +251,7 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"Sertifikacija bežičnog ekrana"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"Omogući detaljniju evidenciju za Wi‑Fi"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"Usporavanje Wi-Fi skeniranja"</string> + <string name="wifi_enhanced_mac_randomization" msgid="5437378364995776979">"Nasumično MAC razvrstavanje po Wi‑Fi‑ju"</string> <string name="mobile_data_always_on" msgid="8275958101875563572">"Mobilni podaci su uvek aktivni"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"Hardversko ubrzanje privezivanja"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"Prikaži Bluetooth uređaje bez naziva"</string> @@ -283,6 +284,7 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"Prikaz opcija za sertifikaciju bežičnog ekrana"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Povećava nivo evidentiranja za Wi‑Fi. Prikaz po SSID RSSI-u u biraču Wi‑Fi mreže"</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"Smanjuje potrošnju baterije i poboljšava učinak mreže"</string> + <string name="wifi_enhanced_mac_randomization_summary" msgid="7925425746373704991">"Ovaj prekidač utiče na ponašanje nasumičnog razvrstavanja MAC adresa samo za režim klijenta.\nKada se ovaj režim aktivira, za mreže na kojima je omogućeno nasumično razvrstavanje MAC adresa može da dođe do ponovnog nasumičnog razvrstavanja MAC adresa tokom povezivanja, u zavisnosti od toga kada se klijent pre toga isključio sa mreže. Do ponovnog nasumičnog razvrstavanja ne dolazi ako se uređaj ponovo poveže za 4 sata ili manje."</string> <string name="wifi_metered_label" msgid="8737187690304098638">"Sa ograničenjem"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"Bez ograničenja"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"Veličine bafera podataka u programu za evidentiranje"</string> @@ -371,6 +373,8 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"Prikaži dijalog Aplikacija ne reaguje za aplikacije u pozadini"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"Prikazuj upozorenja zbog kanala za obaveštenja"</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"Prikazuje upozorenje na ekranu kada aplikacija postavi obaveštenje bez važećeg kanala"</string> + <string name="enforce_shortcuts_for_conversations" msgid="7040735163945040763">"Primenjuj prečice za obaveštenja o konverzacijama"</string> + <string name="enforce_shortcuts_for_conversations_summary" msgid="1860168037282467862">"Zahteva da obaveštenja imaju i dugoročnu prečicu za deljenje kako bi se pojavljivala u odeljku za konverzacije"</string> <string name="force_allow_on_external" msgid="9187902444231637880">"Prinudno dozvoli aplikacije u spoljnoj"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Omogućava upisivanje svih aplikacija u spoljnu memoriju, bez obzira na vrednosti manifesta"</string> <string name="force_resizable_activities" msgid="7143612144399959606">"Prinudno omogući promenu veličine aktivnosti"</string> diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml index cc0d28645856..19c532a91242 100644 --- a/packages/SettingsLib/res/values-be/strings.xml +++ b/packages/SettingsLib/res/values-be/strings.xml @@ -112,7 +112,7 @@ <string name="bluetooth_opp_profile_summary_use_for" msgid="461981154387015457">"Выкарыстоўваць для перадачы файлаў"</string> <string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"Выкарыстоўваць для ўводу"</string> <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="7689393730163320483">"Выкарыстоўваць для слыхавых апаратаў"</string> - <string name="bluetooth_pairing_accept" msgid="2054232610815498004">"Падлучыць"</string> + <string name="bluetooth_pairing_accept" msgid="2054232610815498004">"Спалучыць"</string> <string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"СПАЛУЧЫЦЬ"</string> <string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Скасаваць"</string> <string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"Спалучэнне дае доступ да вашых кантактаў і гісторыі выклікаў пры падключэнні."</string> @@ -206,19 +206,19 @@ <string name="enable_adb" msgid="8072776357237289039">"Адладка USB"</string> <string name="enable_adb_summary" msgid="3711526030096574316">"Рэжым адладкі, калі USB падключаны"</string> <string name="clear_adb_keys" msgid="3010148733140369917">"Адклікаць дазвол USB-адладкі"</string> - <string name="enable_adb_wireless" msgid="6973226350963971018">"Бесправадная адладка"</string> + <string name="enable_adb_wireless" msgid="6973226350963971018">"Адладка па Wi-Fi"</string> <string name="enable_adb_wireless_summary" msgid="7344391423657093011">"Рэжым адладкі з падключанай сеткай Wi‑Fi"</string> <string name="adb_wireless_error" msgid="721958772149779856">"Памылка"</string> - <string name="adb_wireless_settings" msgid="2295017847215680229">"Бесправадная адладка"</string> - <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Каб праглядаць і выкарыстоўваць даступныя прылады, уключыце бесправадную адладку"</string> + <string name="adb_wireless_settings" msgid="2295017847215680229">"Адладка па Wi-Fi"</string> + <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Каб праглядаць і выкарыстоўваць даступныя прылады, уключыце адладку па Wi-Fi"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"Спалучыць прыладу з дапамогай QR-кода"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"Спалучаць новыя прылады з дапамогай сканера QR-кода"</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"Спалучаць новыя прылады з дапамогай сканера QR-кода"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"Спалучыць прыладу з дапамогай кода спалучэння"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"Спалучаць новыя прылады з дапамогай шасцізначнага кода"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"Спалучаныя прылады"</string> <string name="adb_wireless_device_connected_summary" msgid="3039660790249148713">"Цяпер падключана"</string> <string name="adb_wireless_device_details_title" msgid="7129369670526565786">"Падрабязныя звесткі пра прыладу"</string> - <string name="adb_device_forget" msgid="193072400783068417">"Ігнараваць"</string> + <string name="adb_device_forget" msgid="193072400783068417">"Забыць"</string> <string name="adb_device_fingerprint_title_format" msgid="291504822917843701">"Лічбавы адбітак прылады: <xliff:g id="FINGERPRINT_PARAM">%1$s</xliff:g>"</string> <string name="adb_wireless_connection_failed_title" msgid="664211177427438438">"Не ўдалося падключыцца"</string> <string name="adb_wireless_connection_failed_message" msgid="9213896700171602073">"Пераканайцеся, што прылада \"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\" падключана да правільнай сеткі"</string> @@ -231,7 +231,7 @@ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"Не ўдалося спалучыць прыладу. QR-код няправільны, ці прылада падключана не да той самай сеткі."</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP-адрас і порт"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"Сканіраваць QR-код"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"Спалучыць прыладу праз Wi‑Fi шляхам сканіравання QR-кода"</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Спалучэнне прылады праз Wi‑Fi шляхам сканіравання QR-кода"</string> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Падключыцеся да сеткі Wi-Fi"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, адладка, распрацоўшчык"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"Ярлык для справаздачы пра памылкі"</string> @@ -251,6 +251,8 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"Сертыфікацыя бесправаднога экрана"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"Уключыць падрабязны журнал Wi‑Fi"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"Рэгуляванне пошуку сетак Wi‑Fi"</string> + <!-- no translation found for wifi_enhanced_mac_randomization (5437378364995776979) --> + <skip /> <string name="mobile_data_always_on" msgid="8275958101875563572">"Мабільная перадача даных заўсёды актыўная"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"Апаратнае паскарэнне ў рэжыме мадэма"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"Паказваць прылады Bluetooth без назваў"</string> @@ -283,6 +285,8 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"Паказаць опцыі сертыфікацыі бесправаднога экрана"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Пры выбары сеткі Wi-Fi указваць у журнале RSSI для кожнага SSID"</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"Зніжае расход зараду акумулятара і павышае прадукцыйнасць мабільных сетак"</string> + <!-- no translation found for wifi_enhanced_mac_randomization_summary (7925425746373704991) --> + <skip /> <string name="wifi_metered_label" msgid="8737187690304098638">"Сетка з улікам трафіка"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"Сетка без уліку трафіка"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"Памеры буфера журнала"</string> @@ -300,8 +304,8 @@ <string name="tethering_hardware_offload_summary" msgid="7801345335142803029">"Выкарыстоўваць апаратнае паскарэнне ў рэжыме мадэма пры наяўнасці"</string> <string name="adb_warning_title" msgid="7708653449506485728">"Дазволіць адладку USB?"</string> <string name="adb_warning_message" msgid="8145270656419669221">"Адладка USB прызначана толькі для мэтаў распрацоўкі. Яна можа выкарыстоўвацца, каб капіяваць дадзеныя паміж кампутарам і прыладай, усталёўваць прыкладанні на прыладзе без папярэдняга апавяшчэння і чытаць дадзеныя дзённiка."</string> - <string name="adbwifi_warning_title" msgid="727104571653031865">"Дазволіць бесправадную адладку?"</string> - <string name="adbwifi_warning_message" msgid="8005936574322702388">"Бесправадная адладка прызначана толькі для мэт распрацоўкі. Яна можа выкарыстоўвацца, каб капіраваць даныя паміж камп\'ютарам і прыладай, усталёўваць праграмы на прыладзе без апавяшчэння і чытаць даныя журнала."</string> + <string name="adbwifi_warning_title" msgid="727104571653031865">"Дазволіць адладку па Wi-Fi?"</string> + <string name="adbwifi_warning_message" msgid="8005936574322702388">"Адладка па Wi-Fi прызначана толькі для мэт распрацоўкі. Яна можа выкарыстоўвацца, каб капіраваць даныя паміж камп\'ютарам і прыладай, усталёўваць праграмы на прыладзе без апавяшчэння і чытаць даныя журнала."</string> <string name="adb_keys_warning_message" msgid="2968555274488101220">"Адклікаць доступ да адладкі USB з усіх камп\'ютараў, на якiх вы уваходзiлi ў сiстэму?"</string> <string name="dev_settings_warning_title" msgid="8251234890169074553">"Дазволiць налады распрацоўшчыка?"</string> <string name="dev_settings_warning_message" msgid="37741686486073668">"Гэтыя налады прызначаны толькi для распрацоўшыкаў. Яны могуць выклікаць збоi прылад i ўсталяваных на iх прыкладанняў, а таксама перашкаджаць iх працы."</string> @@ -371,6 +375,8 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"Паведамляць аб тым, што праграма не адказвае"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"Паказваць папярэджанні канала апавяшчэннаў"</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"Паказвае папярэджанне на экране, калі праграма публікуе апавяшчэнне без сапраўднага канала"</string> + <string name="enforce_shortcuts_for_conversations" msgid="7040735163945040763">"Выкарыстоўваць ярлыкі для апавяшчэнняў з размоў"</string> + <string name="enforce_shortcuts_for_conversations_summary" msgid="1860168037282467862">"Каб апавяшчэнні паяўляліся ў раздзеле размоў, абавязкова дубліраваць іх з дапамогай ярлыкоў з працяглым паказам"</string> <string name="force_allow_on_external" msgid="9187902444231637880">"Прымусова дазволіць праграмы на вонкавым сховішчы"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Робіць любую праграму даступнай для запісу на вонкавае сховішча, незалежна ад значэнняў маніфеста"</string> <string name="force_resizable_activities" msgid="7143612144399959606">"Зрабіць вокны дзеянняў даступнымі для змены памеру"</string> diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml index ef0951c623bf..0e5ae097d47f 100644 --- a/packages/SettingsLib/res/values-bg/strings.xml +++ b/packages/SettingsLib/res/values-bg/strings.xml @@ -210,9 +210,9 @@ <string name="enable_adb_wireless_summary" msgid="7344391423657093011">"Режим за отстраняване на грешки при връзка с Wi-Fi"</string> <string name="adb_wireless_error" msgid="721958772149779856">"Грешка"</string> <string name="adb_wireless_settings" msgid="2295017847215680229">"Безжично отстраняване на грешки"</string> - <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"За да виждате и използвате наличните устройства, включете функцията за отстраняване на грешки през безжична мрежа"</string> + <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"За да виждате и използвате наличните устройства, включете функцията за безжично отстраняване на грешки"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"Сдвояване на устройството чрез QR код"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"Сдвояване на новите устройства чрез скенер за QR кодове"</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"Сдвояване на новите устройства чрез скенер за QR кодове"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"Сдвояване на устройството чрез код за сдвояване"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"Сдвояване на новите устройства чрез шестцифрен код"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"Сдвоени устройства"</string> @@ -231,7 +231,7 @@ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"Сдвояването на устройството не бе успешно. QR кодът е неправилен или устройството не е свързано със същата мрежа."</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP адрес и порт"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"Сканиране на QR код"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"Сдвояване на устройството през Wi‑Fi чрез сканиране на QR код"</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Сдвояване на устройството през Wi‑Fi чрез сканиране на QR код"</string> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Моля, свържете се с Wi-Fi мрежа"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, отстраняване на грешки, програмиране"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"Пряк път за сигнал за програмна грешка"</string> @@ -251,6 +251,7 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"Безжичен дисплей"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"„Многословно“ регистр. на Wi‑Fi: Актив."</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"Ограничаване на сканирането за Wi-Fi"</string> + <string name="wifi_enhanced_mac_randomization" msgid="5437378364995776979">"Подобр. рандом. на MAC адреса чрез Wi-Fi"</string> <string name="mobile_data_always_on" msgid="8275958101875563572">"Винаги активни мобилни данни"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"Хардуерно ускорение за тетъринга"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"Показване на устройствата с Bluetooth без имена"</string> @@ -283,6 +284,7 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"Показване на опциите за сертифициране на безжичния дисплей"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"По-подробно регистр. на Wi‑Fi – данни за RSSI на SSID в инстр. за избор на Wi‑Fi"</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"Намалява изразходването на батерията и подобрява ефективността на мрежата"</string> + <string name="wifi_enhanced_mac_randomization_summary" msgid="7925425746373704991">"Този превключвател оказва влияние върху поведението при рандомизиране на MAC адреси само в режим на клиентска програма.\nКогато този режим е активиран, MAC адресът на всяка мрежа, за която функцията за рандомизиране е включена, може да бъде повторно рандомизиран по време на свързването в зависимост от това, кога последно клиентската програма е прекратила връзката си с мрежата. Не възниква повторно рандомизиране, ако устройството отново установи връзка до 4 часа."</string> <string name="wifi_metered_label" msgid="8737187690304098638">"С отчитане"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"Без отчитане"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"Размери на регистрац. буфери"</string> @@ -300,8 +302,8 @@ <string name="tethering_hardware_offload_summary" msgid="7801345335142803029">"Да се използва хардуерно ускорение на тетъринга, ако е налице"</string> <string name="adb_warning_title" msgid="7708653449506485728">"Разрешаване на отстраняването на грешки през USB?"</string> <string name="adb_warning_message" msgid="8145270656419669221">"Отстраняването на грешки през USB е предназначено само за програмни цели. Използвайте го за копиране на данни между компютъра и устройството си, за инсталиране на приложения на устройството си без известяване и за четене на регистрационни данни."</string> - <string name="adbwifi_warning_title" msgid="727104571653031865">"Да се разреши ли отстраняването на грешки през безжична мрежа?"</string> - <string name="adbwifi_warning_message" msgid="8005936574322702388">"Отстраняването на грешки през безжична мрежа е предназначено само за програмни цели. Използвайте го за копиране на данни между компютъра и устройството си, за инсталиране на приложения на устройството си без известяване и за четене на регистрационни данни."</string> + <string name="adbwifi_warning_title" msgid="727104571653031865">"Да се разреши ли безжичното отстраняване на грешки?"</string> + <string name="adbwifi_warning_message" msgid="8005936574322702388">"Безжичното отстраняване на грешки е предназначено само за програмни цели. Използвайте го за копиране на данни между компютъра и устройството си, за инсталиране на приложения на устройството си без известяване и за четене на регистрационни данни."</string> <string name="adb_keys_warning_message" msgid="2968555274488101220">"Да се отмени ли достъпът до отстраняването на грешки през USB от всички по-рано упълномощени от вас компютри?"</string> <string name="dev_settings_warning_title" msgid="8251234890169074553">"Да се разрешат ли настройките за програмиране?"</string> <string name="dev_settings_warning_message" msgid="37741686486073668">"Тези настройки са предназначени само за програмиране. Те могат да доведат до прекъсване на работата или неправилно функциониране на устройството ви и приложенията в него."</string> @@ -371,6 +373,8 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"Показване на диалоговия прозорец за грешки от типа ANR за приложенията на заден план"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"Предупрежд. за канала за известия"</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"Показва се предупреждение, когато приложение публикува известие без валиден канал"</string> + <string name="enforce_shortcuts_for_conversations" msgid="7040735163945040763">"Налагане на преки пътища за извест. за разговори"</string> + <string name="enforce_shortcuts_for_conversations_summary" msgid="1860168037282467862">"За известията да се създава рез. копие чрез постоянен пряк път за споделяне, за да се показват в секцията с разговори"</string> <string name="force_allow_on_external" msgid="9187902444231637880">"Външно хран.: принуд. разрешаване на приложенията"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Всички приложения ще отговарят на условията да бъдат записвани във външното хранилище независимо от стойностите в манифеста"</string> <string name="force_resizable_activities" msgid="7143612144399959606">"Възможност за преоразмеряване на активностите"</string> diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml index 1cd8eeae5ead..a377ff36442d 100644 --- a/packages/SettingsLib/res/values-bn/strings.xml +++ b/packages/SettingsLib/res/values-bn/strings.xml @@ -212,7 +212,8 @@ <string name="adb_wireless_settings" msgid="2295017847215680229">"ওয়্যারলেস ডিবাগিং"</string> <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"কোন কোন ডিভাইস উপলভ্য আছে তা দেখে নিয়ে ব্যবহার করার জন্য, ওয়্যারলেস ডিবাগিং চালু করুন"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"QR কোড ব্যবহার করে ডিভাইস যোগ করুন"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"QR কোড স্ক্যানার ব্যবহার করে নতুন ডিভাইস যোগ করুন"</string> + <!-- no translation found for adb_pair_method_qrcode_summary (7130694277228970888) --> + <skip /> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"যোগ করার কোড ব্যবহার করে ডিভাইস যোগ করুন"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"ছয় সংখ্যার কোড ব্যবহার করে নতুন ডিভাইস যোগ করুন"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"যোগ করা ডিভাইস"</string> @@ -231,7 +232,8 @@ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"ডিভাইস যোগ করা যায়নি। এটি দুটি কারণে হয়ে থাকে - QR কোডটি সঠিক নয় বা ডিভাইসটি একই নেটওয়ার্কে কানেক্ট করা নেই।"</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP অ্যাড্রেস ও পোর্ট"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"QR কোড স্ক্যান করুন"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"QR কোড স্ক্যান করে ওয়াই-ফাই ব্যবহার করে ডিভাইস যোগ করুন"</string> + <!-- no translation found for adb_wireless_qrcode_pairing_description (6014121407143607851) --> + <skip /> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"একটি ওয়াই-ফাই নেটওয়ার্কের সাথে কানেক্ট করুন"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, debug, dev"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"ত্রুটি প্রতিবেদনের শর্টকাট"</string> @@ -251,6 +253,8 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"ওয়্যারলেস ডিসপ্লে সার্টিফিকেশন"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"ওয়াই-ফাই ভারবোস লগিং চালু করুন"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"ওয়াই-ফাই স্ক্যান থ্রোটলিং"</string> + <!-- no translation found for wifi_enhanced_mac_randomization (5437378364995776979) --> + <skip /> <string name="mobile_data_always_on" msgid="8275958101875563572">"মোবাইল ডেটা সব সময় সক্রিয় থাক"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"টিথারিং হার্ডওয়্যার অ্যাক্সিলারেশন"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"নামহীন ব্লুটুথ ডিভাইসগুলি দেখুন"</string> @@ -273,7 +277,7 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3233402355917446304">"ব্লুটুথ অডিও LDAC কোডেক: প্লেব্যাক গুণমান"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="7274396574659784285">"ব্লুটুথ অডিও LDAC কোডেক ট্রিগার করুন\nএটি বেছে নেওয়া আছে: প্লেব্যাকের কোয়ালিটি"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="2040810756832027227">"স্ট্রিমিং: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> - <string name="select_private_dns_configuration_title" msgid="7887550926056143018">"ব্যক্তিগত ডিএনএস"</string> + <string name="select_private_dns_configuration_title" msgid="7887550926056143018">"প্রাইভেট ডিএনএস"</string> <string name="select_private_dns_configuration_dialog_title" msgid="3731422918335951912">"ব্যক্তিগত ডিএনএস মোড বেছে নিন"</string> <string name="private_dns_mode_off" msgid="7065962499349997041">"বন্ধ আছে"</string> <string name="private_dns_mode_opportunistic" msgid="1947864819060442354">"অটোমেটিক"</string> @@ -283,6 +287,8 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"ওয়্যারলেস প্রদর্শন সার্টিফিকেশন জন্য বিকল্পগুলি দেখান"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"ওয়াই-ফাই লগিং স্তর বাড়ান, ওয়াই-ফাই চয়নকারীতে SSID RSSI অনুযায়ী দেখান"</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"ব্যাটারির খরচ কমায় এবং নেটওয়ার্কের পারফর্ম্যান্স উন্নত করে"</string> + <!-- no translation found for wifi_enhanced_mac_randomization_summary (7925425746373704991) --> + <skip /> <string name="wifi_metered_label" msgid="8737187690304098638">"মিটার্ড"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"পরিমাপ করা নয়"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"লগার বাফারের আকারগুলি"</string> @@ -301,7 +307,7 @@ <string name="adb_warning_title" msgid="7708653449506485728">"USB ডিবাগিং মঞ্জুর করবেন?"</string> <string name="adb_warning_message" msgid="8145270656419669221">"USB ডিবাগিং কেবলমাত্র বিকাশ করার উদ্দেশ্যে। আপনার কম্পিউটার এবং আপনার ডিভাইসের মধ্যে ডেটা অনুলিপি করতে এটি ব্যবহার করুন, বিজ্ঞপ্তি ছাড়া আপনার ডিভাইসে অ্যাপ্লিকেশানগুলি ইনস্টল করুন এবং ডেটা লগ পড়ুন।"</string> <string name="adbwifi_warning_title" msgid="727104571653031865">"ওয়্যারলেস ডিবাগিং-এর অনুমতি দেবেন?"</string> - <string name="adbwifi_warning_message" msgid="8005936574322702388">"ওয়্যারলেস ডিবাগিং কেবলমাত্র বিকাশ করার উদ্দেশ্যে। আপনার কম্পিউটার এবং আপনার ডিভাইসের মধ্যে ডেটা কপি করতে এটি ব্যবহার করুন, বিজ্ঞপ্তি ছাড়া আপনার ডিভাইসে অ্যাপ ইনস্টল করুন এবং ডেটা লগ পড়ুন।"</string> + <string name="adbwifi_warning_message" msgid="8005936574322702388">"ওয়্যারলেস ডিবাগিং কেবলমাত্র ডেভেলপ করার উদ্দেশ্যে। আপনার কম্পিউটার এবং আপনার ডিভাইসের মধ্যে ডেটা কপি করতে এটি ব্যবহার করুন, বিজ্ঞপ্তি ছাড়া আপনার ডিভাইসে অ্যাপ ইনস্টল করুন এবং ডেটা লগ পড়ুন।"</string> <string name="adb_keys_warning_message" msgid="2968555274488101220">"আপনি আগে যে সব কম্পিউটার USB ডিবাগিং এর অ্যাক্সেসের অনুমতি দিয়েছিলেন তা প্রত্যাহার করবেন?"</string> <string name="dev_settings_warning_title" msgid="8251234890169074553">"উন্নতি সেটিংসের অনুমতি দেবেন?"</string> <string name="dev_settings_warning_message" msgid="37741686486073668">"এইসব সেটিংস কেবলমাত্র উন্নত করার উদ্দেশ্য। সেগুলি কারণে আপনার ডিভাইস ভেঙ্গে এবং অ্যাপ্লিকেশানগুলি ভালো ভাবে কাজ করা নাও কারতে পারে।"</string> @@ -371,6 +377,10 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"ব্যাকগ্রাউন্ডের অ্যাপগুলির জন্য \'অ্যাপ থেকে সাড়া পাওয়া যাচ্ছে না\' মেসেজ দেখান"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"বিজ্ঞপ্তির সতর্কতা দেখুন"</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"অ্যাপ সঠিক চ্যানেল ছাড়া বিজ্ঞপ্তি দেখালে সতর্ক করে"</string> + <!-- no translation found for enforce_shortcuts_for_conversations (7040735163945040763) --> + <skip /> + <!-- no translation found for enforce_shortcuts_for_conversations_summary (1860168037282467862) --> + <skip /> <string name="force_allow_on_external" msgid="9187902444231637880">"বহিরাগততে বলপূর্বক মঞ্জুরি"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"ম্যানিফেস্ট মানগুলি নির্বিশেষে যেকোনো অ্যাপ্লিকেশানকে বাহ্যিক সঞ্চয়স্থানে লেখার উপযুক্ত বানায়"</string> <string name="force_resizable_activities" msgid="7143612144399959606">"আকার পরিবর্তনযোগ্য করার জন্য ক্রিয়াকলাপগুলিকে জোর করুন"</string> diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml index c72411cc10e6..cdd312c036f3 100644 --- a/packages/SettingsLib/res/values-bs/strings.xml +++ b/packages/SettingsLib/res/values-bs/strings.xml @@ -210,9 +210,9 @@ <string name="enable_adb_wireless_summary" msgid="7344391423657093011">"Način rada otklanjanja grešaka kada je WiFi mreža povezana"</string> <string name="adb_wireless_error" msgid="721958772149779856">"Greška"</string> <string name="adb_wireless_settings" msgid="2295017847215680229">"Bežično otklanjanje grešaka"</string> - <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Da vidite i koristite dostupne uređaje, uključite otklanjanje grešaka putem bežične veze"</string> + <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Da vidite i koristite dostupne uređaje, uključite bežično otklanjanje grešaka"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"Uparite uređaj pomoću QR koda"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"Uparite nove uređaje pomoću skenera QR koda"</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"Uparite nove uređaje pomoću skenera QR koda"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"Uparite uređaj pomoću koda za uparivanje"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"Uparite nove uređaje pomoću šestocifrenog koda"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"Upareni uređaji"</string> @@ -231,7 +231,7 @@ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"Uparivanje uređaja nije uspjelo. QR kȏd nije tačan ili uređaj nije povezan na istu mrežu."</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP adresa i priključak"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"Skenirajte QR kôd"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"Uparite uređaj putem WiFi-ja skeniranjem QR koda"</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Uparite uređaj putem WiFi-ja skeniranjem QR koda"</string> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Povežite se na WiFi mrežu"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, otklanjanje grešaka, programer"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"Prečica za izvještaj o greškama"</string> @@ -251,6 +251,7 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"Certifikacija bežičnog prikaza"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"Omogući detaljni zapisnik za WiFi"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"Reguliranje skeniranja WiFi mreže"</string> + <string name="wifi_enhanced_mac_randomization" msgid="5437378364995776979">"Nasum. odabir MAC-a poboljšan WiFi-jem"</string> <string name="mobile_data_always_on" msgid="8275958101875563572">"Prijenos podataka na mobilnoj mreži je uvijek aktivan"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"Hardversko ubrzavanje za povezivanje putem mobitela"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"Prikaži Bluetooth uređaje bez naziva"</string> @@ -283,6 +284,7 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"Prikaz opcija za certifikaciju bežičnog prikaza"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Povećani nivo zapisnika za WiFi. Prikaz po SSID RSSI-ju u Biraču WiFi-ja"</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"Smanjuje potrošnju baterije i poboljšava performanse mreže"</string> + <string name="wifi_enhanced_mac_randomization_summary" msgid="7925425746373704991">"Ovo aktiviranje/deaktiviranje utiče na ponašanje nasumičnog odabira MAC adrese isključivo za način rada klijenta.\nKada je taj način aktiviran, na svakoj mreži na kojoj je omogućen nasumični odabir MAC adrese može doći do ponovnog nasumičnog odabira MAC adrese za vrijeme povezivanja, u zavisnosti od toga kada je posljednji put prekinuta povezanost klijenta s mrežom. Do ponovnog nasumičnog odabira ne dolazi ako se uređaj ponovo poveže u roku od 4 sata ili ranije."</string> <string name="wifi_metered_label" msgid="8737187690304098638">"S naplatom"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"Mreža bez naplate"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"Veličine međumemorije zapisnika"</string> @@ -371,6 +373,8 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"Prikaz dijaloga \"Aplikacija ne reagira\" za aplikacije pokrenute u pozadini"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"Prikaži upozorenja kanala obavještenja"</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"Prikaz upozorenja na ekranu kada aplikacija pošalje obavještenje bez važećeg kanala"</string> + <string name="enforce_shortcuts_for_conversations" msgid="7040735163945040763">"Primijeni prečice za obavještenja o razgovorima"</string> + <string name="enforce_shortcuts_for_conversations_summary" msgid="1860168037282467862">"Traži da obavještenja imaju dugotrajnu prečicu za dijeljenje radi prikaza u odjeljku za razgovore"</string> <string name="force_allow_on_external" msgid="9187902444231637880">"Nametni aplikacije na vanjskoj pohrani"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Omogućava upisivanje svih aplikacija u vanjsku pohranu, bez obzira na prikazane vrijednosti"</string> <string name="force_resizable_activities" msgid="7143612144399959606">"Nametni aktivnostima mijenjanje veličina"</string> @@ -476,7 +480,7 @@ <string name="retail_demo_reset_next" msgid="3688129033843885362">"Naprijed"</string> <string name="retail_demo_reset_title" msgid="1866911701095959800">"Potrebna je lozinka"</string> <string name="active_input_method_subtypes" msgid="4232680535471633046">"Aktivne metode unosa"</string> - <string name="use_system_language_to_select_input_method_subtypes" msgid="4865195835541387040">"Koristite jezik sistema"</string> + <string name="use_system_language_to_select_input_method_subtypes" msgid="4865195835541387040">"Koristi jezik sistema"</string> <string name="failed_to_open_app_settings_toast" msgid="764897252657692092">"Otvaranje postavki za <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g> nije uspjelo"</string> <string name="ime_security_warning" msgid="6547562217880551450">"Ovaj način unosa može prikupiti sav tekst koji upišete, uključujući lične podatke kao što su lozinke i brojevi kreditnih kartica. Način omogućava aplikacija <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. Da li želite koristiti ovaj način unosa?"</string> <string name="direct_boot_unaware_dialog_message" msgid="7845398276735021548">"Napomena: Nakon ponovnog pokretanja, ova aplikacija se neće moći pokrenuti dok ne otključate telefon"</string> @@ -541,7 +545,7 @@ <string name="user_new_user_name" msgid="60979820612818840">"Novi korisnik"</string> <string name="user_new_profile_name" msgid="2405500423304678841">"Novi profil"</string> <string name="user_info_settings_title" msgid="6351390762733279907">"Podaci o korisniku"</string> - <string name="profile_info_settings_title" msgid="105699672534365099">"Podaci o profilu"</string> + <string name="profile_info_settings_title" msgid="105699672534365099">"Informacije o profilu"</string> <string name="user_need_lock_message" msgid="4311424336209509301">"Prije nego vam se omogući kreiranje ograničenog profila, morate postaviti zaključavanje ekrana da biste zaštitili svoje aplikacije i lične podatke."</string> <string name="user_set_lock_button" msgid="1427128184982594856">"Postaviti zaključavanje"</string> <string name="user_switch_to_user" msgid="6975428297154968543">"Prebaci na korisnika <xliff:g id="USER_NAME">%s</xliff:g>"</string> diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml index 765d44259ce4..b60e6aa538d4 100644 --- a/packages/SettingsLib/res/values-ca/strings.xml +++ b/packages/SettingsLib/res/values-ca/strings.xml @@ -195,7 +195,7 @@ </string-array> <string name="choose_profile" msgid="343803890897657450">"Tria un perfil"</string> <string name="category_personal" msgid="6236798763159385225">"Personal"</string> - <string name="category_work" msgid="4014193632325996115">"Feina"</string> + <string name="category_work" msgid="4014193632325996115">"Treball"</string> <string name="development_settings_title" msgid="140296922921597393">"Opcions per a desenvolupadors"</string> <string name="development_settings_enable" msgid="4285094651288242183">"Activa les opcions per a desenvolupadors"</string> <string name="development_settings_summary" msgid="8718917813868735095">"Defineix les opcions per al desenvolupament d\'aplicacions"</string> @@ -212,7 +212,7 @@ <string name="adb_wireless_settings" msgid="2295017847215680229">"Depuració sense fil"</string> <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Per veure i utilitzar els dispositius disponibles, activa la depuració sense fil"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"Vincula el dispositiu amb un codi QR"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"Vincula dispositius nous utilitzant l\'escàner de codis QR"</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"Vincula dispositius nous utilitzant l\'escàner de codis QR"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"Vincula el dispositiu amb un codi de vinculació"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"Vincula dispositius nous utilitzant un codi de sis dígits"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"Dispositius vinculats"</string> @@ -226,12 +226,12 @@ <string name="adb_pairing_device_dialog_pairing_code_label" msgid="3639239786669722731">"Codi de vinculació Wi‑Fi"</string> <string name="adb_pairing_device_dialog_failed_title" msgid="3426758947882091735">"No s\'ha pogut vincular"</string> <string name="adb_pairing_device_dialog_failed_msg" msgid="6611097519661997148">"Assegura\'t que el dispositiu estigui connectat a la mateixa xarxa."</string> - <string name="adb_wireless_qrcode_summary" msgid="8051414549011801917">"Vincula el dispositiu per Wi‑Fi escanejant un codi QR"</string> + <string name="adb_wireless_qrcode_summary" msgid="8051414549011801917">"Escaneja un codi QR per vincular el dispositiu per Wi‑Fi"</string> <string name="adb_wireless_verifying_qrcode_text" msgid="6123192424916029207">"S\'està vinculant el dispositiu…"</string> <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"No s\'ha pogut vincular el dispositiu. O bé el codi QR és incorrecte, o bé el dispositiu no està connectat a la mateixa xarxa."</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"Adreça IP i port"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"Escaneja un codi QR"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"Vincula el dispositiu per Wi‑Fi escanejant un codi QR"</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Escaneja un codi QR per vincular el dispositiu per Wi‑Fi"</string> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Connecta\'t a una xarxa Wi‑Fi"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, depurar, desenvolupador"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"Drecera per a informe d\'errors"</string> @@ -251,6 +251,8 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"Certificació de pantalla sense fil"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"Activa el registre Wi‑Fi detallat"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"Limitació de la cerca de xarxes Wi‑Fi"</string> + <!-- no translation found for wifi_enhanced_mac_randomization (5437378364995776979) --> + <skip /> <string name="mobile_data_always_on" msgid="8275958101875563572">"Dades mòbils sempre actives"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"Acceleració per maquinari per a compartició de xarxa"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"Mostra els dispositius Bluetooth sense el nom"</string> @@ -283,6 +285,8 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"Mostra les opcions per a la certificació de pantalla sense fil"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Augmenta nivell de registre Wi‑Fi, mostra\'l per SSID RSSI al selector de Wi‑Fi"</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"Redueix el consum de bateria i millora el rendiment de la xarxa"</string> + <!-- no translation found for wifi_enhanced_mac_randomization_summary (7925425746373704991) --> + <skip /> <string name="wifi_metered_label" msgid="8737187690304098638">"D\'ús mesurat"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"D\'ús no mesurat"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"Mides de la mem. intermèdia del registrador"</string> @@ -371,6 +375,8 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"Mostra el quadre de diàleg L\'aplicació no respon per a aplicacions en segon pla"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"Mostra avisos del canal de notificacions"</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"Mostra un avís en pantalla quan una aplicació publica una notificació sense un canal vàlid"</string> + <string name="enforce_shortcuts_for_conversations" msgid="7040735163945040763">"Aplica dreceres per a notificacions de converses"</string> + <string name="enforce_shortcuts_for_conversations_summary" msgid="1860168037282467862">"Requereix que les notificacions tinguin una drecera fixa per aparèixer la secció de converses"</string> <string name="force_allow_on_external" msgid="9187902444231637880">"Força permetre aplicacions de manera externa"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Permet que qualsevol aplicació es pugui escriure en un dispositiu d’emmagatzematge extern, independentment dels valors definits"</string> <string name="force_resizable_activities" msgid="7143612144399959606">"Força l\'ajust de la mida de les activitats"</string> diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml index ed2db3a730e7..efc5680004bf 100644 --- a/packages/SettingsLib/res/values-cs/strings.xml +++ b/packages/SettingsLib/res/values-cs/strings.xml @@ -212,7 +212,7 @@ <string name="adb_wireless_settings" msgid="2295017847215680229">"Bezdrátové ladění"</string> <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Chcete-li zobrazit a použít dostupná zařízení, zapněte bezdrátové ladění"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"Párovat zařízení pomocí QR kódu"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"Párovat nová zařízení pomocí skenování QR kódu"</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"Párovat nová zařízení pomocí skeneru QR kódů"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"Párovat zařízení pomocí párovacího kódu"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"Párovat nová zařízení pomocí šestimístného kódu"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"Spárovaná zařízení"</string> @@ -231,7 +231,7 @@ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"Spárování zařízení se nezdařilo. Buď byl QR kód chybný, nebo zařízení není připojeno ke stejné síti."</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP adresa a port"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"Naskenování QR kódu"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"Párovat zařízení přes Wi-Fi naskenováním QR kódu"</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Párovat zařízení přes Wi-Fi naskenováním QR kódu"</string> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Připojte se k síti Wi-Fi"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, ladění, vývoj"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"Zástupce hlášení chyb"</string> @@ -251,6 +251,8 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"Certifikace bezdrát. displeje"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"Podrobné protokolování Wi‑Fi"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"Přibrždění vyhledávání Wi‑Fi"</string> + <!-- no translation found for wifi_enhanced_mac_randomization (5437378364995776979) --> + <skip /> <string name="mobile_data_always_on" msgid="8275958101875563572">"Mobilní data jsou vždy aktivní"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"Hardwarová akcelerace tetheringu"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"Zobrazovat zařízení Bluetooth bez názvů"</string> @@ -283,6 +285,8 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"Zobrazit možnosti certifikace bezdrátového displeje"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Zvýšit úroveň protokolování Wi‑Fi zobrazenou v SSID a RSSI při výběru sítě Wi‑Fi."</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"Snižuje vyčerpávání baterie a vylepšuje výkon sítě"</string> + <!-- no translation found for wifi_enhanced_mac_randomization_summary (7925425746373704991) --> + <skip /> <string name="wifi_metered_label" msgid="8737187690304098638">"Měřená"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"Neměřená"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"Vyrovnávací paměť protokol. nástroje"</string> @@ -371,6 +375,8 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"Zobrazovat dialog „Aplikace neodpovídá“ pro aplikace na pozadí"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"Zobrazovat upozornění ohledně kanálu oznámení"</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"Když aplikace odešle oznámení bez platného kanálu, na obrazovce se zobrazí upozornění"</string> + <string name="enforce_shortcuts_for_conversations" msgid="7040735163945040763">"U oznámení konverzací vyžadovat zkratky"</string> + <string name="enforce_shortcuts_for_conversations_summary" msgid="1860168037282467862">"V sekci konverzace zobrazovat pouze oznámení podložená dlouhodobými sdílecími zkratkami"</string> <string name="force_allow_on_external" msgid="9187902444231637880">"Vynutit povolení aplikací na externím úložišti"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Každou aplikaci bude možné zapsat do externího úložiště, bez ohledu na hodnoty manifestu"</string> <string name="force_resizable_activities" msgid="7143612144399959606">"Vynutit možnost změny velikosti aktivit"</string> diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml index f682b15deb98..4fee673b8292 100644 --- a/packages/SettingsLib/res/values-da/strings.xml +++ b/packages/SettingsLib/res/values-da/strings.xml @@ -206,13 +206,13 @@ <string name="enable_adb" msgid="8072776357237289039">"USB-fejlretning"</string> <string name="enable_adb_summary" msgid="3711526030096574316">"Fejlretningstilstand, når USB er tilsluttet"</string> <string name="clear_adb_keys" msgid="3010148733140369917">"Tilbagekald tilladelser for USB-fejlretning"</string> - <string name="enable_adb_wireless" msgid="6973226350963971018">"Trådløs fejlfinding"</string> + <string name="enable_adb_wireless" msgid="6973226350963971018">"Trådløs fejlretning"</string> <string name="enable_adb_wireless_summary" msgid="7344391423657093011">"Fejlfindingstilstand, når der er Wi-Fi-forbindelse"</string> <string name="adb_wireless_error" msgid="721958772149779856">"Fejl"</string> - <string name="adb_wireless_settings" msgid="2295017847215680229">"Trådløs fejlfinding"</string> + <string name="adb_wireless_settings" msgid="2295017847215680229">"Trådløs fejlretning"</string> <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Du kan se og bruge tilgængelige enheder ved at aktivere trådløs fejlretning"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"Dan par med en enhed ved hjælp af en QR-kode"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"Dan par med nye enheder ved hjælp af QR-kodescanneren"</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"Dan par med nye enheder ved hjælp af QR-kodescanneren"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"Dan par med en enhed ved hjælp af en parringskode"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"Dan par med nye enheder ved hjælp af den sekscifrede kode"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"Parrede enheder"</string> @@ -231,11 +231,11 @@ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"Enheden blev ikke parret. Det skyldes enten, at QR-koden var forkert, eller at enheden ikke er forbundet til det samme netværk."</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP-adresse og port"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"Scan QR-kode"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"Dan par med en enhed via Wi-Fi ved at scanne en QR-kode"</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Dan par med en enhed via Wi-Fi ved at scanne en QR-kode"</string> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Opret forbindelse til et Wi-Fi-netværk"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, fejlfinding, dev"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"Genvej til fejlrapportering"</string> - <string name="bugreport_in_power_summary" msgid="1885529649381831775">"Vis en knap til oprettelse af fejlrapporter i afbrydermenuen"</string> + <string name="bugreport_in_power_summary" msgid="1885529649381831775">"Vis en knap til oprettelse af fejlrapporter i menuen for afbryderknappen"</string> <string name="keep_screen_on" msgid="1187161672348797558">"Lås ikke"</string> <string name="keep_screen_on_summary" msgid="1510731514101925829">"Skærmen går ikke i dvale under opladning"</string> <string name="bt_hci_snoop_log" msgid="7291287955649081448">"Aktivér Bluetooth HCI spionlog"</string> @@ -251,6 +251,7 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"Certificering af trådløs skærm"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"Aktivér detaljeret Wi-Fi-logføring"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"Begrænsning af Wi-Fi-scanning"</string> + <string name="wifi_enhanced_mac_randomization" msgid="5437378364995776979">"Wi‑Fi‑forbedret MAC-randomisering"</string> <string name="mobile_data_always_on" msgid="8275958101875563572">"Mobildata er altid aktiveret"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"Hardwareacceleration ved netdeling"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"Vis Bluetooth-enheder uden navne"</string> @@ -283,6 +284,7 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"Vis valgmuligheder for certificering af trådløs skærm"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Øg mængden af Wi‑Fi-logføring. Vis opdelt efter SSID RSSI i Wi‑Fi-vælgeren"</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"Reducerer batteriforbruget og forbedrer netværkets effektivitet"</string> + <string name="wifi_enhanced_mac_randomization_summary" msgid="7925425746373704991">"Denne skift påvirker kun MAC-randomisering for klienttilstand.\nNår denne tilstand er aktiveret, kan netværk, der har Mac-randomisering aktiveret, få deres MAC-adresser randomiseret igen, når der oprettes forbindelse, afhængigt af hvornår klienten sidst afbrød forbindelse til netværket. Randomisering sker ikke igen, hvis enheden forbinder igen inden for højst 4 timer."</string> <string name="wifi_metered_label" msgid="8737187690304098638">"Forbrugsafregnet"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"Ikke forbrugsafregnet"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"Størrelser for Logger-buffer"</string> @@ -300,7 +302,7 @@ <string name="tethering_hardware_offload_summary" msgid="7801345335142803029">"Brug hardwareacceleration ved netdeling, hvis det er muligt"</string> <string name="adb_warning_title" msgid="7708653449506485728">"Vil du tillade USB-fejlretning?"</string> <string name="adb_warning_message" msgid="8145270656419669221">"USB-fejlretning er kun beregnet til udvikling og kan bruges til at kopiere data mellem din computer og enheden, installere apps på enheden uden notifikation og læse logdata."</string> - <string name="adbwifi_warning_title" msgid="727104571653031865">"Vil du tillade trådløs fejlfinding?"</string> + <string name="adbwifi_warning_title" msgid="727104571653031865">"Vil du tillade trådløs fejlretning?"</string> <string name="adbwifi_warning_message" msgid="8005936574322702388">"Trådløs fejlretning er kun beregnet til udvikling og kan bruges til at kopiere data mellem din computer og enheden, installere apps på enheden uden notifikation og læse logdata."</string> <string name="adb_keys_warning_message" msgid="2968555274488101220">"Vil du ophæve adgangen til USB-fejlretning for alle computere, du tidligere har godkendt?"</string> <string name="dev_settings_warning_title" msgid="8251234890169074553">"Vil du tillade udviklingsindstillinger?"</string> @@ -371,6 +373,8 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"Vis dialogboksen \"Appen svarer ikke\" for baggrundsapps"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"Vis advarsler om notifikationskanal"</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"Viser en advarsel, når en app sender en notifikation uden en gyldig kanal"</string> + <string name="enforce_shortcuts_for_conversations" msgid="7040735163945040763">"Kræv genveje til samtalenotifikationer"</string> + <string name="enforce_shortcuts_for_conversations_summary" msgid="1860168037282467862">"Kræv, at notifikationer bakkes op af en langvarig delingsgenvej, hvis de skal vises i samtalesektionen"</string> <string name="force_allow_on_external" msgid="9187902444231637880">"Gennemtving tilladelse til eksternt lager"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Gør det muligt at overføre enhver app til et eksternt lager uafhængigt af manifestværdier"</string> <string name="force_resizable_activities" msgid="7143612144399959606">"Gennemtving, at aktiviteter kan tilpasses"</string> diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml index 7918022e5a37..37ae78618bb8 100644 --- a/packages/SettingsLib/res/values-de/strings.xml +++ b/packages/SettingsLib/res/values-de/strings.xml @@ -206,13 +206,13 @@ <string name="enable_adb" msgid="8072776357237289039">"USB-Debugging"</string> <string name="enable_adb_summary" msgid="3711526030096574316">"Debugmodus bei Anschluss über USB"</string> <string name="clear_adb_keys" msgid="3010148733140369917">"USB-Debugging-Autorisierungen aufheben"</string> - <string name="enable_adb_wireless" msgid="6973226350963971018">"Kabelloses Debugging"</string> + <string name="enable_adb_wireless" msgid="6973226350963971018">"Debugging über WLAN"</string> <string name="enable_adb_wireless_summary" msgid="7344391423657093011">"Debugging-Modus, wenn eine WLAN-Verbindung besteht"</string> <string name="adb_wireless_error" msgid="721958772149779856">"Fehler"</string> - <string name="adb_wireless_settings" msgid="2295017847215680229">"Kabelloses Debugging"</string> - <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Aktiviere das kabellose Debugging, um verfügbare Geräte zu sehen und zu verwenden"</string> + <string name="adb_wireless_settings" msgid="2295017847215680229">"Debugging über WLAN"</string> + <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Aktiviere \"Debugging über WLAN\", um verfügbare Geräte zu sehen und zu verwenden"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"Gerät über einen QR-Code koppeln"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"Neue Geräte über QR-Codescanner koppeln"</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"Neue Geräte über QR-Codescanner koppeln"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"Gerät über einen Kopplungscode koppeln"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"Neue Geräte mit sechsstelligem Code koppeln"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"Gekoppelte Geräte"</string> @@ -231,11 +231,11 @@ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"Das Gerät konnte nicht gekoppelt werden. Der QR-Code war nicht korrekt oder das Gerät ist nicht mit demselben Netzwerk verbunden."</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP-Adresse & Port"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"QR-Code scannen"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"Scanne einen QR-Code, um ein Gerät über WLAN zu koppeln"</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Scanne einen QR-Code, um ein Gerät über WLAN zu koppeln"</string> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Bitte stell eine WLAN-Verbindung her"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"ADB, Debug, Dev"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"Verknüpfung zu Fehlerbericht"</string> - <string name="bugreport_in_power_summary" msgid="1885529649381831775">"Im Menü \"Ein/Aus\" wird eine Option zum Erstellen eines Fehlerberichts angezeigt"</string> + <string name="bugreport_in_power_summary" msgid="1885529649381831775">"Im Ein-/Aus-Menü wird eine Option zum Erstellen eines Fehlerberichts angezeigt"</string> <string name="keep_screen_on" msgid="1187161672348797558">"Aktiv lassen"</string> <string name="keep_screen_on_summary" msgid="1510731514101925829">"Display wird beim Laden nie in den Ruhezustand versetzt"</string> <string name="bt_hci_snoop_log" msgid="7291287955649081448">"Bluetooth HCI-Snoop-Protokoll aktivieren"</string> @@ -251,6 +251,7 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"Zertifizierung für kabellose Übertragung"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"Ausführliche WLAN-Protokollierung aktivieren"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"Drosselung der WLAN-Suche"</string> + <string name="wifi_enhanced_mac_randomization" msgid="5437378364995776979">"WLAN-erweiterte MAC-Adressrandomisierung"</string> <string name="mobile_data_always_on" msgid="8275958101875563572">"Mobile Datennutzung immer aktiviert"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"Hardwarebeschleunigung für Tethering"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"Bluetooth-Geräte ohne Namen anzeigen"</string> @@ -283,6 +284,7 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"Optionen zur Zertifizierung für kabellose Übertragung anzeigen"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"WLAN-Protokollierungsebene erhöhen, pro SSID RSSI in WiFi Picker anzeigen"</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"Verringert den Akkuverbrauch und verbessert die Netzwerkleistung"</string> + <string name="wifi_enhanced_mac_randomization_summary" msgid="7925425746373704991">"Hiermit wird das Verhalten der MAC-Adressrandomisierung ausschließlich für den Clientmodus umgeschaltet.\nWenn dieser Modus aktiviert ist, werden bei allen Netzwerken, bei denen die MAC-Randomisierung aktiviert ist, die MAC-Adressen während der Verknüpfung abhängig davon, wann der Client zuletzt vom Netzwerk getrennt wurde, wieder randomisiert. Die erneute Randomisierung findet nicht statt, wenn die Verbindung des Geräts innerhalb von maximal 4 Stunden wieder hergestellt wird."</string> <string name="wifi_metered_label" msgid="8737187690304098638">"Kostenpflichtig"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"Kostenlos"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"Logger-Puffergrößen"</string> @@ -300,8 +302,8 @@ <string name="tethering_hardware_offload_summary" msgid="7801345335142803029">"Falls verfügbar, Hardwarebeschleunigung für Tethering verwenden"</string> <string name="adb_warning_title" msgid="7708653449506485728">"USB-Debugging zulassen?"</string> <string name="adb_warning_message" msgid="8145270656419669221">"USB-Debugging ist nur für Entwicklungszwecke vorgesehen. Damit kannst du Daten zwischen deinem Computer und deinem Gerät kopieren, Apps auf deinem Gerät ohne Benachrichtigung installieren und Protokolldaten lesen."</string> - <string name="adbwifi_warning_title" msgid="727104571653031865">"Kabelloses Debugging zulassen?"</string> - <string name="adbwifi_warning_message" msgid="8005936574322702388">"Das kabellose Debugging ist nur für Entwicklungszwecke vorgesehen. Damit kannst du Daten zwischen deinem Computer und deinem Gerät kopieren, Apps auf deinem Gerät ohne Benachrichtigung installieren und Protokolldaten lesen."</string> + <string name="adbwifi_warning_title" msgid="727104571653031865">"\"Debugging über WLAN\" zulassen?"</string> + <string name="adbwifi_warning_message" msgid="8005936574322702388">"\"Debugging über WLAN\" ist nur für Entwicklungszwecke vorgesehen. Damit kannst du Daten zwischen deinem Computer und deinem Gerät kopieren, Apps auf deinem Gerät ohne Benachrichtigung installieren und Protokolldaten lesen."</string> <string name="adb_keys_warning_message" msgid="2968555274488101220">"Zugriff auf USB-Debugging für alle zuvor autorisierten Computer aufheben?"</string> <string name="dev_settings_warning_title" msgid="8251234890169074553">"Entwicklungseinstellungen zulassen?"</string> <string name="dev_settings_warning_message" msgid="37741686486073668">"Diese Einstellungen sind ausschließlich für Entwicklungszwecke gedacht. Sie können dein Gerät und die darauf installierten Apps beschädigen oder zu unerwünschtem Verhalten führen."</string> @@ -371,6 +373,8 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"Bei Abstürzen von Hintergrund-Apps \"App reagiert nicht\"-Dialog anzeigen"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"Benachrichtigungskanal- Warnungen anzeigen"</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"Bei Benachrichtigungen ohne gültigen Kanal wird eine Warnung angezeigt"</string> + <string name="enforce_shortcuts_for_conversations" msgid="7040735163945040763">"Tastenkombination für Benachrichtigungen zur Unterhaltung erzwingen"</string> + <string name="enforce_shortcuts_for_conversations_summary" msgid="1860168037282467862">"Benachrichtigungen müssen durch eine langlebige Tastenkombination zum Teilen unterstützt werden, um im Bereich der Unterhaltung zu erscheinen"</string> <string name="force_allow_on_external" msgid="9187902444231637880">"Sperrung des externen Speichers für alle Apps aufheben"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Jede App kann, ungeachtet der Manifestwerte, in den externen Speicher geschrieben werden"</string> <string name="force_resizable_activities" msgid="7143612144399959606">"Aktivitätengröße darf immer angepasst werden"</string> diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml index b4d7c875bf62..dfc9dd13e982 100644 --- a/packages/SettingsLib/res/values-el/strings.xml +++ b/packages/SettingsLib/res/values-el/strings.xml @@ -206,13 +206,13 @@ <string name="enable_adb" msgid="8072776357237289039">"Εντοπισμός σφαλμάτων USB"</string> <string name="enable_adb_summary" msgid="3711526030096574316">"Λειτουργία εντοπισμού σφαλμάτων όταν το USB είναι συνδεδεμένο"</string> <string name="clear_adb_keys" msgid="3010148733140369917">"Ανάκληση εξ/σεων εντ/σμού σφ/των USB"</string> - <string name="enable_adb_wireless" msgid="6973226350963971018">"Εντοπισμός σφαλμ. ασύρ. σύνδεσης"</string> + <string name="enable_adb_wireless" msgid="6973226350963971018">"Ασύρματος εντοπισμός σφαλμάτων"</string> <string name="enable_adb_wireless_summary" msgid="7344391423657093011">"Λειτουργία εντοπισμού σφαλμάτων όταν το Wi‑Fi είναι συνδεδεμένο"</string> <string name="adb_wireless_error" msgid="721958772149779856">"Σφάλμα"</string> - <string name="adb_wireless_settings" msgid="2295017847215680229">"Εντοπισμός σφαλμ. ασύρ. σύνδεσης"</string> - <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Για να δείτε και να χρησιμοποιήσετε τις διαθέσιμες συσκευές, ενεργοποιήστε τον εντοπισμό σφαλμάτων ασύρματης σύνδεσης"</string> + <string name="adb_wireless_settings" msgid="2295017847215680229">"Ασύρματος εντοπισμός σφαλμάτων"</string> + <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Για να δείτε και να χρησιμοποιήσετε τις διαθέσιμες συσκευές, ενεργοποιήστε τον ασύρματο εντοπισμό σφαλμάτων"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"Σύζευξη συσκευής με κωδικό QR"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"Σύζευξη νέων συσκευών με τη χρήση σαρωτή κωδικών QR"</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"Σύζευξη νέων συσκευών με τη χρήση σαρωτή κωδικών QR"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"Σύζευξη συσκευής με κωδικό σύζευξης"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"Σύζευξη νέων συσκευών με τη χρήση εξαψήφιου κωδικού"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"Συσκευές σε σύζευξη"</string> @@ -231,7 +231,7 @@ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"Η σύζευξη της συσκευής απέτυχε. Ο κωδικός QR ήταν λανθασμένος ή η συσκευή δεν είναι συνδεδεμένη στο ίδιο δίκτυο."</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"Διεύθυνση IP και θύρα"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"Σάρωση κωδικού QR"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"Σύζευξη συσκευής μέσω Wi‑Fi με τη σάρωση ενός κωδικού QR"</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Σύζευξη συσκευής μέσω Wi‑Fi με τη σάρωση ενός κωδικού QR"</string> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Συνδεθείτε σε ένα δίκτυο Wi-Fi"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, εντοπισμός σφαλμάτων, προγραμματιστής"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"Συντόμευση αναφοράς σφαλμάτων"</string> @@ -251,6 +251,7 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"Πιστοποίηση ασύρματης οθόνης"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"Ενεργοποίηση λεπτομερ. καταγραφής Wi-Fi"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"Περιορισμός σάρωσης Wi-Fi"</string> + <string name="wifi_enhanced_mac_randomization" msgid="5437378364995776979">"Ρύθμ. τυχαίας σειράς MAC με βελτ. Wi‑Fi"</string> <string name="mobile_data_always_on" msgid="8275958101875563572">"Πάντα ενεργά δεδομένα κινητής τηλεφωνίας"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"Σύνδεση επιτάχυνσης υλικού"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"Εμφάνιση συσκευών Bluetooth χωρίς ονόματα"</string> @@ -283,6 +284,7 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"Εμφάνιση επιλογών για πιστοποίηση ασύρματης οθόνης"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Αύξηση επιπέδου καταγ. Wi-Fi, εμφάνιση ανά SSID RSSI στο εργαλείο επιλογής Wi-Fi"</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"Περιορίζει την κατανάλωση της μπαταρίας και βελτιώνει την απόδοση του δικτύου"</string> + <string name="wifi_enhanced_mac_randomization_summary" msgid="7925425746373704991">"Αυτός ο διακόπτης επηρεάζει τη συμπεριφορά της ρύθμισης τυχαίας σειράς διευθύνσεων MAC μόνο για τη λειτουργία εφαρμογής πελάτη.\nΌταν αυτή η λειτουργία είναι ενεργοποιημένη, σε όλα τα δίκτυα που είναι ενεργή η ρύθμιση τυχαίας σειράς διευθύνσεων MAC ενδέχεται να αλλάξει ξανά η τυχαία σειρά των διευθύνσεων MAC κατά τη συσχέτιση, ανάλογα με το πότε έγινε η τελευταία αποσύνδεση της εφαρμογής πελάτη από το δίκτυο. Αν η συσκευή επανασυνδεθεί μέσα σε 4 ώρες ή λιγότερες, τότε δεν θα αλλάξει η τυχαία σειρά."</string> <string name="wifi_metered_label" msgid="8737187690304098638">"Μέτρηση με βάση τη χρήση"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"Χωρίς μέτρηση με βάση τη χρήση"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"Μέγεθος προσωρινής μνήμης για τη λειτουργία καταγραφής"</string> @@ -300,8 +302,8 @@ <string name="tethering_hardware_offload_summary" msgid="7801345335142803029">"Χρήση της σύνδεσης επιτάχυνσης υλικού εάν υπάρχει"</string> <string name="adb_warning_title" msgid="7708653449506485728">"Να επιτρέπεται ο εντοπισμός σφαλμάτων USB;"</string> <string name="adb_warning_message" msgid="8145270656419669221">"Ο εντοπισμός σφαλμάτων USB προορίζεται μόνο για σκοπούς προγραμματισμού. Χρησιμοποιήστε τον για αντιγραφή δεδομένων μεταξύ του υπολογιστή και της συσκευής σας, για την εγκατάσταση εφαρμογών στη συσκευή σας χωρίς προειδοποίηση και για την ανάγνωση δεδομένων καταγραφής."</string> - <string name="adbwifi_warning_title" msgid="727104571653031865">"Να επιτρέπεται ο εντοπισμός σφαλμάτων ασύρματης σύνδεσης;"</string> - <string name="adbwifi_warning_message" msgid="8005936574322702388">"Ο εντοπισμός σφαλμάτων ασύρματης σύνδεσης προορίζεται μόνο για σκοπούς προγραμματισμού. Χρησιμοποιήστε τον για αντιγραφή δεδομένων μεταξύ του υπολογιστή και της συσκευής σας, για την εγκατάσταση εφαρμογών στη συσκευή σας χωρίς ειδοποίηση και για την ανάγνωση δεδομένων καταγραφής."</string> + <string name="adbwifi_warning_title" msgid="727104571653031865">"Να επιτρέπεται ο ασύρματος εντοπισμός σφαλμάτων;"</string> + <string name="adbwifi_warning_message" msgid="8005936574322702388">"Ο ασύρματος εντοπισμός σφαλμάτων προορίζεται μόνο για σκοπούς προγραμματισμού. Χρησιμοποιήστε τον για αντιγραφή δεδομένων μεταξύ του υπολογιστή και της συσκευής σας, για την εγκατάσταση εφαρμογών στη συσκευή σας χωρίς ειδοποίηση και για την ανάγνωση δεδομένων καταγραφής."</string> <string name="adb_keys_warning_message" msgid="2968555274488101220">"Ανάκληση πρόσβασης στον εντοπισμό σφαλμάτων USB από όλους τους υπολογιστές για τους οποίους είχατε εξουσιοδότηση στο παρελθόν;"</string> <string name="dev_settings_warning_title" msgid="8251234890169074553">"Να επιτρέπεται η χρήση των ρυθμίσεων ανάπτυξης;"</string> <string name="dev_settings_warning_message" msgid="37741686486073668">"Αυτές οι ρυθμίσεις προορίζονται για χρήση κατά την ανάπτυξη. Μπορούν να προκαλέσουν προβλήματα στη λειτουργία της συσκευής και των εφαρμογών σας."</string> @@ -371,6 +373,8 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"Εμφάνιση του παραθύρου \"Η εφαρμογή δεν αποκρίνεται\" για εφαρμογές παρασκηνίου"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"Εμφάνιση προειδοπ. καναλιού ειδοπ."</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"Εμφανίζει προειδοποίηση όταν μια εφαρμογή δημοσιεύει ειδοποίηση χωρίς έγκυρο κανάλι"</string> + <string name="enforce_shortcuts_for_conversations" msgid="7040735163945040763">"Επιβολή συντομεύσεων για ειδοποιήσεις συνομιλίας"</string> + <string name="enforce_shortcuts_for_conversations_summary" msgid="1860168037282467862">"Να απαιτείται η υποστήριξη των ειδοπ. από μια συντόμευση κοινοποίησης μεγάλης διάρκειας για να εμφανίζονται στην ενότητα συνομιλίας"</string> <string name="force_allow_on_external" msgid="9187902444231637880">"Να επιτρέπονται υποχρεωτικά εφαρμογές σε εξωτ.συσ."</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Κάνει κάθε εφαρμογή κατάλληλη για εγγραφή σε εξωτερικό αποθηκευτικό χώρο, ανεξάρτητα από τις τιμές του μανιφέστου"</string> <string name="force_resizable_activities" msgid="7143612144399959606">"Αναγκαστική δυνατότητα αλλαγής μεγέθους δραστηριοτήτων"</string> diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml index 4cc274452b61..a932bceb02a5 100644 --- a/packages/SettingsLib/res/values-en-rAU/strings.xml +++ b/packages/SettingsLib/res/values-en-rAU/strings.xml @@ -212,7 +212,7 @@ <string name="adb_wireless_settings" msgid="2295017847215680229">"Wireless debugging"</string> <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"To see and use available devices, turn on wireless debugging"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"Pair device with QR code"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"Pair new devices using QR code scanner"</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"Pair new devices using QR code scanner"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"Pair device with pairing code"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"Pair new devices using six-digit code"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"Paired devices"</string> @@ -231,7 +231,7 @@ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"Failed to pair the device. Either the QR code was incorrect, or the device is not connected to the same network."</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP address & port"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"Scan QR code"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"Pair device over Wi‑Fi by scanning a QR code"</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Pair device over Wi‑Fi by scanning a QR code"</string> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Please connect to a Wi‑Fi network"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, debug, dev"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"Bug report shortcut"</string> @@ -251,6 +251,7 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"Wireless display certification"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"Enable Wi‑Fi verbose logging"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"Wi‑Fi scan throttling"</string> + <string name="wifi_enhanced_mac_randomization" msgid="5437378364995776979">"Wi‑Fi‑enhanced MAC randomisation"</string> <string name="mobile_data_always_on" msgid="8275958101875563572">"Mobile data always active"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"Tethering hardware acceleration"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"Show Bluetooth devices without names"</string> @@ -274,7 +275,7 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="7274396574659784285">"Trigger Bluetooth Audio LDAC\nCodec Selection: Playback Quality"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="2040810756832027227">"Streaming: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> <string name="select_private_dns_configuration_title" msgid="7887550926056143018">"Private DNS"</string> - <string name="select_private_dns_configuration_dialog_title" msgid="3731422918335951912">"Select private DNS mode"</string> + <string name="select_private_dns_configuration_dialog_title" msgid="3731422918335951912">"Select Private DNS Mode"</string> <string name="private_dns_mode_off" msgid="7065962499349997041">"Off"</string> <string name="private_dns_mode_opportunistic" msgid="1947864819060442354">"Automatic"</string> <string name="private_dns_mode_provider" msgid="3619040641762557028">"Private DNS provider hostname"</string> @@ -283,6 +284,7 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"Show options for wireless display certification"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Increase Wi‑Fi logging level, show per SSID RSSI in Wi‑Fi Picker"</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"Reduces battery drain and improves network performance"</string> + <string name="wifi_enhanced_mac_randomization_summary" msgid="7925425746373704991">"This toggle affects MAC randomisation behaviour for client mode only.\nWhen this mode is activated, any networks that have MAC randomisation enabled may have their MAC addresses re‑randomised during association, depending on when the client last disconnected from the network. Re‑randomisation does not occur if the device reconnects in four hours or less."</string> <string name="wifi_metered_label" msgid="8737187690304098638">"Metered"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"Unmetered"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"Logger buffer sizes"</string> @@ -371,6 +373,8 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"Display App Not Responding dialogue for background apps"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"Show notification channel warnings"</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"Displays on-screen warning when an app posts a notification without a valid channel"</string> + <string name="enforce_shortcuts_for_conversations" msgid="7040735163945040763">"Enforce shortcuts for conversation notifications"</string> + <string name="enforce_shortcuts_for_conversations_summary" msgid="1860168037282467862">"Require notifications to be backed by a long-lived sharing shortcut in order to appear in the conversation section"</string> <string name="force_allow_on_external" msgid="9187902444231637880">"Force allow apps on external"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Makes any app eligible to be written to external storage, regardless of manifest values"</string> <string name="force_resizable_activities" msgid="7143612144399959606">"Force activities to be resizeable"</string> diff --git a/packages/SettingsLib/res/values-en-rCA/strings.xml b/packages/SettingsLib/res/values-en-rCA/strings.xml index 4cc274452b61..a932bceb02a5 100644 --- a/packages/SettingsLib/res/values-en-rCA/strings.xml +++ b/packages/SettingsLib/res/values-en-rCA/strings.xml @@ -212,7 +212,7 @@ <string name="adb_wireless_settings" msgid="2295017847215680229">"Wireless debugging"</string> <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"To see and use available devices, turn on wireless debugging"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"Pair device with QR code"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"Pair new devices using QR code scanner"</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"Pair new devices using QR code scanner"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"Pair device with pairing code"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"Pair new devices using six-digit code"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"Paired devices"</string> @@ -231,7 +231,7 @@ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"Failed to pair the device. Either the QR code was incorrect, or the device is not connected to the same network."</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP address & port"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"Scan QR code"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"Pair device over Wi‑Fi by scanning a QR code"</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Pair device over Wi‑Fi by scanning a QR code"</string> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Please connect to a Wi‑Fi network"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, debug, dev"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"Bug report shortcut"</string> @@ -251,6 +251,7 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"Wireless display certification"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"Enable Wi‑Fi verbose logging"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"Wi‑Fi scan throttling"</string> + <string name="wifi_enhanced_mac_randomization" msgid="5437378364995776979">"Wi‑Fi‑enhanced MAC randomisation"</string> <string name="mobile_data_always_on" msgid="8275958101875563572">"Mobile data always active"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"Tethering hardware acceleration"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"Show Bluetooth devices without names"</string> @@ -274,7 +275,7 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="7274396574659784285">"Trigger Bluetooth Audio LDAC\nCodec Selection: Playback Quality"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="2040810756832027227">"Streaming: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> <string name="select_private_dns_configuration_title" msgid="7887550926056143018">"Private DNS"</string> - <string name="select_private_dns_configuration_dialog_title" msgid="3731422918335951912">"Select private DNS mode"</string> + <string name="select_private_dns_configuration_dialog_title" msgid="3731422918335951912">"Select Private DNS Mode"</string> <string name="private_dns_mode_off" msgid="7065962499349997041">"Off"</string> <string name="private_dns_mode_opportunistic" msgid="1947864819060442354">"Automatic"</string> <string name="private_dns_mode_provider" msgid="3619040641762557028">"Private DNS provider hostname"</string> @@ -283,6 +284,7 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"Show options for wireless display certification"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Increase Wi‑Fi logging level, show per SSID RSSI in Wi‑Fi Picker"</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"Reduces battery drain and improves network performance"</string> + <string name="wifi_enhanced_mac_randomization_summary" msgid="7925425746373704991">"This toggle affects MAC randomisation behaviour for client mode only.\nWhen this mode is activated, any networks that have MAC randomisation enabled may have their MAC addresses re‑randomised during association, depending on when the client last disconnected from the network. Re‑randomisation does not occur if the device reconnects in four hours or less."</string> <string name="wifi_metered_label" msgid="8737187690304098638">"Metered"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"Unmetered"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"Logger buffer sizes"</string> @@ -371,6 +373,8 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"Display App Not Responding dialogue for background apps"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"Show notification channel warnings"</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"Displays on-screen warning when an app posts a notification without a valid channel"</string> + <string name="enforce_shortcuts_for_conversations" msgid="7040735163945040763">"Enforce shortcuts for conversation notifications"</string> + <string name="enforce_shortcuts_for_conversations_summary" msgid="1860168037282467862">"Require notifications to be backed by a long-lived sharing shortcut in order to appear in the conversation section"</string> <string name="force_allow_on_external" msgid="9187902444231637880">"Force allow apps on external"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Makes any app eligible to be written to external storage, regardless of manifest values"</string> <string name="force_resizable_activities" msgid="7143612144399959606">"Force activities to be resizeable"</string> diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml index 4cc274452b61..a932bceb02a5 100644 --- a/packages/SettingsLib/res/values-en-rGB/strings.xml +++ b/packages/SettingsLib/res/values-en-rGB/strings.xml @@ -212,7 +212,7 @@ <string name="adb_wireless_settings" msgid="2295017847215680229">"Wireless debugging"</string> <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"To see and use available devices, turn on wireless debugging"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"Pair device with QR code"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"Pair new devices using QR code scanner"</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"Pair new devices using QR code scanner"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"Pair device with pairing code"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"Pair new devices using six-digit code"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"Paired devices"</string> @@ -231,7 +231,7 @@ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"Failed to pair the device. Either the QR code was incorrect, or the device is not connected to the same network."</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP address & port"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"Scan QR code"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"Pair device over Wi‑Fi by scanning a QR code"</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Pair device over Wi‑Fi by scanning a QR code"</string> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Please connect to a Wi‑Fi network"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, debug, dev"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"Bug report shortcut"</string> @@ -251,6 +251,7 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"Wireless display certification"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"Enable Wi‑Fi verbose logging"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"Wi‑Fi scan throttling"</string> + <string name="wifi_enhanced_mac_randomization" msgid="5437378364995776979">"Wi‑Fi‑enhanced MAC randomisation"</string> <string name="mobile_data_always_on" msgid="8275958101875563572">"Mobile data always active"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"Tethering hardware acceleration"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"Show Bluetooth devices without names"</string> @@ -274,7 +275,7 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="7274396574659784285">"Trigger Bluetooth Audio LDAC\nCodec Selection: Playback Quality"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="2040810756832027227">"Streaming: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> <string name="select_private_dns_configuration_title" msgid="7887550926056143018">"Private DNS"</string> - <string name="select_private_dns_configuration_dialog_title" msgid="3731422918335951912">"Select private DNS mode"</string> + <string name="select_private_dns_configuration_dialog_title" msgid="3731422918335951912">"Select Private DNS Mode"</string> <string name="private_dns_mode_off" msgid="7065962499349997041">"Off"</string> <string name="private_dns_mode_opportunistic" msgid="1947864819060442354">"Automatic"</string> <string name="private_dns_mode_provider" msgid="3619040641762557028">"Private DNS provider hostname"</string> @@ -283,6 +284,7 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"Show options for wireless display certification"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Increase Wi‑Fi logging level, show per SSID RSSI in Wi‑Fi Picker"</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"Reduces battery drain and improves network performance"</string> + <string name="wifi_enhanced_mac_randomization_summary" msgid="7925425746373704991">"This toggle affects MAC randomisation behaviour for client mode only.\nWhen this mode is activated, any networks that have MAC randomisation enabled may have their MAC addresses re‑randomised during association, depending on when the client last disconnected from the network. Re‑randomisation does not occur if the device reconnects in four hours or less."</string> <string name="wifi_metered_label" msgid="8737187690304098638">"Metered"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"Unmetered"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"Logger buffer sizes"</string> @@ -371,6 +373,8 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"Display App Not Responding dialogue for background apps"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"Show notification channel warnings"</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"Displays on-screen warning when an app posts a notification without a valid channel"</string> + <string name="enforce_shortcuts_for_conversations" msgid="7040735163945040763">"Enforce shortcuts for conversation notifications"</string> + <string name="enforce_shortcuts_for_conversations_summary" msgid="1860168037282467862">"Require notifications to be backed by a long-lived sharing shortcut in order to appear in the conversation section"</string> <string name="force_allow_on_external" msgid="9187902444231637880">"Force allow apps on external"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Makes any app eligible to be written to external storage, regardless of manifest values"</string> <string name="force_resizable_activities" msgid="7143612144399959606">"Force activities to be resizeable"</string> diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml index 4cc274452b61..a932bceb02a5 100644 --- a/packages/SettingsLib/res/values-en-rIN/strings.xml +++ b/packages/SettingsLib/res/values-en-rIN/strings.xml @@ -212,7 +212,7 @@ <string name="adb_wireless_settings" msgid="2295017847215680229">"Wireless debugging"</string> <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"To see and use available devices, turn on wireless debugging"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"Pair device with QR code"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"Pair new devices using QR code scanner"</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"Pair new devices using QR code scanner"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"Pair device with pairing code"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"Pair new devices using six-digit code"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"Paired devices"</string> @@ -231,7 +231,7 @@ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"Failed to pair the device. Either the QR code was incorrect, or the device is not connected to the same network."</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP address & port"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"Scan QR code"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"Pair device over Wi‑Fi by scanning a QR code"</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Pair device over Wi‑Fi by scanning a QR code"</string> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Please connect to a Wi‑Fi network"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, debug, dev"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"Bug report shortcut"</string> @@ -251,6 +251,7 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"Wireless display certification"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"Enable Wi‑Fi verbose logging"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"Wi‑Fi scan throttling"</string> + <string name="wifi_enhanced_mac_randomization" msgid="5437378364995776979">"Wi‑Fi‑enhanced MAC randomisation"</string> <string name="mobile_data_always_on" msgid="8275958101875563572">"Mobile data always active"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"Tethering hardware acceleration"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"Show Bluetooth devices without names"</string> @@ -274,7 +275,7 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="7274396574659784285">"Trigger Bluetooth Audio LDAC\nCodec Selection: Playback Quality"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="2040810756832027227">"Streaming: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> <string name="select_private_dns_configuration_title" msgid="7887550926056143018">"Private DNS"</string> - <string name="select_private_dns_configuration_dialog_title" msgid="3731422918335951912">"Select private DNS mode"</string> + <string name="select_private_dns_configuration_dialog_title" msgid="3731422918335951912">"Select Private DNS Mode"</string> <string name="private_dns_mode_off" msgid="7065962499349997041">"Off"</string> <string name="private_dns_mode_opportunistic" msgid="1947864819060442354">"Automatic"</string> <string name="private_dns_mode_provider" msgid="3619040641762557028">"Private DNS provider hostname"</string> @@ -283,6 +284,7 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"Show options for wireless display certification"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Increase Wi‑Fi logging level, show per SSID RSSI in Wi‑Fi Picker"</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"Reduces battery drain and improves network performance"</string> + <string name="wifi_enhanced_mac_randomization_summary" msgid="7925425746373704991">"This toggle affects MAC randomisation behaviour for client mode only.\nWhen this mode is activated, any networks that have MAC randomisation enabled may have their MAC addresses re‑randomised during association, depending on when the client last disconnected from the network. Re‑randomisation does not occur if the device reconnects in four hours or less."</string> <string name="wifi_metered_label" msgid="8737187690304098638">"Metered"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"Unmetered"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"Logger buffer sizes"</string> @@ -371,6 +373,8 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"Display App Not Responding dialogue for background apps"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"Show notification channel warnings"</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"Displays on-screen warning when an app posts a notification without a valid channel"</string> + <string name="enforce_shortcuts_for_conversations" msgid="7040735163945040763">"Enforce shortcuts for conversation notifications"</string> + <string name="enforce_shortcuts_for_conversations_summary" msgid="1860168037282467862">"Require notifications to be backed by a long-lived sharing shortcut in order to appear in the conversation section"</string> <string name="force_allow_on_external" msgid="9187902444231637880">"Force allow apps on external"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Makes any app eligible to be written to external storage, regardless of manifest values"</string> <string name="force_resizable_activities" msgid="7143612144399959606">"Force activities to be resizeable"</string> diff --git a/packages/SettingsLib/res/values-en-rXC/strings.xml b/packages/SettingsLib/res/values-en-rXC/strings.xml index e935a74e64cc..6295fe6dd16c 100644 --- a/packages/SettingsLib/res/values-en-rXC/strings.xml +++ b/packages/SettingsLib/res/values-en-rXC/strings.xml @@ -212,7 +212,7 @@ <string name="adb_wireless_settings" msgid="2295017847215680229">"Wireless debugging"</string> <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"To see and use available devices, turn on wireless debugging"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"Pair device with QR code"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"Pair new devices using QR code Scanner"</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"Pair new devices using QR code scanner"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"Pair device with pairing code"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"Pair new devices using six digit code"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"Paired devices"</string> @@ -231,7 +231,7 @@ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"Failed to pair the device. Either the QR code was incorrect, or the device is not connected to the same network."</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP address & Port"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"Scan QR code"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"Pair device over Wi‑Fi by scanning a QR Code"</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Pair device over Wi‑Fi by scanning a QR code"</string> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Please connect to a Wi‑Fi network"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, debug, dev"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"Bug report shortcut"</string> @@ -251,6 +251,7 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"Wireless display certification"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"Enable Wi‑Fi Verbose Logging"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"Wi‑Fi scan throttling"</string> + <string name="wifi_enhanced_mac_randomization" msgid="5437378364995776979">"Wi‑Fi‑enhanced MAC randomization"</string> <string name="mobile_data_always_on" msgid="8275958101875563572">"Mobile data always active"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"Tethering hardware acceleration"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"Show Bluetooth devices without names"</string> @@ -283,6 +284,7 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"Show options for wireless display certification"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Increase Wi‑Fi logging level, show per SSID RSSI in Wi‑Fi Picker"</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"Reduces battery drain & improves network performance"</string> + <string name="wifi_enhanced_mac_randomization_summary" msgid="7925425746373704991">"This toggle affects MAC randomization behavior for client mode only.\nWhen this mode is activated, any networks that have MAC randomization enabled may have their MAC addresses re‑randomized during association, depending on when the client last disconnected from the network. Re‑randomization does not occur if the device reconnects in 4 hours or less."</string> <string name="wifi_metered_label" msgid="8737187690304098638">"Metered"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"Unmetered"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"Logger buffer sizes"</string> @@ -371,6 +373,8 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"Display App Not Responding dialog for background apps"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"Show notification channel warnings"</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"Displays on-screen warning when an app posts a notification without a valid channel"</string> + <string name="enforce_shortcuts_for_conversations" msgid="7040735163945040763">"Enforce shortcuts for conversation notifications"</string> + <string name="enforce_shortcuts_for_conversations_summary" msgid="1860168037282467862">"Require notifications to be backed by a long-lived sharing shortcut in order to appear in the conversation section"</string> <string name="force_allow_on_external" msgid="9187902444231637880">"Force allow apps on external"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Makes any app eligible to be written to external storage, regardless of manifest values"</string> <string name="force_resizable_activities" msgid="7143612144399959606">"Force activities to be resizable"</string> diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml index 6cb975f799ab..b212eb6a484a 100644 --- a/packages/SettingsLib/res/values-es-rUS/strings.xml +++ b/packages/SettingsLib/res/values-es-rUS/strings.xml @@ -23,7 +23,7 @@ <string name="wifi_fail_to_scan" msgid="2333336097603822490">"No se pueden buscar las redes."</string> <string name="wifi_security_none" msgid="7392696451280611452">"Ninguna"</string> <string name="wifi_remembered" msgid="3266709779723179188">"Guardada"</string> - <string name="wifi_disconnected" msgid="7054450256284661757">"Desconectada"</string> + <string name="wifi_disconnected" msgid="7054450256284661757">"Desconectado"</string> <string name="wifi_disabled_generic" msgid="2651916945380294607">"Inhabilitada"</string> <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"Error de configuración IP"</string> <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"No se estableció conexión debido a la mala calidad de la red"</string> @@ -212,7 +212,7 @@ <string name="adb_wireless_settings" msgid="2295017847215680229">"Depuración inalámbrica"</string> <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Para ver y usar los dispositivos disponibles, activa la depuración inalámbrica"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"Vincular dispositivo mediante código QR"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"Vincular dispositivos nuevos mediante escáner de código QR"</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"Vincular dispositivos nuevos mediante escáner de código QR"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"Vincular dispositivo mediante código de sincroniz."</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"Vincular dispositivos nuevos mediante código de seis dígitos"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"Dispositivos vinculados"</string> @@ -231,7 +231,7 @@ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"Error al vincular el dispositivo. El código QR era incorrecto o el dispositivo no está conectado a la misma red."</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"Dirección IP y puerto"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"Escanear código QR"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"Escanea un código QR para vincular el dispositivo mediante Wi‑Fi"</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Escanea un código QR para vincular el dispositivo mediante Wi‑Fi"</string> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Conéctate a una red Wi-Fi"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, debug, dev"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"Acceso directo para informes de errores"</string> @@ -251,6 +251,8 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"Certificación de pantalla inalámbrica"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"Habilitar registro detallado de Wi-Fi"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"Limitación de búsqueda de Wi-Fi"</string> + <!-- no translation found for wifi_enhanced_mac_randomization (5437378364995776979) --> + <skip /> <string name="mobile_data_always_on" msgid="8275958101875563572">"Datos móviles siempre activados"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"Aceleración de hardware de conexión mediante dispositivo móvil"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"Mostrar dispositivos Bluetooth sin nombre"</string> @@ -283,6 +285,8 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"Mostrar opciones de certificación de pantalla inalámbrica"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Aumentar nivel de registro Wi-Fi; mostrar por SSID RSSI en el selector de Wi-Fi"</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"Reduce el consumo de batería y mejora el rendimiento de la red"</string> + <!-- no translation found for wifi_enhanced_mac_randomization_summary (7925425746373704991) --> + <skip /> <string name="wifi_metered_label" msgid="8737187690304098638">"Con uso medido"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"Sin tarifa plana"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"Tamaños de búfer de Logger"</string> @@ -371,6 +375,8 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"Mostrar diálogo cuando las apps en segundo plano no responden"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"Alertas de notificaciones"</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"Advertencia en pantalla cuando una app publica una notificación sin canal válido"</string> + <string name="enforce_shortcuts_for_conversations" msgid="7040735163945040763">"Acc. dir. notif. de conv."</string> + <string name="enforce_shortcuts_for_conversations_summary" msgid="1860168037282467862">"Notif. requieren acc. dir. permanente de uso comp."</string> <string name="force_allow_on_external" msgid="9187902444231637880">"Forzar permisos en almacenamiento externo"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Cualquier app puede escribirse en un almacenamiento externo, sin importar los valores del manifiesto"</string> <string name="force_resizable_activities" msgid="7143612144399959606">"Forzar actividades para que cambien de tamaño"</string> @@ -429,7 +435,7 @@ <string name="power_discharge_by_enhanced" msgid="563438403581662942">"Duración aproximada hasta <xliff:g id="TIME">%1$s</xliff:g> según el uso (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_discharge_by_only_enhanced" msgid="3268796172652988877">"Debería durar aproximadamente hasta <xliff:g id="TIME">%1$s</xliff:g> según el uso"</string> <string name="power_discharge_by" msgid="4113180890060388350">"Duración aproximada hasta: <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_discharge_by_only" msgid="92545648425937000">"Debería durar aproximadamente hasta <xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="power_discharge_by_only" msgid="92545648425937000">"Debería durar aproximadamente hasta: <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Hasta <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Es posible que la batería se agote para las <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"Tiempo restante: menos de <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> diff --git a/packages/SettingsLib/res/values-es/arrays.xml b/packages/SettingsLib/res/values-es/arrays.xml index a403e3e6519e..6e69c713ffd5 100644 --- a/packages/SettingsLib/res/values-es/arrays.xml +++ b/packages/SettingsLib/res/values-es/arrays.xml @@ -26,7 +26,7 @@ <item msgid="6050951078202663628">"Estableciendo conexión..."</item> <item msgid="8356618438494652335">"Autenticando..."</item> <item msgid="2837871868181677206">"Obteniendo dirección IP…"</item> - <item msgid="4613015005934755724">"Conexión establecida"</item> + <item msgid="4613015005934755724">"Conectado"</item> <item msgid="3763530049995655072">"Suspendida"</item> <item msgid="7852381437933824454">"Desconectando..."</item> <item msgid="5046795712175415059">"Desconectado"</item> diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml index d77772364f77..413e9fd64ec1 100644 --- a/packages/SettingsLib/res/values-es/strings.xml +++ b/packages/SettingsLib/res/values-es/strings.xml @@ -212,7 +212,7 @@ <string name="adb_wireless_settings" msgid="2295017847215680229">"Depuración inalámbrica"</string> <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Para ver y utilizar los dispositivos disponibles, activa la depuración inalámbrica"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"Vincular dispositivo con código QR"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"Vincula nuevos dispositivos con el escáner de códigos QR"</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"Vincula nuevos dispositivos con el escáner de códigos QR"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"Vincular dispositivo con código de sincronización"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"Vincula nuevos dispositivos con un código de seis dígitos"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"Dispositivos vinculados"</string> @@ -230,8 +230,8 @@ <string name="adb_wireless_verifying_qrcode_text" msgid="6123192424916029207">"Vinculando dispositivo…"</string> <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"No se ha podido vincular el dispositivo. El código QR no era correcto o el dispositivo no estaba conectado a la misma red."</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"Dirección IP y puerto"</string> - <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"Escanear código QR"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"Vincula un dispositivo a través de Wi‑Fi con un código QR"</string> + <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"Escanea el código QR"</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Vincula un dispositivo a través de Wi‑Fi escaneando un código QR"</string> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Conéctate a una red Wi-Fi"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, depuración, desarrollo"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"Atajo a informe de errores"</string> @@ -251,6 +251,7 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"Certificación de pantalla inalámbrica"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"Habilitar registro de Wi-Fi detallado"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"Limitación de búsqueda de redes Wi‑Fi"</string> + <string name="wifi_enhanced_mac_randomization" msgid="5437378364995776979">"Aleatorización de MAC mejorada por Wi-Fi"</string> <string name="mobile_data_always_on" msgid="8275958101875563572">"Datos móviles siempre activos"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"Aceleración por hardware para conexión compartida"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"Mostrar dispositivos Bluetooth sin nombre"</string> @@ -283,6 +284,7 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"Mostrar opciones para la certificación de la pantalla inalámbrica"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Aumentar el nivel de registro de Wi-Fi y mostrar por SSID RSSI en el selector Wi-Fi"</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"Reduce el consumo de batería y mejora el rendimiento de las redes"</string> + <string name="wifi_enhanced_mac_randomization_summary" msgid="7925425746373704991">"Este interruptor afecta al comportamiento al aleatorizar direcciones MAC solo en el modo del cliente.\nCuando este modo está actualizado, según hace cuánto el cliente se haya desconectado por última vez de la red, es posible que las redes que tengan habilitada esta aleatorización vean que sus direcciones MAC vuelven a aleatorizarse durante la asociación. No se volverán a aleatorizar si el dispositivo se vuelve a conectar en un plazo de cuatro horas."</string> <string name="wifi_metered_label" msgid="8737187690304098638">"Medida"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"No medida"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"Tamaños del búfer para registrar"</string> @@ -371,6 +373,8 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"Mostrar el diálogo de que la aplicación no responde para aplicaciones en segundo plano"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"Ver advertencias del canal de notificaciones"</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"Mostrar una advertencia en pantalla cuando una aplicación publica una notificación sin un canal válido"</string> + <string name="enforce_shortcuts_for_conversations" msgid="7040735163945040763">"Implementar atajos en notific. de conversaciones"</string> + <string name="enforce_shortcuts_for_conversations_summary" msgid="1860168037282467862">"Exigir que las notificaciones tengan un atajo para compartir y que así aparezcan en la sección de conversaciones"</string> <string name="force_allow_on_external" msgid="9187902444231637880">"Forzar permitir aplicaciones de forma externa"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Hacer que cualquier aplicación se pueda escribir en un dispositivo de almacenamiento externo independientemente de los valores definidos"</string> <string name="force_resizable_activities" msgid="7143612144399959606">"Forzar el ajuste de tamaño de las actividades"</string> @@ -427,9 +431,9 @@ <!-- no translation found for power_remaining_duration_only_short (7438846066602840588) --> <skip /> <string name="power_discharge_by_enhanced" msgid="563438403581662942">"Debería durar aproximadamente hasta <xliff:g id="TIME">%1$s</xliff:g> según el uso (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_discharge_by_only_enhanced" msgid="3268796172652988877">"Duración aproximada hasta: <xliff:g id="TIME">%1$s</xliff:g> (según el uso)"</string> + <string name="power_discharge_by_only_enhanced" msgid="3268796172652988877">"Debería durar hasta las <xliff:g id="TIME">%1$s</xliff:g> basado en tu uso"</string> <string name="power_discharge_by" msgid="4113180890060388350">"Debería durar aproximadamente hasta <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_discharge_by_only" msgid="92545648425937000">"Duración aproximada hasta: <xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="power_discharge_by_only" msgid="92545648425937000">"Debería durar hasta las <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Hasta: <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Es probable que te quedes sin batería sobre esta hora: <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"Tiempo restante: menos de <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> @@ -443,8 +447,8 @@ <string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7703677921000858479">"Es posible que el tablet se apague pronto (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string> <string name="power_remaining_duration_shutdown_imminent" product="device" msgid="4374784375644214578">"Es posible que el dispositivo se apague pronto (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string> <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string> - <string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"<xliff:g id="TIME">%1$s</xliff:g> hasta que termine de cargarse"</string> - <string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> (<xliff:g id="TIME">%2$s</xliff:g> hasta que termine de cargarse)"</string> + <string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"<xliff:g id="TIME">%1$s</xliff:g> hasta cargarse completamente"</string> + <string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> (<xliff:g id="TIME">%2$s</xliff:g> hasta cargarse completamente)"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"Desconocido"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"Cargando"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Cargando rápidamente"</string> @@ -505,7 +509,7 @@ <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Duración"</string> <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Preguntar siempre"</string> <string name="zen_mode_forever" msgid="3339224497605461291">"Hasta que se desactive"</string> - <string name="time_unit_just_now" msgid="3006134267292728099">"Justo ahora"</string> + <string name="time_unit_just_now" msgid="3006134267292728099">"justo ahora"</string> <string name="media_transfer_this_device_name" msgid="2716555073132169240">"Altavoz del teléfono"</string> <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"No se ha podido conectar; reinicia el dispositivo"</string> <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Dispositivo de audio con cable"</string> @@ -532,7 +536,7 @@ <string name="user_add_user_message_long" msgid="1527434966294733380">"Puedes compartir este dispositivo si creas más usuarios. Cada uno tendrá su propio espacio y podrá personalizarlo con aplicaciones, un fondo de pantalla y mucho más. Los usuarios también pueden ajustar opciones del dispositivo, como la conexión Wi‑Fi, que afectan a todos los usuarios.\n\nCuando añadas un usuario, tendrá que configurar su espacio.\n\nCualquier usuario puede actualizar aplicaciones de todos los usuarios. Es posible que no se transfieran los servicios y opciones de accesibilidad al nuevo usuario."</string> <string name="user_add_user_message_short" msgid="3295959985795716166">"Al añadir un usuario nuevo, este debe configurar su espacio.\n\nCualquier usuario puede actualizar las aplicaciones del resto de usuarios."</string> <string name="user_setup_dialog_title" msgid="8037342066381939995">"¿Configurar usuario ahora?"</string> - <string name="user_setup_dialog_message" msgid="269931619868102841">"Asegúrate de que la persona pueda acceder al dispositivo y configurar su espacio."</string> + <string name="user_setup_dialog_message" msgid="269931619868102841">"Asegúrate de que la persona está disponible en este momento para usar el dispositivo y configurar su espacio."</string> <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"¿Quieres configurar un perfil ahora?"</string> <string name="user_setup_button_setup_now" msgid="1708269547187760639">"Configurar ahora"</string> <string name="user_setup_button_setup_later" msgid="8712980133555493516">"Ahora no"</string> diff --git a/packages/SettingsLib/res/values-et/strings.xml b/packages/SettingsLib/res/values-et/strings.xml index 1fa41596a3ac..73320100c2d6 100644 --- a/packages/SettingsLib/res/values-et/strings.xml +++ b/packages/SettingsLib/res/values-et/strings.xml @@ -212,7 +212,7 @@ <string name="adb_wireless_settings" msgid="2295017847215680229">"Juhtmevaba silumine"</string> <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Saadaolevate seadmete nägemiseks ja kasutamiseks lülitage sisse juhtmevaba silumine"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"Seadme sidumine QR-koodiga"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"Uute seadmete sidumine QR-koodi skanneriga"</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"Uute seadmete sidumine QR-koodi skanneriga"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"Seadme sidumine sidumiskoodiga"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"Uute seadmete sidumine kuuekohalise koodiga"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"Seotud seadmed"</string> @@ -231,7 +231,7 @@ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"Seadme sidumine ebaõnnestus. QR-kood oli vale või seade ei ole ühendatud samasse võrku."</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP-aadress ja port"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"QR-koodi skannimine"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"Siduge seade WiFi kaudu, skannides QR-koodi"</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Siduge seade WiFi kaudu, skannides QR-koodi"</string> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Looge ühendus WiFi-võrguga"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, silumine, arendus"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"Veaaruande otsetee"</string> @@ -251,6 +251,7 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"Juhtmeta ekraaniühenduse sertifitseerimine"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"Luba WiFi sõnaline logimine"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"WiFi-skannimise ahendamine"</string> + <string name="wifi_enhanced_mac_randomization" msgid="5437378364995776979">"WiFi-põhine MAC-i juhuslikustamine"</string> <string name="mobile_data_always_on" msgid="8275958101875563572">"Hoia mobiilne andmeside alati aktiivne"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"Ühenduse jagamise riistvaraline kiirendus"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"Kuva ilma nimedeta Bluetoothi seadmed"</string> @@ -283,6 +284,7 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"Juhtmeta ekraaniühenduse sertifitseerimisvalikute kuvamine"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Suurenda WiFi logimistaset, kuva WiFi valijas SSID RSSI järgi"</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"Aeglustab aku tühjenemist ja parandab võrgu toimivust"</string> + <string name="wifi_enhanced_mac_randomization_summary" msgid="7925425746373704991">"See lüliti mõjutab MAC-aadressi juhuslikustamise käitumist ainult kliendirežiimis.\nSelle režiimi aktiveerimisel võidakse seostamise ajal MAC-aadressid uuesti juhuslikustada kõigi võrkude jaoks, millel on MAC-aadressi juhuslikustamine lubatud, olenevalt sellest, millal klient viimati ühenduse võrguga katkestas. Uuesti juhuslikustamist ei toimu juhul, kui seade loob uuesti ühenduse kuni 4 tunni jooksul."</string> <string name="wifi_metered_label" msgid="8737187690304098638">"Mahupõhine"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"Mittemahupõhine"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"Logija puhvri suurused"</string> @@ -371,6 +373,8 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"Kuva taustarakenduste puhul dialoog Rakendus ei reageeri"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"Kuva märguandekanali hoiatused"</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"Esitab ekraanil hoiatuse, kui rakendus postitab kehtiva kanalita märguande"</string> + <string name="enforce_shortcuts_for_conversations" msgid="7040735163945040763">"Otseteede jõustamine vestluste märguannete jaoks"</string> + <string name="enforce_shortcuts_for_conversations_summary" msgid="1860168037282467862">"Nõutakse märguannete toetamist pikaajalise jagamise otseteega, et selle saaks vestluse jaotises kuvada"</string> <string name="force_allow_on_external" msgid="9187902444231637880">"Luba rakendused välises salvestusruumis"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Lubab mis tahes rakendusi kirjutada välisesse salvestusruumi manifesti väärtustest olenemata"</string> <string name="force_resizable_activities" msgid="7143612144399959606">"Muuda tegevuste suurused muudetavaks"</string> @@ -416,8 +420,8 @@ <string name="daltonizer_mode_deuteranomaly" msgid="3507284319584683963">"Deuteranomaalia (punane-roheline)"</string> <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"Protanomaalia (punane-roheline)"</string> <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Tritanomaalia (sinine-kollane)"</string> - <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"Värvide korrigeerimine"</string> - <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1284746051652993443">"Värviparandus võimaldab kohandada seadmes kuvatavaid värve"</string> + <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"Värvikorrigeerimine"</string> + <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1284746051652993443">"Värvikorrigeerimine võimaldab kohandada seadmes kuvatavaid värve"</string> <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Alistas <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="8264199158671531431">"Ligikaudu <xliff:g id="TIME_REMAINING">%1$s</xliff:g> jäänud"</string> diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml index 2700162afc03..33987aa39b41 100644 --- a/packages/SettingsLib/res/values-eu/strings.xml +++ b/packages/SettingsLib/res/values-eu/strings.xml @@ -126,7 +126,7 @@ <string name="bluetooth_talkback_imaging" msgid="8781682986822514331">"Irudietarako gailua"</string> <string name="bluetooth_talkback_headphone" msgid="8613073829180337091">"Entzungailua"</string> <string name="bluetooth_talkback_input_peripheral" msgid="5133944817800149942">"Idazteko gailua"</string> - <string name="bluetooth_talkback_bluetooth" msgid="1143241359781999989">"Bluetooth gailua"</string> + <string name="bluetooth_talkback_bluetooth" msgid="1143241359781999989">"Bluetooth bidezko gailua"</string> <string name="bluetooth_hearingaid_left_pairing_message" msgid="8561855779703533591">"Ezkerreko audifonoa parekatzen…"</string> <string name="bluetooth_hearingaid_right_pairing_message" msgid="2655347721696331048">"Eskuineko audifonoa parekatzen…"</string> <string name="bluetooth_hearingaid_left_battery_level" msgid="7375621694748104876">"Ezkerrekoa. Bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> @@ -212,7 +212,7 @@ <string name="adb_wireless_settings" msgid="2295017847215680229">"Hari gabeko arazketa"</string> <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Erabilgarri dauden gailuak ikusteko eta erabiltzeko, aktibatu hari gabeko arazketa"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"Parekatu gailua QR kodearekin"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"Parekatu gailu gehiago QR kodea eskaneatuta"</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"Parekatu gailu gehiago QR kodea eskaneatuta"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"Parekatu gailua parekatze-kodearekin"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"Parekatu gailu gehiago sei digituko kodearekin"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"Parekatutako gailuak"</string> @@ -231,11 +231,11 @@ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"Ezin izan da parekatu gailua. QR kodea ez da zuzena edo gailua ez dago sare berera konektatuta."</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP helbidea eta ataka"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"Eskaneatu QR kodea"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"Parekatu gailua wifi-sare baten bidez QR kode bat eskaneatuta"</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Parekatu gailua wifi-sare baten bidez QR kode bat eskaneatuta"</string> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Konektatu wifi-sare batera"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, araztu, gailua"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"Akatsen txostenerako lasterbidea"</string> - <string name="bugreport_in_power_summary" msgid="1885529649381831775">"Pizteko menuan, erakutsi akatsen txostena sortzeko botoia"</string> + <string name="bugreport_in_power_summary" msgid="1885529649381831775">"Itzaltzeko menuan, erakutsi akatsen txostena sortzeko botoia"</string> <string name="keep_screen_on" msgid="1187161672348797558">"Mantendu aktibo"</string> <string name="keep_screen_on_summary" msgid="1510731514101925829">"Pantaila ez da ezarriko inoiz inaktibo kargatu bitartean"</string> <string name="bt_hci_snoop_log" msgid="7291287955649081448">"Gaitu Bluetooth HCI miatze-erregistroa"</string> @@ -251,6 +251,8 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"Hari gabe bistaratzeko ziurtagiria"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"Gaitu wifi-sareetan saioa hasteko modu xehatua"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"Wifi-sareen bilaketaren muga"</string> + <!-- no translation found for wifi_enhanced_mac_randomization (5437378364995776979) --> + <skip /> <string name="mobile_data_always_on" msgid="8275958101875563572">"Datu-konexioa beti aktibo"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"Konexioa partekatzeko hardwarearen azelerazioa"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"Erakutsi Bluetooth bidezko gailuak izenik gabe"</string> @@ -283,6 +285,8 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"Erakutsi hari gabe bistaratzeko ziurtagiriaren aukerak"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Erakutsi datu gehiago wifi-sareetan saioa hastean. Erakutsi sarearen identifikatzailea eta seinalearen indarra wifi-sareen hautatzailean."</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"Bateria gutxiago kontsumituko da, eta sarearen errendimendua hobetuko."</string> + <!-- no translation found for wifi_enhanced_mac_randomization_summary (7925425746373704991) --> + <skip /> <string name="wifi_metered_label" msgid="8737187690304098638">"Sare neurtua"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"Neurtu gabeko sarea"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"Erregistroen buffer-tamainak"</string> @@ -371,6 +375,8 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"Erakutsi aplikazioak ez erantzutearen (ANR) leihoa atzeko planoan dabiltzan aplikazioen kasuan"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"Erakutsi jakinarazpenen kanalen abisuak"</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"Bistaratu abisuak aplikazioek baliozko kanalik gabeko jakinarazpenak argitaratzean"</string> + <string name="enforce_shortcuts_for_conversations" msgid="7040735163945040763">"Erabili lasterbideak elkarrizketen jakinarazpenetan"</string> + <string name="enforce_shortcuts_for_conversations_summary" msgid="1860168037282467862">"Eskatu jakinarazpenak partekatze-lasterbide iragankor batean oinarrituta egotea elkarrizketa-atalean agertzeko"</string> <string name="force_allow_on_external" msgid="9187902444231637880">"Behartu aplikazioak onartzea kanpoko memorian"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Aplikazioek kanpoko memorian idatz dezakete, ezarritako balioak kontuan izan gabe"</string> <string name="force_resizable_activities" msgid="7143612144399959606">"Behartu jardueren tamaina doitu ahal izatea"</string> diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml index 1c32926772f9..1687e54ca071 100644 --- a/packages/SettingsLib/res/values-fa/strings.xml +++ b/packages/SettingsLib/res/values-fa/strings.xml @@ -212,7 +212,7 @@ <string name="adb_wireless_settings" msgid="2295017847215680229">"اشکالزدایی بیسیم"</string> <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"برای مشاهده و استفاده از دستگاههای در دسترس، اشکالزدایی بیسیم را روشن کنید"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"مرتبط کردن دستگاه با کد QR"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"دستگاههای جدید را با استفاده از اسکنر کد QR مرتبط کنید"</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"دستگاههای جدید را بااستفاده از اسکنر کد QR مرتبط کنید"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"مرتبط کردن دستگاه با کد مرتبطسازی"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"دستگاههای جدید را با استفاده از کد شش رقمی مرتبط کنید"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"دستگاههای مرتبطشده"</string> @@ -231,7 +231,7 @@ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"مرتبط کردن دستگاه انجام نشد. یا کد QR اشتباه بوده است، یا دستگاه به همان شبکه متصل نیست."</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"نشانی IP و درگاه"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"اسکن کد QR"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"دستگاه را ازطریق Wi‑Fi و با اسکن کردن کد QR مرتبط کنید"</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"دستگاه را ازطریق Wi‑Fi و با اسکن کردن کد QR مرتبط کنید"</string> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"لطفاً به شبکه Wi-Fi متصل شوید"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"ADB (پل اشکالزدایی Android)، اشکالزدایی کردن، برنامهنویس"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"میانبر گزارش مشکل"</string> @@ -251,6 +251,7 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"گواهینامه نمایش بیسیم"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"فعال کردن گزارشگیری طولانی Wi‑Fi"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"محدود کردن اسکن کردن Wi‑Fi"</string> + <string name="wifi_enhanced_mac_randomization" msgid="5437378364995776979">"تصادفیسازی MAC بهبودیافته برای Wi-Fi"</string> <string name="mobile_data_always_on" msgid="8275958101875563572">"داده تلفن همراه همیشه فعال باشد"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"شتاب سختافزاری اتصال به اینترنت با تلفن همراه"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"نمایش دستگاههای بلوتوث بدون نام"</string> @@ -283,6 +284,7 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"نمایش گزینهها برای گواهینامه نمایش بیسیم"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"افزایش سطح گزارشگیری Wi‑Fi، نمایش به ازای SSID RSSI در انتخابکننده Wi‑Fi"</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"تخلیه باتری راکاهش میدهد و عملکرد شبکه را بهبود میبخشد"</string> + <string name="wifi_enhanced_mac_randomization_summary" msgid="7925425746373704991">"فعال/غیرفعال کردن این تنظیم فقط درحالت کارخواه بر عملکرد تصادفیسازی MAC تأثیر میگذارد.\nوقتی این حالت فعال باشد، ممکن است در شبکههایی که تصادفیسازی MAC فعال است، نشانیهای MAC درطول ارتباط دوباره تصادفیسازی شوند، بسته به اینکه اتصال کارخواه آخرین بار چه زمانی از شبکه قطع شده باشد. اگر دستگاه ظرف ۴ ساعت یا کمتر دوباره متصل شود، تصادفیسازی مجدد انجام نمیشود."</string> <string name="wifi_metered_label" msgid="8737187690304098638">"محدودشده"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"محدودنشده"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"اندازههای حافظه موقت ثبتکننده"</string> @@ -371,6 +373,8 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"نمایش گفتگوی \"برنامه پاسخ نمیدهد\" برای برنامههای پسزمینه"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"نمایش هشدارهای کانال اعلان"</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"هنگامی که برنامهای بدون وجود کانالی معتبر، اعلانی پست میکند، هشدار روی صفحهای نمایش میدهد"</string> + <string name="enforce_shortcuts_for_conversations" msgid="7040735163945040763">"اجرای میانبرها برای اعلانهای مکالمه"</string> + <string name="enforce_shortcuts_for_conversations_summary" msgid="1860168037282467862">"اعلانها باید با میانبر ماندگار همرسانی پشتیبانی شوند تا در بخش مکالمه نشان داده شوند"</string> <string name="force_allow_on_external" msgid="9187902444231637880">"اجازه اجباری به برنامههای دستگاه ذخیره خارجی"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"بدون توجه به مقادیر آشکار، هر برنامهای را برای نوشتن در حافظه خارجی واجد شرایط میکند"</string> <string name="force_resizable_activities" msgid="7143612144399959606">"اجبار فعالیتها به قابل تغییر اندازه بودن"</string> diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml index 765e08edd552..db9872bc71f1 100644 --- a/packages/SettingsLib/res/values-fi/strings.xml +++ b/packages/SettingsLib/res/values-fi/strings.xml @@ -212,7 +212,7 @@ <string name="adb_wireless_settings" msgid="2295017847215680229">"Langaton virheenkorjaus"</string> <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Laita langaton virheenkorjaus päälle, niin voit nähdä saatavilla olevat laitteet ja käyttää niitä"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"Muodosta laitepari QR-koodilla"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"Muodosta uusia laitepareja QR-koodiskannerilla"</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"Muodosta uusia laitepareja QR-koodiskannerilla"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"Yhdistä laite laiteparikoodilla"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"Muodosta uusia laitepareja kuusinumeroisella koodilla"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"Laiteparit"</string> @@ -231,7 +231,7 @@ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"Laiteparin muodostus ei onnistunut. QR-koodi oli virheellinen, tai laitetta ei ole yhdistetty samaan verkkoon."</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP-osoite & portti"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"Skannaa QR-koodi"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"Muodosta laitepari Wi-Fi-yhteyden kautta skannaamalla QR-koodi"</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Muodosta laitepari Wi-Fi-yhteyden kautta skannaamalla QR-koodi"</string> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Yhdistä langattomaan verkkoon"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, virheenkorjaus, kehittäminen"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"Virheraportin pikakuvake"</string> @@ -251,6 +251,8 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"Langattoman näytön sertifiointi"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"Käytä Wi-Fin laajennettua lokikirjausta"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"Wi‑Fi-haun rajoitus"</string> + <!-- no translation found for wifi_enhanced_mac_randomization (5437378364995776979) --> + <skip /> <string name="mobile_data_always_on" msgid="8275958101875563572">"Mobiilidata aina käytössä"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"Laitteistokiihdytyksen yhteyden jakaminen"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"Näytä nimettömät Bluetooth-laitteet"</string> @@ -278,11 +280,13 @@ <string name="private_dns_mode_off" msgid="7065962499349997041">"Pois käytöstä"</string> <string name="private_dns_mode_opportunistic" msgid="1947864819060442354">"Automaattinen"</string> <string name="private_dns_mode_provider" msgid="3619040641762557028">"Yksityisen DNS-tarjoajan isäntänimi"</string> - <string name="private_dns_mode_provider_hostname_hint" msgid="6564868953748514595">"Anna isäntänimi tai DNS-tarjoaja."</string> + <string name="private_dns_mode_provider_hostname_hint" msgid="6564868953748514595">"Anna isäntänimi tai DNS-tarjoaja"</string> <string name="private_dns_mode_provider_failure" msgid="8356259467861515108">"Ei yhteyttä"</string> <string name="wifi_display_certification_summary" msgid="8111151348106907513">"Näytä langattoman näytön sertifiointiin liittyvät asetukset."</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Lisää Wi‑Fin lokikirjaustasoa, näytä SSID RSSI -kohtaisesti Wi‑Fi-valitsimessa."</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"Vähentää virrankulutusta ja parantaa verkon toimintaa"</string> + <!-- no translation found for wifi_enhanced_mac_randomization_summary (7925425746373704991) --> + <skip /> <string name="wifi_metered_label" msgid="8737187690304098638">"Maksullinen"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"Maksuton"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"Lokipuskurien koot"</string> @@ -371,6 +375,8 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"Näytä taustalla olevien sovellusten Sovellus ei vastaa ‑valintaikkunat."</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"Näytä ilmoituskanavan varoitukset"</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"Näyttää varoituksen, kun sovellus julkaisee ilmoituksen ilman kelvollista kanavaa."</string> + <string name="enforce_shortcuts_for_conversations" msgid="7040735163945040763">"Pakota pikanäppäimet keskusteluilmoituksissa"</string> + <string name="enforce_shortcuts_for_conversations_summary" msgid="1860168037282467862">"Vaadi ilmoitusten tukemista pitkäaikaisella jakopikanäppäimellä, jotta ne näkyvät keskusteluosiossa"</string> <string name="force_allow_on_external" msgid="9187902444231637880">"Salli aina ulkoinen tallennus"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Mahdollistaa sovelluksen tietojen tallentamisen ulkoiseen tallennustilaan luetteloarvoista riippumatta."</string> <string name="force_resizable_activities" msgid="7143612144399959606">"Pakota kaikki toiminnot hyväksymään koon muutos"</string> diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml index d118e1fcb013..4778cba3adce 100644 --- a/packages/SettingsLib/res/values-fr-rCA/strings.xml +++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml @@ -212,7 +212,7 @@ <string name="adb_wireless_settings" msgid="2295017847215680229">"Débogage sans fil"</string> <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Pour afficher et utiliser les appareils à proximité, activez le débogage sans fil"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"Associer l\'appareil à l\'aide d\'un code QR"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"Associer les nouveaux appareils à l\'aide d\'un lecteur de code QR"</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"Associer les nouveaux appareils à l\'aide d\'un lecteur de code QR"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"Associer l\'appareil avec un code d\'association"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"Associer les nouveaux appareils à l\'aide d\'un code à six chiffres"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"Appareils associés"</string> @@ -231,7 +231,7 @@ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"Échec de l\'association de l\'appareil Soit le code QR est incorrect, soit l\'appareil n\'est pas connecté au même réseau."</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"Adresse IP et port"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"Numériser le code QR"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"Associer un appareil par Wi-Fi en numérisant un code QR"</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Associer un appareil par Wi-Fi en numérisant un code QR"</string> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Veuillez vous connecter à un réseau Wi-Fi"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, débogage, concepteur"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"Raccourci de rapport de bogue"</string> @@ -243,7 +243,7 @@ <string name="oem_unlock_enable" msgid="5334869171871566731">"Déverrouillage par le fabricant"</string> <string name="oem_unlock_enable_summary" msgid="5857388174390953829">"Autoriser le déverrouillage du fichier d\'amorce"</string> <string name="confirm_enable_oem_unlock_title" msgid="8249318129774367535">"Permettre le déverrouillage par le fabricant?"</string> - <string name="confirm_enable_oem_unlock_text" msgid="854131050791011970">"AVERTISSEMENT : Les fonctions de protection de l\'appareil ne fonctionneront pas sur cet appareil lorsque ce paramètre est activé."</string> + <string name="confirm_enable_oem_unlock_text" msgid="854131050791011970">"AVERTISSEMENT : Les fonctionnalités de protection de l\'appareil ne fonctionneront pas sur cet appareil lorsque ce paramètre est activé."</string> <string name="mock_location_app" msgid="6269380172542248304">"Sélectionner l\'application de localisation factice"</string> <string name="mock_location_app_not_set" msgid="6972032787262831155">"Aucune application de localisation factice définie"</string> <string name="mock_location_app_set" msgid="4706722469342913843">"Application de localisation factice : <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> @@ -251,6 +251,7 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"Certification de l\'affichage sans fil"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"Autoriser enreg. données Wi-Fi détaillées"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"Limiter la recherche de réseaux Wi-Fi"</string> + <string name="wifi_enhanced_mac_randomization" msgid="5437378364995776979">"Sélect. aléatoire adr. MAC optim. par Wi‑Fi"</string> <string name="mobile_data_always_on" msgid="8275958101875563572">"Données cellulaires toujours actives"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"Accélération matérielle pour le partage de connexion"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"Afficher les appareils Bluetooth sans nom"</string> @@ -283,6 +284,7 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"Afficher les options pour la certification d\'affichage sans fil"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Détailler davantage les données Wi-Fi, afficher par SSID RSSI dans sélect. Wi-Fi"</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"Réduit l\'utilisation de la pile et améliore les performances réseau"</string> + <string name="wifi_enhanced_mac_randomization_summary" msgid="7925425746373704991">"Ce commutateur a un impact sur le comportement de sélection aléatoire des adresses MAC pour le mode client uniquement.\nLorsque ce mode est activé, l\'association pourrait forcer la réorganisation de manière aléatoire des adresses MAC pour les réseaux sur lesquels la sélection aléatoire des adresses MAC est activée, en fonction de la dernière fois que le client s\'est déconnecté du réseau. La réorganisation de manière aléatoire des adresses MAC ne se produit pas si l\'appareil se reconnecter d\'ici quatre heures ou moins."</string> <string name="wifi_metered_label" msgid="8737187690304098638">"Facturé à l\'usage"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"Non mesuré"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"Tailles des mémoires tampons d\'enregistreur"</string> @@ -371,6 +373,8 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"Afficher le message « L\'application ne répond plus » pour les applications en arrière-plan"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"Affich. avertiss. canal notification"</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"Afficher avertiss. à l\'écran quand une app présente une notific. sans canal valide"</string> + <string name="enforce_shortcuts_for_conversations" msgid="7040735163945040763">"Appliquer les raccourcis pour les notifications de conversation"</string> + <string name="enforce_shortcuts_for_conversations_summary" msgid="1860168037282467862">"Exiger le soutien des notifications par un raccourci de partage longue durée pour qu\'elles s\'affichent dans la section des conversations"</string> <string name="force_allow_on_external" msgid="9187902444231637880">"Forcer l\'autor. d\'applis sur stockage externe"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Rend possible l\'enregistrement de toute application sur un espace de stockage externe, indépendamment des valeurs du fichier manifeste"</string> <string name="force_resizable_activities" msgid="7143612144399959606">"Forcer les activités à être redimensionnables"</string> diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml index f2dcbbaed91b..1b6ca29f473e 100644 --- a/packages/SettingsLib/res/values-fr/strings.xml +++ b/packages/SettingsLib/res/values-fr/strings.xml @@ -206,13 +206,13 @@ <string name="enable_adb" msgid="8072776357237289039">"Débogage USB"</string> <string name="enable_adb_summary" msgid="3711526030096574316">"Mode débogage lorsqu\'un câble USB est connecté"</string> <string name="clear_adb_keys" msgid="3010148733140369917">"Annuler autorisations pour débog. USB"</string> - <string name="enable_adb_wireless" msgid="6973226350963971018">"Débogage via Wi-Fi"</string> + <string name="enable_adb_wireless" msgid="6973226350963971018">"Débogage sans fil"</string> <string name="enable_adb_wireless_summary" msgid="7344391423657093011">"Mode de débogage en connexion Wi-Fi"</string> <string name="adb_wireless_error" msgid="721958772149779856">"Erreur"</string> - <string name="adb_wireless_settings" msgid="2295017847215680229">"Débogage via Wi-Fi"</string> + <string name="adb_wireless_settings" msgid="2295017847215680229">"Débogage sans fil"</string> <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Pour afficher et utiliser les appareils disponibles, activez le débogage sans fil"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"Associer l\'appareil avec un code QR"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"Associer les nouveaux appareils à l\'aide d\'un lecteur de code QR"</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"Associer les nouveaux appareils à l\'aide d\'un lecteur de code QR"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"Associer l\'appareil avec un code d\'association"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"Associer les nouveaux appareils à l\'aide d\'un code à six chiffres"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"Appareils associés"</string> @@ -231,7 +231,7 @@ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"Échec de l\'association à l\'appareil. Le code QR est incorrect, ou l\'appareil n\'est pas connecté au même réseau."</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"Adresse IP et port"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"Scanner un code QR"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"Associer l\'appareil via le Wi‑Fi à l\'aide d\'un code QR"</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Associer l\'appareil via le Wi‑Fi à l\'aide d\'un code QR"</string> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Connectez-vous à un réseau Wi-Fi"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, débogage, dev"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"Raccourci vers rapport de bug"</string> @@ -251,6 +251,7 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"Certification affichage sans fil"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"Autoriser l\'enregistrement d\'infos Wi-Fi détaillées"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"Limiter la recherche Wi‑Fi"</string> + <string name="wifi_enhanced_mac_randomization" msgid="5437378364995776979">"Chgt aléatoire d\'adresse MAC sur Wi-Fi"</string> <string name="mobile_data_always_on" msgid="8275958101875563572">"Données mobiles toujours actives"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"Accélération matérielle pour le partage de connexion"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"Afficher les appareils Bluetooth sans nom"</string> @@ -283,6 +284,7 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"Afficher les options pour la certification de l\'affichage sans fil"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Détailler les infos Wi-Fi, afficher par RSSI de SSID dans l\'outil de sélection Wi-Fi"</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"Réduit la décharge de la batterie et améliore les performances du réseau"</string> + <string name="wifi_enhanced_mac_randomization_summary" msgid="7925425746373704991">"Ce paramètre modifie uniquement le changement aléatoire de l\'adresse MAC en mode client.\nSi ce mode est activé, les réseaux pour lesquels le changement aléatoire d\'adresse MAC est activé peuvent faire l\'objet de nouveaux changements aléatoires d\'adresse lors des associations, en fonction du temps écoulé depuis la dernière fois que le client s\'est déconnecté du réseau. Aucun changement aléatoire d\'adresse n\'a lieu si un appareil se connecte à nouveau après un délai inférieur à quatre heures."</string> <string name="wifi_metered_label" msgid="8737187690304098638">"Facturé à l\'usage"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"Non facturé à l\'usage"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"Tailles des tampons de l\'enregistreur"</string> @@ -300,8 +302,8 @@ <string name="tethering_hardware_offload_summary" msgid="7801345335142803029">"Utiliser l\'accélération matérielle pour le partage de connexion, si disponible"</string> <string name="adb_warning_title" msgid="7708653449506485728">"Autoriser le débogage USB ?"</string> <string name="adb_warning_message" msgid="8145270656419669221">"Le débogage USB est conçu uniquement pour le développement. Utilisez-le pour copier des données entre votre ordinateur et votre appareil, installer des applications sur votre appareil sans notification et lire les données de journal."</string> - <string name="adbwifi_warning_title" msgid="727104571653031865">"Autoriser le débogage via Wi-Fi ?"</string> - <string name="adbwifi_warning_message" msgid="8005936574322702388">"Le débogage via Wi-Fi est conçu uniquement pour le développement. Utilisez-le pour copier des données entre votre ordinateur et votre appareil, installer des applications sur votre appareil sans notification et lire les données des journaux."</string> + <string name="adbwifi_warning_title" msgid="727104571653031865">"Autoriser le débogage sans fil ?"</string> + <string name="adbwifi_warning_message" msgid="8005936574322702388">"Le débogage sans fil est conçu uniquement pour le développement. Utilisez-le pour copier des données entre votre ordinateur et votre appareil, installer des applications sur votre appareil sans notification et lire les données des journaux."</string> <string name="adb_keys_warning_message" msgid="2968555274488101220">"Voulez-vous vraiment désactiver l\'accès au débogage USB de tous les ordinateurs précédemment autorisés ?"</string> <string name="dev_settings_warning_title" msgid="8251234890169074553">"Activer les paramètres de développement ?"</string> <string name="dev_settings_warning_message" msgid="37741686486073668">"Ces paramètres sont en cours de développement. Ils peuvent endommager votre appareil et les applications qui s\'y trouvent, ou provoquer leur dysfonctionnement."</string> @@ -371,6 +373,8 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"Afficher la boîte de dialogue \"L\'application ne répond plus\" pour les applications en arrière-plan"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"Afficher les avertissements liés aux canaux de notification"</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"Afficher un avertissement lorsqu\'une application publie une notification sans canal valide"</string> + <string name="enforce_shortcuts_for_conversations" msgid="7040735163945040763">"Utiliser des raccourcis pour les notifications des conversations"</string> + <string name="enforce_shortcuts_for_conversations_summary" msgid="1860168037282467862">"Exiger la sauvegarde des notifications via un raccourci de partage permanent pour qu\'elles s\'affichent dans la section des conversations"</string> <string name="force_allow_on_external" msgid="9187902444231637880">"Forcer l\'autorisation d\'applis sur stockage externe"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Autoriser l\'enregistrement de toute application sur un espace de stockage externe, indépendamment des valeurs du fichier manifeste"</string> <string name="force_resizable_activities" msgid="7143612144399959606">"Forcer le redimensionnement des activités"</string> diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml index 9ee490f09ae2..bbc4e18754fe 100644 --- a/packages/SettingsLib/res/values-gl/strings.xml +++ b/packages/SettingsLib/res/values-gl/strings.xml @@ -206,13 +206,13 @@ <string name="enable_adb" msgid="8072776357237289039">"Depuración por USB"</string> <string name="enable_adb_summary" msgid="3711526030096574316">"Modo de depuración de erros cando o USB está conectado"</string> <string name="clear_adb_keys" msgid="3010148733140369917">"Revogar as autorizacións de depuración por USB"</string> - <string name="enable_adb_wireless" msgid="6973226350963971018">"Depuración de erros sen fíos"</string> + <string name="enable_adb_wireless" msgid="6973226350963971018">"Depuración sen fíos"</string> <string name="enable_adb_wireless_summary" msgid="7344391423657093011">"Modo de depuración de erros ao conectarse a wifi"</string> <string name="adb_wireless_error" msgid="721958772149779856">"Produciuse un erro"</string> - <string name="adb_wireless_settings" msgid="2295017847215680229">"Depuración de erros sen fíos"</string> - <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Para ver e usar os dispositivos dispoñibles, activa a depuración de erros sen fíos"</string> + <string name="adb_wireless_settings" msgid="2295017847215680229">"Depuración sen fíos"</string> + <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Para ver e usar os dispositivos dispoñibles, activa a depuración sen fíos"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"Vincular o dispositivo cun código QR"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"Vincula dispositivos novos mediante un escáner de códigos QR"</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"Vincula dispositivos novos mediante un escáner de códigos QR"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"Vincular o dispositivo co código de sincronización"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"Vincula dispositivos novos mediante un código de seis díxitos"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"Dispositivos vinculados"</string> @@ -231,7 +231,7 @@ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"Produciuse un erro ao sincronizar o dispositivo. O código QR era incorrecto ou o dispositivo non está conectado á mesma rede."</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"Enderezo IP e porto"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"Escanear o código QR"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"Vincula o dispositivo a través da wifi escaneando un código QR"</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Vincula o dispositivo a través da wifi escaneando un código QR"</string> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Conéctate a unha rede wifi"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, depuración, programador"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"Atallo do informe de erros"</string> @@ -251,6 +251,7 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"Certificado de visualización sen fíos"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"Activar rexistro detallado da wifi"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"Limitación da busca de wifi"</string> + <string name="wifi_enhanced_mac_randomization" msgid="5437378364995776979">"Selección aleatoria de enderezo MAC"</string> <string name="mobile_data_always_on" msgid="8275958101875563572">"Datos móbiles sempre activados"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"Aceleración de hardware para conexión compartida"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"Mostrar dispositivos Bluetooth sen nomes"</string> @@ -283,6 +284,7 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"Mostra opcións para o certificado de visualización sen fíos"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Aumenta o nivel de rexistro da wifi, móstrao por SSID RSSI no selector de wifi"</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"Reduce o consumo de batería e mellora o rendemento da rede"</string> + <string name="wifi_enhanced_mac_randomization_summary" msgid="7925425746373704991">"Esta opción só lle afecta ao comportamento da selección aleatoria de enderezo MAC do modo de cliente.\nCando este modo está activado, os enderezos MAC das redes que teñan activada a selección automática de enderezo MAC pódense volver seleccionar aleatoriamente durante a asociación. Isto depende de cando se desconectase da rede cada cliente por última vez, xa que a selección aleatoria non se repite se transcorreron 4 horas ou menos desde a última conexión."</string> <string name="wifi_metered_label" msgid="8737187690304098638">"Sen tarifa plana"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"Con tarifa plana"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"Tamaño dos búfers do rexistrador"</string> @@ -300,8 +302,8 @@ <string name="tethering_hardware_offload_summary" msgid="7801345335142803029">"Se está dispoñible, úsase a aceleración de hardware para conexión compartida"</string> <string name="adb_warning_title" msgid="7708653449506485728">"Queres permitir a depuración por USB?"</string> <string name="adb_warning_message" msgid="8145270656419669221">"A depuración de erros USB está deseñada unicamente para fins de programación. Utilízaa para copiar datos entre o ordenador e o dispositivo, instalar aplicacións no dispositivo sen enviar notificacións e ler os datos do rexistro."</string> - <string name="adbwifi_warning_title" msgid="727104571653031865">"Queres permitir a depuración de erros sen fíos?"</string> - <string name="adbwifi_warning_message" msgid="8005936574322702388">"A depuración de erros sen fíos está deseñada unicamente para fins de programación. Utilízaa para copiar datos entre o ordenador e o dispositivo, instalar aplicacións no dispositivo sen recibir notificacións e ler os datos do rexistro."</string> + <string name="adbwifi_warning_title" msgid="727104571653031865">"Queres permitir a depuración sen fíos?"</string> + <string name="adbwifi_warning_message" msgid="8005936574322702388">"A depuración sen fíos está deseñada unicamente para fins de programación. Utilízaa para copiar datos entre o ordenador e o dispositivo, instalar aplicacións no dispositivo sen recibir notificacións e ler os datos do rexistro."</string> <string name="adb_keys_warning_message" msgid="2968555274488101220">"Queres revogar o acceso á depuración por USB desde todos os ordenadores que autorizaches previamente?"</string> <string name="dev_settings_warning_title" msgid="8251234890169074553">"Permitir a configuración de programación?"</string> <string name="dev_settings_warning_message" msgid="37741686486073668">"Esta configuración só está destinada á programación. Esta pode provocar que o dispositivo e as aplicacións fallen ou se comporten incorrectamente."</string> @@ -371,6 +373,8 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"Indica que unha aplicación en segundo plano non responde"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"Mostrar avisos de notificacións"</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"Mostra avisos cando unha aplicación publica notificacións sen unha canle válida"</string> + <string name="enforce_shortcuts_for_conversations" msgid="7040735163945040763">"Usar atallos para notificacións de conversas"</string> + <string name="enforce_shortcuts_for_conversations_summary" msgid="1860168037282467862">"Require que as notificacións teñan un atallo de uso compartido permanente para aparecer na sección de conversas"</string> <string name="force_allow_on_external" msgid="9187902444231637880">"Forzar permiso de aplicacións de forma externa"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Permite que calquera aplicación compatible se poida escribir nun almacenamento externo, independentemente dos valores do manifesto"</string> <string name="force_resizable_activities" msgid="7143612144399959606">"Forzar o axuste do tamaño das actividades"</string> diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml index 2fced2bdb6cf..7210b7b35609 100644 --- a/packages/SettingsLib/res/values-gu/strings.xml +++ b/packages/SettingsLib/res/values-gu/strings.xml @@ -212,7 +212,7 @@ <string name="adb_wireless_settings" msgid="2295017847215680229">"વાયરલેસ ડિબગીંગ"</string> <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"ઉપલબ્ધ ડિવાઇસને જોવા અને તેનો ઉપયોગ કરવા માટે, વાયરલેસ ડિબગીંગ ચાલુ કરો"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"QR કોડ વડે ડિવાઇસનું જોડાણ બનાવો"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"QR કોડ સ્કૅનરનો ઉપયોગ કરીને નવા ડિવાઇસનું જોડાણ બનાવો"</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"QR કોડ સ્કૅનરનો ઉપયોગ કરીને નવા ડિવાઇસનું જોડાણ બનાવો"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"જોડાણ કરવાના કોડ વડે ડિવાઇસનું જોડાણ બનાવો"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"છ અંકના કોડનો ઉપયોગ કરીને નવા ડિવાઇસનું જોડાણ બનાવો"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"જોડાણ કરેલા ડિવાઇસ"</string> @@ -231,7 +231,7 @@ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"ડિવાઇસનું જોડાણ કરવામાં નિષ્ફળ રહ્યાં. કાં તો QR કોડ ખોટો હતો અથવા ડિવાઇસ સમાન નેટવર્ક સાથે કનેક્ટ કરેલું નથી."</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP ઍડ્રેસ & પોર્ટ"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"QR કોડ સ્કૅન કરો"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"QR કોડને સ્કૅન કરીને વાઇ-ફાઇ પર ડિવાઇસનું જોડાણ બનાવો"</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"QR કોડને સ્કૅન કરીને વાઇ-ફાઇ પર ડિવાઇસનું જોડાણ બનાવો"</string> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"કૃપા કરીને વાઇ-ફાઇ નેટવર્કથી કનેક્ટ કરો"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, ડિબગ, ડેવ"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"બગ રિપોર્ટ શોર્ટકટ"</string> @@ -251,6 +251,8 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"વાયરલેસ ડિસ્પ્લે પ્રમાણન"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"વાઇ-ફાઇ વર્બોઝ લૉગિંગ ચાલુ કરો"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"વાઇ-ફાઇ સ્કૅનની ક્ષમતા મર્યાદિત કરવી"</string> + <!-- no translation found for wifi_enhanced_mac_randomization (5437378364995776979) --> + <skip /> <string name="mobile_data_always_on" msgid="8275958101875563572">"મોબાઇલ ડેટા હંમેશાં સક્રિય"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"ટિથરિંગ માટે હાર્ડવેર ગતિવૃદ્ધિ"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"નામ વિનાના બ્લૂટૂથ ઉપકરણો બતાવો"</string> @@ -276,13 +278,15 @@ <string name="select_private_dns_configuration_title" msgid="7887550926056143018">"ખાનગી DNS"</string> <string name="select_private_dns_configuration_dialog_title" msgid="3731422918335951912">"ખાનગી DNS મોડને પસંદ કરો"</string> <string name="private_dns_mode_off" msgid="7065962499349997041">"બંધ"</string> - <string name="private_dns_mode_opportunistic" msgid="1947864819060442354">"આપમેળે"</string> + <string name="private_dns_mode_opportunistic" msgid="1947864819060442354">"ઑટોમૅટિક"</string> <string name="private_dns_mode_provider" msgid="3619040641762557028">"ખાનગી DNS પ્રદાતા હોસ્ટનું નામ"</string> <string name="private_dns_mode_provider_hostname_hint" msgid="6564868953748514595">"DNS પ્રદાતાના હોસ્ટનું નામ દાખલ કરો"</string> <string name="private_dns_mode_provider_failure" msgid="8356259467861515108">"કનેક્ટ કરી શકાયું નથી"</string> <string name="wifi_display_certification_summary" msgid="8111151348106907513">"વાયરલેસ ડિસ્પ્લે પ્રમાણપત્ર માટેના વિકલ્પો બતાવો"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"વાઇ-ફાઇ લોગિંગ સ્તર વધારો, વાઇ-ફાઇ પીકરમાં SSID RSSI દીઠ બતાવો"</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"બૅટરીનો ચાર્જ ઝડપથી ઓછો થવાનું ટાળે છે અને નેટવર્કની કાર્યક્ષમતામાં સુધારો કરે છે"</string> + <!-- no translation found for wifi_enhanced_mac_randomization_summary (7925425746373704991) --> + <skip /> <string name="wifi_metered_label" msgid="8737187690304098638">"મીટર કરેલ"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"મીટર ન કરેલ"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"લોગર બફર કદ"</string> @@ -371,6 +375,8 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"બૅકગ્રાઉન્ડ ઍપ માટે \"ઍપ પ્રતિસાદ આપતી નથી\" સંવાદ બતાવો"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"નોટિફિકેશન ચૅનલની ચેતવણી બતાવો"</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"ઍપ્લિકેશન માન્ય ચૅનલ વિના નોટિફિકેશન પોસ્ટ કરે તો સ્ક્રીન પર ચેતવણી દેખાય છે"</string> + <string name="enforce_shortcuts_for_conversations" msgid="7040735163945040763">"વાતચીત સૂચનો માટે શૉર્ટકટ"</string> + <string name="enforce_shortcuts_for_conversations_summary" msgid="1860168037282467862">"વાતચીત વિભાગમાં દેખાવા એક લાંબું ટકતા શેરિંગ શૉર્ટકટ દ્વારા ટેકો મેળવતા નોટિફિકેશન જરૂરી છે"</string> <string name="force_allow_on_external" msgid="9187902444231637880">"બાહ્ય પર એપ્લિકેશનોને મંજૂરી આપવાની ફરજ પાડો"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"મેનિફેસ્ટ મૂલ્યોને ધ્યાનમાં લીધા સિવાય, કોઈપણ ઍપ્લિકેશનને બાહ્ય સ્ટોરેજ પર લખાવા માટે લાયક બનાવે છે"</string> <string name="force_resizable_activities" msgid="7143612144399959606">"પ્રવૃત્તિઓને ફરીથી કદ યોગ્ય થવા માટે ફરજ પાડો"</string> diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml index cb4110017241..f3a6e2594ffe 100644 --- a/packages/SettingsLib/res/values-hi/strings.xml +++ b/packages/SettingsLib/res/values-hi/strings.xml @@ -206,13 +206,13 @@ <string name="enable_adb" msgid="8072776357237289039">"USB डीबग करना"</string> <string name="enable_adb_summary" msgid="3711526030096574316">"डीबग मोड जब USB कनेक्ट किया गया हो"</string> <string name="clear_adb_keys" msgid="3010148733140369917">"USB डीबग करने की मंज़ूरी रद्द करें"</string> - <string name="enable_adb_wireless" msgid="6973226350963971018">"वायरलेस डीबग करना"</string> + <string name="enable_adb_wireless" msgid="6973226350963971018">"वॉयरलेस डीबगिंग"</string> <string name="enable_adb_wireless_summary" msgid="7344391423657093011">"डिवाइस के वाई-फ़ाई से कनेक्ट हाेने पर, डीबग मोड चालू करें"</string> <string name="adb_wireless_error" msgid="721958772149779856">"गड़बड़ी"</string> - <string name="adb_wireless_settings" msgid="2295017847215680229">"वायरलेस डीबग करना"</string> - <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"उपलब्ध डिवाइस देखने और इस्तेमाल करने के लिए, वायरलेस डीबग करने की सुविधा चालू करें"</string> + <string name="adb_wireless_settings" msgid="2295017847215680229">"वॉयरलेस डीबगिंग"</string> + <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"उपलब्ध डिवाइस देखने और इस्तेमाल करने के लिए, वॉयरलेस डीबगिंग की सुविधा चालू करें"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"क्यूआर कोड की मदद से डिवाइस जोड़ें"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"क्यूआर कोड स्कैनर का इस्तेमाल करके, नए डिवाइस जोड़ें"</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"क्यूआर कोड स्कैनर का इस्तेमाल करके, नए डिवाइस जोड़ें"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"जोड़ने का कोड इस्तेमाल करके, डिवाइस जोड़ें"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"छह अंकों का कोड इस्तेमाल करके, नए डिवाइस जोड़ें"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"जोड़े गए डिवाइस"</string> @@ -231,7 +231,7 @@ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"डिवाइस को जोड़ा नहीं जा सका. शायद, क्यूआर कोड ठीक नहीं था या फिर आपका डिवाइस और दूसरा डिवाइस, दाेनाें एक ही नेटवर्क से नहीं जुड़े हैं."</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"आईपी पता और पोर्ट"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"क्यूआर कोड स्कैन करें"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"क्यूआर कोड स्कैन करके, वाई-फ़ाई से डिवाइस को जोड़ें"</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"क्यूआर कोड स्कैन करके, वाई-फ़ाई नेटवर्क से डिवाइस जोड़ें"</string> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"कृपया किसी वाई-फ़ाई नेटवर्क से कनेक्ट करें"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, debug, dev"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"गड़बड़ी की रिपोर्ट का शॉर्टकट"</string> @@ -251,6 +251,7 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"वायरलेस डिसप्ले सर्टिफ़िकेशन"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"वाई-फ़ाई वर्बोस लॉगिंग चालू करें"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"वाई-फ़ाई के लिए स्कैन की संख्या कम करें"</string> + <string name="wifi_enhanced_mac_randomization" msgid="5437378364995776979">"बेहतर वाई-फ़ाई नेटवर्क से जुड़ने पर मैक पता बदलने की सुविधा"</string> <string name="mobile_data_always_on" msgid="8275958101875563572">"मोबाइल डेटा हमेशा चालू"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"हार्डवेयर से तेज़ी लाने के लिए टेदर करें"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"बिना नाम वाले ब्लूटूथ डिवाइस दिखाएं"</string> @@ -283,6 +284,7 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"वायरलेस डिसप्ले सर्टिफ़िकेशन के विकल्प दिखाएं"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"वाई-फ़ाई लॉगिंग का स्तर बढ़ाएं, वाई-फ़ाई पिकर में प्रति SSID RSSI दिखाएं"</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"बैटरी की खपत कम और नेटवर्क की परफ़ॉर्मेंस बेहतर होती है"</string> + <string name="wifi_enhanced_mac_randomization_summary" msgid="7925425746373704991">"इस टॉगल से सिर्फ़ क्लाइंट मोड में, वाई-फ़ाई नेटवर्क से जुड़ते समय मैक पते को बदलने की सुविधा पर असर पड़ता है.\nजब इस मोड को चालू किया जाता है, तब ऐसे किसी भी नेटवर्क का मैक पता फिर से बदला जा सकता है जिन पर मैक पते को बदलने की सुविधा चालू होती है. ऐसा तभी होता है, जब वे नेटवर्क जुड़े हों. यह इस पर भी निर्भर करता है कि क्लाइंट ने उसे नेटवर्क से कब डिसकनेक्ट किया था. अगर डिवाइस चार घंटे या उससे कम में, फिर से कनेक्ट होता है, तो मैक पते को दोबारा बदला नहीं जा सकता."</string> <string name="wifi_metered_label" msgid="8737187690304098638">"डेटा इस्तेमाल करने की सीमा तय की गई है"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"डेटा इस्तेमाल करने की सीमा तय नहीं की गई है"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"लॉगर बफ़र आकार"</string> @@ -300,8 +302,8 @@ <string name="tethering_hardware_offload_summary" msgid="7801345335142803029">"हार्डवेयर से तेज़ी लाने के लिए टेदर करने की सुविधा मौजूद होने पर उसका इस्तेमाल करें"</string> <string name="adb_warning_title" msgid="7708653449506485728">"USB डीबग करने की अनुमति दें?"</string> <string name="adb_warning_message" msgid="8145270656419669221">"USB डीबग करने का मकसद केवल डेवेलप करना है. इसका इस्तेमाल आपके कंप्यूटर और आपके डिवाइस के बीच डेटा को कॉपी करने, बिना सूचना के आपके डिवाइस पर ऐप इंस्टॉल करने और लॉग डेटा पढ़ने के लिए करें."</string> - <string name="adbwifi_warning_title" msgid="727104571653031865">"वायरलेस डीबग करने की अनुमति देना चाहते हैं?"</string> - <string name="adbwifi_warning_message" msgid="8005936574322702388">"वायरलेस डीबग करने का मकसद सिर्फ़ डेवलपमेंट करना है. इसका इस्तेमाल, आपके कंप्यूटर और डिवाइस के बीच डेटा कॉपी करने, बिना सूचना के आपके डिवाइस पर ऐप्लिकेशन इंस्टॉल करने, और लॉग डेटा पढ़ने के लिए करें."</string> + <string name="adbwifi_warning_title" msgid="727104571653031865">"वॉयरलेस डीबगिंग की अनुमति देना चाहते हैं?"</string> + <string name="adbwifi_warning_message" msgid="8005936574322702388">"वॉयरलेस डीबगिंग का मकसद सिर्फ़ डेवलपमेंट करना है. इसका इस्तेमाल, आपके कंप्यूटर और डिवाइस के बीच डेटा कॉपी करने, बिना सूचना के आपके डिवाइस पर ऐप्लिकेशन इंस्टॉल करने, और लॉग डेटा पढ़ने के लिए करें."</string> <string name="adb_keys_warning_message" msgid="2968555274488101220">"उन सभी कंप्यूटरों से USB डीबग करने की पहुंचर रद्द करें, जिन्हें आपने पहले इसकी मंज़ूरी दी थी?"</string> <string name="dev_settings_warning_title" msgid="8251234890169074553">"विकास सेटिंग की अनुमति दें?"</string> <string name="dev_settings_warning_message" msgid="37741686486073668">"ये सेटिंग केवल विकास संबंधी उपयोग के प्रयोजन से हैं. वे आपके डिवाइस और उस पर स्थित ऐप्लिकेशन को खराब कर सकती हैं या उनके दुर्व्यवहार का कारण हो सकती हैं."</string> @@ -371,6 +373,8 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"बैकग्राउंड में चलने वाले ऐप्लिकेशन के लिए, यह ऐप्लिकेशन नहीं चल रहा मैसेज दिखाएं"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"सूचना चैनल चेतावनी दिखाएं"</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"ऐप्लिकेशन, मान्य चैनल के बिना सूचना पोस्ट करे तो स्क्रीन पर चेतावनी दिखाएं"</string> + <string name="enforce_shortcuts_for_conversations" msgid="7040735163945040763">"सिर्फ़ वही सूचनाएं दिखाएं जो बातचीत सेक्शन में सही शॉर्टकट के साथ भी लिंक हैं"</string> + <string name="enforce_shortcuts_for_conversations_summary" msgid="1860168037282467862">"ज़रूरी सूचनाओं के लिए ऐसा शेयरिंग शॉर्टकट होना चाहिए जो हमेशा (long-lived) मौजूद रहे, ताकि सूचनाओं को बातचीत वाले सेक्शन में देखा जा सके"</string> <string name="force_allow_on_external" msgid="9187902444231637880">"ऐप्लिकेशन को बाहरी मेमोरी पर ही चलाएं"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"इससे कोई भी ऐप्लिकेशन बाहरी मेमोरी में रखने लायक बन जाता है चाहे उसकी मेनिफ़ेस्ट वैल्यू कुछ भी हो"</string> <string name="force_resizable_activities" msgid="7143612144399959606">"विंडो के हिसाब से गतिविधियों का आकार बदल दें"</string> diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml index f1608d0d7c6e..5dbbdb2fb687 100644 --- a/packages/SettingsLib/res/values-hr/strings.xml +++ b/packages/SettingsLib/res/values-hr/strings.xml @@ -212,7 +212,7 @@ <string name="adb_wireless_settings" msgid="2295017847215680229">"Bežično otklanjanje pogrešaka"</string> <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Da biste vidjeli dostupne uređaje i mogli se njima koristiti, uključite bežično otklanjanje pogrešaka"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"Uparivanje uređaja pomoću QR koda"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"Uparivanje novih uređaja pomoću čitača QR koda"</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"Uparivanje novih uređaja pomoću čitača QR koda"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"Uparivanje uređaja pomoću koda za uparivanje"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"Uparivanje novih uređaja pomoću šesteroznamenkastog koda"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"Upareni uređaji"</string> @@ -230,8 +230,8 @@ <string name="adb_wireless_verifying_qrcode_text" msgid="6123192424916029207">"Uparivanje uređaja…"</string> <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"Uparivanje uređaja nije uspjelo. QR kôd je neispravan ili uređaj nije povezan na istu mrežu."</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP adresa i priključak"</string> - <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"Skeniraj QR kôd"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"Uparivanje uređaja putem Wi-Fija skeniranjem QR koda"</string> + <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"Skenirajte QR kôd"</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Uparivanje uređaja putem Wi-Fija skeniranjem QR koda"</string> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Povežite se s Wifi mrežom"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, otklanjanje pogrešaka, razvoj"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"Prečac izvješća o pogreškama"</string> @@ -251,6 +251,7 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"Certifikacija bežičnog prikaza"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"Omogući opširnu prijavu na Wi-Fi"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"Usporavanje traženja Wi-Fija"</string> + <string name="wifi_enhanced_mac_randomization" msgid="5437378364995776979">"Nasum. odabir MAC-a poboljšan Wi‑Fi‑jem"</string> <string name="mobile_data_always_on" msgid="8275958101875563572">"Mobilni podaci uvijek aktivni"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"Hardversko ubrzanje za modemsko povezivanje"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"Prikaži Bluetooth uređaje bez naziva"</string> @@ -283,6 +284,7 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"Prikaz opcija za certifikaciju bežičnog prikaza"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Povećana razina prijave na Wi‑Fi, prikaz po SSID RSSI-ju u Biraču Wi‑Fi-ja"</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"Smanjuje potrošnju baterije i poboljšava rad mreže"</string> + <string name="wifi_enhanced_mac_randomization_summary" msgid="7925425746373704991">"Ovaj prekidač utječe na ponašanje nasumičnog odabira MAC-a samo za način korisnika.\nKad je aktiviran ovaj način rada, kod bilo koje mreže koja ima omogućen nasumični odabir MAC-a može doći do ponovnog nasumičnog odabira MAC adrese tijekom povezivanja, ovisno o tome kad se klijent posljednji put odspojio s mreže. Nema ponovnog nasumičnog odabira ako se uređaj ponovno spoji za manje od 4 sata."</string> <string name="wifi_metered_label" msgid="8737187690304098638">"S ograničenim prometom"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"Bez ograničenja prometa"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"Veličine međuspremnika zapisnika"</string> @@ -371,6 +373,8 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"Dijalog o pozadinskim aplikacijama koje ne reagiraju"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"Prikaži upozorenja kanala obavijesti"</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"Prikazuje upozorenje na zaslonu kada aplikacija objavi obavijest bez važećeg kanala"</string> + <string name="enforce_shortcuts_for_conversations" msgid="7040735163945040763">"Primjena prečaca za obavijesti razgovora"</string> + <string name="enforce_shortcuts_for_conversations_summary" msgid="1860168037282467862">"Obavijesti moraju imati dugotrajni prečac za dijeljenje da bi se prikazale u odjeljku razgovora"</string> <string name="force_allow_on_external" msgid="9187902444231637880">"Prisilno dopusti aplikacije u vanjskoj pohrani"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Aplikacije se mogu zapisivati u vanjsku pohranu neovisno o vrijednostima manifesta"</string> <string name="force_resizable_activities" msgid="7143612144399959606">"Nametni mogućnost promjene veličine za aktivnosti"</string> diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml index bb2f17cecab7..15f008bcb1f7 100644 --- a/packages/SettingsLib/res/values-hu/strings.xml +++ b/packages/SettingsLib/res/values-hu/strings.xml @@ -212,7 +212,7 @@ <string name="adb_wireless_settings" msgid="2295017847215680229">"Vezeték nélküli hibakeresés"</string> <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"A rendelkezésre álló eszközök megtekintéséhez és használatához kapcsolja be a vezeték nélküli hibakeresést"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"Eszköz párosítása QR-kóddal"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"Párosítsa az új eszközöket QR-kód-szkennelő használatával"</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"Párosítsa az új eszközöket QR-kód-szkennelő használatával"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"Eszköz párosítása párosítókóddal"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"Párosítsa az új eszközöket hatjegyű kód használatával"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"Párosított eszközök"</string> @@ -231,7 +231,7 @@ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"Nem sikerült az eszközzel való párosítás. Vagy helytelen volt a QR-kód, vagy az eszköz másik hálózathoz csatlakozott."</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP-cím és port"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"QR-kód beolvasása"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"Párosítsa az eszközt Wi-Fi-n keresztül QR-kód beolvasásával"</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Párosítsa az eszközt Wi-Fi-n keresztül QR-kód beolvasásával"</string> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Csatlakozzon Wi-Fi-hálózathoz"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, debug, dev"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"Hibabejelentési gomb"</string> @@ -251,6 +251,7 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"Vezeték nélküli kijelző tanúsítványa"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"Részletes Wi-Fi-naplózás engedélyezése"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"Wi-Fi-hálózat szabályozása"</string> + <string name="wifi_enhanced_mac_randomization" msgid="5437378364995776979">"Wi‑Fi‑re kiterjesztett, randomizált MAC"</string> <string name="mobile_data_always_on" msgid="8275958101875563572">"A mobilhálózati kapcsolat mindig aktív"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"Internetmegosztás hardveres gyorsítása"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"Név nélküli Bluetooth-eszközök megjelenítése"</string> @@ -283,6 +284,7 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"Vezeték nélküli kijelző tanúsítványával kapcsolatos lehetőségek megjelenítése"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Wi‑Fi-naplózási szint növelése, RSSI/SSID megjelenítése a Wi‑Fi-választóban"</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"Csökkenti az akkumulátorhasználatot, és javítja a hálózat teljesítményét"</string> + <string name="wifi_enhanced_mac_randomization_summary" msgid="7925425746373704991">"Kizárólag ügyfélmód esetében be- vagy kikapcsolja a MAC-címet randomizáló viselkedést.\nHa a mód aktív, az olyan hálózatokon, amelyeken engedélyezve van a MAC-címek randomizálása, a társítás során újra megtörténhet a randomizálás, attól függően, hogy az ügyfél mikor bontotta utoljára a kapcsolatot a hálózattal. Az ismételt randomizálás nem következik be, ha az eszköz négy órán belül újracsatlakozik."</string> <string name="wifi_metered_label" msgid="8737187690304098638">"Forgalomkorlátos"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"Nem forgalomkorlátos"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"Naplózási puffer mérete"</string> @@ -371,6 +373,8 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"Az Alkalmazás nem válaszol ablak megjelenítése a háttérben futó alkalmazásoknál"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"Értesítő csatorna figyelmeztetései"</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"Figyelmeztet, ha egy alkalmazás érvényes csatorna nélkül küld értesítést"</string> + <string name="enforce_shortcuts_for_conversations" msgid="7040735163945040763">"Gyorsparancsok kényszerítése beszélgetésértesítésekhez"</string> + <string name="enforce_shortcuts_for_conversations_summary" msgid="1860168037282467862">"Megköveteli, hogy az értesítéseket hosszú életű megosztási gyorsparancs támogassa, hogy megjelenhessenek a beszélgetési szakaszban"</string> <string name="force_allow_on_external" msgid="9187902444231637880">"Külső tárhely alkalmazásainak engedélyezése"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Lehetővé teszi bármely alkalmazás külső tárhelyre való írását a jegyzékértékektől függetlenül"</string> <string name="force_resizable_activities" msgid="7143612144399959606">"Tevékenységek átméretezésének kényszerítése"</string> @@ -426,10 +430,10 @@ <string name="power_discharging_duration_enhanced" msgid="1800465736237672323">"Körülbelül <xliff:g id="TIME_REMAINING">%1$s</xliff:g> maradt hátra az eszköz használata alapján (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <!-- no translation found for power_remaining_duration_only_short (7438846066602840588) --> <skip /> - <string name="power_discharge_by_enhanced" msgid="563438403581662942">"A használat alapján nagyjából még ennyit bír: <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_discharge_by_only_enhanced" msgid="3268796172652988877">"A használat alapján nagyjából még ennyit bír: <xliff:g id="TIME">%1$s</xliff:g>"</string> - <string name="power_discharge_by" msgid="4113180890060388350">"Nagyjából még ennyit bír: <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_discharge_by_only" msgid="92545648425937000">"Nagyjából még ennyit bír: <xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="power_discharge_by_enhanced" msgid="563438403581662942">"A használat alapján nagyjából eddig bírja: <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_discharge_by_only_enhanced" msgid="3268796172652988877">"A használat alapján nagyjából eddig bírja: <xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="power_discharge_by" msgid="4113180890060388350">"Nagyjából eddig bírja: <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_discharge_by_only" msgid="92545648425937000">"Nagyjából eddig bírja: <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Eddig: <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Az akkumulátor lemerülhet a következő időpontig: <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"Kevesebb mint <xliff:g id="THRESHOLD">%1$s</xliff:g> van hátra"</string> @@ -443,7 +447,7 @@ <string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7703677921000858479">"Előfordulhat, hogy a táblagép hamarosan kikapcsol (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string> <string name="power_remaining_duration_shutdown_imminent" product="device" msgid="4374784375644214578">"Előfordulhat, hogy az eszköz hamarosan kikapcsol (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string> <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string> - <string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"<xliff:g id="TIME">%1$s</xliff:g> van hátra a feltöltésig"</string> + <string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"<xliff:g id="TIME">%1$s</xliff:g> van hátra a feltöltésből"</string> <string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> a feltöltésig"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"Ismeretlen"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"Töltés"</string> diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml index 9cc883a928d5..7774a803e1f7 100644 --- a/packages/SettingsLib/res/values-hy/strings.xml +++ b/packages/SettingsLib/res/values-hy/strings.xml @@ -212,7 +212,7 @@ <string name="adb_wireless_settings" msgid="2295017847215680229">"Անլար վրիպազերծում"</string> <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Հասանելի սարքերը տեսնելու և օգտագործելու համար միացրեք անլար վրիպազերծումը"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"Զուգակցեք սարքը՝ օգտագործելով QR կոդը"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"Զուգակցեք նոր սարքեր՝ օգտագործելով QR կոդերի սկաները"</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"Զուգակցեք նոր սարքեր՝ օգտագործելով QR կոդերի սկաները"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"Զուգակցեք սարքը՝ օգտագործելով զուգակցման կոդը"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"Զուգակցեք նոր սարքեր՝ օգտագործելով վեցանիշ կոդը"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"Զուգակցված սարքեր"</string> @@ -231,7 +231,7 @@ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"Չհաջողվեց զուգակցել սարքի հետ։ Հնարավոր է, որ QR կոդը սխալ է, կամ սարքը միացված չէ միևնույն ցանցին։"</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP հասցե և միացք"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"QR կոդի սկանավորում"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"Զուգակցեք սարքը՝ Wi‑Fi-ի օգնությամբ սկանավորելով QR կոդը"</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Զուգակցեք սարքը՝ Wi‑Fi-ի օգնությամբ սկանավորելով QR կոդը"</string> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Միացեք Wi-Fi ցանցի"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, վրիպազերծում, ծրագրավորող"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"Սխալի հաղորդման դյուրանցում"</string> @@ -251,6 +251,7 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"Անլար էկրանների հավաստագրում"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"Միացնել Wi‑Fi մանրամասն գրանցամատյանները"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"Wi‑Fi-ի որոնման սահմանափակում"</string> + <string name="wifi_enhanced_mac_randomization" msgid="5437378364995776979">"MAC հասցեների պատահական ընտրություն Wi-Fi-ին միանալիս"</string> <string name="mobile_data_always_on" msgid="8275958101875563572">"Բջջային ինտերնետը միշտ ակտիվ է"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"Սարքակազմի արագացման միացում"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"Ցուցադրել Bluetooth սարքերն առանց անունների"</string> @@ -283,6 +284,7 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"Ցույց տալ անլար էկրանների հավաստագրման ընտրանքները"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Բարձրացնել մակարդակը, Wi‑Fi ընտրիչում ամեն մի SSID-ի համար ցույց տալ RSSI"</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"Նվազեցնում է մարտկոցի սպառումը և լավացնում ցանցի աշխատանքը"</string> + <string name="wifi_enhanced_mac_randomization_summary" msgid="7925425746373704991">"Այս կարգավորումը միացնում է MAC հասցեների պատահական ընտրությունը միայն սպասառուի ռեժիմում։\nԵրբ այս ռեժիմն ակտիվացված է, բոլոր ցանցերը, որոնց համար միացված է MAC հասցեների պատահական ընտրությունը, կապակցման ժամանակ կարող են նորից պատահական MAC հասցե ընտրել՝ կախված այն բանից, թե երբ է սպասառուն վերջին անգամ անջատվել ցանցից։ Պատահական ընտրության կրկնությունը տեղի չի ունենում, եթե սարքը նորից է միանում ցանցին 4 ժամից պակաս ժամանակահատվածում։"</string> <string name="wifi_metered_label" msgid="8737187690304098638">"Վճարովի թրաֆիկ"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"Անսահմանափակ թրաֆիկ"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"Մատյանի բուֆերի չափերը"</string> @@ -371,6 +373,8 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"Ցուցադրել «Հավելվածը չի արձագանքում» պատուհանը ֆոնային հավելվածների համար"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"Ցուցադրել ծանուցումների ալիքի զգուշացումները"</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"Էկրանին ցուցադրվում է զգուշացում, երբ որևէ հավելված փակցնում է ծանուցում առանց վավեր ալիքի"</string> + <string name="enforce_shortcuts_for_conversations" msgid="7040735163945040763">"Միացնել զրույցների ծանուցումների դյուրանցումները"</string> + <string name="enforce_shortcuts_for_conversations_summary" msgid="1860168037282467862">"Պահանջել, որ ծանուցումները պահվեն երկարաժամկետ հասանելիության դյուրանցումով՝ զրույցների բաժնում հայտնվելու համար"</string> <string name="force_allow_on_external" msgid="9187902444231637880">"Թույլատրել պահումն արտաքին կրիչներում"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Թույլ է տալիս ցանկացած հավելված պահել արտաքին սարքում՝ մանիֆեստի արժեքներից անկախ"</string> <string name="force_resizable_activities" msgid="7143612144399959606">"Չափերի փոփոխում բազմապատուհան ռեժիմում"</string> @@ -503,7 +507,7 @@ <string name="alarm_template" msgid="3346777418136233330">"<xliff:g id="WHEN">%1$s</xliff:g>-ին"</string> <string name="alarm_template_far" msgid="6382760514842998629">"<xliff:g id="WHEN">%1$s</xliff:g>-ին"</string> <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Տևողություն"</string> - <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Հարցնել ամեն անգամ"</string> + <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Ամեն անգամ հարցնել"</string> <string name="zen_mode_forever" msgid="3339224497605461291">"Մինչև չանջատեք"</string> <string name="time_unit_just_now" msgid="3006134267292728099">"Հենց նոր"</string> <string name="media_transfer_this_device_name" msgid="2716555073132169240">"Հեռախոսի բարձրախոս"</string> diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml index d80eba24066f..861e97efeeb3 100644 --- a/packages/SettingsLib/res/values-in/strings.xml +++ b/packages/SettingsLib/res/values-in/strings.xml @@ -112,8 +112,8 @@ <string name="bluetooth_opp_profile_summary_use_for" msgid="461981154387015457">"Gunakan untuk transfer file"</string> <string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"Gunakan untuk masukan"</string> <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="7689393730163320483">"Gunakan untuk Alat Bantu Dengar"</string> - <string name="bluetooth_pairing_accept" msgid="2054232610815498004">"Sandingkan"</string> - <string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"SANDINGKAN"</string> + <string name="bluetooth_pairing_accept" msgid="2054232610815498004">"Sambungkan"</string> + <string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"SAMBUNGKAN"</string> <string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Batal"</string> <string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"Penyandingan memberi akses ke kontak dan histori panggilan saat tersambung"</string> <string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"Tidak dapat menyandingkan dengan <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string> @@ -212,7 +212,7 @@ <string name="adb_wireless_settings" msgid="2295017847215680229">"Proses debug nirkabel"</string> <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Untuk melihat dan menggunakan perangkat yang tersedia, aktifkan proses debug nirkabel"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"Sambungkan perangkat dengan kode QR"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"Sambungkan perangkat baru menggunakan Pemindai kode QR"</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"Sambungkan perangkat baru menggunakan pemindai kode QR"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"Sambungkan perangkat dengan kode penghubung"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"Sambungkan perangkat baru menggunakan kode enam digit"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"Perangkat disambungkan"</string> @@ -231,7 +231,7 @@ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"Gagal menyambungkan perangkat. Kode QR salah, atau perangkat tidak tersambung ke jaringan yang sama."</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"Alamat IP & Port"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"Memindai kode QR"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"Menyambungkan perangkat melalui Wi‑Fi dengan memindai Kode QR"</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Menyambungkan perangkat melalui Wi‑Fi dengan memindai Kode QR"</string> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Harap sambungkan ke jaringan Wi-Fi"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, debug, dev"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"Pintasan laporan bug"</string> @@ -251,6 +251,7 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"Sertifikasi layar nirkabel"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"Aktifkan Pencatatan Log Panjang Wi-Fi"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"Pembatasan pemindaian Wi‑Fi"</string> + <string name="wifi_enhanced_mac_randomization" msgid="5437378364995776979">"Pengacakan MAC yang ditingkatkan Wi-Fi"</string> <string name="mobile_data_always_on" msgid="8275958101875563572">"Kuota selalu aktif"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"Akselerasi hardware tethering"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"Tampilkan perangkat Bluetooth tanpa nama"</string> @@ -283,6 +284,7 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"Tampilkan opsi untuk sertifikasi layar nirkabel"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Tingkatkan level pencatatan log Wi-Fi, tampilkan per SSID RSSI di Pemilih Wi‑Fi"</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"Memperlambat kehabisan baterai & meningkatkan performa jaringan"</string> + <string name="wifi_enhanced_mac_randomization_summary" msgid="7925425746373704991">"Pengaktifan mode ini memengaruhi perilaku pengacakan MAC hanya untuk mode klien.\nSaat mode ini diaktifkan, jaringan yang mengaktifkan pengacakan MAC mungkin mengalami pengacakan ulang alamat MAC selama terhubung, bergantung pada kapan klien terakhir kali terputus dari jaringan. Pengacakan ulang tidak terjadi jika perangkat terhubung kembali dalam 4 jam atau kurang."</string> <string name="wifi_metered_label" msgid="8737187690304098638">"Berbayar"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"Tidak berbayar"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"Ukuran buffer pencatat log"</string> @@ -371,6 +373,8 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"Tampilkan dialog Aplikasi Tidak Merespons untuk aplikasi yang berjalan di background"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"Tampilkan peringatan saluran notifikasi"</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"Menampilkan peringatan di layar saat aplikasi memposting notifikasi tanpa channel yang valid"</string> + <string name="enforce_shortcuts_for_conversations" msgid="7040735163945040763">"Terapkan pintasan untuk notifikasi percakapan"</string> + <string name="enforce_shortcuts_for_conversations_summary" msgid="1860168037282467862">"Mengharuskan notifikasi didukung oleh pintasan berbagi yang berdurasi panjang untuk muncul di bagian percakapan"</string> <string name="force_allow_on_external" msgid="9187902444231637880">"Paksa izinkan aplikasi di eksternal"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Membuat semua aplikasi dapat ditulis ke penyimpanan eksternal, terlepas dari nilai manifes"</string> <string name="force_resizable_activities" msgid="7143612144399959606">"Paksa aktivitas agar ukurannya dapat diubah"</string> diff --git a/packages/SettingsLib/res/values-is/strings.xml b/packages/SettingsLib/res/values-is/strings.xml index 2e96446f974d..7f7d79c63d3f 100644 --- a/packages/SettingsLib/res/values-is/strings.xml +++ b/packages/SettingsLib/res/values-is/strings.xml @@ -212,7 +212,7 @@ <string name="adb_wireless_settings" msgid="2295017847215680229">"Þráðlaus villuleit"</string> <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Til að sjá og nota tiltæk tæki skal kveikja á þráðlausri villuleit"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"Para tæki með QR-kóða"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"Para ný tæki með QR-kóðaskanna"</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"Para ný tæki með QR-kóðaskanna"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"Para tæki með pörunarkóða"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"Para ný tæki með sex tölustafa kóða"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"Pöruð tæki"</string> @@ -231,7 +231,7 @@ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"Ekki tókst að para við tækið. Annað hvort var QR-kóðinn rangur eða tækið ekki tengt sama neti."</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP-tala og gátt"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"Skanna QR-kóða"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"Tengja tæki með Wi-Fi með því að skanna QR-kóða"</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Tengja tæki með Wi-Fi með því að skanna QR-kóða"</string> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Tengstu Wi-Fi neti"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, villuleit, dev"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"Flýtileið í villutilkynningu"</string> @@ -251,6 +251,8 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"Vottun þráðlausra skjáa"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"Kveikja á ítarlegri skráningu Wi-Fi"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"Hægja á Wi‑Fi leit"</string> + <!-- no translation found for wifi_enhanced_mac_randomization (5437378364995776979) --> + <skip /> <string name="mobile_data_always_on" msgid="8275958101875563572">"Alltaf kveikt á farsímagögnum"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"Vélbúnaðarhröðun fyrir tjóðrun"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"Sýna Bluetooth-tæki án heita"</string> @@ -283,6 +285,8 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"Sýna valkosti fyrir vottun þráðlausra skjáa"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Auka skráningarstig Wi-Fi, sýna RSSI fyrir hvert SSID í Wi-Fi vali"</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"Dregur úr rafhlöðunotkun og eykur netafköst"</string> + <!-- no translation found for wifi_enhanced_mac_randomization_summary (7925425746373704991) --> + <skip /> <string name="wifi_metered_label" msgid="8737187690304098638">"Mæld notkun"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"Notkun ekki mæld"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"Annálsritastærðir biðminna"</string> @@ -371,6 +375,8 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"Sýna „Forrit svarar ekki“ fyrir bakgrunnsforrit"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"Sýna viðvaranir tilkynningarásar"</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"Birtir viðvörun á skjánum þegar forrit birtir tilkynningu án gildrar rásar"</string> + <string name="enforce_shortcuts_for_conversations" msgid="7040735163945040763">"Þvinga flýtileiðir fyrir tilkynningar um samtöl"</string> + <string name="enforce_shortcuts_for_conversations_summary" msgid="1860168037282467862">"Krefjast þess að flýtileiðir séu studdar af langvarandi deilingarflýtileið fyrir birtingu í samtalshluta"</string> <string name="force_allow_on_external" msgid="9187902444231637880">"Þvinga fram leyfi forrita í ytri geymslu"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Gerir öll forrit skrifanleg í ytra geymslurými, óháð gildum í upplýsingaskrá"</string> <string name="force_resizable_activities" msgid="7143612144399959606">"Þvinga breytanlega stærð virkni"</string> diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml index 2de543d745f1..2945af6def39 100644 --- a/packages/SettingsLib/res/values-it/strings.xml +++ b/packages/SettingsLib/res/values-it/strings.xml @@ -23,7 +23,7 @@ <string name="wifi_fail_to_scan" msgid="2333336097603822490">"Impossibile cercare reti"</string> <string name="wifi_security_none" msgid="7392696451280611452">"Nessuna"</string> <string name="wifi_remembered" msgid="3266709779723179188">"Salvata"</string> - <string name="wifi_disconnected" msgid="7054450256284661757">"Nessuna connessione"</string> + <string name="wifi_disconnected" msgid="7054450256284661757">"Non connessa"</string> <string name="wifi_disabled_generic" msgid="2651916945380294607">"Disattivata"</string> <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"Errore configurazione IP"</string> <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"Impossibile connettersi a causa della bassa qualità della rete"</string> @@ -212,7 +212,7 @@ <string name="adb_wireless_settings" msgid="2295017847215680229">"Debug wireless"</string> <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Per trovare e utilizzare i dispositivi disponibili, attiva il debug wireless"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"Accoppia il dispositivo con il codice QR"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"Accoppia i nuovi dispositivi utilizzando lo scanner di codici QR"</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"Accoppia i nuovi dispositivi utilizzando lo scanner di codici QR"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"Accoppia dispositivo con codice di accoppiamento"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"Accoppia i nuovi dispositivi utilizzando un codice di sei cifre"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"Dispositivi accoppiati"</string> @@ -231,7 +231,7 @@ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"Impossibile accoppiare il dispositivo. Il codice QR non era corretto oppure il dispositivo non è connesso alla stessa rete."</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"Indirizzo IP e porta"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"Scansiona codice QR"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"Accoppia il dispositivo tramite Wi-Fi eseguendo la scansione di un codice QR"</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Accoppia il dispositivo tramite Wi-Fi scansionando un codice QR"</string> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Collegati a una rete Wi-Fi"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"ADB, debug, sviluppatori"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"Scorciatoia segnalazione bug"</string> @@ -251,6 +251,7 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"Certificazione display wireless"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"Attiva logging dettagliato Wi-Fi"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"Limita ricerca di reti Wi‑Fi"</string> + <string name="wifi_enhanced_mac_randomization" msgid="5437378364995776979">"Randomizzazione MAC con Wi‑Fi migliorato"</string> <string name="mobile_data_always_on" msgid="8275958101875563572">"Dati mobili sempre attivi"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"Tethering accelerazione hardware"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"Mostra dispositivi Bluetooth senza nome"</string> @@ -283,6 +284,7 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"Mostra opzioni per la certificazione display wireless"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Aumenta livello di logging Wi-Fi, mostra SSID RSSI nel selettore Wi-Fi"</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"Riduce il consumo della batteria e migliora le prestazioni della rete"</string> + <string name="wifi_enhanced_mac_randomization_summary" msgid="7925425746373704991">"Questa opzione influenza il comportamento della randomizzazione MAC solo nella modalità client.\nQuando questa modalità è attiva, durante l\'associazione gli indirizzi MAC di tutte le reti con randomizzazione MAC abilitata potrebbero essere nuovamente sottoposti a randomizzazione, a seconda di quando il client è stato disconnesso l\'ultima volta dalla rete. La randomizzazione non viene eseguita nuovamente se il dispositivo si riconnette entro quattro ore o meno."</string> <string name="wifi_metered_label" msgid="8737187690304098638">"A consumo"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"Non a consumo"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"Dimensioni buffer logger"</string> @@ -371,6 +373,8 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"Mostra finestra di dialogo ANR per app in background"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"Mostra avvisi canale di notifica"</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"Viene mostrato un avviso sullo schermo quando un\'app pubblica una notifica senza un canale valido"</string> + <string name="enforce_shortcuts_for_conversations" msgid="7040735163945040763">"Applica scorciatoie per notifiche delle conversazioni"</string> + <string name="enforce_shortcuts_for_conversations_summary" msgid="1860168037282467862">"Richiedi il supporto di una scorciatoia di condivisione di lunga durata per la visualizzazione delle notifiche nella sezione delle conversazioni"</string> <string name="force_allow_on_external" msgid="9187902444231637880">"Forza autorizzazione app su memoria esterna"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Consente l\'installazione di qualsiasi app su memoria esterna, indipendentemente dai valori manifest"</string> <string name="force_resizable_activities" msgid="7143612144399959606">"Imponi formato modificabile alle attività"</string> @@ -426,10 +430,10 @@ <string name="power_discharging_duration_enhanced" msgid="1800465736237672323">"Tempo rimanente in base al tuo utilizzo (<xliff:g id="LEVEL">%2$s</xliff:g>): <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> <!-- no translation found for power_remaining_duration_only_short (7438846066602840588) --> <skip /> - <string name="power_discharge_by_enhanced" msgid="563438403581662942">"Tempo stimato rimanente in base al tuo utilizzo: <xliff:g id="TIME">%1$s</xliff:g> circa (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_discharge_by_only_enhanced" msgid="3268796172652988877">"Tempo stimato rimanente in base al tuo utilizzo: <xliff:g id="TIME">%1$s</xliff:g> circa"</string> - <string name="power_discharge_by" msgid="4113180890060388350">"Tempo stimato rimanente: <xliff:g id="TIME">%1$s</xliff:g> circa (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_discharge_by_only" msgid="92545648425937000">"Tempo stimato rimanente: <xliff:g id="TIME">%1$s</xliff:g> circa"</string> + <string name="power_discharge_by_enhanced" msgid="563438403581662942">"Ora stimata esaurimento batteria in base al tuo utilizzo: <xliff:g id="TIME">%1$s</xliff:g> circa (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_discharge_by_only_enhanced" msgid="3268796172652988877">"Ora stimata esaurimento batteria in base al tuo utilizzo: <xliff:g id="TIME">%1$s</xliff:g> circa"</string> + <string name="power_discharge_by" msgid="4113180890060388350">"Ora stimata esaurimento batteria: <xliff:g id="TIME">%1$s</xliff:g> circa (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_discharge_by_only" msgid="92545648425937000">"Ora stimata esaurimento batteria: <xliff:g id="TIME">%1$s</xliff:g> circa"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Fino alle ore <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"La batteria potrebbe esaurirsi entro <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"Tempo rimanente: meno di <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml index 61f35abbe526..321558406acb 100644 --- a/packages/SettingsLib/res/values-iw/strings.xml +++ b/packages/SettingsLib/res/values-iw/strings.xml @@ -212,7 +212,7 @@ <string name="adb_wireless_settings" msgid="2295017847215680229">"ניפוי באגים אלחוטי"</string> <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"כדי להציג את המכשירים הזמינים ולהשתמש בהם, יש להפעיל ניפוי באגים אלחוטי"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"התאמת מכשיר באמצעות קוד QR"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"התאמת מכשירים חדשים באמצעות סורק של קודי QR"</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"התאמת מכשירים חדשים באמצעות סורק של קודי QR"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"התאמת מכשיר באמצעות קוד התאמה"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"התאמת מכשירים חדשים באמצעות קוד בן שש ספרות"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"מכשירים מותאמים"</string> @@ -231,7 +231,7 @@ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"התאמת המכשיר נכשלה. קוד ה-QR היה שגוי או שהמכשיר לא מחובר לאותה רשת."</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"יציאה וכתובת IP"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"סריקת קוד QR"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"יש לסרוק קוד QR כדי להתאים מכשיר באמצעות Wi‑Fi"</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"יש לסרוק קוד QR כדי להתאים מכשיר באמצעות Wi‑Fi"</string> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"יש להתחבר לרשת Wi-Fi"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, ניפוי באגים, פיתוח"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"קיצור של דוח באגים"</string> @@ -251,6 +251,7 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"אישור של תצוגת WiFi"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"הפעלת רישום מפורט של Wi‑Fi ביומן"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"ויסות סריקה לנקודות Wi-Fi"</string> + <string name="wifi_enhanced_mac_randomization" msgid="5437378364995776979">"רנדומיזציה משופרת של כתובות MAC ב-Wi‑Fi"</string> <string name="mobile_data_always_on" msgid="8275958101875563572">"חבילת הגלישה פעילה תמיד"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"שיפור מהירות באמצעות חומרה לצורך שיתוף אינטרנט בין ניידים"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"הצגת מכשירי Bluetooth ללא שמות"</string> @@ -283,6 +284,7 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"הצג אפשרויות עבור אישור של תצוגת WiFi"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"העלה את רמת הרישום של Wi‑Fi ביומן, הצג לכל SSID RSSI ב-Wi‑Fi Picker"</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"מפחית את קצב התרוקנות הסוללה ומשפר את ביצועי הרשת"</string> + <string name="wifi_enhanced_mac_randomization_summary" msgid="7925425746373704991">"לחצן החלפת המצב משפיע על התנהגות הרנדומיזציה של כתובות MAC במצב לקוח בלבד.\nכשמצב זה מופעל, ברשת שבה מופעלת רנדומיזציה של כתובות MAC, ייתכן שתתבצע רנדומיזציה מחדש של כתובות ה-MAC במהלך השיוך, בהתאם למועד הניתוק האחרון של הלקוח מהרשת. לא תתבצע רנדומיזציה מחדש אם המכשיר מתחבר מחדש תוך ארבע שעות או פחות."</string> <string name="wifi_metered_label" msgid="8737187690304098638">"נמדדת"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"לא נמדדת"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"גדלי מאגר של יומן רישום"</string> @@ -371,6 +373,8 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"הצגת תיבת דו-שיח של \'אפליקציה לא מגיבה\' עבור אפליקציות שפועלות ברקע"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"אזהרות לגבי ערוץ התראות"</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"הצגת אזהרה כשאפליקציה שולחת התראה ללא ערוץ חוקי"</string> + <string name="enforce_shortcuts_for_conversations" msgid="7040735163945040763">"אילוץ קיצורי דרך להתראות על שיחות"</string> + <string name="enforce_shortcuts_for_conversations_summary" msgid="1860168037282467862">"כדי שההודעות יופיעו בקטע השיחות, יש צורך בגיבוי שלהן באמצעות קיצור דרך לשיתוף בעל מחזור חיים ארוך"</string> <string name="force_allow_on_external" msgid="9187902444231637880">"אילוץ הרשאת אפליקציות באחסון חיצוני"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"מאפשר כתיבה של כל אפליקציה באחסון חיצוני, ללא התחשבות בערכי המניפסט"</string> <string name="force_resizable_activities" msgid="7143612144399959606">"אלץ יכולת קביעת גודל של הפעילויות"</string> diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml index ea9cfd8a7d51..85641939b578 100644 --- a/packages/SettingsLib/res/values-ja/strings.xml +++ b/packages/SettingsLib/res/values-ja/strings.xml @@ -212,7 +212,7 @@ <string name="adb_wireless_settings" msgid="2295017847215680229">"ワイヤレス デバッグ"</string> <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"利用可能なデバイスを確認して使用するには、ワイヤレス デバッグをオンにしてください"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"QR コードによるデバイスのペア設定"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"QR コードスキャナを使って新しいデバイスをペア設定します"</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"QR コードスキャナを使って新しいデバイスをペア設定します"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"ペア設定コードによるデバイスのペア設定"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"6 桁のコードを使って新しいデバイスをペア設定します"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"ペア設定済みのデバイス"</string> @@ -231,7 +231,7 @@ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"デバイスをペア設定できませんでした。QR コードが間違っているか、デバイスが同じネットワークに接続されていません。"</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP アドレスとポート"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"QR コードのスキャン"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"QR コードをスキャンして Wi-Fi 経由でデバイスをペア設定します"</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"QR コードをスキャンして Wi-Fi 経由でデバイスをペア設定します"</string> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Wi-Fi ネットワークに接続してください"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, デバッグ, dev"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"バグレポートのショートカット"</string> @@ -251,6 +251,8 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"ワイヤレスディスプレイ認証"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"Wi-Fi詳細ログの有効化"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"Wi‑Fi スキャン スロットリング"</string> + <!-- no translation found for wifi_enhanced_mac_randomization (5437378364995776979) --> + <skip /> <string name="mobile_data_always_on" msgid="8275958101875563572">"モバイルデータを常に ON にする"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"テザリング時のハードウェア アクセラレーション"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"Bluetooth デバイスを名前なしで表示"</string> @@ -283,6 +285,8 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"ワイヤレスディスプレイ認証のオプションを表示"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Wi-Fiログレベルを上げて、Wi-Fi選択ツールでSSID RSSIごとに表示します"</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"電池の消耗が軽減され、ネットワーク パフォーマンスが改善されます"</string> + <!-- no translation found for wifi_enhanced_mac_randomization_summary (7925425746373704991) --> + <skip /> <string name="wifi_metered_label" msgid="8737187690304098638">"従量制"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"定額制"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"ログバッファのサイズ"</string> @@ -371,6 +375,8 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"バックグラウンド アプリが応答しない場合にダイアログを表示"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"通知チャネルの警告を表示"</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"アプリから有効なチャネルのない通知が投稿されたときに画面上に警告を表示します"</string> + <string name="enforce_shortcuts_for_conversations" msgid="7040735163945040763">"会話通知用のショートカット"</string> + <string name="enforce_shortcuts_for_conversations_summary" msgid="1860168037282467862">"会話セクションに表示されるように、通知が長期の共有ショートカットに対応することを要件とします"</string> <string name="force_allow_on_external" msgid="9187902444231637880">"外部ストレージへのアプリの書き込みを許可"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"マニフェストの値に関係なく、すべてのアプリを外部ストレージに書き込めるようになります"</string> <string name="force_resizable_activities" msgid="7143612144399959606">"アクティビティをサイズ変更可能にする"</string> diff --git a/packages/SettingsLib/res/values-ka/strings.xml b/packages/SettingsLib/res/values-ka/strings.xml index 106bc18f8451..d15b9c4fbe0f 100644 --- a/packages/SettingsLib/res/values-ka/strings.xml +++ b/packages/SettingsLib/res/values-ka/strings.xml @@ -212,7 +212,7 @@ <string name="adb_wireless_settings" msgid="2295017847215680229">"შეცდომების უსადენო გამართვა"</string> <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"ხელმისაწვდომი მოწყობილობების სანახავად და გამოსაყენებლად ჩართეთ შეცდომების უსადენო გამართვა"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"ახალი მოწყობილობების დაწყვილება QR კოდით"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"ახალი მოწყობილობების დაწყვილება QR კოდის სკანერის გამოყენებით"</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"ახალი მოწყობილობების დაწყვილება QR კოდის სკანერის გამოყენებით"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"მოწყობილობის დაწყვილება დაკავშირების კოდით"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"ახალი მოწყობილობების დაწყვილება ექვსნიშნა კოდის გამოყენებით"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"დაწყვილებული მოწყობილობები"</string> @@ -231,7 +231,7 @@ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"მოწყობილობის დაწყვილება ვერ მოხერხდა. QR კოდი არასწორი იყო ან მოწყობილობა იმავე ქსელთან არ არის დაკავშირებული."</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP მისამართი და პორტი"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"QR კოდის სკანირება"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"მოწყობილობის დაწყვილება Wi-Fi-ის მეშვეობით QR კოდის სკანირებით"</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"მოწყობილობის დაწყვილება Wi-Fi-ის მეშვეობით QR კოდის სკანირებით"</string> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"დაუკავშირდით Wi-Fi ქსელს"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, შეცდომების გამართვა, დეველოპერული"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"ხარვეზის შეტყობინების მალსახმობი"</string> @@ -251,6 +251,7 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"უსადენო ეკრანის სერტიფიცირება"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"Wi‑Fi-ს დაწვრილებითი აღრიცხვის ჩართვა"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"Wi‑Fi სკანირების რეგულირება"</string> + <string name="wifi_enhanced_mac_randomization" msgid="5437378364995776979">"Wi‑Fi‑თ გაძლიერებული MAC მისამართის შემთხვევითობა"</string> <string name="mobile_data_always_on" msgid="8275958101875563572">"მობილური ინტერნეტის ყოველთვის გააქტიურება"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"ტეტერინგის აპარატურული აჩქარება"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"Bluetooth-მოწყობილობების ჩვენება სახელების გარეშე"</string> @@ -283,6 +284,7 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"უსადენო ეკრანის სერტიფიცირების ვარიანტების ჩვენება"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Wi‑Fi-ს აღრიცხვის დონის გაზრდა, Wi‑Fi ამომრჩეველში ყოველ SSID RSSI-ზე ჩვენება"</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"ამცირებს ბატარეის ხარჯვას და აუმჯობესებს ქსელის მუშაობას"</string> + <string name="wifi_enhanced_mac_randomization_summary" msgid="7925425746373704991">"ეს გადასართავი მხოლოდ კლიენტის რეჟიმში მოქმედებს MAC მისამართის შემთხვევითობაზე.\nამ რეჟიმის გააქტიურების შემთხვევაში, ნებისმიერმა ქსელმა, რომლისთვისაც MAC მისამართის შემთხვევითობა ჩართულია, შეიძლება ხელახლა მოახდინოს MAC მისამართთა შემთხვევითობის განხორციელება დაკავშირებისას, იმის გათვალისწინებით, თუ როდის გაწყვიტა კლიენტმა ბოლოს ქსელთან კავშირი. შემთხვევითობა აღარ განმეორდება, თუ ეს მოწყობილობა ქსელს 4 საათის ფარგლებში ან უფრო ნაკლებ დროში დაუკავშირდება."</string> <string name="wifi_metered_label" msgid="8737187690304098638">"ლიმიტირებული"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"არალიმიტირებული"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"ჟურნალიზაციის ბუფერის ზომები"</string> @@ -371,6 +373,8 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"„აპი არ რეაგირებს“ შეტყობინების ჩვენება, როცა ფონური აპლიკაცია არ პასუხობს"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"შეტყობინებათა არხის გაფრთხილებების ჩვენება"</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"ეკრანზე აჩვენებს გაფრთხილებას, როცა აპი შეტყობინებას სწორი არხის გარეშე განათავსებს"</string> + <string name="enforce_shortcuts_for_conversations" msgid="7040735163945040763">"მალსახმობების მოთხოვნა მიმოწერის შეტყობინებებისთვის"</string> + <string name="enforce_shortcuts_for_conversations_summary" msgid="1860168037282467862">"მოითხოვეთ, შეტყობინებები ეყრდნობოდეს ხანგრძლივად არსებულ გაზიარების მალსახმობებს მიმოწერის სექციაში გამოსაჩენად"</string> <string name="force_allow_on_external" msgid="9187902444231637880">"აპების დაშვება გარე მეხსიერებაში"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"აპები ჩაიწერება გარე მეხსიერებაზე აღწერის ფაილების მნიშვნელობების მიუხედავად"</string> <string name="force_resizable_activities" msgid="7143612144399959606">"ზომაცვლადი აქტივობების იძულება"</string> diff --git a/packages/SettingsLib/res/values-kk/arrays.xml b/packages/SettingsLib/res/values-kk/arrays.xml index 3c96f43ca548..fe5b5d2f00da 100644 --- a/packages/SettingsLib/res/values-kk/arrays.xml +++ b/packages/SettingsLib/res/values-kk/arrays.xml @@ -26,7 +26,7 @@ <item msgid="6050951078202663628">"Қосылуда..."</item> <item msgid="8356618438494652335">"Растауда…"</item> <item msgid="2837871868181677206">"IP мекенжайына қол жеткізуде…"</item> - <item msgid="4613015005934755724">"Қосылған"</item> + <item msgid="4613015005934755724">"Жалғанған"</item> <item msgid="3763530049995655072">"Уақытша тоқтатылды"</item> <item msgid="7852381437933824454">"Ажыратуда…"</item> <item msgid="5046795712175415059">"Ажыратылған"</item> diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml index 0ef83bb183cb..828f18bce78b 100644 --- a/packages/SettingsLib/res/values-kk/strings.xml +++ b/packages/SettingsLib/res/values-kk/strings.xml @@ -206,13 +206,13 @@ <string name="enable_adb" msgid="8072776357237289039">"USB жөндеу"</string> <string name="enable_adb_summary" msgid="3711526030096574316">"USB жалғанғандағы жөндеу режимі"</string> <string name="clear_adb_keys" msgid="3010148733140369917">"USB жөндеу рұқсаттарынан бас тарту"</string> - <string name="enable_adb_wireless" msgid="6973226350963971018">"Сымсыз желі арқылы түзету"</string> + <string name="enable_adb_wireless" msgid="6973226350963971018">"Сымсыз түзету"</string> <string name="enable_adb_wireless_summary" msgid="7344391423657093011">"Wi‑Fi желісіне жалғанған кездегі түзету режимі"</string> <string name="adb_wireless_error" msgid="721958772149779856">"Қате"</string> - <string name="adb_wireless_settings" msgid="2295017847215680229">"Сымсыз желі арқылы түзету"</string> - <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Қолжетімді құрылғыларды көру және пайдалану үшін сымсыз желі арқылы түзетуді іске қосыңыз."</string> + <string name="adb_wireless_settings" msgid="2295017847215680229">"Сымсыз түзету"</string> + <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Қолжетімді құрылғыларды көру және пайдалану үшін сымсыз түзетуді іске қосыңыз."</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"Құрылғыны QR коды арқылы жұптау"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"Жаңа құрылғыларды QR коды сканері арқылы жұптау"</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"Жаңа құрылғыларды QR коды сканерімен жұптау"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"Құрылғыны кодпен жұптау"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"Жаңа құрылғыларды алты цифрлық код арқылы жұптау"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"Жұпталған құрылғылар"</string> @@ -231,7 +231,7 @@ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"Құрылғы жұпталмады. QR коды дұрыс емес немесе құрылғы бір желіге жалғанбаған."</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP мекенжайы және порт"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"QR кодын сканерлеу"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"QR кодын сканерлеп, құрылғыны Wi‑Fi арқылы жұптау"</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"QR кодын сканерлеп, құрылғыны Wi‑Fi арқылы жұптау"</string> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Wi-Fi желісіне қосылыңыз."</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, түзету, әзірлеуші"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"Қате туралы хабарлау"</string> @@ -251,6 +251,8 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"Сымсыз дисплей сертификаты"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"Wi‑Fi егжей-тегжейлі журналы"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"Wi‑Fi іздеуін шектеу"</string> + <!-- no translation found for wifi_enhanced_mac_randomization (5437378364995776979) --> + <skip /> <string name="mobile_data_always_on" msgid="8275958101875563572">"Мобильдік интернет әрқашан қосулы"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"Тетеринг режиміндегі аппараттық жеделдету"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"Bluetooth құрылғыларын атаусыз көрсету"</string> @@ -283,6 +285,8 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"Сымсыз дисплей сертификаты опцияларын көрсету"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Wi‑Fi тіркеу деңгейін арттыру, Wi‑Fi таңдағанда әр SSID RSSI бойынша көрсету"</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"Батарея зарядының шығынын азайтады және желі жұмысын жақсартады."</string> + <!-- no translation found for wifi_enhanced_mac_randomization_summary (7925425746373704991) --> + <skip /> <string name="wifi_metered_label" msgid="8737187690304098638">"Трафик саналады"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"Трафик саналмайды"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"Журналға тіркеуші буферінің өлшемдері"</string> @@ -300,8 +304,8 @@ <string name="tethering_hardware_offload_summary" msgid="7801345335142803029">"Тетеринг режиміндегі аппараттық жеделдетуді пайдалану (қолжетімді болса)"</string> <string name="adb_warning_title" msgid="7708653449506485728">"USB жөндеулеріне рұқсат берілсін бе?"</string> <string name="adb_warning_message" msgid="8145270656419669221">"USB жөндеу дамыту мақсаттарына ғана арналған. Оны компьютер және құрылғы арасында дерек көшіру, құрылғыға ескертусіз қолданба орнату және тіркелім деректерін оқу үшін қолданыңыз."</string> - <string name="adbwifi_warning_title" msgid="727104571653031865">"Сымсыз желі арқылы түзетуге рұқсат берілсін бе?"</string> - <string name="adbwifi_warning_message" msgid="8005936574322702388">"Сымсыз желі арқылы түзету функциясы дамыту мақсаттарына ғана арналған. Оны компьютер және құрылғы арасында дерек көшіру, құрылғыға ескертусіз қолданба орнату және журнал деректерін оқу үшін қолданыңыз."</string> + <string name="adbwifi_warning_title" msgid="727104571653031865">"Сымсыз түзетуге рұқсат берілсін бе?"</string> + <string name="adbwifi_warning_message" msgid="8005936574322702388">"Сымсыз түзету функциясы дамыту мақсаттарына ғана арналған. Оны компьютер және құрылғы арасында дерек көшіру, құрылғыға ескертусіз қолданба орнату және журнал деректерін оқу үшін қолданыңыз."</string> <string name="adb_keys_warning_message" msgid="2968555274488101220">"Бұған дейін рұқсат берілген барлық компьютерлерде USB жөндеу функциясына тыйым салынсын ба?"</string> <string name="dev_settings_warning_title" msgid="8251234890169074553">"Жетілдіру параметрлеріне рұқсат берілсін бе?"</string> <string name="dev_settings_warning_message" msgid="37741686486073668">"Бұл параметрлер жетілдіру мақсатында ғана қолданылады. Олар құрылғыңыз бен қолданбаларыңыздың бұзылуына немесе әдеттен тыс әрекеттерге себеп болуы мүмкін."</string> @@ -371,6 +375,8 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"Фондық қолданбалар үшін \"Қолданба жауап бермейді\" терезесін шығару"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"Хабарландыру арнасының ескертулерін көрсету"</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"Қолданба жарамсыз арна арқылы хабарландыру жариялағанда, экранға ескерту шығарады"</string> + <string name="enforce_shortcuts_for_conversations" msgid="7040735163945040763">"Чат хабарландырулары үшін таңбашаларды пайдалану"</string> + <string name="enforce_shortcuts_for_conversations_summary" msgid="1860168037282467862">"Хабарландырулар чат бөлімінде көрсетілуі үшін, оларды ұзақ көрсетілетін таңбаша арқылы міндетті түрде қайталап көрсету"</string> <string name="force_allow_on_external" msgid="9187902444231637880">"Сыртқы жадта қолданбаларға рұқсат ету"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Манифест мәндеріне қарамастан, кез келген қолданбаны сыртқы жадқа жазу мүмкіндігін береді"</string> <string name="force_resizable_activities" msgid="7143612144399959606">"Әрекеттердің өлшемін өзгертуге рұқсат ету"</string> @@ -426,10 +432,10 @@ <string name="power_discharging_duration_enhanced" msgid="1800465736237672323">"Пайдалану деректеріңізге сәйкес енді шамамен <xliff:g id="TIME_REMAINING">%1$s</xliff:g> қалды (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <!-- no translation found for power_remaining_duration_only_short (7438846066602840588) --> <skip /> - <string name="power_discharge_by_enhanced" msgid="563438403581662942">"Пайдалануға байланысты шамамен <xliff:g id="TIME">%1$s</xliff:g> уақытқа жетеді (<xliff:g id="LEVEL">%2$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="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$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_enhanced" msgid="563438403581662942">"Пайдалануға байланысты шамамен <xliff:g id="TIME">%1$s</xliff:g> дейін жетеді (<xliff:g id="LEVEL">%2$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="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$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_suggestion_battery_run_out" msgid="6332089307827787087">"Батарея заряды <xliff:g id="TIME">%1$s</xliff:g> сағатқа қарай бітуі мүмкін."</string> <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"<xliff:g id="THRESHOLD">%1$s</xliff:g> шамасынан аз қалды"</string> diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml index 4cf8beda4098..ab297f24a4b5 100644 --- a/packages/SettingsLib/res/values-km/strings.xml +++ b/packages/SettingsLib/res/values-km/strings.xml @@ -212,7 +212,7 @@ <string name="adb_wireless_settings" msgid="2295017847215680229">"ការជួសជុលដោយឥតខ្សែ"</string> <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"ដើម្បីមើលឃើញ និងប្រើឧបករណ៍ដែលមាន សូមបើកការជួសជុលដោយឥតខ្សែ"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"ផ្គូផ្គងឧបករណ៍ដោយប្រើកូដ QR"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"ផ្គូផ្គងឧបករណ៍ថ្មីដោយប្រើកម្មវិធីស្កេនកូដ QR"</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"ផ្គូផ្គងឧបករណ៍ថ្មីដោយប្រើកម្មវិធីស្កេនកូដ QR"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"ផ្គូផ្គងឧបករណ៍ដោយប្រើកូដផ្គូផ្គង"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"ផ្គូផ្គងឧបករណ៍ថ្មីដោយប្រើកូដប្រាំមួយខ្ទង់"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"ឧបករណ៍ដែលបានផ្គូផ្គង"</string> @@ -231,7 +231,7 @@ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"មិនអាចផ្គូផ្គងឧបករណ៍បានទេ។ កូដ QR មិនត្រឹមត្រូវ ឬមិនបានភ្ជាប់ឧបករណ៍ទៅបណ្ដាញដូចគ្នា។"</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"អាសយដ្ឋាន IP និងច្រក"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"ស្កេនកូដ QR"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"ផ្គូផ្គងឧបករណ៍តាមរយៈ Wi‑Fi ដោយស្កេនកូដ QR"</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"ផ្គូផ្គងឧបករណ៍តាមរយៈ Wi‑Fi ដោយស្កេនកូដ QR"</string> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"សូមភ្ជាប់ទៅបណ្តាញ Wi-Fi"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, ជួសជុល, dev"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"ផ្លូវកាត់រាយការណ៍កំហុស"</string> @@ -251,6 +251,7 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"សេចក្តីបញ្ជាក់ការបង្ហាញឥតខ្សែ"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"បើកកំណត់ហេតុរៀបរាប់ Wi-Fi"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"ការពន្យឺតការស្កេន Wi‑Fi"</string> + <string name="wifi_enhanced_mac_randomization" msgid="5437378364995776979">"ការតម្រៀប MAC ដែលបានកែលម្អ Wi-Fi តាមលំដាប់ចៃដន្យ"</string> <string name="mobile_data_always_on" msgid="8275958101875563572">"ទិន្នន័យទូរសព្ទចល័តដំណើរការជានិច្ច"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"ការបង្កើនល្បឿនផ្នែករឹងសម្រាប់ការភ្ជាប់"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"បង្ហាញឧបករណ៍ប្ល៊ូធូសគ្មានឈ្មោះ"</string> @@ -283,6 +284,7 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"បង្ហាញជម្រើសសម្រាប់សេចក្តីបញ្ជាក់ការបង្ហាញឥតខ្សែ"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"បង្កើនកម្រិតកំណត់ហេតុ Wi-Fi បង្ហាញក្នុង SSID RSSI ក្នុងកម្មវិធីជ្រើសរើស Wi-Fi"</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"កាត់បន្ថយការប្រើប្រាស់ថ្ម និងកែលម្អប្រតិបត្តិការបណ្ដាញ"</string> + <string name="wifi_enhanced_mac_randomization_summary" msgid="7925425746373704991">"ការបិទ/បើកនេះប៉ះពាល់ដល់សកម្មភាពតម្រៀប MAC តាមលំដាប់ចៃដន្យសម្រាប់មុខងារភ្ញៀវតែប៉ុណ្ណោះ។\nនៅពេលបើកដំណើរការមុខងារនេះ បណ្ដាញទាំងឡាយដែលបានបើកការតម្រៀប MAC តាមលំដាប់ចៃដន្យប្រហែលជាត្រូវបានតម្រៀបអាសយដ្ឋាន MAC របស់វាតាមលំដាប់ចៃដន្យឡើងវិញ អំឡុពេលភ្ជាប់ ដោយផ្អែកលើពេលវេលាដែលភ្ញៀវបានផ្ដាច់លើកចុងក្រោយពីបណ្ដាញ។ ការតម្រៀបតាមលំដាប់ចៃដន្យឡើងវិញមិនកើតឡើងទេ ប្រសិនបើឧបករណ៍ភ្ជាប់ឡើងវិញក្នុងរយៈពេល 4 ម៉ោង ឬឆាប់ជាងនេះ។"</string> <string name="wifi_metered_label" msgid="8737187690304098638">"មានការកំណត់"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"មិនមានការកំណត់"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"ទំហំកន្លែងផ្ទុករបស់ logger"</string> @@ -371,6 +373,8 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"បង្ហាញប្រអប់កម្មវិធីមិនឆ្លើយតបសម្រាប់កម្មវិធីផ្ទៃខាងក្រោយ"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"បង្ហាញការព្រមានអំពីបណ្តាញជូនដំណឹង"</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"បង្ហាញការព្រមាននៅលើអេក្រង់ នៅពេលកម្មវិធីបង្ហោះការជូនដំណឹងដោយមិនមានបណ្តាញត្រឹមត្រូវ"</string> + <string name="enforce_shortcuts_for_conversations" msgid="7040735163945040763">"ជំរុញឱ្យប្រើផ្លូវកាត់សម្រាប់ការជូនដំណឹងពីការសន្ទនា"</string> + <string name="enforce_shortcuts_for_conversations_summary" msgid="1860168037282467862">"តម្រូវឱ្យបម្រុងទុកការជូនដំណឹង តាមរយៈផ្លូវកាត់ចែករំលែកដែលមានអាយុកាលយូរទើបអាចបង្ហាញនៅក្នុងផ្នែកនៃការសន្ទនាបាន"</string> <string name="force_allow_on_external" msgid="9187902444231637880">"បង្ខំឲ្យអនុញ្ញាតកម្មវិធីលើឧបករណ៍ផ្ទុកខាងក្រៅ"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"ធ្វើឲ្យកម្មវិធីទាំងឡាយមានសិទ្ធិសរសេរទៅកាន់ឧបករណ៍ផ្ទុកខាងក្រៅ ដោយមិនគិតពីតម្លៃជាក់លាក់"</string> <string name="force_resizable_activities" msgid="7143612144399959606">"បង្ខំឲ្យសកម្មភាពអាចប្តូរទំហំបាន"</string> diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml index ed854ac3af49..5bba830a40d7 100644 --- a/packages/SettingsLib/res/values-kn/strings.xml +++ b/packages/SettingsLib/res/values-kn/strings.xml @@ -212,7 +212,7 @@ <string name="adb_wireless_settings" msgid="2295017847215680229">"ವೈರ್ಲೆಸ್ ಡೀಬಗ್ ಮಾಡುವಿಕೆ"</string> <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"ಲಭ್ಯವಿರುವ ಸಾಧನಗಳನ್ನು ನೋಡಲು ಮತ್ತು ಬಳಸಲು, ವೈರ್ಲೆಸ್ ಡೀಬಗ್ ಮಾಡುವಿಕೆಯನ್ನು ಆನ್ ಮಾಡಿ"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"QR ಕೋಡ್ ಬಳಸಿ ಸಾಧನವನ್ನು ಜೋಡಿಸಿ"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"QR ಕೋಡ್ ಸ್ಕ್ಯಾನರ್ ಬಳಸಿ ಹೊಸ ಸಾಧನಗಳನ್ನು ಜೋಡಿಸಿ"</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"QR ಕೋಡ್ ಸ್ಕ್ಯಾನರ್ ಬಳಸಿ ಹೊಸ ಸಾಧನಗಳನ್ನು ಜೋಡಿಸಿ"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"ಜೋಡಿಸುವ ಕೋಡ್ ಬಳಸಿ ಸಾಧನವನ್ನು ಜೋಡಿಸಿ"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"ಆರು ಅಂಕಿಯ ಕೋಡ್ ಬಳಸಿ ಹೊಸ ಸಾಧನಗಳನ್ನು ಜೋಡಿಸಿ"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"ಜೋಡಿಸಲಾದ ಸಾಧನಗಳು"</string> @@ -231,7 +231,7 @@ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"ಸಾಧನವನ್ನು ಜೋಡಿಸಲು ವಿಫಲವಾಗಿದೆ. QR ಕೋಡ್ ತಪ್ಪಾಗಿದೆ ಅಥವಾ ಸಾಧನವು ಒಂದೇ ನೆಟ್ವರ್ಕ್ಗೆ ಕನೆಕ್ಟ್ ಆಗಿಲ್ಲ."</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP ವಿಳಾಸ ಮತ್ತು ಪೋರ್ಟ್"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"QR ಕೋಡ್ ಸ್ಕ್ಯಾನ್ ಮಾಡಿ"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"QR ಕೋಡ್ ಅನ್ನು ಸ್ಕ್ಯಾನ್ ಮಾಡುವ ಮೂಲಕ ವೈ-ಫೈ ನೆಟ್ವರ್ಕ್ನಲ್ಲಿ ಸಾಧನವನ್ನು ಜೋಡಿಸಿ"</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"QR ಕೋಡ್ ಅನ್ನು ಸ್ಕ್ಯಾನ್ ಮಾಡುವ ಮೂಲಕ ವೈ-ಫೈನಲ್ಲಿ ಸಾಧನವನ್ನು ಜೋಡಿಸಿ"</string> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"ವೈ-ಫೈ ನೆಟ್ವರ್ಕ್ಗೆ ಸಂಪರ್ಕಿಸಿ"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, ಡೀಬಗ್, dev"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"ದೋಷ ವರದಿಯ ಶಾರ್ಟ್ಕಟ್"</string> @@ -251,6 +251,8 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"ವೈರ್ಲೆಸ್ ಪ್ರದರ್ಶನ ಪ್ರಮಾಣೀಕರಣ"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"Wi‑Fi ವೆರ್ಬೋಸ್ ಲಾಗಿಂಗ್ ಸಕ್ರಿಯಗೊಳಿಸಿ"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"ವೈ-ಫೈ ಸ್ಕ್ಯಾನ್ ನಿರ್ಬಂಧಿಸಲಾಗುತ್ತಿದೆ"</string> + <!-- no translation found for wifi_enhanced_mac_randomization (5437378364995776979) --> + <skip /> <string name="mobile_data_always_on" msgid="8275958101875563572">"ಮೊಬೈಲ್ ಡೇಟಾ ಯಾವಾಗಲೂ ಸಕ್ರಿಯ"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"ಟೆಥರಿಂಗ್ಗಾಗಿ ಹಾರ್ಡ್ವೇರ್ ವೇಗವರ್ಧನೆ"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"ಹೆಸರುಗಳಿಲ್ಲದ ಬ್ಲೂಟೂತ್ ಸಾಧನಗಳನ್ನು ತೋರಿಸಿ"</string> @@ -283,6 +285,8 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"ವೈರ್ಲೆಸ್ ಪ್ರದರ್ಶನ ಪ್ರಮಾಣೀಕರಣಕ್ಕಾಗಿ ಆಯ್ಕೆಗಳನ್ನು ತೋರಿಸು"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Wi‑Fi ಲಾಗಿಂಗ್ ಮಟ್ಟನ್ನು ಹೆಚ್ಚಿಸಿ, Wi‑Fi ಆಯ್ಕೆಯಲ್ಲಿ ಪ್ರತಿಯೊಂದು SSID RSSI ತೋರಿಸಿ"</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"ಬ್ಯಾಟರಿ ಹೆಚ್ಚು ಬಾಳಿಕೆ ಬರುವಂತೆ ಮಾಡುತ್ತದೆ ಮತ್ತು ನೆಟ್ವರ್ಕ್ ಕಾರ್ಯಕ್ಷಮತೆಯನ್ನು ಸುಧಾರಿಸುತ್ತದೆ"</string> + <!-- no translation found for wifi_enhanced_mac_randomization_summary (7925425746373704991) --> + <skip /> <string name="wifi_metered_label" msgid="8737187690304098638">"ಮೀಟರ್ ಮಾಡಲಾಗಿದೆ"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"ಮೀಟರ್ ಮಾಡಲಾಗಿಲ್ಲ"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"ಲಾಗರ್ ಬಫರ್ ಗಾತ್ರಗಳು"</string> @@ -371,6 +375,8 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"ಹಿನ್ನೆಲೆ ಅಪ್ಲಿಕೇಶನ್ಗಳಿಗಾಗಿ ಅಪ್ಲಿಕೇಶನ್ ಪ್ರತಿಕ್ರಿಯಿಸುತ್ತಿಲ್ಲ ಎಂಬ ಸಂಭಾಷಣೆ ತೋರಿಸಿ"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"ಅಧಿಸೂಚನೆ ಎಚ್ಚರಿಕೆ ತೋರಿಸಿ"</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"ಅಮಾನ್ಯ ಚಾನಲ್ ಅಧಿಸೂಚನೆಗಾಗಿ ಪರದೆಯಲ್ಲಿ ಎಚ್ಚರಿಕೆ"</string> + <string name="enforce_shortcuts_for_conversations" msgid="7040735163945040763">"ಸಂಭಾಷಣೆ ಅಧಿಸೂಚನೆಗಳಿಗಾಗಿ ಶಾರ್ಟ್ಕಟ್ಗಳನ್ನು ಜಾರಿಗೊಳಿಸಿ"</string> + <string name="enforce_shortcuts_for_conversations_summary" msgid="1860168037282467862">"ಸಂಭಾಷಣೆ ವಿಭಾಗದಲ್ಲಿ ಕಾಣಿಸಿಕೊಳ್ಳಲು, ಅಧಿಸೂಚನೆಗಳನ್ನು ದೀರ್ಘಕಾಲದ ಹಂಚಿಕೆ ಶಾರ್ಟ್ಕಟ್ ಮೂಲಕ ಬೆಂಬಲಿಸುವ ಅಗತ್ಯವಿದೆ"</string> <string name="force_allow_on_external" msgid="9187902444231637880">"ಬಾಹ್ಯವಾಗಿ ಅಪ್ಲಿಕೇಶನ್ಗಳನ್ನು ಒತ್ತಾಯವಾಗಿ ಅನುಮತಿಸಿ"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"ಮ್ಯಾನಿಫೆಸ್ಟ್ ಮೌಲ್ಯಗಳು ಯಾವುದೇ ಆಗಿದ್ದರೂ, ಬಾಹ್ಯ ಸಂಗ್ರಹಣೆಗೆ ಬರೆಯಲು ಯಾವುದೇ ಅಪ್ಲಿಕೇಶನ್ ಅನ್ನು ಅರ್ಹಗೊಳಿಸುತ್ತದೆ"</string> <string name="force_resizable_activities" msgid="7143612144399959606">"ಚಟುವಟಿಕೆಗಳನ್ನು ಮರುಗಾತ್ರಗೊಳಿಸುವಂತೆ ಒತ್ತಾಯ ಮಾಡಿ"</string> diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml index 6f642c3f59ee..a98bfd350543 100644 --- a/packages/SettingsLib/res/values-ko/strings.xml +++ b/packages/SettingsLib/res/values-ko/strings.xml @@ -212,7 +212,7 @@ <string name="adb_wireless_settings" msgid="2295017847215680229">"무선 디버깅"</string> <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"사용 가능한 기기를 보고 사용하려면 무선 디버깅을 사용 설정하세요."</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"QR 코드로 기기 페어링"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"QR 코드 스캐너를 사용하여 새 기기 페어링"</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"QR 코드 스캐너를 사용하여 새 기기 페어링"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"페어링 코드로 기기 페어링"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"6자리 코드를 사용하여 새 기기 페어링"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"페어링된 기기"</string> @@ -231,7 +231,7 @@ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"기기를 페어링할 수 없습니다. QR 코드가 잘못되었거나 기기가 동일한 네트워크에 연결되어 있지 않습니다."</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP 주소 및 포트"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"QR 코드 스캔"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"QR 코드를 스캔하여 Wi‑Fi를 통해 기기 페어링"</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"QR 코드를 스캔하여 Wi‑Fi를 통해 기기 페어링"</string> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Wi-Fi 네트워크에 연결하세요."</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, 디버그, 개발자"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"버그 신고 바로가기"</string> @@ -251,6 +251,7 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"무선 디스플레이 인증서"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"Wi-Fi 상세 로깅 사용"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"Wi‑Fi 검색 제한"</string> + <string name="wifi_enhanced_mac_randomization" msgid="5437378364995776979">"Wi‑Fi로 MAC 무작위 순서 지정 개선"</string> <string name="mobile_data_always_on" msgid="8275958101875563572">"항상 모바일 데이터 활성화"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"테더링 하드웨어 가속"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"이름이 없는 블루투스 기기 표시"</string> @@ -283,6 +284,7 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"무선 디스플레이 인증서 옵션 표시"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Wi‑Fi 로깅 수준을 높이고, Wi‑Fi 선택도구에서 SSID RSSI당 값을 표시"</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"배터리 소모를 줄이고 네트워크 성능 개선"</string> + <string name="wifi_enhanced_mac_randomization_summary" msgid="7925425746373704991">"이 전환은 클라이언트 모드의 MAC 무작위 순서 지정 방식에만 영향을 줍니다.\n이 모드를 활성화하면 네트워크와 클라이언트 연결이 끊긴 마지막 시점에 따라 MAC 무작위 순서 지정이 사용 설정된 네트워크에서 연결 중에 MAC 주소를 다시 무작위 순서로 지정할 수 있습니다. 기기가 4시간 이내에 재연결된 경우 무작위 순서 지정이 다시 발생하지 않습니다."</string> <string name="wifi_metered_label" msgid="8737187690304098638">"종량제 네트워크"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"무제한 네트워크"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"로거 버퍼 크기"</string> @@ -371,6 +373,8 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"백그라운드 앱과 관련해 앱 응답 없음 대화상자 표시"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"알림 채널 경고 표시"</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"앱에서 유효한 채널 없이 알림을 게시하면 화면에 경고 표시"</string> + <string name="enforce_shortcuts_for_conversations" msgid="7040735163945040763">"대화 알림에 단축키 적용"</string> + <string name="enforce_shortcuts_for_conversations_summary" msgid="1860168037282467862">"알림이 대화 섹션에 표시되려면 오래 지속되는 공유 단축키의 지원을 받도록 요구"</string> <string name="force_allow_on_external" msgid="9187902444231637880">"외부에서 앱 강제 허용"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"매니페스트 값과 관계없이 모든 앱이 외부 저장소에 작성되도록 허용"</string> <string name="force_resizable_activities" msgid="7143612144399959606">"활동의 크기가 조정 가능하도록 설정"</string> diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml index 417e5115ba5a..33b0aaf40833 100644 --- a/packages/SettingsLib/res/values-ky/strings.xml +++ b/packages/SettingsLib/res/values-ky/strings.xml @@ -37,7 +37,7 @@ <string name="wifi_no_internet" msgid="1774198889176926299">"Интернетке туташпай турат"</string> <string name="saved_network" msgid="7143698034077223645">"<xliff:g id="NAME">%1$s</xliff:g> тарабынан сакталды"</string> <string name="connected_via_network_scorer" msgid="7665725527352893558">"%1$s аркылуу автоматтык түрдө туташты"</string> - <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Тармактар рейтингинин автору аркылуу автоматтык түрдө туташты"</string> + <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Тармактар рейтингинин булагы аркылуу автоматтык түрдө туташты"</string> <string name="connected_via_passpoint" msgid="7735442932429075684">"%1$s аркылуу жеткиликтүү"</string> <string name="connected_via_app" msgid="3532267661404276584">"<xliff:g id="NAME">%1$s</xliff:g> аркылуу туташты"</string> <string name="available_via_passpoint" msgid="1716000261192603682">"%1$s аркылуу жеткиликтүү"</string> @@ -146,7 +146,7 @@ <string name="tether_settings_title_usb" msgid="3728686573430917722">"USB модем"</string> <string name="tether_settings_title_wifi" msgid="4803402057533895526">"Wi-Fi байланыш түйүнү"</string> <string name="tether_settings_title_bluetooth" msgid="916519902721399656">"Bluetooth модем"</string> - <string name="tether_settings_title_usb_bluetooth" msgid="1727111807207577322">"Жалгаштыруу"</string> + <string name="tether_settings_title_usb_bluetooth" msgid="1727111807207577322">"Модем режими"</string> <string name="tether_settings_title_all" msgid="8910259483383010470">"Модем режими"</string> <string name="managed_user_title" msgid="449081789742645723">"Жумуш профилинин колднмлр"</string> <string name="user_guest" msgid="6939192779649870792">"Конок"</string> @@ -171,7 +171,7 @@ <string name="tts_engine_security_warning" msgid="3372432853837988146">"Бул кепти синтездөө каражаты бардык айтыла турган текстти, анын ичинде сырсөздөр жана насыя карточкасынын номери сыяктуу жеке маалыматты, топтошу мүмкүн. Ал <xliff:g id="TTS_PLUGIN_ENGINE_NAME">%s</xliff:g> каражатынан алынат. Бул кепти синтездөө каражаты колдонулсунбу?"</string> <string name="tts_engine_network_required" msgid="8722087649733906851">"Бул тилде кеп синтезаторун иштетүү үчүн Интернетке туташуу керек."</string> <string name="tts_default_sample_string" msgid="6388016028292967973">"Бул айтылганды синтездөөнүн мисалы"</string> - <string name="tts_status_title" msgid="8190784181389278640">"Абалкы тилдин абалы"</string> + <string name="tts_status_title" msgid="8190784181389278640">"Демейки тилдин абалы"</string> <string name="tts_status_ok" msgid="8583076006537547379">"<xliff:g id="LOCALE">%1$s</xliff:g> толук колдоого алынган"</string> <string name="tts_status_requires_network" msgid="8327617638884678896">"<xliff:g id="LOCALE">%1$s</xliff:g> желеге туташууну талап кылат"</string> <string name="tts_status_not_supported" msgid="2702997696245523743">"<xliff:g id="LOCALE">%1$s</xliff:g> колдоого алынган эмес"</string> @@ -201,18 +201,18 @@ <string name="development_settings_summary" msgid="8718917813868735095">"Колдонмо өндүрүү мүмкүнчүлүктөрүн орнотуу"</string> <string name="development_settings_not_available" msgid="355070198089140951">"Бул колдонуучуга өнүктүүрүүчү мүмкүнчүлүктөрү берилген эмес."</string> <string name="vpn_settings_not_available" msgid="2894137119965668920">"Бул колдонуучу VPN жөндөөлөрүн колдоно албайт"</string> - <string name="tethering_settings_not_available" msgid="266821736434699780">"Бул колдонуучу тетеринг жөндөөлөрүн колдоно албайт"</string> + <string name="tethering_settings_not_available" msgid="266821736434699780">"Бул колдонуучу модем режиминин жөндөөлөрүн өзгөртө албайт"</string> <string name="apn_settings_not_available" msgid="1147111671403342300">"Бул колдонуучу мүмкүндүк алуу түйүнүнүн аталышынын жөндөөлөрүн колдоно албайт"</string> <string name="enable_adb" msgid="8072776357237289039">"USB аркылуу мүчүлүштүктөрдү оңдоо"</string> <string name="enable_adb_summary" msgid="3711526030096574316">"USB компьютерге сайылганда мүчүлүштүктөрдү оңдоо режими иштейт"</string> <string name="clear_adb_keys" msgid="3010148733140369917">"USB аркылуу мүчүлүштүктөрдү оңдоо уруксатын артка кайтаруу"</string> - <string name="enable_adb_wireless" msgid="6973226350963971018">"Мүчүлүштүктөрдү зымсыз оңдоо"</string> + <string name="enable_adb_wireless" msgid="6973226350963971018">"Мүчүлүштүктөрдү Wi-Fi аркылуу оңдоо"</string> <string name="enable_adb_wireless_summary" msgid="7344391423657093011">"Wi‑Fi\'га туташтырылганда мүчүлүштүктөрдү оңдоо режими"</string> <string name="adb_wireless_error" msgid="721958772149779856">"Ката"</string> - <string name="adb_wireless_settings" msgid="2295017847215680229">"Мүчүлүштүктөрдү зымсыз оңдоо"</string> - <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Жеткиликтүү түзмөктөрдү көрүү үчүн мүчүлүштүктөрдү зымсыз оңдоону күйгүзүңүз"</string> + <string name="adb_wireless_settings" msgid="2295017847215680229">"Мүчүлүштүктөрдү Wi-Fi аркылуу оңдоо"</string> + <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Жеткиликтүү түзмөктөрдү көрүү үчүн мүчүлүштүктөрдү Wi-Fi аркылуу оңдоону күйгүзүңүз"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"QR кодун колдонуп, түзмөктү жупташтырыңыз"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"QR кодунун сканерин колдонуп, жаңы түзмөктөрдү жупташтырыңыз"</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"QR кодунун сканерин колдонуп, жаңы түзмөктөрдү жупташтырыңыз"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"Жупташтыруучу код менен түзмөктү жупташтырыңыз"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"Алты сандан турган кодду колдонуп, жаңы түзмөктөрдү жупташтырыңыз"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"Жупташтырылган түзмөктөр"</string> @@ -231,7 +231,7 @@ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"Түзмөк жупташтырылган жок. QR коду туура эмес же түзмөк бир тармакка туташпай турат."</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP дареги жана Оюкча"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"QR кодун скандоо"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"QR кодун скандап, түзмөктү Wi‑Fi аркылуу жупташтырыңыз"</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"QR кодун скандап, түзмөктү Wi‑Fi аркылуу жупташтырыңыз"</string> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Wi-Fi тармагына туташыңыз"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, мүчүлүштүктөрдү оңдоо, иштеп чыгуу"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"Ката жөнүндө кабарлоо"</string> @@ -251,6 +251,8 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"Зымсыз мониторлорду тастыктамалоо"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"Wi‑Fi дайын-даректүү журналы"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"Wi‑Fi тармактарын издөөнү жөнгө салуу"</string> + <!-- no translation found for wifi_enhanced_mac_randomization (5437378364995776979) --> + <skip /> <string name="mobile_data_always_on" msgid="8275958101875563572">"Мобилдик Интернет иштей берет"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"Модем режиминде аппараттын иштешин тездетүү"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"Аталышсыз Bluetooth түзмөктөрү көрсөтүлсүн"</string> @@ -283,6 +285,8 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"Зымсыз мониторлорду тастыктамалоо параметрлери көрүнүп турат"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Wi-Fi тандалганда ар бир SSID үчүн RSSI көрүнүп турат"</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"Батареянын коротулушун чектеп, тармактын иштешин жакшыртат"</string> + <!-- no translation found for wifi_enhanced_mac_randomization_summary (7925425746373704991) --> + <skip /> <string name="wifi_metered_label" msgid="8737187690304098638">"Трафик ченелет"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"Чектелбеген тармак"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"Журнал буферинин өлчөмү"</string> @@ -300,8 +304,8 @@ <string name="tethering_hardware_offload_summary" msgid="7801345335142803029">"Мүмкүнчүлүккө жараша, модем режиминде аппарат тезирээк иштей баштайт"</string> <string name="adb_warning_title" msgid="7708653449506485728">"USB аркылуу жөндөөгө уруксат бересизби?"</string> <string name="adb_warning_message" msgid="8145270656419669221">"USB-жөндөө - өндүрүү максатында гана түзүлгөн. Аны компүтериңиз менен түзмөгүңүздүн ортосунда берилиштерди алмашуу, түзмөгүңүзгө колдонмолорду эскертүүсүз орнотуу жана лог берилиштерин окуу үчүн колдонсоңуз болот."</string> - <string name="adbwifi_warning_title" msgid="727104571653031865">"Мүчүлүштүктөрдү зымсыз оңдоого уруксат берилсинби?"</string> - <string name="adbwifi_warning_message" msgid="8005936574322702388">"Мүчүлүштүктөрдү зымсыз оңдоо – өндүрүү максатында гана түзүлгөн. Аны компьютериңиз менен түзмөгүңүздүн ортосунда маалыматты алмашуу, колдонмолорду түзмөгүңүзгө эскертүүсүз орнотуу жана маалыматтар таржымалын окуу үчүн колдонсоңуз болот."</string> + <string name="adbwifi_warning_title" msgid="727104571653031865">"Мүчүлүштүктөрдү Wi-Fi аркылуу оңдоого уруксат берилсинби?"</string> + <string name="adbwifi_warning_message" msgid="8005936574322702388">"Мүчүлүштүктөрдү Wi-Fi аркылуу оңдоо – өндүрүү максатында гана түзүлгөн. Аны компьютериңиз менен түзмөгүңүздүн ортосунда маалыматты алмашуу, колдонмолорду түзмөгүңүзгө эскертүүсүз орнотуу жана маалыматтар таржымалын окуу үчүн колдонсоңуз болот."</string> <string name="adb_keys_warning_message" msgid="2968555274488101220">"Сиз мурун USB жөндөөлөрүнө уруксат берген бардык компүтерлердин жеткиси жокко чыгарылсынбы?"</string> <string name="dev_settings_warning_title" msgid="8251234890169074553">"Жөндөөлөрдү өзгөртүү"</string> <string name="dev_settings_warning_message" msgid="37741686486073668">"Бул орнотуулар өндүрүүчүлөр үчүн гана берилген. Булар түзмөгүңүздүн колдонмолорун бузулушуна же туура эмес иштешине алып келиши мүмкүн."</string> @@ -371,6 +375,8 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"Фондогу колдонмо жооп бербей жатат деп билдирип турат"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"Билдирмелер каналынын эскертүүлөрүн көрсөтүү"</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"Тыюу салынган каналдын колдонмосунун жаңы билдирмелери тууралуу эскертүүлөр көрүнөт"</string> + <string name="enforce_shortcuts_for_conversations" msgid="7040735163945040763">"Жазышуу билдирмелери үчүн ыкчам баскычтарды иштетиңиз"</string> + <string name="enforce_shortcuts_for_conversations_summary" msgid="1860168037282467862">"Жазышуу бөлүмүндө көрсөтүү үчүн билдирмелерди узак убакытка колдонулуучу ыкчам баскычтар менен колдоону талап кылыңыз"</string> <string name="force_allow_on_external" msgid="9187902444231637880">"Тышкы сактагычка сактоого уруксат берүү"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Манифест маанилерине карабастан бардык колдонмолорду тышкы сактагычка сактоого уруксат берет"</string> <string name="force_resizable_activities" msgid="7143612144399959606">"Бир нече терезе режиминде өлчөмдү өзгөртүү"</string> @@ -428,8 +434,8 @@ <skip /> <string name="power_discharge_by_enhanced" msgid="563438403581662942">"Колдонгонуңузга караганда болжол менен <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$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="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$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" msgid="4113180890060388350">"Болжол менен саат <xliff:g id="TIME">%1$s</xliff:g> өчөт, (<xliff:g id="LEVEL">%2$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_suggestion_battery_run_out" msgid="6332089307827787087">"Батарея <xliff:g id="TIME">%1$s</xliff:g> отуруп калышы мүмкүн"</string> <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"<xliff:g id="THRESHOLD">%1$s</xliff:g> жетпеген убакыт калды"</string> diff --git a/packages/SettingsLib/res/values-lo/strings.xml b/packages/SettingsLib/res/values-lo/strings.xml index 58c8c39b4ea5..bdbc8efd976f 100644 --- a/packages/SettingsLib/res/values-lo/strings.xml +++ b/packages/SettingsLib/res/values-lo/strings.xml @@ -212,7 +212,7 @@ <string name="adb_wireless_settings" msgid="2295017847215680229">"ການດີບັກໄຮ້ສາຍ"</string> <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"ເພື່ອເບິ່ງ ແລະ ໃຊ້ອຸປະກອນທີ່ມີຢູ່, ກະລຸນາເປີດການດີບັກໄຮ້ສາຍ"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"ຈັບຄູ່ອຸປະກອນດ້ວຍລະຫັດ QR"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"ຈັບຄູ່ອຸປະກອນໃໝ່ໂດຍໃຊ້ຕົວສະແກນລະຫັດ QR"</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"ຈັບຄູ່ອຸປະກອນໃໝ່ໂດຍໃຊ້ຕົວສະແກນລະຫັດ QR"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"ຈັບຄູ່ອຸປະກອນໂດຍໃຊ້ລະຫັດການຈັບຄູ່"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"ຈັບຄູ່ອຸປະກອນໃໝ່ໂດຍໃຊ້ລະຫັດຫົກຕົວເລກ"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"ອຸປະກອນທີ່ຈັບຄູ່ແລ້ວ"</string> @@ -231,7 +231,7 @@ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"ຈັບຄູ່ອຸປະກອນບໍ່ສຳເລັດ. ລະຫັດ QR ບໍ່ຖືກຕ້ອງ ຫຼື ອຸປະກອນບໍ່ໄດ້ເຊື່ອມຕໍ່ຫາເຄືອຂ່າຍດຽວກັນ."</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"ທີ່ຢູ່ IP ແລະ ຜອດ"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"ສະແກນລະຫັດ QR"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"ຈັບຄູ່ອຸປະກອນຜ່ານ Wi‑Fi ໂດຍການສະແກນລະຫັດ QR"</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"ຈັບຄູ່ອຸປະກອນຜ່ານ Wi‑Fi ໂດຍການສະແກນລະຫັດ QR"</string> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"ກະລຸນາເຊື່ອມຕໍ່ກັບເຄືອຂ່າຍ Wi-Fi"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, debug, dev"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"ທາງລັດລາຍງານຂໍ້ຜິດພາດ"</string> @@ -251,6 +251,8 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"ສະແດງການຮັບຮອງຂອງລະບົບໄຮ້ສາຍ"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"ເປີດນຳໃຊ້ການເກັບປະຫວັດ Verbose Wi‑Fi"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"ການຈຳກັດການສະແກນ Wi‑Fi"</string> + <!-- no translation found for wifi_enhanced_mac_randomization (5437378364995776979) --> + <skip /> <string name="mobile_data_always_on" msgid="8275958101875563572">"ເປີດໃຊ້ອິນເຕີເນັດມືຖືຕະຫຼອດເວລາ"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"ເປີດໃຊ້ການເລັ່ງຄວາມໄວດ້ວຍຮາດແວ"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"ສະແດງອຸປະກອນ Bluetooth ທີ່ບໍ່ມີຊື່"</string> @@ -283,6 +285,8 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"ສະແດງໂຕເລືອກສຳລັບການສະແດງການຮັບຮອງລະບົບໄຮ້ສາຍ"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"ເພີ່ມລະດັບການເກັບປະຫວັດ Wi‑Fi, ສະແດງຕໍ່ SSID RSSI ໃນ Wi‑Fi Picker"</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"ຫຼຸດການໃຊ້ແບັດເຕີຣີ ແລະ ປັບປຸງປະສິດທິພາບເຄືອຂ່າຍ"</string> + <!-- no translation found for wifi_enhanced_mac_randomization_summary (7925425746373704991) --> + <skip /> <string name="wifi_metered_label" msgid="8737187690304098638">"ມີການວັດແທກ"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"ບໍ່ໄດ້ວັດແທກ"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"ຂະໜາດບັບເຟີຕົວບັນທຶກ"</string> @@ -371,6 +375,8 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"ສະແດງກ່ອງຂໍ້ຄວາມບໍ່ຕອບສະໜອງແອັບສຳລັບແອັບພື້ນຫຼັງ"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"ສະແດງຄຳເຕືອນຊ່ອງການແຈ້ງເຕືອນ"</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"ສະແດງຄຳເຕືອນໃນໜ້າຈໍເມື່ອແອັບໂພສການແຈ້ງເຕືອນໂດຍບໍ່ມີຊ່ອງທີ່ຖືກຕ້ອງ"</string> + <string name="enforce_shortcuts_for_conversations" msgid="7040735163945040763">"ບັງຄັບໃຊ້ທາງລັດສຳລັບການແຈ້ງເຕືອນການສົນທະນາ"</string> + <string name="enforce_shortcuts_for_conversations_summary" msgid="1860168037282467862">"ຕ້ອງໃຊ້ການແຈ້ງເຕືອນເພື່ອຮັບການສະໜັບສະໜຸນໂດຍທາງລັດການແບ່ງປັນທີ່ຢູ່ດົນເພື່ອໃຫ້ປາກົດໃນພາກສ່ວນການສົນທະນາ"</string> <string name="force_allow_on_external" msgid="9187902444231637880">"ບັງຄັບອະນຸຍາດແອັບຢູ່ພາຍນອກ"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"ເຮັດໃຫ້ທຸກແອັບມີສິດໄດ້ຮັບການຂຽນໃສ່ພື້ນທີ່ຈັດເກັບຂໍ້ມູນພາຍນອກ, ໂດຍບໍ່ຄຳນຶງເຖິງຄ່າ manifest"</string> <string name="force_resizable_activities" msgid="7143612144399959606">"ບັງຄັງໃຫ້ການເຄື່ອນໄຫວປ່ຽນຂະໜາດໄດ້"</string> diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml index 94800ea8b3a7..e2ccc3a30877 100644 --- a/packages/SettingsLib/res/values-lt/strings.xml +++ b/packages/SettingsLib/res/values-lt/strings.xml @@ -212,7 +212,7 @@ <string name="adb_wireless_settings" msgid="2295017847215680229">"Belaidžio ryšio derinimas"</string> <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Jei norite peržiūrėti ir naudoti pasiekiamus įrenginius, įjunkite belaidžio ryšio derinimą"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"Įrenginio susiejimas naudojant QR kodą"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"Susiekite naujus įrenginius naudodami QR kodų skaitytuvą"</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"Susiekite naujus įrenginius naudodami QR kodų skaitytuvą"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"Įrenginio susiejimas naudojant susiejimo kodą"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"Susiekite naujus įrenginius naudodami šešių skaitmenų kodą"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"Susieti įrenginiai"</string> @@ -231,7 +231,7 @@ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"Nepavyko susieti įrenginio. Netinkamas QR kodas arba įrenginys neprijungtas prie to paties tinklo."</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP adresas ir prievadas"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"QR kodo nuskaitymas"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"Susiekite įrenginį „Wi‑Fi“ ryšiu nuskaitydami QR kodą"</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Susiekite įrenginį „Wi‑Fi“ ryšiu nuskaitydami QR kodą"</string> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Prisijunkite prie „Wi-Fi“ tinklo"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"ADB, derinti, kūrėjas"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"Pranešimo apie riktą spartusis klavišas"</string> @@ -251,6 +251,7 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"Belaidžio rodymo sertifikavimas"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"Įgal. „Wi‑Fi“ daugiaž. įraš. į žurnalą"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"„Wi‑Fi“ nuskaitymo ribojimas"</string> + <string name="wifi_enhanced_mac_randomization" msgid="5437378364995776979">"„Wi‑Fi“ patob. atsit. MAC adr. parink."</string> <string name="mobile_data_always_on" msgid="8275958101875563572">"Mobiliojo ryšio duomenys visada suaktyvinti"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"Įrenginio kaip modemo naudojimo aparatinės įrangos spartinimas"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"Rodyti „Bluetooth“ įrenginius be pavadinimų"</string> @@ -283,6 +284,7 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"Rodyti belaidžio rodymo sertifikavimo parinktis"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Padidinti „Wi‑Fi“ įrašymo į žurnalą lygį, rodyti SSID RSSI „Wi-Fi“ rinkiklyje"</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"Sumažinamas akumuliatoriaus eikvojimas ir patobulinamas tinklo našumas"</string> + <string name="wifi_enhanced_mac_randomization_summary" msgid="7925425746373704991">"Perjungiamas tik atsitiktinis MAC adreso parinkimas dirbant kliento režimu.\nKai suaktyvintas šis režimas, visuose tinkluose, kuriuose įgalintas atsitiktinis MAC adreso parinkimas, susiejant šie adresai gali būti atsitiktinai parenkami iš naujo, atsižvelgiant į tai, kada klientas paskutinį kartą atsijungė nuo tinklo. Atsitiktinis MAC adreso parinkimas nevykdomas iš naujo, jei įrenginys vėl prisijungia ne daugiau nei po keturių valandų."</string> <string name="wifi_metered_label" msgid="8737187690304098638">"Matuojamas"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"Neišmatuotas"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"Registruotuvo buferio dydžiai"</string> @@ -371,6 +373,8 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"Foninėse programose rodyti dialogo langą „Programa neatsako“"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"Rodyti pran. kan. įspėj."</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"Ekr. rod. įsp., kai progr. pask. pr. be tink. kan."</string> + <string name="enforce_shortcuts_for_conversations" msgid="7040735163945040763">"Nustatyti pokalbio pranešimų šaukinius"</string> + <string name="enforce_shortcuts_for_conversations_summary" msgid="1860168037282467862">"Kad pranešimai būtų rodomi pokalbių skiltyje, būtinas ilgalaikis jų bendrinimo šaukinys"</string> <string name="force_allow_on_external" msgid="9187902444231637880">"Priverstinai leisti programas išorinėje atmintin."</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Nustatoma, kad visas programas būtų galima įrašyti į išorinę saugyklą, nepaisant aprašo verčių"</string> <string name="force_resizable_activities" msgid="7143612144399959606">"Priv. nust., kad veiksm. b. g. atl. kelių d. lang."</string> diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml index d7816aa54a1a..64368b7b0e95 100644 --- a/packages/SettingsLib/res/values-lv/strings.xml +++ b/packages/SettingsLib/res/values-lv/strings.xml @@ -212,7 +212,7 @@ <string name="adb_wireless_settings" msgid="2295017847215680229">"Bezvadu atkļūdošana"</string> <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Lai skatītu un izmantotu pieejamās ierīces, ieslēdziet bezvadu atkļūdošanu."</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"Ierīču savienošana pārī, izmantojot QR kodu"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"Savienot pārī jaunas ierīces, izmantojot QR koda skeneri"</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"Savienot pārī jaunas ierīces, izmantojot QR koda skeneri"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"Ierīču savienošana pārī, izmantojot kodu"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"Savienojiet pārī jaunas ierīces, izmantojot sešu ciparu kodu"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"Pārī savienotās ierīces"</string> @@ -231,7 +231,7 @@ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"Neizdevās izveidot savienojumu pārī ar ierīci. QR kods nebija pareizs, vai ierīcei nebija izveidots savienojums ar to pašu tīklu."</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP adrese un ports"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"QR koda skenēšana"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"Izveidojiet savienojumu pārī ar ierīci Wi‑Fi tīklā, skenējot QR kodu."</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Izveidojiet savienojumu pārī ar ierīci Wi‑Fi tīklā, skenējot QR kodu."</string> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Lūdzu, izveidojiet savienojumu ar Wi-Fi tīklu"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, atkļūdošana, izstrādātājiem"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"Kļūdu pārskata saīsne"</string> @@ -251,6 +251,7 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"Bezvadu attēlošanas sertifikācija"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"Iespējot Wi‑Fi detalizēto reģistrēšanu"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"Wi‑Fi meklēšanas ierobežošana"</string> + <string name="wifi_enhanced_mac_randomization" msgid="5437378364995776979">"MAC adrešu nejauša izveide ar Wi-Fi"</string> <string name="mobile_data_always_on" msgid="8275958101875563572">"Vienmēr aktīvs mobilo datu savienojums"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"Paātrināta aparatūras darbība piesaistei"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"Rādīt Bluetooth ierīces bez nosaukumiem"</string> @@ -283,6 +284,7 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"Rādīt bezvadu attēlošanas sertifikācijas iespējas"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Palieliniet Wi‑Fi reģistrēšanas līmeni; rādīt katram SSID RSSI Wi‑Fi atlasītājā."</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"Samazina akumulatora izlādi un uzlabo tīkla veiktspēju"</string> + <string name="wifi_enhanced_mac_randomization_summary" msgid="7925425746373704991">"Šis slēdzis ietekmē MAC adrešu nejaušas izveides darbību tikai klienta režīmā.\nJa šis režīms ir aktivizēts, visos tīklos, kuros MAC adrešu nejauša izveide ir iespējota, saistīšanas laikā MAC adreses var tikt atkārtoti nejauši izveidotas atkarībā no tā, kad klients pēdējoreiz pārtrauca savienojumu ar tīklu. Atkārtota nejauša izveide netiek veikta, ja ierīces savienojums tiek atjaunots ne vairāk kā 4 stundu laikā."</string> <string name="wifi_metered_label" msgid="8737187690304098638">"Maksas"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"Bezmaksas"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"Reģistrētāja buferu lielumi"</string> @@ -371,6 +373,8 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"Rādīt fona lietotņu dialoglodziņu Lietotne nereaģē"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"Paziņojumu kanāla brīdinājumi"</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"Brīdinājums ekrānā, kad lietotne publicē paziņojumu, nenorādot derīgu kanālu"</string> + <string name="enforce_shortcuts_for_conversations" msgid="7040735163945040763">"Ieviest saīsnes sarunu paziņojumiem"</string> + <string name="enforce_shortcuts_for_conversations_summary" msgid="1860168037282467862">"Pieprasīt izmantot paziņojumiem ilgstošas darbības kopīgošanas saīsni rādīšanai sarunu sadaļā"</string> <string name="force_allow_on_external" msgid="9187902444231637880">"Lietotņu piespiedu atļaušana ārējā krātuvē"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Ļauj jebkuru lietotni ierakstīt ārējā krātuvē neatkarīgi no manifesta vērtības."</string> <string name="force_resizable_activities" msgid="7143612144399959606">"Pielāgot darbības"</string> diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml index 754c3a07db15..934fcf74f9f8 100644 --- a/packages/SettingsLib/res/values-mk/strings.xml +++ b/packages/SettingsLib/res/values-mk/strings.xml @@ -23,7 +23,7 @@ <string name="wifi_fail_to_scan" msgid="2333336097603822490">"Не може да скенира за мрежи"</string> <string name="wifi_security_none" msgid="7392696451280611452">"Ниедна"</string> <string name="wifi_remembered" msgid="3266709779723179188">"Зачувано"</string> - <string name="wifi_disconnected" msgid="7054450256284661757">"Исклучен"</string> + <string name="wifi_disconnected" msgid="7054450256284661757">"Прекината врска"</string> <string name="wifi_disabled_generic" msgid="2651916945380294607">"Оневозможено"</string> <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"Конфигурирањето ИП не успеа"</string> <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"Не е поврзано поради нискиот квалитет на мрежата"</string> @@ -37,7 +37,7 @@ <string name="wifi_no_internet" msgid="1774198889176926299">"Нема пристап до интернет"</string> <string name="saved_network" msgid="7143698034077223645">"Зачувано од <xliff:g id="NAME">%1$s</xliff:g>"</string> <string name="connected_via_network_scorer" msgid="7665725527352893558">"Автоматски поврзано преку %1$s"</string> - <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Автоматски поврзано преку оператор за оценување мрежа"</string> + <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Автоматски поврзано преку оценувач на мрежа"</string> <string name="connected_via_passpoint" msgid="7735442932429075684">"Поврзано преку %1$s"</string> <string name="connected_via_app" msgid="3532267661404276584">"Поврзано преку <xliff:g id="NAME">%1$s</xliff:g>"</string> <string name="available_via_passpoint" msgid="1716000261192603682">"Достапно преку %1$s"</string> @@ -143,10 +143,10 @@ <string name="data_usage_uninstalled_apps" msgid="1933665711856171491">"Отстранети апликации"</string> <string name="data_usage_uninstalled_apps_users" msgid="5533981546921913295">"Отстранети апликации и корисници"</string> <string name="data_usage_ota" msgid="7984667793701597001">"Ажурирања на системот"</string> - <string name="tether_settings_title_usb" msgid="3728686573430917722">"Поврзување со USB"</string> + <string name="tether_settings_title_usb" msgid="3728686573430917722">"Интернет преку USB"</string> <string name="tether_settings_title_wifi" msgid="4803402057533895526">"Преносл. точка на пристап"</string> - <string name="tether_settings_title_bluetooth" msgid="916519902721399656">"Поврзување со Bluetooth"</string> - <string name="tether_settings_title_usb_bluetooth" msgid="1727111807207577322">"Поврзување"</string> + <string name="tether_settings_title_bluetooth" msgid="916519902721399656">"Интернет преку Bluetooth"</string> + <string name="tether_settings_title_usb_bluetooth" msgid="1727111807207577322">"Врзување"</string> <string name="tether_settings_title_all" msgid="8910259483383010470">"Поврзување и пренослива точка на пристап"</string> <string name="managed_user_title" msgid="449081789742645723">"Сите апликации за работа"</string> <string name="user_guest" msgid="6939192779649870792">"Гостин"</string> @@ -212,7 +212,7 @@ <string name="adb_wireless_settings" msgid="2295017847215680229">"Безжично отстранување грешки"</string> <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"За да ги гледате и користите достапните уреди, вклучете го безжичното отстранување грешки"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"Спарете уред преку QR-код"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"Спарете нови уреди преку скенер за QR-код"</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"Спарете нови уреди преку скенер за QR-код"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"Спарете уред преку код за спарување"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"Спарете нови уреди преку шестцифрен код"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"Спарени уреди"</string> @@ -231,7 +231,7 @@ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"Уредот не успеа да се спари. Или QR-кодот беше погрешен или уредот не е поврзан на истата мрежа."</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP-адреса и порта"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"Скенирајте QR-код"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"Спарете го уредот преку Wi‑Fi со скенирање QR-код"</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Спарете го уредот преку Wi‑Fi со скенирање QR-код"</string> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Поврзете се на Wi-Fi-мрежа"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, отстранува грешка, програмер"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"Кратенка за извештај за грешка"</string> @@ -251,6 +251,7 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"Приказ на сертификација на безжична мрежа"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"Овозможи преопширно пријавување Wi‑Fi"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"Регулирање на скенирањето за Wi‑Fi"</string> + <string name="wifi_enhanced_mac_randomization" msgid="5437378364995776979">"Рандомизација на MAC подобрена со Wi‑Fi"</string> <string name="mobile_data_always_on" msgid="8275958101875563572">"Мобилниот интернет е секогаш активен"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"Хардверско забрзување за врзување"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"Прикажувај уреди со Bluetooth без имиња"</string> @@ -283,6 +284,7 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"Покажи ги опциите за безжичен приказ на сертификат"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Зголеми Wi‑Fi ниво на пријавување, прикажи по SSID RSSI во Wi‑Fi бирач"</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"Го намалува искористувањето на батеријата и ја подобрува изведбата на мрежата"</string> + <string name="wifi_enhanced_mac_randomization_summary" msgid="7925425746373704991">"Овој прекинувач влијае на однесувањето на рандомизацијата на MAC само за клиентски режим.\nКога е активиран режимов, можно е да се изврши повторна рандомизација на MAC-адресите на сите мрежи што имаат овозможена рандомизација на MAC за време на асоцијацијата, зависно од тоа кога клиентот последен пат се исклучил од мрежата. Повторната рандомизација не се случува ако уредот се поврзе повторно во рок од 4 часа или помалку."</string> <string name="wifi_metered_label" msgid="8737187690304098638">"Со ограничен интернет"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"Без ограничен интернет"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"Величини на меѓумеморија за дневникот"</string> @@ -301,7 +303,7 @@ <string name="adb_warning_title" msgid="7708653449506485728">"Овозможи отстранување грешки на USB?"</string> <string name="adb_warning_message" msgid="8145270656419669221">"Отстранувањето грешки на USB е наменето само за целите на развој. Користете го за копирање податоци меѓу вашиот компјутер и вашиот уред, за инсталирање апликации на вашиот уред без известување и за читање евиденција на податоци."</string> <string name="adbwifi_warning_title" msgid="727104571653031865">"Да се дозволи безжично отстранување грешки?"</string> - <string name="adbwifi_warning_message" msgid="8005936574322702388">"Безжичното отстранување грешки е наменето само за развојни цели. Користете го за копирање податоци помеѓу компјутерот и уредот, за инсталирање апликации на уредот без известување и за читање податоци од евиденцијата."</string> + <string name="adbwifi_warning_message" msgid="8005936574322702388">"Безжичното отстранување грешки е наменето само за програмирање. Користете го за копирање податоци помеѓу компјутерот и уредот, за инсталирање апликации на уредот без известување и за читање податоци од евиденцијата."</string> <string name="adb_keys_warning_message" msgid="2968555274488101220">"Отповикај пристап кон отстранување грешка од USB од сите претходно овластени компјутери?"</string> <string name="dev_settings_warning_title" msgid="8251234890169074553">"Дозволи поставки за развој?"</string> <string name="dev_settings_warning_message" msgid="37741686486073668">"Овие поставки се наменети само за употреба за развој. Тие може да предизвикаат уредот и апликациите во него да се расипат или да се однесуваат необично."</string> @@ -371,6 +373,8 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"Прикажи го дијалогот „Апликацијата не реагира“ за апликации во заднина"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"Прикажи ги предупредувањата на каналот за известувањe"</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"Предупредува кога апликација дава известување без важечки канал"</string> + <string name="enforce_shortcuts_for_conversations" msgid="7040735163945040763">"Кратенки за известувањата"</string> + <string name="enforce_shortcuts_for_conversations_summary" msgid="1860168037282467862">"Известувања со долготрајна кратенка за споделување"</string> <string name="force_allow_on_external" msgid="9187902444231637880">"Принуд. дозволете апликации на надворешна меморија"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Прави секоја апликација да биде подобна за запишување на надворешна меморија, независно од вредностите на манифестот"</string> <string name="force_resizable_activities" msgid="7143612144399959606">"Принуди ги активностите да ја менуваат големината"</string> diff --git a/packages/SettingsLib/res/values-ml/strings.xml b/packages/SettingsLib/res/values-ml/strings.xml index c593bee5e1f6..dbca5e7f3956 100644 --- a/packages/SettingsLib/res/values-ml/strings.xml +++ b/packages/SettingsLib/res/values-ml/strings.xml @@ -206,13 +206,14 @@ <string name="enable_adb" msgid="8072776357237289039">"USB ഡീബഗ്ഗിംഗ്"</string> <string name="enable_adb_summary" msgid="3711526030096574316">"USB കണക്റ്റുചെയ്തിരിക്കുമ്പോഴുള്ള ഡീബഗ് മോഡ്"</string> <string name="clear_adb_keys" msgid="3010148733140369917">"USB ഡീബഗ്ഗിംഗ് അംഗീകാരം പിൻവലിക്കുക"</string> - <string name="enable_adb_wireless" msgid="6973226350963971018">"വയർലെസ് ഡീബഗ് ചെയ്യൽ"</string> + <string name="enable_adb_wireless" msgid="6973226350963971018">"വയർലെസ് ഡീബഗ്ഗിംഗ്"</string> <string name="enable_adb_wireless_summary" msgid="7344391423657093011">"വൈഫൈ കണക്റ്റ് ചെയ്തിരിക്കുമ്പോൾ ഡീബഗ് ചെയ്യൽ മോഡിലാക്കുക"</string> <string name="adb_wireless_error" msgid="721958772149779856">"പിശക്"</string> - <string name="adb_wireless_settings" msgid="2295017847215680229">"വയർലെസ് ഡീബഗ് ചെയ്യൽ"</string> - <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"ലഭ്യമായ ഉപകരണങ്ങൾ കാണാനും ഉപയോഗിക്കാനും വയർലെസ് ഡീബഗ് ചെയ്യൽ ഓണാക്കുക"</string> + <string name="adb_wireless_settings" msgid="2295017847215680229">"വയർലെസ് ഡീബഗ്ഗിംഗ്"</string> + <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"ലഭ്യമായ ഉപകരണങ്ങൾ കാണാനും ഉപയോഗിക്കാനും വയർലെസ് ഡീബഗ്ഗിംഗ് ഓണാക്കുക"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"QR കോഡ് ഉപയോഗിച്ച് ഉപകരണം ജോടിയാക്കുക"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"QR കോഡ് സ്കാനർ ഉപയോഗിച്ച് പുതിയ ഉപകരണങ്ങൾ ജോടിയാക്കുക"</string> + <!-- no translation found for adb_pair_method_qrcode_summary (7130694277228970888) --> + <skip /> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"ജോടിയാക്കൽ കോഡ് ഉപയോഗിച്ച് ഉപകരണം ജോടിയാക്കുക"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"ആറക്ക കോഡ് ഉപയോഗിച്ച് പുതിയ ഉപകരണങ്ങൾ ജോടിയാക്കുക"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"ജോടിയാക്കിയ ഉപകരണങ്ങൾ"</string> @@ -231,7 +232,8 @@ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"ഉപകരണം ജോടിയാക്കാനായില്ല. ഒന്നുകിൽ QR കോഡ് തെറ്റായിരുന്നു അല്ലെങ്കിൽ ഉപകരണം ഒരേ നെറ്റ്വർക്കിൽ അല്ല കണക്റ്റ് ചെയ്തിട്ടുള്ളത്."</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP വിലാസവും പോർട്ടും"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"QR കോഡ് സ്കാൻ ചെയ്യുക"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"QR കോഡ് സ്കാൻ ചെയ്ത് വൈഫൈയിലൂടെ ഉപകരണം ജോടിയാക്കുക"</string> + <!-- no translation found for adb_wireless_qrcode_pairing_description (6014121407143607851) --> + <skip /> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"ഒരു വൈഫൈ നെറ്റ്വർക്കിലേക്ക് കണക്റ്റ് ചെയ്യുക"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, debug, dev"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"ബഗ് റിപ്പോർട്ട് കുറുക്കുവഴി"</string> @@ -251,6 +253,8 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"വയർലെസ് ഡിസ്പ്ലേ സർട്ടിഫിക്കേഷൻ"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"വൈഫൈ വെർബോസ് ലോഗിംഗ് പ്രവർത്തനക്ഷമമാക്കുക"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"വൈഫൈ സ്കാൻ പ്രവർത്തനരഹിതമാക്കുന്നു"</string> + <!-- no translation found for wifi_enhanced_mac_randomization (5437378364995776979) --> + <skip /> <string name="mobile_data_always_on" msgid="8275958101875563572">"മൊബൈൽ ഡാറ്റ എല്ലായ്പ്പോഴും സജീവം"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"ടെതറിംഗ് ഹാർഡ്വെയർ ത്വരിതപ്പെടുത്തൽ"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"പേരില്ലാത്ത Bluetooth ഉപകരണങ്ങൾ കാണിക്കുക"</string> @@ -283,7 +287,9 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"വയർലെസ് ഡിസ്പ്ലേ സർട്ടിഫിക്കേഷനായി ഓപ്ഷനുകൾ ദൃശ്യമാക്കുക"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"വൈഫൈ പിക്കറിൽ ഓരോ SSID RSSI പ്രകാരം കാണിക്കാൻ വൈഫൈ ലോഗിംഗ് നില വർദ്ധിപ്പിക്കുക"</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"ബാറ്ററി ചാർജ് വേഗത്തിൽ തീരുന്ന അവസ്ഥ കുറച്ച് നെറ്റ്വർക്ക് പ്രകടനം മെച്ചപ്പെടുത്തുന്നു"</string> - <string name="wifi_metered_label" msgid="8737187690304098638">"മീറ്റർചെയ്ത"</string> + <!-- no translation found for wifi_enhanced_mac_randomization_summary (7925425746373704991) --> + <skip /> + <string name="wifi_metered_label" msgid="8737187690304098638">"മീറ്റർ ചെയ്തത്"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"മീറ്റർമാപകമല്ലാത്തത്"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"ലോഗർ ബഫർ വലുപ്പം"</string> <string name="select_logd_size_dialog_title" msgid="2105401994681013578">"ഓരോ ലോഗ് ബഫറിനും വലുപ്പം തിരഞ്ഞെടുക്കൂ"</string> @@ -300,8 +306,8 @@ <string name="tethering_hardware_offload_summary" msgid="7801345335142803029">"ലഭ്യമാണെങ്കിൽ \'ടെതറിംഗ് ഹാർഡ്വെയർ ത്വരിതപ്പെടുത്തൽ\' ഉപയോഗിക്കുക"</string> <string name="adb_warning_title" msgid="7708653449506485728">"USB ഡീബഗ്ഗുചെയ്യാൻ അനുവദിക്കണോ?"</string> <string name="adb_warning_message" msgid="8145270656419669221">"USB ഡീബഗ്ഗിംഗ് വികസന ആവശ്യകതകൾക്ക് മാത്രമുള്ളതാണ്. നിങ്ങളുടെ കമ്പ്യൂട്ടറിനും ഉപകരണത്തിനുമിടയിൽ ഡാറ്റ പകർത്തുന്നതിനും അറിയിപ്പില്ലാതെ തന്നെ നിങ്ങളുടെ ഉപകരണത്തിൽ അപ്ലിക്കേഷനുകൾ ഇൻസ്റ്റാളുചെയ്യുന്നതിനും ലോഗ് ഡാറ്റ റീഡുചെയ്യുന്നതിനും ഇത് ഉപയോഗിക്കുക."</string> - <string name="adbwifi_warning_title" msgid="727104571653031865">"വയർലെസ് ഡീബഗ് ചെയ്യൽ അനുവദിക്കണോ?"</string> - <string name="adbwifi_warning_message" msgid="8005936574322702388">"വയർലെസ് ഡീബഗ് ചെയ്യൽ ഡെവലപ്മെന്റ് ആവശ്യങ്ങൾക്ക് മാത്രമുള്ളതാണ്. നിങ്ങളുടെ കമ്പ്യൂട്ടറിൽ നിന്ന് ഉപകരണത്തിലേക്കും തിരിച്ചും ഡാറ്റ പകർത്തുന്നതിനും ലോഗ് ഡാറ്റ റീഡ് ചെയ്യുന്നതിനും അറിയിപ്പില്ലാതെ നിങ്ങളുടെ ഉപകരണത്തിൽ ആപ്പുകൾ ഇൻസ്റ്റാൾ ചെയ്യുന്നതിനും ഇത് ഉപയോഗിക്കുക."</string> + <string name="adbwifi_warning_title" msgid="727104571653031865">"വയർലെസ് ഡീബഗ്ഗിംഗ് അനുവദിക്കണോ?"</string> + <string name="adbwifi_warning_message" msgid="8005936574322702388">"വയർലെസ് ഡീബഗ്ഗിംഗ് ഡെവലപ്മെന്റ് ആവശ്യങ്ങൾക്ക് മാത്രമുള്ളതാണ്. നിങ്ങളുടെ കമ്പ്യൂട്ടറിൽ നിന്ന് ഉപകരണത്തിലേക്കും തിരിച്ചും ഡാറ്റ പകർത്തുന്നതിനും അറിയിപ്പില്ലാതെ തന്നെ നിങ്ങളുടെ ഉപകരണത്തിൽ ആപ്പുകൾ ഇൻസ്റ്റാൾ ചെയ്യുന്നതിനും ലോഗ് ഡാറ്റ റീഡ് ചെയ്യുന്നതിനും ഇത് ഉപയോഗിക്കുക."</string> <string name="adb_keys_warning_message" msgid="2968555274488101220">"നിങ്ങൾ മുമ്പ് അംഗീകരിച്ച എല്ലാ കമ്പ്യൂട്ടറുകളിൽ നിന്നും USB ഡീബഗ്ഗുചെയ്യുന്നതിനുള്ള ആക്സസ്സ് പിൻവലിക്കണോ?"</string> <string name="dev_settings_warning_title" msgid="8251234890169074553">"വികസന ക്രമീകരണങ്ങൾ അനുവദിക്കണോ?"</string> <string name="dev_settings_warning_message" msgid="37741686486073668">"ഈ ക്രമീകരണങ്ങൾ വികസന ഉപയോഗത്തിന് മാത്രമായുള്ളതാണ്. അവ നിങ്ങളുടെ ഉപകരണവും അതിലെ അപ്ലിക്കേഷനുകളും തകരാറിലാക്കുന്നതിനോ തെറ്റായി പ്രവർത്തിക്കുന്നതിനോ ഇടയാക്കാം."</string> @@ -371,6 +377,10 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"പശ്ചാത്തല ആപ്പുകൾക്കായി \'ആപ്പ് പ്രതികരിക്കുന്നില്ല\' ഡയലോഗ് പ്രദര്ശിപ്പിക്കുക"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"ചാനൽ മുന്നറിയിപ്പ് കാണിക്കൂ"</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"സാധുതയുള്ള ചാനലിൽ അല്ലാതെ ഒരു ആപ്പ്, അറിയിപ്പ് പോസ്റ്റ് ചെയ്യുമ്പോൾ ഓൺ-സ്ക്രീൻ മുന്നറിയിപ്പ് പ്രദർശിപ്പിക്കുന്നു"</string> + <!-- no translation found for enforce_shortcuts_for_conversations (7040735163945040763) --> + <skip /> + <!-- no translation found for enforce_shortcuts_for_conversations_summary (1860168037282467862) --> + <skip /> <string name="force_allow_on_external" msgid="9187902444231637880">"ബാഹ്യമായതിൽ നിർബന്ധിച്ച് അനുവദിക്കുക"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"മാനിഫെസ്റ്റ് മൂല്യങ്ങൾ പരിഗണിക്കാതെ, ബാഹ്യ സ്റ്റോറേജിലേക്ക് എഴുതപ്പെടുന്നതിന് ഏതൊരു ആപ്പിനെയും യോഗ്യമാക്കുന്നു"</string> <string name="force_resizable_activities" msgid="7143612144399959606">"വലുപ്പം മാറ്റാൻ പ്രവർത്തനങ്ങളെ നിർബന്ധിക്കുക"</string> diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml index d3e41f727409..69e4c710356a 100644 --- a/packages/SettingsLib/res/values-mn/strings.xml +++ b/packages/SettingsLib/res/values-mn/strings.xml @@ -206,13 +206,13 @@ <string name="enable_adb" msgid="8072776357237289039">"USB дебаг"</string> <string name="enable_adb_summary" msgid="3711526030096574316">"USB холбодсон үеийн согог засах горим"</string> <string name="clear_adb_keys" msgid="3010148733140369917">"USB дебагын зөвшөөрлийг хураах"</string> - <string name="enable_adb_wireless" msgid="6973226350963971018">"Утасгүй алдаа засах"</string> + <string name="enable_adb_wireless" msgid="6973226350963971018">"Wireless debugging"</string> <string name="enable_adb_wireless_summary" msgid="7344391423657093011">"Wi-Fi холбогдсон үед дебаг хийх горим"</string> <string name="adb_wireless_error" msgid="721958772149779856">"Алдаа"</string> - <string name="adb_wireless_settings" msgid="2295017847215680229">"Утасгүй алдаа засах"</string> - <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Боломжтой төхөөрөмжүүдийг харах болох ашиглахын тулд утасгүй алдаа засахыг асаана уу"</string> + <string name="adb_wireless_settings" msgid="2295017847215680229">"Wireless debugging"</string> + <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Боломжтой төхөөрөмжүүдийг харах болох ашиглахын тулд wireless debugging-г асаана уу"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"Хурдан хариу үйлдлийн кодоор төхөөрөмжийг хослуул"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"Хурдан хариу үйлдлийн кодын сканнерыг ашиглан шинэ төхөөрөмжүүдийг хослуулна уу"</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"Хурдан хариу үйлдлийн кодын сканнер ашиглан шинэ төхөөрөмжүүдийг хослуулна уу"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"Хослуулах кодоор төхөөрөмжийг хослуулна уу"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"Зургаан оронтой кодыг ашиглан шинэ төхөөрөмжүүдийг хослуулна уу"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"Хослуулсан төхөөрөмжүүд"</string> @@ -231,7 +231,7 @@ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"Төхөөрөмжийг хослуулж чадсангүй. Хурдан хариу үйлдлийн код буруу эсвэл төхөөрөмжийг ижил сүлжээнд холбоогүй байна."</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP хаяг ба порт"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"Хурдан хариу үйлдлийн кодыг скан хийх"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"Хурдан хариу үйлдлийн кодыг скан хийж Wi-Fi-р төхөөрөмжийг хослуулна уу"</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Хурдан хариу үйлдлийн кодыг скан хийж Wi-Fi-р төхөөрөмжийг хослуулна уу"</string> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Wi-Fi сүлжээнд холбогдоно уу"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, дебаг хийх, dev"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"Алдаа мэдээлэх товчлол"</string> @@ -251,6 +251,8 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"Утасгүй дэлгэцийн сертификат"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"Wi‑Fi дэлгэрэнгүй лог-г идэвхжүүлэх"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"Wi‑Fi скан бууруулалт"</string> + <!-- no translation found for wifi_enhanced_mac_randomization (5437378364995776979) --> + <skip /> <string name="mobile_data_always_on" msgid="8275958101875563572">"Мобайл дата байнга идэвхтэй"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"Модем болгох техник хангамжийн хурдасгуур"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"Нэргүй Bluetooth төхөөрөмжийг харуулах"</string> @@ -283,6 +285,8 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"Утасгүй дэлгэцийн сертификатын сонголтыг харуулах"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Wi‑Fi лог-н түвшинг нэмэгдүүлэх, Wi‑Fi Сонгогч дээрх SSID-д ногдох RSSI-г харуулах"</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"Батарей зарцуулалтыг бууруулж, сүлжээний гүйцэтгэлийг сайжруулдаг"</string> + <!-- no translation found for wifi_enhanced_mac_randomization_summary (7925425746373704991) --> + <skip /> <string name="wifi_metered_label" msgid="8737187690304098638">"Хязгаартай"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"Хязгааргүй"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"Логгерын буферын хэмжээ"</string> @@ -300,8 +304,8 @@ <string name="tethering_hardware_offload_summary" msgid="7801345335142803029">"Модем болгох техник хангамжийн хурдасгуурыг боломжтой тохиолдолд ашиглах"</string> <string name="adb_warning_title" msgid="7708653449506485728">"USB дебаг хийхийг зөвшөөрөх үү?"</string> <string name="adb_warning_message" msgid="8145270656419669221">"USB дебаг нь зөвхөн хөгжүүлэлтийн зорилготой. Үүнийг өөрийн компьютер болон төхөөрөмжийн хооронд өгөгдөл хуулах, өөрийн төхөөрөмж дээр мэдэгдэлгүйгээр аппликейшн суулгах, лог датаг унших зэрэгт ашиглаж болно."</string> - <string name="adbwifi_warning_title" msgid="727104571653031865">"Утасгүй алдаа засахыг зөвшөөрөх үү?"</string> - <string name="adbwifi_warning_message" msgid="8005936574322702388">"Утасгүй алдаа засах нь зөвхөн хөгжүүлэлтийн зориулалттай. Үүнийг компьютер болон төхөөрөмж хооронд өгөгдөл хуулах, төхөөрөмждөө мэдэгдэлгүйгээр аппууд суулгах болон лог өгөгдлийг унших зэрэгт ашиглана уу."</string> + <string name="adbwifi_warning_title" msgid="727104571653031865">"Wireless debugging-г зөвшөөрөх үү?"</string> + <string name="adbwifi_warning_message" msgid="8005936574322702388">"Wireless debugging нь зөвхөн хөгжүүлэлтийн зориулалттай. Үүнийг компьютер болон төхөөрөмж хооронд өгөгдөл хуулах, төхөөрөмждөө мэдэгдэлгүйгээр аппууд суулгах болон лог өгөгдлийг унших зэрэгт ашиглана уу."</string> <string name="adb_keys_warning_message" msgid="2968555274488101220">"Таны өмнө нь зөвшөөрөл өгсөн бүх компьютерээс USB дебаг хандалтыг нь хураах уу?"</string> <string name="dev_settings_warning_title" msgid="8251234890169074553">"Хөгжлийн тохиргоог зөвшөөрөх үү?"</string> <string name="dev_settings_warning_message" msgid="37741686486073668">"Эдгээр тохиргоо нь зөвхөн хөгжүүлэлтэд ашиглах зорилготой. Эдгээр нь таны төхөөрөмж буюу түүн дээрх аппликейшнүүдийг эвдрэх, буруу ажиллах шалтгаан нь болж болно."</string> @@ -371,6 +375,8 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"Апп хариу өгөхгүй байна гэсэн харилцах цонхыг цаана байгаа аппад харуулах"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"Мэдэгдлийн сувгийн анхааруулгыг харуулах"</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"Апп хүчинтэй суваггүйгээр мэдэгдэл гаргах үед дэлгэцэд сануулга харуулна"</string> + <string name="enforce_shortcuts_for_conversations" msgid="7040735163945040763">"Харилцан ярианы мэдэгдлийн товчлолыг хэрэгжүүлэх"</string> + <string name="enforce_shortcuts_for_conversations_summary" msgid="1860168037282467862">"Харилцан ярианы хэсэгт харуулахын тулд санах ойд хадгалсан хуваалцах товчлолоор мэдэгдлийг нөөцлөхийг шаардах"</string> <string name="force_allow_on_external" msgid="9187902444231637880">"Аппыг гадаад санах ойд хадгалахыг зөвшөөрөх"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Манифест утгыг нь үл хамааран дурын апп-г гадаад санах ойд бичих боломжтой болгодог"</string> <string name="force_resizable_activities" msgid="7143612144399959606">"Үйл ажиллагааны хэмжээг өөрчилж болохуйц болгох"</string> diff --git a/packages/SettingsLib/res/values-mr/strings.xml b/packages/SettingsLib/res/values-mr/strings.xml index c222bd353890..749f6ee5cf41 100644 --- a/packages/SettingsLib/res/values-mr/strings.xml +++ b/packages/SettingsLib/res/values-mr/strings.xml @@ -212,7 +212,7 @@ <string name="adb_wireless_settings" msgid="2295017847215680229">"वायरलेस डीबगिंग"</string> <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"उपलब्ध डिव्हाइस पाहण्यासाठी आणि वापरण्यासाठी वायरलेस डीबगिंग सुरू करा"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"QR कोडसह डिव्हाइस जोडा"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"QR कोड स्कॅनर वापरून नवीन डिव्हाइस जोडा"</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"QR कोड स्कॅनर वापरून नवीन डिव्हाइस पेअर करा"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"पेअरींग कोडसह डिव्हाइस जोडा"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"सहा अंकी कोड वापरून नवीन डिव्हाइस जोडा"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"पेअर केलेले डिव्हाइस"</string> @@ -231,7 +231,7 @@ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"डिव्हाइस पेअर करता आले नाही. QR कोड चुकीचा होता किंवा डिव्हाइस समान नेटवर्कशी कनेक्ट केलेले नाही."</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"आयपी अॅड्रेस आणि पोर्ट"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"QR कोड स्कॅन करा"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"QR कोड स्कॅन करून वाय-फाय वापरून डिव्हाइस पेअर करा"</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"QR कोड स्कॅन करून वाय-फाय वरून डिव्हाइस पेअर करा"</string> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"कृपया एका वाय-फाय नेटवर्कशी कनेक्ट करा"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"ADB, डीबग, डेव्हलपर"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"बग रिपोर्ट शॉर्टकट"</string> @@ -251,6 +251,8 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"वायरलेस डिस्प्ले प्रमाणीकरण"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"वाय-फाय व्हर्बोझ लॉगिंग सुरू करा"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"वाय-फाय स्कॅन थ्रॉटलिंग"</string> + <!-- no translation found for wifi_enhanced_mac_randomization (5437378364995776979) --> + <skip /> <string name="mobile_data_always_on" msgid="8275958101875563572">"मोबाइल डेटा नेहमी सक्रिय"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"टेदरिंग हार्डवेअर प्रवेग"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"नावांशिवाय ब्लूटूथ डिव्हाइस दाखवा"</string> @@ -283,6 +285,8 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"वायरलेस डिस्प्ले प्रमाणिकरणाचे पर्याय दाखवा"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"वाय-फाय लॉगिंग स्तर वाढवा, वाय-फाय सिलेक्टरमध्ये प्रति SSID RSSI दर्शवा"</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"बॅटरी जलदरीतीने संपण्यापासून रोखते आणि नेटवर्क परफॉर्मन्समध्ये सुधारणा करते"</string> + <!-- no translation found for wifi_enhanced_mac_randomization_summary (7925425746373704991) --> + <skip /> <string name="wifi_metered_label" msgid="8737187690304098638">"मीटरने मोजलेले"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"मीटरने न मोजलेले"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"लॉगर बफर आकार"</string> @@ -301,7 +305,7 @@ <string name="adb_warning_title" msgid="7708653449506485728">"USB डीबग करण्यास अनुमती द्यायची?"</string> <string name="adb_warning_message" msgid="8145270656419669221">"USB डीबग करण्याचा हेतू फक्त विकास उद्देशांसाठी आहे. याचा वापर तुमचा कॉंप्युटर आणि तुमचे डिव्हाइस यांच्या दरम्यान डेटा कॉपी करण्यासाठी करा, सूचनेशिवाय तुमच्या डिव्हाइस वर अॅप्स इंस्टॉल करा आणि लॉग डेटा वाचा."</string> <string name="adbwifi_warning_title" msgid="727104571653031865">"वायरलेस डीबगिंग करण्याची अनुमती द्यायची आहे का?"</string> - <string name="adbwifi_warning_message" msgid="8005936574322702388">"वायरलेस डीबग करण्याचा हेतू फक्त विकास उद्देशांसाठी आहे. याचा वापर तुमचा कॉंप्युटर आणि तुमचे डिव्हाइस यांच्या दरम्यान डेटा कॉपी करण्यासाठी करा, सूचनेशिवाय तुमच्या डिव्हाइसवर अॅप्स इंस्टॉल करा आणि लॉग डेटा वाचा."</string> + <string name="adbwifi_warning_message" msgid="8005936574322702388">"वायरलेस डीबगिंग करण्याचा हेतू फक्त विकास उद्देशांसाठी आहे. याचा वापर तुमचा कॉंप्युटर आणि तुमचे डिव्हाइस यांच्या दरम्यान डेटा कॉपी करण्यासाठी करा, सूचनेशिवाय तुमच्या डिव्हाइसवर अॅप्स इंस्टॉल करा आणि लॉग डेटा वाचा."</string> <string name="adb_keys_warning_message" msgid="2968555274488101220">"तुम्ही पूर्वी ऑथोराइझ केलेल्या सर्व संगणकांवरुन USB डीबग करण्यासाठी अॅक्सेस रीव्होक करायचा?"</string> <string name="dev_settings_warning_title" msgid="8251234890169074553">"विकास सेटिंग्जला अनुमती द्यायची?"</string> <string name="dev_settings_warning_message" msgid="37741686486073668">"या सेटिंग्जचा हेतू फक्त विकास वापरासाठी आहे. त्यामुळे तुमचे डिव्हाइस आणि त्यावरील ॲप्लिकेशन ब्रेक होऊ शकतात किंवा नेहमीपेक्षा वेगळे वर्तन करू शकतात."</string> @@ -371,6 +375,8 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"बॅकग्राउंड अॅप्ससाठी अॅप प्रतिसाद देत नाही दाखवते"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"सूचना चॅनेल चेतावण्या दाखवा"</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"एखादे अॅप वैध चॅनेलशिवाय सूचना पोस्ट करते तेव्हा स्क्रीनवर चेतावणी देते"</string> + <string name="enforce_shortcuts_for_conversations" msgid="7040735163945040763">"संभाषण सूचना शॉर्टकट ठेवा"</string> + <string name="enforce_shortcuts_for_conversations_summary" msgid="1860168037282467862">"सूचनांना जुन्या शॉर्टकटचा सपोर्ट आवश्यक"</string> <string name="force_allow_on_external" msgid="9187902444231637880">"बाह्यवर ॲप्सना अनुमती देण्याची सक्ती करा"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"manifest मूल्यांकडे दुर्लक्ष करून, कोणत्याही ॲपला बाह्य स्टोरेजवर लेखन केले जाण्यासाठी पात्र बनविते"</string> <string name="force_resizable_activities" msgid="7143612144399959606">"ॲक्टिव्हिटीचा आकार बदलण्यायोग्य होण्याची सक्ती करा"</string> diff --git a/packages/SettingsLib/res/values-ms/strings.xml b/packages/SettingsLib/res/values-ms/strings.xml index 1dc3dc4fbdb2..09a558db495f 100644 --- a/packages/SettingsLib/res/values-ms/strings.xml +++ b/packages/SettingsLib/res/values-ms/strings.xml @@ -155,7 +155,7 @@ <string name="launch_defaults_some" msgid="3631650616557252926">"Beberapa lalai ditetapkan"</string> <string name="launch_defaults_none" msgid="8049374306261262709">"Tiada lalai ditetapkan"</string> <string name="tts_settings" msgid="8130616705989351312">"Tetapan teks kepada pertuturan"</string> - <string name="tts_settings_title" msgid="7602210956640483039">"Output teks ke pertuturan"</string> + <string name="tts_settings_title" msgid="7602210956640483039">"Output teks kepada pertuturan"</string> <string name="tts_default_rate_title" msgid="3964187817364304022">"Kadar pertuturan"</string> <string name="tts_default_rate_summary" msgid="3781937042151716987">"Kelajuan pertuturan teks"</string> <string name="tts_default_pitch_title" msgid="6988592215554485479">"Pic"</string> @@ -212,7 +212,7 @@ <string name="adb_wireless_settings" msgid="2295017847215680229">"Penyahpepijatan wayarles"</string> <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Untuk melihat dan menggunakan peranti yang tersedia, hidupkan penyahpepijatan wayarles"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"Gandingkan peranti dengan kod QR"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"Gandingkan peranti baharu menggunakan Pengimbas kod QR"</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"Gandingkan peranti baharu menggunakan pengimbas kod QR"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"Gandingkan peranti dengan kod gandingan"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"Gandingkan peranti baharu menggunakan kod enam digit"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"Peranti gandingan"</string> @@ -231,7 +231,7 @@ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"Gagal menggandingkan peranti. Kod QR salah atau peranti tidak disambungkan kepada rangkaian yang sama."</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"Alamat IP & Port"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"Imbas kod QR"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"Gandingkan peranti melalui Wi-Fi dengan mengimbas Kod QR"</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Gandingkan peranti melalui Wi-Fi dengan mengimbas kod QR"</string> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Sila sambungkan kepada rangkaian Wi-Fi"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, debug, dev"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"Pintasan laporan pepijat"</string> @@ -251,6 +251,7 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"Pensijilan paparan wayarles"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"Dayakan Pengelogan Berjela-jela Wi-Fi"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"Pendikitan pengimbasan Wi-Fi"</string> + <string name="wifi_enhanced_mac_randomization" msgid="5437378364995776979">"Perawakan MAC dipertingkat Wi‑Fi"</string> <string name="mobile_data_always_on" msgid="8275958101875563572">"Data mudah alih sentiasa aktif"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"Pecutan perkakasan penambatan"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"Tunjukkan peranti Bluetooth tanpa nama"</string> @@ -283,6 +284,7 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"Tunjukkan pilihan untuk pensijilan paparan wayarles"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Tingkatkan tahap pengelogan Wi-Fi, tunjuk setiap SSID RSSI dalam Pemilih Wi-Fi"</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"Mengurangkan penyusutan bateri & meningkatkan prestasi rangkaian"</string> + <string name="wifi_enhanced_mac_randomization_summary" msgid="7925425746373704991">"Togol ini melibatkan gelagat perawakan MAC untuk mod pelanggan sahaja.\nApabila mod ini diaktifkan, alamat MAC bagi mana-mana rangkaian yang telah mendayakan perawakan MAC mungkin dirawakkan semula semasa perkaitan, bergantung pada kali terakhir pelanggan diputuskan sambungan daripada rangkaian. Perawakan semula tidak berlaku jika peranti menyambung semula dalam tempoh 4 jam atau kurang."</string> <string name="wifi_metered_label" msgid="8737187690304098638">"Bermeter"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"Tidak bermeter"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"Saiz penimbal pengelog"</string> @@ -371,6 +373,8 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"Paparkan dialog Apl Tiada Respons untuk apl latar belakang"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"Papar amaran saluran pemberitahuan"</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"Memaparkan amaran pada skrin apabila apl menyiarkan pemberitahuan tanpa saluran sah"</string> + <string name="enforce_shortcuts_for_conversations" msgid="7040735163945040763">"Kuat kuasakan pintasan utk pemberitahuan perbualan"</string> + <string name="enforce_shortcuts_for_conversations_summary" msgid="1860168037282467862">"Perlukan pemberitahuan disokong oleh pintasan perkongsian hayat panjang untuk muncul dalam bahagian perbualan"</string> <string name="force_allow_on_external" msgid="9187902444231637880">"Benarkan apl secara paksa pada storan luaran"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Menjadikan sebarang apl layak ditulis ke storan luaran, tanpa mengambil kira nilai manifes"</string> <string name="force_resizable_activities" msgid="7143612144399959606">"Paksa aktiviti supaya boleh diubah saiz"</string> diff --git a/packages/SettingsLib/res/values-my/strings.xml b/packages/SettingsLib/res/values-my/strings.xml index e6ebaf9afb13..b525a0a146c4 100644 --- a/packages/SettingsLib/res/values-my/strings.xml +++ b/packages/SettingsLib/res/values-my/strings.xml @@ -116,7 +116,7 @@ <string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"ချိတ်တွဲရန်"</string> <string name="bluetooth_pairing_decline" msgid="6483118841204885890">"မလုပ်တော့"</string> <string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"ချိတ်တွဲမှုက ချိတ်ဆက်ထားလျှင် သင်၏ အဆက်အသွယ်များ နှင့် ခေါ်ဆိုမှု မှတ်တမ်းကို ရယူခွင့် ပြုသည်။"</string> - <string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>နှင့် တွဲချိတ်မရပါ"</string> + <string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> နှင့် တွဲချိတ်မရပါ"</string> <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"ပင်နံပါတ် သို့မဟုတ် ဖြတ်သန်းခွင့်ကီးမမှန်ကန်သောကြောင့်<xliff:g id="DEVICE_NAME">%1$s</xliff:g>နှင့် တွဲချိတ်မရပါ။"</string> <string name="bluetooth_pairing_device_down_error_message" msgid="2554424863101358857">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>နှင့်ဆက်သွယ်မရပါ"</string> <string name="bluetooth_pairing_rejected_error_message" msgid="5943444352777314442">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>နှင့်တွဲချိတ်ရန် ပယ်ချခံရသည်"</string> @@ -212,12 +212,12 @@ <string name="adb_wireless_settings" msgid="2295017847215680229">"ကြိုးမဲ့ အမှားရှာပြင်ခြင်း"</string> <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"ရနိုင်သည့် စက်ပစ္စည်းများကို ကြည့်ပြီး အသုံးပြုနိုင်ရန် ကြိုးမဲ့ အမှားရှာပြင်ခြင်းကို ဖွင့်ပါ"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"QR ကုဒ်ဖြင့် စက်ပစ္စည်းကို အတူတွဲပါ"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"QR ကုဒ်ဖတ်စက် သုံး၍ စက်ပစ္စည်းသစ်များကို အတူတွဲပါ"</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"QR ကုဒ် စကင်ဖတ်စက် သုံး၍ စက်အသစ်များကို အတူတွဲနိုင်သည်"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"တွဲချိတ်ကုဒ်ဖြင့် စက်ပစ္စည်းကို အတူတွဲပါ"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"ဂဏန်းခြောက်လုံးကုဒ်ဖြင့် စက်ပစ္စည်းသစ်များကို အတူတွဲပါ"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"တွဲချိတ်ပြီး စက်ပစ္စည်းများ"</string> <string name="adb_wireless_device_connected_summary" msgid="3039660790249148713">"လက်ရှိ ချိတ်ဆက်ထားသည်"</string> - <string name="adb_wireless_device_details_title" msgid="7129369670526565786">"စက်ပစ္စည်း အသေးစိတ်"</string> + <string name="adb_wireless_device_details_title" msgid="7129369670526565786">"စက်အသေးစိတ်များ"</string> <string name="adb_device_forget" msgid="193072400783068417">"မေ့ပစ်ရန်"</string> <string name="adb_device_fingerprint_title_format" msgid="291504822917843701">"စက်ပစ္စည်း လက်ဗွေ- <xliff:g id="FINGERPRINT_PARAM">%1$s</xliff:g>"</string> <string name="adb_wireless_connection_failed_title" msgid="664211177427438438">"ချိတ်ဆက်ခြင်း မအောင်မြင်ပါ"</string> @@ -231,7 +231,7 @@ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"စက်ပစ္စည်းကို အတူတွဲ၍မရပါ။ QR ကုဒ်မမှန်ပါ သို့မဟုတ် စက်ပစ္စည်းသည် ကွန်ရက်တစ်ခုတည်းသို့ ချိတ်ဆက်မထားပါ။"</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"အိုင်ပီ (IP) လိပ်စာနှင့် ပို့တ်"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"QR ကုဒ်ကို စကင်ဖတ်ပါ"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"QR ကုဒ် စကင်ဖတ်ခြင်းဖြင့် Wi-Fi ပေါ်တွင် စက်ပစ္စည်းကို အတူတွဲပါ"</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"QR ကုဒ် စကင်ဖတ်ခြင်းဖြင့် Wi-Fi ပေါ်တွင် စက်ကို အတူတွဲနိုင်သည်"</string> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Wi-Fi ကွန်ရက်သို့ ချိတ်ဆက်ပါ"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, debug, dev"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"ချွတ်ယွင်းမှု အစီရင်ခံရန် ဖြတ်လမ်း"</string> @@ -251,6 +251,7 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"ကြိုးမဲ့ပြသမှု အသိအမှတ်ပြုလက်မှတ်"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"Wi‑Fi Verbose မှတ်တမ်းတင်ခြင်းအား ဖွင့်မည်"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"Wi‑Fi ရှာဖွေခြင်း ထိန်းချုပ်မှု"</string> + <string name="wifi_enhanced_mac_randomization" msgid="5437378364995776979">"Wi‑Fi တိုးမြှင့် MAC ကျပန်းပြုလုပ်ခြင်း"</string> <string name="mobile_data_always_on" msgid="8275958101875563572">"မိုဘိုင်းဒေတာကို အမြဲဖွင့်ထားရန်"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"ဖုန်းကို မိုဒမ်အဖြစ်အသုံးပြုမှု စက်ပစ္စည်းဖြင့် အရှိန်မြှင့်တင်ခြင်း"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"အမည်မရှိသော ဘလူးတုသ်စက်ပစ္စည်းများကို ပြသရန်"</string> @@ -283,6 +284,7 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"ကြိုးမဲ့ အခင်းအကျင်း အသိအမှတ်ပြုလက်မှတ်အတွက် ရွေးချယ်စရာများပြရန်"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Wi‑Fi မှတ်တမ်းတင်ခြင်း နှုန်းအားမြင့်ကာ၊ Wi‑Fi ရွေးရာတွင် SSID RSSI ဖြင့်ပြပါ"</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"ဘက်ထရီ အသုံးပြုမှုကို လျှော့ကျစေပြီး ကွန်ရက်စွမ်းဆောင်ရည်ကို ပိုမိုကောင်းမွန်စေသည်"</string> + <string name="wifi_enhanced_mac_randomization_summary" msgid="7925425746373704991">"ဤဖွင့်ပိတ်ခလုတ်က ကလိုင်းယင့်မုဒ် အတွက်သာ MAC ကျပန်းပြုလုပ်ခြင်း အပြုအမူကို သက်ရောက်စေသည်။\nဤမုဒ်အသုံးပြုသည့်အခါ MAC ကျပန်းပြုလုပ်ခြင်း ဖွင့်ထားသော ကွန်ရက်များသည် ကွန်ရက်မှ ကလိုင်းယင့် ချိတ်ဆက်မှုဖြုတ်သည့် နောက်ဆုံးအချိန်ပေါ် မူတည်၍ ချိတ်ဆက်နေစဉ်အတွင်း ၎င်းတို့၏ MAC လိပ်စာများကို ပြန်လည်ကျပန်းပြုလုပ်နိုင်သည်။ စက်သည် ၄ နာရီအတွင်း ပြန်ချိန်ဆက်ထားပါက ပြန်လည်ကျပန်းပြုလုပ်မည် မဟုတ်ပါ။"</string> <string name="wifi_metered_label" msgid="8737187690304098638">"အခမဲ့ မဟုတ်ပါ"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"အခမဲ့"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"မှတ်တမ်းကြားခံနယ် အရွယ်အစားများ"</string> @@ -371,6 +373,8 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"နောက်ခံ အက်ပ်များအတွက် \'အက်ပ်တုံ့ပြန်မှုမရှိ\' ဟု ပြရန်"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"ချန်နယ်သတိပေးချက်များပြပါ"</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"ချန်နယ်မရှိဘဲ အကြောင်းကြားလျှင် စကရင်တွင်သတိပေးသည်"</string> + <string name="enforce_shortcuts_for_conversations" msgid="7040735163945040763">"ဖြတ်လမ်းလင့်ခ် သုံးရန်"</string> + <string name="enforce_shortcuts_for_conversations_summary" msgid="1860168037282467862">"အချိန်ကြာမျှဝေသော ဖြတ်လမ်းလင့်ခ် သုံးရန် လိုအပ်သည်"</string> <string name="force_allow_on_external" msgid="9187902444231637880">"ပြင်ပစက်တွင် အက်ပ်များခွင့်ပြုရန်"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"တိကျစွာ သတ်မှတ်ထားသည့်တန်ဖိုးများရှိသော်လည်း၊ ပြင်ပသိုလှောင်ခန်းများသို့ မည်သည့်အက်ပ်ကိုမဆို ဝင်ရောက်ခွင့်ပြုပါ"</string> <string name="force_resizable_activities" msgid="7143612144399959606">"လုပ်ဆောင်ချက်များ အရွယ်ပြောင်းနိုင်ခြင်း"</string> @@ -464,7 +468,7 @@ <item msgid="7529124349186240216">"၁၀၀%"</item> </string-array> <string name="charge_length_format" msgid="6941645744588690932">"ပြီးခဲ့သည့် <xliff:g id="ID_1">%1$s</xliff:g> က"</string> - <string name="remaining_length_format" msgid="4310625772926171089">"<xliff:g id="ID_1">%1$s</xliff:g> ကျန်ပါသည်"</string> + <string name="remaining_length_format" msgid="4310625772926171089">"<xliff:g id="ID_1">%1$s</xliff:g> ကျန်"</string> <string name="screen_zoom_summary_small" msgid="6050633151263074260">"သေး"</string> <string name="screen_zoom_summary_default" msgid="1888865694033865408">"မူရင်း"</string> <string name="screen_zoom_summary_large" msgid="4706951482598978984">"ကြီး"</string> diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml index 58213a7cef04..cc883ab1e63d 100644 --- a/packages/SettingsLib/res/values-nb/strings.xml +++ b/packages/SettingsLib/res/values-nb/strings.xml @@ -112,7 +112,7 @@ <string name="bluetooth_opp_profile_summary_use_for" msgid="461981154387015457">"Bruk til filoverføring"</string> <string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"Bruk for inndata"</string> <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="7689393730163320483">"Bruk for høreapparater"</string> - <string name="bluetooth_pairing_accept" msgid="2054232610815498004">"Sammenkoble"</string> + <string name="bluetooth_pairing_accept" msgid="2054232610815498004">"Koble til"</string> <string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"KOBLE TIL"</string> <string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Avbryt"</string> <string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"Med sammenkobling får den andre enheten tilgang til kontaktene og anropsloggen din når den er tilkoblet."</string> @@ -212,7 +212,7 @@ <string name="adb_wireless_settings" msgid="2295017847215680229">"Trådløs feilsøking"</string> <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"For å se og bruke tilgjengelige enheter, slå på trådløs feilsøking"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"Koble til enheten med en QR-kode"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"Koble til nye enheter med en QR-kodeskanner"</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"Koble til nye enheter med en QR-kodeskanner"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"Koble til enheten med en tilkoblingskode"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"Koble til nye enheter med en sekssifret kode"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"Tilkoblede enheter"</string> @@ -231,7 +231,7 @@ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"Kunne ikke koble til enheten. Enten var QR-koden feil, eller enheten er ikke koblet til samme nettverk."</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP-adresse og port"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"Skann QR-koden"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"Koble til enheten via Wi-Fi ved å skanne en QR-kode"</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Koble til enheten via Wi-Fi ved å skanne en QR-kode"</string> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Koble til et Wi-Fi-nettverk"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, feilsøking, utvikler"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"Snarvei til feilrapport"</string> @@ -251,6 +251,7 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"Trådløs skjermsertifisering"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"Slå på detaljert Wi-Fi-loggføring"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"Begrensning av Wi‑Fi-skanning"</string> + <string name="wifi_enhanced_mac_randomization" msgid="5437378364995776979">"Wi‑Fi‑forbedret MAC-tilfeldiggjøring"</string> <string name="mobile_data_always_on" msgid="8275958101875563572">"Mobildata er alltid aktiv"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"Maskinvareakselerasjon for internettdeling"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"Vis Bluetooth-enheter uten navn"</string> @@ -283,6 +284,7 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"Vis alternativer for sertifisering av trådløs skjerm"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Øk Wi-Fi-loggenivå – vis per SSID RSSI i Wi-Fi-velgeren"</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"Reduserer batteriforbruket og forbedrer nettverksytelsen"</string> + <string name="wifi_enhanced_mac_randomization_summary" msgid="7925425746373704991">"Denne av/på-bryteren påvirker bare atferden til MAC-tilfeldiggjøring for klientmodus.\nNår denne modusen er aktivert, kan nettverk som har tilfeldig valgt MAC, få MAC-adressen tilfeldig valgt på nytt under tilknytning, avhengig av når klienten sist ble koblet fra nettverket. Ny tilfeldiggjøring oppstår ikke hvis enheten kobler seg til igjen innen fire timer."</string> <string name="wifi_metered_label" msgid="8737187690304098638">"Med datamåling"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"Uten datamåling"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"Bufferstørrelser for logg"</string> @@ -371,6 +373,8 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"Vis Appen svarer ikke-dialog for bakgrunnsapper"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"Vis varselskanaladvarsler"</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"Viser advarsler på skjermen når apper publiserer varsler uten en gyldig kanal"</string> + <string name="enforce_shortcuts_for_conversations" msgid="7040735163945040763">"Håndhev snarveier for samtalevarsler"</string> + <string name="enforce_shortcuts_for_conversations_summary" msgid="1860168037282467862">"Krev at varsler støttes av en langvarig delingssnarvei for å vises i samtaledelen"</string> <string name="force_allow_on_external" msgid="9187902444231637880">"Tving frem tillatelse for ekstern lagring av apper"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Dette gjør at alle apper kan lagres på eksterne lagringsmedier – uavhengig av manifestverdier"</string> <string name="force_resizable_activities" msgid="7143612144399959606">"Tving aktiviteter til å kunne endre størrelse"</string> diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml index cc26483b791b..eaac303d86c8 100644 --- a/packages/SettingsLib/res/values-ne/strings.xml +++ b/packages/SettingsLib/res/values-ne/strings.xml @@ -206,13 +206,13 @@ <string name="enable_adb" msgid="8072776357237289039">"USB डिबग गर्दै"</string> <string name="enable_adb_summary" msgid="3711526030096574316">"USB जडित हुँदा डिबग मोड"</string> <string name="clear_adb_keys" msgid="3010148733140369917">"USB डिबग गर्ने प्राधिकरणहरू उल्टाउनुहोस्"</string> - <string name="enable_adb_wireless" msgid="6973226350963971018">"वायरलेस डिबग गर्ने प्रक्रिया"</string> + <string name="enable_adb_wireless" msgid="6973226350963971018">"वायरलेस डिबगिङ"</string> <string name="enable_adb_wireless_summary" msgid="7344391423657093011">"Wi‑Fi मा जोडिँदा डिबग मोड सक्षम पार्ने कि नपार्ने"</string> <string name="adb_wireless_error" msgid="721958772149779856">"त्रुटि"</string> - <string name="adb_wireless_settings" msgid="2295017847215680229">"वायरलेस डिबग गर्ने प्रक्रिया"</string> - <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"उपलब्ध यन्त्रहरू हेर्न र प्रयोग गर्न वायरलेस डिबग गर्ने प्रक्रिया सक्रिय गर्नुहोस्"</string> + <string name="adb_wireless_settings" msgid="2295017847215680229">"वायरलेस डिबगिङ"</string> + <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"उपलब्ध यन्त्रहरू हेर्न र प्रयोग गर्न वायरलेस डिबगिङ सेवा सक्रिय गर्नुहोस्"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"QR कोडमार्फत यन्त्रको जोडा बनाउनुहोस्"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"QR कोड स्क्यानर प्रयोग गरी नयाँ यन्त्रहरूको जोडा बनाउनुहोस्"</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"QR कोड स्क्यानर प्रयोग गरी नयाँ यन्त्रहरूको जोडा बनाउनुहोस्"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"जोडा मिलाउने कोडमार्फत यन्त्रको जोडा बनाउनुहोस्"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"छ अङ्कको कोड प्रयोग गरी नयाँ यन्त्रहरूको जोडा बनाउनुहोस्"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"जोडा बनाइएका यन्त्रहरू"</string> @@ -231,7 +231,7 @@ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"यन्त्रसँग जोडा बनाउन सकिएन। कि त QR कोड गलत छ कि यन्त्र उही नेटवर्कमा जोडिएको छैन।"</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP ठेगाना र पोर्ट"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"QR कोड स्क्यान गर्नुहोस्"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"QR कोड स्क्यान गरेर Wi‑Fi प्रयोग गरी यन्त्रको जोडा बनाउनुहोस्"</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"QR कोड स्क्यान गरी Wi‑Fi मार्फत यन्त्रको जोडा बनाउनुहोस्"</string> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"कृपया कुनै Wi-Fi मा कनेक्ट गर्नुहोस्"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, debug, dev"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"बग प्रतिवेदन सर्टकट"</string> @@ -251,6 +251,8 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"ताररहित प्रदर्शन प्रमाणीकरण"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"Wi-Fi वर्बोज लग सक्षम पार्नुहोस्"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"Wi‑Fi स्क्यान थ्रोटलिङ"</string> + <!-- no translation found for wifi_enhanced_mac_randomization (5437378364995776979) --> + <skip /> <string name="mobile_data_always_on" msgid="8275958101875563572">"मोबाइल डेटा सधैँ सक्रिय राख्नुहोस्"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"टेदरिङको लागि हार्डवेयरको प्रवेग"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"नामकरण नगरिएका ब्लुटुथ यन्त्रहरू देखाउनुहोस्"</string> @@ -283,6 +285,8 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"ताररहित प्रदर्शन प्रमाणीकरणका लागि विकल्पहरू देखाउनुहोस्"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Wi-Fi लग स्तर बढाउनुहोस्, Wi-Fi चयनकर्तामा प्रति SSID RSSI देखाइन्छ"</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"ब्याट्रीको खपत कम गरी नेटवर्कको कार्यसम्पादनमा सुधार गर्दछ"</string> + <!-- no translation found for wifi_enhanced_mac_randomization_summary (7925425746373704991) --> + <skip /> <string name="wifi_metered_label" msgid="8737187690304098638">"सशुल्क वाइफाइ"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"मिटर नगरिएको"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"लगर बफर आकारहरू"</string> @@ -300,8 +304,8 @@ <string name="tethering_hardware_offload_summary" msgid="7801345335142803029">"उपलब्ध भएमा टेदरिङको लागि हार्डवेयरको प्रवेग प्रयोग गर्नुहोस्"</string> <string name="adb_warning_title" msgid="7708653449506485728">"USB डिबग गर्न लागि अनुमति दिने हो?"</string> <string name="adb_warning_message" msgid="8145270656419669221">"युएसबी डिबगिङ विकास प्रयोजनका लागि मात्र निर्मित हुन्छ। यसलाई तपाईँको कम्प्युटर र तपाईँको उपकरणका बीच डेटा प्रतिलिपि गर्न, बिना सूचना तपाईँको उपकरणमा अनुप्रयोगहरू स्थापना गर्न र लग डेटा पढ्नका लागि प्रयोग गर्नुहोस्।"</string> - <string name="adbwifi_warning_title" msgid="727104571653031865">"वायरलेस डिबग गर्ने प्रक्रिया सक्षम पार्ने हो?"</string> - <string name="adbwifi_warning_message" msgid="8005936574322702388">"वायरलेस डिबग गर्ने प्रक्रिया विकास प्रयोजनका लागि मात्रै हो। यसलाई आफ्ना कम्प्युटर र उपकरणका बिच डेटा प्रतिलिपि गर्न, सूचना नदिई आफ्नो उपकरणमा अनुप्रयोगहरू स्थापना गर्न र लगसम्बन्धी डेटा रिड गर्नका लागि प्रयोग गर्नुहोस्।"</string> + <string name="adbwifi_warning_title" msgid="727104571653031865">"वायरलेस डिबगिङ सेवा सक्षम पार्ने हो?"</string> + <string name="adbwifi_warning_message" msgid="8005936574322702388">"वायरलेस डिबगिङ डिभलपमेन्ट प्रयोजनका लागि मात्रै हो। यसलाई आफ्ना कम्प्युटर र उपकरणका बिच डेटा प्रतिलिपि गर्न, सूचना नदिई आफ्नो उपकरणमा अनुप्रयोगहरू स्थापना गर्न र लग डेटा पढ्न प्रयोग गर्नुहोस्।"</string> <string name="adb_keys_warning_message" msgid="2968555274488101220">"तपाईं पहिले नै अधिकृत गर्नुभएका सबै कम्प्यूटरबाट USB डिबग गर्नको लागि पहुँच रद्द गर्ने हो?"</string> <string name="dev_settings_warning_title" msgid="8251234890169074553">"विकास सेटिङहरू अनुमति दिने हो?"</string> <string name="dev_settings_warning_message" msgid="37741686486073668">"यी सेटिङहरू केवल विकास प्रयोगको लागि विचार गरिएको हो। तिनीहरूले तपाईंको उपकरण र अनुप्रयोगहरूलाई विच्छेदन गर्न वा दुर्व्यवहार गर्न सक्दछ।"</string> @@ -371,6 +375,8 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"पृष्ठभूमिका अनुप्रयोगहरूको संवादको प्रतिक्रिया नदिइरहेका अनुप्रयोगहरू प्रदर्शन गर्नुहोस्"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"सूचना च्यानलका चेतावनी देखाउनुहोस्"</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"अनुप्रयोगले कुनै मान्य च्यानल बिना सूचना पोस्ट गर्दा स्क्रिनमा चेतावनी देखाउँछ"</string> + <string name="enforce_shortcuts_for_conversations" msgid="7040735163945040763">"कुराकानी नामक स्थानमा मान्य सर्टकटसँग पनि लिंक गरिएका सूचनाहरू मात्र देखाइयोस्"</string> + <string name="enforce_shortcuts_for_conversations_summary" msgid="1860168037282467862">"कुराकानी नामक स्थानमा सूचनाहरू देखिन सकून् भन्नाका खातिर ती सूचनामा सधैँ सक्रिय रहने (long-lived) सेयरिङ सर्टकट समावेश भएको हुनु पर्छ"</string> <string name="force_allow_on_external" msgid="9187902444231637880">"बाह्यमा बल प्रयोगको अनुमति प्राप्त अनुप्रयोगहरू"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"म्यानिफेेस्टका मानहरूको ख्याल नगरी कुनै पनि अनुप्रयोगलाई बाह्य भण्डारणमा लेख्न सकिने खाले बनाउँछ"</string> <string name="force_resizable_activities" msgid="7143612144399959606">"आकार बदल्न योग्य हुने बनाउन गतिविधिहरूलाई बाध्यात्मक बनाउनुहोस्।"</string> @@ -467,9 +473,9 @@ <string name="remaining_length_format" msgid="4310625772926171089">"<xliff:g id="ID_1">%1$s</xliff:g> बाँकी"</string> <string name="screen_zoom_summary_small" msgid="6050633151263074260">"सानो"</string> <string name="screen_zoom_summary_default" msgid="1888865694033865408">"पूर्वनिर्धारित"</string> - <string name="screen_zoom_summary_large" msgid="4706951482598978984">"ठूलो"</string> - <string name="screen_zoom_summary_very_large" msgid="7317423942896999029">"अझ ठूलो"</string> - <string name="screen_zoom_summary_extremely_large" msgid="1438045624562358554">"सबैभन्दा ठूलो"</string> + <string name="screen_zoom_summary_large" msgid="4706951482598978984">"ठुलो"</string> + <string name="screen_zoom_summary_very_large" msgid="7317423942896999029">"अझ ठुलो"</string> + <string name="screen_zoom_summary_extremely_large" msgid="1438045624562358554">"सबैभन्दा ठुलो"</string> <string name="screen_zoom_summary_custom" msgid="3468154096832912210">"आफू अनुकूल (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string> <string name="content_description_menu_button" msgid="6254844309171779931">"मेनु"</string> <string name="retail_demo_reset_message" msgid="5392824901108195463">"डेमो मोडमा फ्याक्ट्री रिसेट गर्न पासवर्ड प्रविष्टि गर्नुहोस्"</string> diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml index 57fc87aa8d6f..c566dc23d2b0 100644 --- a/packages/SettingsLib/res/values-nl/strings.xml +++ b/packages/SettingsLib/res/values-nl/strings.xml @@ -212,7 +212,7 @@ <string name="adb_wireless_settings" msgid="2295017847215680229">"Draadloze foutopsporing"</string> <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Schakel draadloze foutopsporing in om beschikbare apparaten te bekijken en te gebruiken"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"Apparaat koppelen met QR-code"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"Nieuwe apparaten koppelen via QR-codescanner"</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"Nieuwe apparaten koppelen via QR-codescanner"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"Apparaat koppelen met koppelingscode"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"Nieuwe apparaten koppelen via een zescijferige code"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"Gekoppelde apparaten"</string> @@ -231,7 +231,7 @@ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"Kan het apparaat niet koppelen. De QR-code was onjuist of het apparaat is niet verbonden met hetzelfde netwerk."</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP-adres en poort"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"QR-code scannen"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"Apparaat koppelen via wifi door een QR-code te scannen"</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Apparaat koppelen via wifi door een QR-code te scannen"</string> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Maak verbinding met een wifi-netwerk"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, foutopsporing, ontwikkeling"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"Snelle link naar bugrapport"</string> @@ -251,6 +251,7 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"Certificering van draadloze weergave"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"Uitgebreide wifi-logregistratie insch."</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"Wifi-scannen beperken"</string> + <string name="wifi_enhanced_mac_randomization" msgid="5437378364995776979">"Via wifi ondersteunde MAC-herschikking"</string> <string name="mobile_data_always_on" msgid="8275958101875563572">"Mobiele data altijd actief"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"Hardwareversnelling voor tethering"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"Bluetooth-apparaten zonder namen weergeven"</string> @@ -283,6 +284,7 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"Opties weergeven voor certificering van draadloze weergave"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Logniveau voor wifi verhogen, weergeven per SSID RSSI in wifi-kiezer"</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"Verlaagt het batterijverbruik en verbetert de netwerkprestaties"</string> + <string name="wifi_enhanced_mac_randomization_summary" msgid="7925425746373704991">"Deze schakelaar beïnvloedt het gedrag van MAC-herschikking uitsluitend voor de clientmodus.\nAls deze modus is ingeschakeld, worden de MAC-adressen van netwerken die MAC-herschikking hebben ingeschakeld, mogelijk opnieuw in willekeurige volgorde herschikt als verbinding wordt gemaakt. Dit is afhankelijk van wanneer de client voor het laatst de verbinding met het netwerk verbrak. Opnieuw herschikken gebeurt niet als het apparaat binnen vier uur opnieuw verbinding maakt."</string> <string name="wifi_metered_label" msgid="8737187690304098638">"Met datalimiet"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"Gratis"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"Logger-buffergrootten"</string> @@ -371,6 +373,8 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"Dialoogvenster \'App reageert niet\' weergeven voor achtergrond-apps"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"Kanaalwaarschuwingen voor meldingen weergeven"</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"Geeft een waarschuwing op het scherm weer wanneer een app een melding post zonder geldig kanaal"</string> + <string name="enforce_shortcuts_for_conversations" msgid="7040735163945040763">"Snelkoppelingen voor gespreksmeldingen afdwingen"</string> + <string name="enforce_shortcuts_for_conversations_summary" msgid="1860168037282467862">"Vereisen dat meldingen een langdurige snelkoppeling voor delen krijgen om bij gesprekken te kunnen worden getoond"</string> <string name="force_allow_on_external" msgid="9187902444231637880">"Toestaan van apps op externe opslag afdwingen"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Hiermee komt elke app in aanmerking voor schrijven naar externe opslag, ongeacht de manifestwaarden"</string> <string name="force_resizable_activities" msgid="7143612144399959606">"Formaat activiteiten geforceerd aanpasbaar maken"</string> diff --git a/packages/SettingsLib/res/values-or/strings.xml b/packages/SettingsLib/res/values-or/strings.xml index 3a7f2c5acaa6..f14d67f262a7 100644 --- a/packages/SettingsLib/res/values-or/strings.xml +++ b/packages/SettingsLib/res/values-or/strings.xml @@ -86,7 +86,7 @@ <string name="bluetooth_profile_opp" msgid="6692618568149493430">"ଫାଇଲ୍ ଟ୍ରାନ୍ସଫର୍"</string> <string name="bluetooth_profile_hid" msgid="2969922922664315866">"ଇନ୍ପୁଟ୍ ଡିଭାଇସ୍"</string> <string name="bluetooth_profile_pan" msgid="1006235139308318188">"ଇଣ୍ଟର୍ନେଟ୍ ଆକ୍ସେସ୍"</string> - <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"ଯୋଗାଯୋଗ ସେୟାରିଙ୍ଗ୍"</string> + <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"ଯୋଗାଯୋଗ ସେୟାରିଂ"</string> <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"ଯୋଗାଯୋଗ ସେୟାର୍ କରିବା ପାଇଁ ବ୍ୟବହାର କରନ୍ତୁ"</string> <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"ଇଣ୍ଟର୍ନେଟ୍ ସଂଯୋଗ ଶେୟାରିଙ୍ଗ"</string> <string name="bluetooth_profile_map" msgid="8907204701162107271">"ଟେକ୍ସଟ୍ ମେସେଜ୍"</string> @@ -126,7 +126,7 @@ <string name="bluetooth_talkback_imaging" msgid="8781682986822514331">"ଇମେଜିଙ୍ଗ"</string> <string name="bluetooth_talkback_headphone" msgid="8613073829180337091">"ହେଡ୍ଫୋନ୍"</string> <string name="bluetooth_talkback_input_peripheral" msgid="5133944817800149942">"ଇନ୍ପୁଟ୍ ଉପକରଣ"</string> - <string name="bluetooth_talkback_bluetooth" msgid="1143241359781999989">"ବ୍ଲୁଟୂଥ୍"</string> + <string name="bluetooth_talkback_bluetooth" msgid="1143241359781999989">"ବ୍ଲୁଟୁଥ"</string> <string name="bluetooth_hearingaid_left_pairing_message" msgid="8561855779703533591">"ବାମ ଶ୍ରବଣ ଯନ୍ତ୍ର ପେୟାର୍ କରାଯାଉଛି…"</string> <string name="bluetooth_hearingaid_right_pairing_message" msgid="2655347721696331048">"ଡାହାଣ ଶ୍ରବଣ ଯନ୍ତ୍ର ପେୟାର୍ କରାଯାଉଛି…"</string> <string name="bluetooth_hearingaid_left_battery_level" msgid="7375621694748104876">"ବାମ - <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> ବ୍ୟାଟେରୀ"</string> @@ -143,10 +143,10 @@ <string name="data_usage_uninstalled_apps" msgid="1933665711856171491">"କଢ଼ାଯାଇଥିବା ଆପ୍ଗୁଡ଼ିକ"</string> <string name="data_usage_uninstalled_apps_users" msgid="5533981546921913295">"ଆପ୍ ଏବଂ ଉପଯୋଗକର୍ତ୍ତା ବାହାର କରାଗଲା"</string> <string name="data_usage_ota" msgid="7984667793701597001">"ସିଷ୍ଟମ୍ ଅପ୍ଡେଟ୍"</string> - <string name="tether_settings_title_usb" msgid="3728686573430917722">"USB ଟିଥରିଙ୍ଗ"</string> + <string name="tether_settings_title_usb" msgid="3728686573430917722">"USB ଟିଥରିଂ"</string> <string name="tether_settings_title_wifi" msgid="4803402057533895526">"ପୋର୍ଟବଲ୍ ହଟସ୍ପଟ୍"</string> - <string name="tether_settings_title_bluetooth" msgid="916519902721399656">"ବ୍ଲୁଟୂଥ ଟିଥରିଙ୍ଗ"</string> - <string name="tether_settings_title_usb_bluetooth" msgid="1727111807207577322">"ଟିଥର୍ କରୁଛି"</string> + <string name="tether_settings_title_bluetooth" msgid="916519902721399656">"ବ୍ଲୁଟୁଥ ଟିଥରିଂ"</string> + <string name="tether_settings_title_usb_bluetooth" msgid="1727111807207577322">"ଟିଥରିଂ"</string> <string name="tether_settings_title_all" msgid="8910259483383010470">"ଟିଥରିଙ୍ଗ ଓ ପୋର୍ଟବଲ୍ ହଟ୍ସ୍ପଟ୍"</string> <string name="managed_user_title" msgid="449081789742645723">"ସମସ୍ତ କାର୍ଯ୍ୟ ଆପ୍"</string> <string name="user_guest" msgid="6939192779649870792">"ଅତିଥି"</string> @@ -206,13 +206,14 @@ <string name="enable_adb" msgid="8072776357237289039">"USB ଡିବଗ୍ ହେଉଛି"</string> <string name="enable_adb_summary" msgid="3711526030096574316">"USB ସଂଯୁକ୍ତ ହେବାବେଳେ ଡିବଗ୍ ମୋଡ୍"</string> <string name="clear_adb_keys" msgid="3010148733140369917">"USB ଡିବଗିଙ୍ଗ ଅଧିକାରକୁ କାଢ଼ିଦିଅନ୍ତୁ"</string> - <string name="enable_adb_wireless" msgid="6973226350963971018">"ୱେୟାରଲେସ୍ ଡିବଗିଂ"</string> + <string name="enable_adb_wireless" msgid="6973226350963971018">"ୱାୟାରଲେସ୍ ଡିବଗିଂ"</string> <string name="enable_adb_wireless_summary" msgid="7344391423657093011">"ୱାଇ-ଫାଇ ସଂଯୁକ୍ତ ଥିବା ବେଳେ ଡିବଗ୍ ମୋଡ୍"</string> <string name="adb_wireless_error" msgid="721958772149779856">"ତ୍ରୁଟି"</string> - <string name="adb_wireless_settings" msgid="2295017847215680229">"ୱେୟାରଲେସ୍ ଡିବଗିଂ"</string> - <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"ଉପଲବ୍ଧ ଡିଭାଇସଗୁଡ଼ିକୁ ଦେଖିବାକୁ ଏବଂ ବ୍ୟବହାର କରିବାକୁ ୱେୟାରଲେସ୍ ଡିବଗିଂ ଚାଲୁ କରନ୍ତୁ"</string> + <string name="adb_wireless_settings" msgid="2295017847215680229">"ୱାୟାରଲେସ୍ ଡିବଗିଂ"</string> + <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"ଉପଲବ୍ଧ ଡିଭାଇସଗୁଡ଼ିକୁ ଦେଖିବାକୁ ଏବଂ ବ୍ୟବହାର କରିବାକୁ ୱାୟାରଲେସ୍ ଡିବଗିଂ ଚାଲୁ କରନ୍ତୁ"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"QR କୋଡରେ ଡିଭାଇସକୁ ପେୟାର୍ କରନ୍ତୁ"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"QR କୋଡ୍ ସ୍କାନର୍ ବ୍ୟବହାର କରି ନୂଆ ଡିଭାଇସଗୁଡ଼ିକୁ ପେୟାର୍ କରନ୍ତୁ"</string> + <!-- no translation found for adb_pair_method_qrcode_summary (7130694277228970888) --> + <skip /> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"ପେୟାରିଂ କୋଡରେ ଡିଭାଇସକୁ ପେୟାର୍ କରନ୍ତୁ"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"ଛଅ ଡିଜିଟ୍ କୋଡ୍ ବ୍ୟବହାର କରି ନୂଆ ଡିଭାଇସଗୁଡ଼ିକୁ ପେୟାର୍ କରନ୍ତୁ"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"ପେୟାର୍ ହୋଇଥିବା ଡିଭାଇସଗୁଡ଼ିକ"</string> @@ -231,7 +232,8 @@ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"ଡିଭାଇସରୁ ପେୟାର୍ ହେବାରେ ବିଫଳ ହୋଇଛି। QR କୋଡ୍ ସଠିକ୍ ନଥିଲା ବା ଡିଭାଇସ୍ ସମାନ ନେଟୱାର୍କରେ ସଂଯୋଗ ହୋଇନାହିଁ।"</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP ଠିକଣା ଓ ପୋର୍ଟ"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"QR କୋଡ୍ ସ୍କାନ୍ କରନ୍ତୁ"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"ଏକ QR କୋଡ୍ ସ୍କାନ୍ କରି ୱାଇ-ଫାଇରେ ଡିଭାଇସ୍ ପେୟାର୍ କରନ୍ତୁ"</string> + <!-- no translation found for adb_wireless_qrcode_pairing_description (6014121407143607851) --> + <skip /> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"ଦୟାକରି ଏକ ୱାଇ-ଫାଇ ନେଟୱାର୍କରେ ସଂଯୋଗ କରନ୍ତୁ"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, ଡିବଗ୍, dev"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"ବଗ୍ ରିପୋର୍ଟ ସର୍ଟକଟ୍"</string> @@ -251,6 +253,8 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"ୱାୟରଲେସ୍ ଡିସ୍ପ୍ଲେ ସାର୍ଟିଫିକେସନ୍"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"ୱାଇ-ଫାଇ ଭର୍ବୋସ୍ ଲଗିଙ୍ଗ ସକ୍ଷମ କରନ୍ତୁ"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"ୱାଇ-ଫାଇ ସ୍କାନ୍ ନିୟନ୍ତ୍ରଣ"</string> + <!-- no translation found for wifi_enhanced_mac_randomization (5437378364995776979) --> + <skip /> <string name="mobile_data_always_on" msgid="8275958101875563572">"ମୋବାଇଲ୍ ଡାଟା ସର୍ବଦା ସକ୍ରିୟ"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"ଟିଥରିଙ୍ଗ ହାର୍ଡୱେର ଆକ୍ସିଲିରେସନ୍"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"ବ୍ଲୁଟୂଥ୍ ଡିଭାଇସ୍ଗୁଡ଼ିକୁ ନାମ ବିନା ଦେଖନ୍ତୁ"</string> @@ -283,6 +287,8 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"ୱେୟାରଲେସ୍ ଡିସ୍ପ୍ଲେ ସାର୍ଟିଫିକେସନ୍ ପାଇଁ ବିକଳ୍ପ ଦେଖାନ୍ତୁ"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"ୱାଇ-ଫାଇ ଲଗିଙ୍ଗ ସ୍ତର ବଢ଼ାନ୍ତୁ, ୱାଇ-ଫାଇ ପିକର୍ରେ ପ୍ରତି SSID RSSI ଦେଖାନ୍ତୁ"</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"ବ୍ୟାଟେରୀ ଖର୍ଚ୍ଚ କମ୍ ଏବଂ ନେଟ୍ୱାର୍କ କାର୍ଯ୍ୟକ୍ଷମତା ଉନ୍ନତ କରିଥାଏ"</string> + <!-- no translation found for wifi_enhanced_mac_randomization_summary (7925425746373704991) --> + <skip /> <string name="wifi_metered_label" msgid="8737187690304098638">"ମପାଯାଉଥିବା"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"ମପାଯାଉନଥିବା"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"ଲଗର୍ ବଫର୍ ସାଇଜ୍"</string> @@ -300,8 +306,8 @@ <string name="tethering_hardware_offload_summary" msgid="7801345335142803029">"ଯଦି ଉପଲବ୍ଧ ଥାଏ, ଟିଥରିଙ୍ଗ ହାର୍ଡୱେର୍ ଆକ୍ସିଲିରେସନ୍ ବ୍ୟବହାର କରନ୍ତୁ"</string> <string name="adb_warning_title" msgid="7708653449506485728">"USB ଡିବଗିଙ୍ଗ କରିବେ?"</string> <string name="adb_warning_message" msgid="8145270656419669221">"USB ଡିବଗିଂ କେବଳ ଡେଭଲପମେଣ୍ଟ ଉଦ୍ଦେଶ୍ୟ ପାଇଁ ଉଦ୍ଦିଷ୍ଟ ଅଟେ। ଆପଣଙ୍କ କମ୍ପ୍ୟୁଟର ଏବଂ ଡିଭାଇସ୍ ମଧ୍ୟରେ ଡାଟା କପି କରିବାକୁ, ବିନା ବିଜ୍ଞପ୍ତିରେ ଆପଣଙ୍କ ଡିଭାଇସରେ ଆପସ୍ ସଂସ୍ଥାପନ କରିବାକୁ, ଏବଂ ଲଗ୍ ଡାଟା ପଢିବାକୁ ଏହା ବ୍ୟବହାର କରନ୍ତୁ।"</string> - <string name="adbwifi_warning_title" msgid="727104571653031865">"ୱେୟାରଲେସ୍ ଡିବଗିଂ ପାଇଁ ଅନୁମତି ଦେବେ?"</string> - <string name="adbwifi_warning_message" msgid="8005936574322702388">"ୱେୟାରଲେସ୍ ଡିବଗିଂ କେବଳ ଉନ୍ନତି ଉଦ୍ଦେଶ୍ୟ ପାଇଁ ଉଦ୍ଦିଷ୍ଟ ଅଟେ। ଆପଣଙ୍କ କମ୍ପ୍ୟୁଟର ଏବଂ ଡିଭାଇସ୍ ମଧ୍ୟରେ ଡାଟା କପି କରିବାକୁ, ବିନା ବିଜ୍ଞପ୍ତିରେ ଆପଣଙ୍କ ଡିଭାଇସରେ ଆପ୍ସ ଇନଷ୍ଟଲ୍ କରିବାକୁ ଏବଂ ଲଗ୍ ଡାଟା ପଢ଼ିବା ପାଇଁ ଏହାକୁ ବ୍ୟବହାର କରନ୍ତୁ।"</string> + <string name="adbwifi_warning_title" msgid="727104571653031865">"ୱାୟାରଲେସ୍ ଡିବଗିଂ ପାଇଁ ଅନୁମତି ଦେବେ?"</string> + <string name="adbwifi_warning_message" msgid="8005936574322702388">"ୱାୟାରଲେସ୍ ଡିବଗିଂ କେବଳ ଉନ୍ନତି ପାଇଁ ଉଦ୍ଦିଷ୍ଟ ଅଟେ। ଆପଣଙ୍କ କମ୍ପ୍ୟୁଟର ଏବଂ ଡିଭାଇସ୍ ମଧ୍ୟରେ ଡାଟା କପି କରିବାକୁ, ବିନା ବିଜ୍ଞପ୍ତିରେ ଆପଣଙ୍କ ଡିଭାଇସରେ ଆପ୍ସ ଇନଷ୍ଟଲ୍ କରିବାକୁ ଏବଂ ଲଗ୍ ଡାଟା ପଢ଼ିବା ପାଇଁ ଏହାକୁ ବ୍ୟବହାର କରନ୍ତୁ।"</string> <string name="adb_keys_warning_message" msgid="2968555274488101220">"ଅଧିକୃତ ସମସ୍ତ କମ୍ପ୍ୟୁଟରରୁ USB ଡିବଗ୍ କରିବା ଆକ୍ସେସ୍ ପ୍ରତ୍ୟାହାର କରିବେ କି?"</string> <string name="dev_settings_warning_title" msgid="8251234890169074553">"ଡେଭଲପମେଣ୍ଟ ସେଟିଙ୍ଗ ଅନୁମତି ଦେବେ?"</string> <string name="dev_settings_warning_message" msgid="37741686486073668">"ଏହି ସେଟିଙ୍ଗଗୁଡ଼ିକ କେବଳ ବିକାଶ ବ୍ୟବହାର ପାଇଁ ଉଦ୍ଦିଷ୍ଟ। ସେଗୁଡ଼ିକ କାରଣରୁ ଆପଣଙ୍କ ଡିଭାଇସ୍ ଓ ଆପ୍ଲିକେଶନ୍ଗୁଡ଼ିକ ଠିକ୍ ଭାବେ କାମ ନକରିପାରେ।"</string> @@ -371,6 +377,10 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"ବ୍ୟାକ୍ଗ୍ରାଉଣ୍ଡ ଆପ୍ଗୁଡ଼ିକ ପାଇଁ \"ଆପ୍ ଉତ୍ତର ଦେଉନାହିଁ\" ଡାୟଲଗ୍ ଦେଖାନ୍ତୁ"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"ବିଜ୍ଞପ୍ତି ଚେନାଲ୍ ଚେତାବନୀ ଦେଖାନ୍ତୁ"</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"ବୈଧ ଚ୍ୟାନେଲ୍ ବିନା ଗୋଟିଏ ଆପ୍ ଏକ ବିଜ୍ଞପ୍ତି ପୋଷ୍ଟ କରିବାବେଳେ ଅନ୍-ସ୍କ୍ରୀନ୍ ସତର୍କତା ଦେଖାଏ"</string> + <!-- no translation found for enforce_shortcuts_for_conversations (7040735163945040763) --> + <skip /> + <!-- no translation found for enforce_shortcuts_for_conversations_summary (1860168037282467862) --> + <skip /> <string name="force_allow_on_external" msgid="9187902444231637880">"ଆପ୍କୁ ଏକ୍ସଟର୍ନଲ୍ ମେମୋରୀରେ ଫୋର୍ସ୍ ଅନୁମତି ଦିଅନ୍ତୁ"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"ଯେକୌଣସି ଆପ୍କୁ ଏକ୍ସଟର୍ନଲ୍ ଷ୍ଟୋରେଜ୍ରେ ଲେଖାଯୋଗ୍ୟ କରନ୍ତୁ, ମେନିଫେଷ୍ଟ ମୂଲ୍ୟ ଯାହା ହୋଇଥାଉ ନା କାହିଁକି"</string> <string name="force_resizable_activities" msgid="7143612144399959606">"ୱିଣ୍ଡୋ ହିସାବରେ କାର୍ଯ୍ୟକଳାପର ଆକାର ବଦଳାନ୍ତୁ"</string> diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml index 980225710156..83046c48ad69 100644 --- a/packages/SettingsLib/res/values-pa/strings.xml +++ b/packages/SettingsLib/res/values-pa/strings.xml @@ -112,8 +112,8 @@ <string name="bluetooth_opp_profile_summary_use_for" msgid="461981154387015457">"ਫਾਈਲ ਟ੍ਰਾਂਸਫਰ ਲਈ ਵਰਤੋ"</string> <string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"ਇਨਪੁਟ ਲਈ ਵਰਤੋ"</string> <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="7689393730163320483">"ਸੁਣਨ ਦੇ ਸਾਧਨਾਂ ਲਈ ਵਰਤੋ"</string> - <string name="bluetooth_pairing_accept" msgid="2054232610815498004">"ਪੇਅਰ ਕਰੋ"</string> - <string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"ਪੇਅਰ ਕਰੋ"</string> + <string name="bluetooth_pairing_accept" msgid="2054232610815498004">"ਜੋੜਾਬੱਧ ਕਰੋ"</string> + <string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"ਜੋੜਾਬੱਧ ਕਰੋ"</string> <string name="bluetooth_pairing_decline" msgid="6483118841204885890">"ਰੱਦ ਕਰੋ"</string> <string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"ਜੋੜਾਬੱਧ ਕਰਨਾ ਕਨੈਕਟ ਕੀਤੇ ਜਾਣ ਤੇ ਤੁਹਾਡੇ ਸੰਪਰਕਾਂ ਅਤੇ ਕਾਲ ਇਤਿਹਾਸ ਤੱਕ ਪਹੁੰਚ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string> <string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> ਨਾਲ ਪੇਅਰ ਨਹੀਂ ਕਰ ਸਕਿਆ।"</string> @@ -195,7 +195,7 @@ </string-array> <string name="choose_profile" msgid="343803890897657450">"ਪ੍ਰੋਫਾਈਲ ਚੁਣੋ"</string> <string name="category_personal" msgid="6236798763159385225">"ਨਿੱਜੀ"</string> - <string name="category_work" msgid="4014193632325996115">"ਦਫ਼ਤਰ"</string> + <string name="category_work" msgid="4014193632325996115">"ਕਾਰਜ-ਸਥਾਨ"</string> <string name="development_settings_title" msgid="140296922921597393">"ਵਿਕਾਸਕਾਰ ਵਿਕਲਪ"</string> <string name="development_settings_enable" msgid="4285094651288242183">"ਵਿਕਾਸਕਾਰ ਵਿਕਲਪਾਂ ਨੂੰ ਚਾਲੂ ਕਰੋ"</string> <string name="development_settings_summary" msgid="8718917813868735095">"ਐਪ ਵਿਕਾਸ ਲਈ ਚੋਣਾਂ ਸੈੱਟ ਕਰੋ"</string> @@ -212,7 +212,7 @@ <string name="adb_wireless_settings" msgid="2295017847215680229">"ਵਾਇਰਲੈੱਸ ਡੀਬੱਗਿੰਗ"</string> <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"ਉਪਲਬਧ ਡੀਵਾਈਸਾਂ ਨੂੰ ਦੇਖਣ ਅਤੇ ਵਰਤਣ ਲਈ, ਵਾਇਰਲੈੱਸ ਡੀਬੱਗਿੰਗ ਚਾਲੂ ਕਰੋ"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"QR ਕੋਡ ਨਾਲ ਡੀਵਾਈਸ ਨੂੰ ਜੋੜਾਬੱਧ ਕਰੋ"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"QR ਕੋਡ ਸਕੈਨਰ ਵਰਤ ਕੇ ਨਵੇਂ ਡੀਵਾਈਸਾਂ ਨੂੰ ਜੋੜਾਬੱਧ ਕਰੋ"</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"QR ਕੋਡ ਸਕੈਨਰ ਵਰਤ ਕੇ ਨਵੇਂ ਡੀਵਾਈਸਾਂ ਨੂੰ ਜੋੜਾਬੱਧ ਕਰੋ"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"ਜੋੜਾਬੱਧਕਰਨ ਕੋਡ ਨਾਲ ਡੀਵਾਈਸ ਜੋੜਾਬੱਧ ਕਰੋ"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"ਛੇ ਅੰਕਾਂ ਵਾਲਾ ਕੋਡ ਵਰਤ ਕੇ ਨਵੇਂ ਡੀਵਾਈਸਾਂ ਨੂੰ ਜੋੜਾਬੱਧ ਕਰੋ"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"ਜੋੜਾਬੱਧ ਕੀਤੇ ਡੀਵਾਈਸ"</string> @@ -231,7 +231,7 @@ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"ਡੀਵਾਈਸ ਨੂੰ ਜੋੜਾਬੱਧ ਕਰਨਾ ਅਸਫਲ ਰਿਹਾ। ਜਾਂ ਤਾਂ QR ਕੋਡ ਗਲਤ ਸੀ, ਜਾਂ ਡੀਵਾਈਸ ਉਸੇ ਨੈੱਟਵਰਕ ਨਾਲ ਕਨੈਕਟ ਨਹੀਂ ਹੈ।"</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP ਪਤਾ & ਪੋਰਟ"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"QR ਕੋਡ ਸਕੈਨ ਕਰੋ"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"QR ਕੋਡ ਸਕੈਨ ਕਰਕੇ ਵਾਈ-ਫਾਈ \'ਤੇ ਡੀਵਾਈਸ ਜੋੜਾਬੱਧ ਕਰੋ"</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"QR ਕੋਡ ਸਕੈਨ ਕਰਕੇ ਵਾਈ-ਫਾਈ \'ਤੇ ਡੀਵਾਈਸ ਜੋੜਾਬੱਧ ਕਰੋ"</string> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"ਕਿਰਪਾ ਕਰਕੇ ਕਿਸੇ ਵਾਈ-ਫਾਈ ਨੈੱਟਵਰਕ ਨਾਲ ਕਨੈਕਟ ਕਰੋ"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, ਡੀਬੱਗ, dev"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"ਬੱਗ ਰਿਪੋਰਟ ਸ਼ਾਰਟਕੱਟ"</string> @@ -251,6 +251,8 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"ਵਾਇਰਲੈੱਸ ਡਿਸਪਲੇ ਪ੍ਰਮਾਣੀਕਰਨ"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"ਵਾਈ-ਫਾਈ ਵਰਬੋਸ ਲੌਗਿੰਗ ਚਾਲੂ ਕਰੋ"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"ਸੀਮਤ ਵਾਈ‑ਫਾਈ ਸਕੈਨ"</string> + <!-- no translation found for wifi_enhanced_mac_randomization (5437378364995776979) --> + <skip /> <string name="mobile_data_always_on" msgid="8275958101875563572">"ਮੋਬਾਈਲ ਡਾਟਾ ਹਮੇਸ਼ਾਂ ਕਿਰਿਆਸ਼ੀਲ"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"ਟੈਦਰਿੰਗ ਹਾਰਡਵੇਅਰ ਐਕਸੈੱਲਰੇਸ਼ਨ"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"ਅਨਾਮ ਬਲੂਟੁੱਥ ਡੀਵਾਈਸਾਂ ਦਿਖਾਓ"</string> @@ -283,6 +285,8 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"ਵਾਇਰਲੈੱਸ ਡਿਸਪਲੇ ਪ੍ਰਮਾਣੀਕਰਨ ਲਈ ਚੋਣਾਂ ਪ੍ਰਦਰਸ਼ਿਤ ਕਰੋ"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"ਵਾਈ‑ਫਾਈ ਲੌਗਿੰਗ ਪੱਧਰ ਵਧਾਓ, ਵਾਈ‑ਫਾਈ Picker ਵਿੱਚ ਪ੍ਰਤੀ SSID RSSI ਦਿਖਾਓ"</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"ਬੈਟਰੀ ਦੀ ਵਰਤੋਂ ਘਟਾ ਕੇ ਨੈੱਟਵਰਕ ਕਾਰਗੁਜ਼ਾਰੀ ਨੂੰ ਬਿਹਤਰ ਬਣਾਉਂਦਾ ਹੈ"</string> + <!-- no translation found for wifi_enhanced_mac_randomization_summary (7925425746373704991) --> + <skip /> <string name="wifi_metered_label" msgid="8737187690304098638">"ਮੀਟਰਬੱਧ ਕੀਤਾ ਗਿਆ"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"ਗੈਰ-ਮੀਟਰਬੱਧ ਕੀਤਾ ਗਿਆ"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"ਲੌਗਰ ਬਫ਼ਰ ਆਕਾਰ"</string> @@ -371,6 +375,8 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"ਬੈਕਗ੍ਰਾਊਂਡ ਐਪਾਂ ਲਈ \'ਐਪ ਪ੍ਰਤਿਕਿਰਿਆ ਨਹੀਂ ਦੇ ਰਹੀ ਹੈ\' ਵਿੰਡੋ ਦਿਖਾਓ"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"ਸੂਚਨਾ ਚੈਨਲ ਚਿਤਾਵਨੀਆਂ ਦਿਖਾਓ"</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"ਐਪ ਵੱਲੋਂ ਵੈਧ ਚੈਨਲ ਤੋਂ ਬਿਨਾਂ ਸੂਚਨਾ ਪੋਸਟ ਕਰਨ \'ਤੇ ਸਕ੍ਰੀਨ \'ਤੇ ਚਿਤਾਵਨੀ ਦਿਖਾਉਂਦੀ ਹੈ"</string> + <string name="enforce_shortcuts_for_conversations" msgid="7040735163945040763">"ਗੱਲਬਾਤ ਸੰਬੰਧੀ ਸੂਚਨਾਵਾਂ ਲਈ ਸ਼ਾਰਟਕੱਟ ਲਾਗੂ ਕਰੋ"</string> + <string name="enforce_shortcuts_for_conversations_summary" msgid="1860168037282467862">"ਗੱਲਬਾਤ ਸੈਕਸ਼ਨ ਵਿੱਚ ਦਿਸਣ ਲਈ ਚਿਰਸਥਾਈ ਸਾਂਝਾਕਰਨ ਸ਼ਾਰਟਕੱਟ ਨਾਲ ਸੂਚਨਾਵਾਂ ਦਾ ਬੈਕਅੱਪ ਲੈਣਾ ਲੋੜੀਂਦਾ ਹੈ"</string> <string name="force_allow_on_external" msgid="9187902444231637880">"ਐਪਾਂ ਨੂੰ ਜ਼ਬਰਦਸਤੀ ਬਾਹਰੀ ਸਟੋਰੇਜ \'ਤੇ ਆਗਿਆ ਦਿਓ"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"ਮੈਨੀਫੈਸਟ ਮੁੱਲਾਂ ਦੀ ਪਰਵਾਹ ਕੀਤੇ ਬਿਨਾਂ, ਕਿਸੇ ਵੀ ਐਪ ਨੂੰ ਬਾਹਰੀ ਸਟੋਰੇਜ \'ਤੇ ਲਿਖਣ ਦੇ ਯੋਗ ਬਣਾਉਂਦੀ ਹੈ"</string> <string name="force_resizable_activities" msgid="7143612144399959606">"ਮੁੜ-ਆਕਾਰ ਬਦਲਣ ਲਈ ਸਰਗਰਮੀਆਂ \'ਤੇ ਜ਼ੋਰ ਦਿਓ"</string> diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml index 734b25757bfc..114e302f4bae 100644 --- a/packages/SettingsLib/res/values-pl/strings.xml +++ b/packages/SettingsLib/res/values-pl/strings.xml @@ -212,7 +212,7 @@ <string name="adb_wireless_settings" msgid="2295017847215680229">"Debugowanie bezprzewodowe"</string> <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Aby wyświetlić dostępne urządzenia i ich używać, włącz debugowanie bezprzewodowe"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"Sparuj urządzenie przy pomocy kodu QR"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"Sparuj nowe urządzenie, skanując kod QR"</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"Sparuj nowe urządzenie, skanując kod QR"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"Sparuj urządzenie przy pomocy kodu parowania"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"Sparuj nowe urządzenie przy pomocy 6-cyfrowego kodu"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"Sparowane urządzenia"</string> @@ -231,7 +231,7 @@ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"Nie udało się sparować z urządzeniem. Kod QR jest nieprawidłowy albo urządzenie nie jest podłączone do tej samej sieci."</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"Adres IP i port"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"Zeskanuj kod QR"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"Sparuj urządzenia przez Wi-Fi, skanując kod QR"</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Sparuj urządzenia przez Wi-Fi, skanując kod QR"</string> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Połącz się z siecią Wi-Fi"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, debug, dev"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"Skrót do zgłoszenia błędu"</string> @@ -251,6 +251,7 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"Wyświetlacz bezprzewodowy"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"Szczegółowy dziennik Wi-Fi"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"Ograniczanie skanowania Wi-Fi"</string> + <string name="wifi_enhanced_mac_randomization" msgid="5437378364995776979">"Randomizacja MAC ulepszona w zakresie Wi‑Fi"</string> <string name="mobile_data_always_on" msgid="8275958101875563572">"Mobilna transmisja danych zawsze aktywna"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"Akceleracja sprzętowa tetheringu"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"Pokaż urządzenia Bluetooth bez nazw"</string> @@ -283,6 +284,7 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"Pokaż opcje certyfikacji wyświetlacza bezprzewodowego"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Zwiększ poziom rejestrowania Wi‑Fi, pokazuj według RSSI SSID w selektorze Wi‑Fi"</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"Zmniejsza zużycie baterii i zwiększa wydajność sieci"</string> + <string name="wifi_enhanced_mac_randomization_summary" msgid="7925425746373704991">"Ten przełącznik wpływa na zachowanie randomizacji MAC tylko w przypadku trybu klienta.\nKiedy ten tryb jest aktywny, adresy MAC dowolnej sieci, która ma włączoną randomizację MAC, podczas powiązywania mogą zostać poddane ponownej randomizacji, w zależności od tego, kiedy klient ostatni raz rozłączył się z siecią. Ponowna randomizacja nie zachodzi, jeśli urządzenie połączy się ponownie w ciągu 4 lub mniejszej liczby godzin."</string> <string name="wifi_metered_label" msgid="8737187690304098638">"Użycie danych jest mierzone"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"Użycie danych nie jest mierzone"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"Rozmiary bufora rejestratora"</string> @@ -371,6 +373,8 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"Wyświetlaj okno Aplikacja nie odpowiada dla aplikacji w tle"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"Pokaż ostrzeżenia kanału powiadomień"</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"Wyświetla ostrzeżenie, gdy aplikacja publikuje powiadomienie bez prawidłowego kanału"</string> + <string name="enforce_shortcuts_for_conversations" msgid="7040735163945040763">"Wymuszaj skróty do powiadomień o rozmowie"</string> + <string name="enforce_shortcuts_for_conversations_summary" msgid="1860168037282467862">"Wymagaj używania długoterminowych skrótów do udostępniania powiadomień, które pojawiałyby się w sekcji rozmowy"</string> <string name="force_allow_on_external" msgid="9187902444231637880">"Wymuś zezwalanie na aplikacje w pamięci zewnętrznej"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Pozwala na zapis aplikacji w pamięci zewnętrznej niezależnie od wartości w pliku manifestu"</string> <string name="force_resizable_activities" msgid="7143612144399959606">"Wymuś zmianę rozmiaru okien aktywności"</string> diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml index d98c9ff071bf..845433df6d96 100644 --- a/packages/SettingsLib/res/values-pt-rBR/strings.xml +++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml @@ -212,7 +212,7 @@ <string name="adb_wireless_settings" msgid="2295017847215680229">"Depuração por Wi-Fi"</string> <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Para ver e usar dispositivos disponíveis, ative a depuração por Wi-Fi"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"Parear o dispositivo com um código QR"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"Parear novos dispositivos usando um leitor de código QR"</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"Parear novos dispositivos usando um leitor de código QR"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"Parear o dispositivo com um código de pareamento"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"Parear novos dispositivos usando um código de seis dígitos"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"Dispositivos pareados"</string> @@ -231,7 +231,7 @@ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"Falha ao parear o dispositivo. O código QR está incorreto ou o dispositivo não está conectado à mesma rede."</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"Endereço IP e porta"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"Ler código QR"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"Parear dispositivo na rede Wi‑Fi fazendo a leitura do código QR"</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Parear dispositivo na rede Wi‑Fi fazendo a leitura do código QR"</string> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Conecte-se a uma rede Wi-Fi"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, debug, dev"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"Atalho para relatório de bugs"</string> @@ -251,6 +251,7 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"Certificação de Display sem fio"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"Ativar registro detalhado de Wi-Fi"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"Limitar busca por Wi-Fi"</string> + <string name="wifi_enhanced_mac_randomization" msgid="5437378364995776979">"MAC aleatório melhorado por Wi-Fi"</string> <string name="mobile_data_always_on" msgid="8275958101875563572">"Dados móveis sempre ativos"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"Aceleração de hardware de tethering"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"Mostrar dispositivos Bluetooth sem nomes"</string> @@ -283,6 +284,7 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"Mostrar opções de certificação de Display sem fio"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Aumentar o nível de registro de Wi-Fi; mostrar conforme o RSSI do SSID no seletor de Wi-Fi"</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"Reduz o consumo de bateria e melhora o desempenho da rede"</string> + <string name="wifi_enhanced_mac_randomization_summary" msgid="7925425746373704991">"Essa opção afeta o comportamento de ordem aleatória de MAC somente para o modo cliente.\nQuando esse modo é ativado, todas as redes que tiverem a ordem aleatória de MAC ativada poderão ter a ordem aleatória refeita durante a associação, dependendo de quando o cliente se desconectou da rede pela última vez. A ordem aleatória não será refeita se o dispositivo se reconectar em até quatro horas."</string> <string name="wifi_metered_label" msgid="8737187690304098638">"Limitada"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"Ilimitada"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"Tamanhos de buffer de logger"</string> @@ -300,8 +302,8 @@ <string name="tethering_hardware_offload_summary" msgid="7801345335142803029">"Usar aceleração de hardware de tethering quando disponível"</string> <string name="adb_warning_title" msgid="7708653449506485728">"Permitir a depuração USB?"</string> <string name="adb_warning_message" msgid="8145270656419669221">"A depuração USB serve apenas para fins de desenvolvimento. Use-a para copiar dados entre o computador e o dispositivo, instalar apps no seu aparelho sem notificação e ler dados de registro."</string> - <string name="adbwifi_warning_title" msgid="727104571653031865">"Permitir a depuração sem fio?"</string> - <string name="adbwifi_warning_message" msgid="8005936574322702388">"A depuração sem fio serve apenas para fins de desenvolvimento. Use-a para copiar dados entre o computador e o dispositivo, instalar apps no seu aparelho sem notificação e ler dados de registro."</string> + <string name="adbwifi_warning_title" msgid="727104571653031865">"Permitir a depuração por Wi-Fi?"</string> + <string name="adbwifi_warning_message" msgid="8005936574322702388">"A depuração por Wi-Fi serve apenas para fins de desenvolvimento. Use para copiar dados entre o computador e o dispositivo, instalar apps no seu aparelho sem notificação e ler dados de registro."</string> <string name="adb_keys_warning_message" msgid="2968555274488101220">"Revogar o acesso à depuração USB para todos os computadores autorizados?"</string> <string name="dev_settings_warning_title" msgid="8251234890169074553">"Ativar as configurações de desenvolvimento?"</string> <string name="dev_settings_warning_message" msgid="37741686486073668">"Essas configurações são destinadas apenas para o uso de desenvolvedores. Elas podem causar a desativação ou mau funcionamento do dispositivo e dos apps contidos nele."</string> @@ -371,6 +373,8 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"Exibir a caixa de diálogo \"App não responde\" para apps em segundo plano"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"Mostrar avisos de notificações"</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"Exibir aviso na tela quando um app posta notificação sem canal válido"</string> + <string name="enforce_shortcuts_for_conversations" msgid="7040735163945040763">"Usar atalhos para notificações de conversa"</string> + <string name="enforce_shortcuts_for_conversations_summary" msgid="1860168037282467862">"Exigir que as notificações sejam apoiadas por um atalho de compartilhamento de longa duração para que elas possam aparecer na seção de conversa"</string> <string name="force_allow_on_external" msgid="9187902444231637880">"Forçar permissão de apps em armazenamento externo"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Qualificar apps para gravação em armazenamento externo, independentemente de valores de manifestos"</string> <string name="force_resizable_activities" msgid="7143612144399959606">"Forçar atividades a serem redimensionáveis"</string> @@ -426,10 +430,10 @@ <string name="power_discharging_duration_enhanced" msgid="1800465736237672323">"Tempo restante aproximado, com base no seu uso: <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <!-- no translation found for power_remaining_duration_only_short (7438846066602840588) --> <skip /> - <string name="power_discharge_by_enhanced" msgid="563438403581662942">"Deve durar até cerca de <xliff:g id="TIME">%1$s</xliff:g> com base no seu uso (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_discharge_by_only_enhanced" msgid="3268796172652988877">"Deve durar até cerca de <xliff:g id="TIME">%1$s</xliff:g> com base no seu uso"</string> - <string name="power_discharge_by" msgid="4113180890060388350">"Deve durar até cerca de <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_discharge_by_only" msgid="92545648425937000">"Deve durar até cerca de <xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="power_discharge_by_enhanced" msgid="563438403581662942">"Deve durar até por volta de <xliff:g id="TIME">%1$s</xliff:g> com base no seu uso (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_discharge_by_only_enhanced" msgid="3268796172652988877">"Deve durar até por volta de <xliff:g id="TIME">%1$s</xliff:g> com base no seu uso"</string> + <string name="power_discharge_by" msgid="4113180890060388350">"Deve durar até por volta de <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_discharge_by_only" msgid="92545648425937000">"Deve durar até por volta de <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Até <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"A bateria pode acabar neste horário: <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"Menos de <xliff:g id="THRESHOLD">%1$s</xliff:g> restante(s)"</string> diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml index c12f2d7d5616..a008504420c6 100644 --- a/packages/SettingsLib/res/values-pt-rPT/strings.xml +++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml @@ -212,7 +212,7 @@ <string name="adb_wireless_settings" msgid="2295017847215680229">"Depuração sem fios"</string> <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Para ver e utilizar dispositivos disponíveis, ative a depuração sem fios."</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"Sincronize o dispositivo com o código QR"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"Sincronize novos dispositivos com o leitor de códigos QR."</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"Sincronize novos dispositivos com o leitor de códigos QR."</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"Sincronize dispositivo com código de sincronização"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"Sincronize novos dispositivos através do código de seis dígitos."</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"Dispositivos sincronizados"</string> @@ -231,7 +231,7 @@ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"Falha ao sincronizar o dispositivo. O código QR estava incorreto ou o dispositivo não está ligado à mesma rede."</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"Porta e endereço IP"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"Leia o código QR"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"Sincronize o dispositivo através de Wi-Fi ao ler um código QR."</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Sincronize o dispositivo através de Wi-Fi ao ler um código QR."</string> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Estabeleça ligação a uma rede Wi-Fi."</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, depurar, programador"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"Atalho para relatório de erro"</string> @@ -242,7 +242,7 @@ <string name="bt_hci_snoop_log_summary" msgid="6808538971394092284">"Capturar os pacotes Bluetooth (ative/desative o Bluetooth após alterar esta definição)"</string> <string name="oem_unlock_enable" msgid="5334869171871566731">"Desbloqueio de OEM"</string> <string name="oem_unlock_enable_summary" msgid="5857388174390953829">"Permitir o desbloqueio do carregador de arranque"</string> - <string name="confirm_enable_oem_unlock_title" msgid="8249318129774367535">"Pretende permitir o desbloqueio de OEM?"</string> + <string name="confirm_enable_oem_unlock_title" msgid="8249318129774367535">"Permitir o desbloqueio de OEM?"</string> <string name="confirm_enable_oem_unlock_text" msgid="854131050791011970">"AVISO: as funcionalidades de proteção do dispositivo não funcionam neste dispositivo enquanto esta definição estiver ativada."</string> <string name="mock_location_app" msgid="6269380172542248304">"Selecionar aplicação de localização fictícia"</string> <string name="mock_location_app_not_set" msgid="6972032787262831155">"Aplicação de localização fictícia não definida"</string> @@ -251,6 +251,7 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"Certificação de display sem fios"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"Ativar o registo verboso de Wi-Fi"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"Controlo da procura de Wi‑Fi"</string> + <string name="wifi_enhanced_mac_randomization" msgid="5437378364995776979">"Seleção aleatória do MAC otimizado Wi-Fi"</string> <string name="mobile_data_always_on" msgid="8275958101875563572">"Dados móveis sempre ativos"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"Aceleração de hardware para ligação (à Internet) via telemóvel"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"Mostrar dispositivos Bluetooth sem nomes"</string> @@ -283,6 +284,7 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"Mostrar opções da certificação de display sem fios"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Aumentar o nível de reg. de Wi-Fi, mostrar por RSSI de SSID no Selec. de Wi-Fi"</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"Reduz o consumo rápido da bateria e melhora o desempenho da rede"</string> + <string name="wifi_enhanced_mac_randomization_summary" msgid="7925425746373704991">"Este botão ativar/desativar afeta o comportamento da seleção aleatória do MAC apenas para o modo de cliente.\nQuando este modo está ativado, qualquer rede que tenha a seleção aleatória do MAC ativa pode fazer com que os seus endereços MAC sejam novamente selecionados de forma aleatória durante a associação, dependendo de quando o cliente se desligou da rede pela última vez. A nova seleção aleatória não ocorre se a ligação do dispositivo for restabelecida em 4 horas ou menos."</string> <string name="wifi_metered_label" msgid="8737187690304098638">"Acesso limitado"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"Acesso ilimitado"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"Tamanhos da memória intermédia do registo"</string> @@ -300,7 +302,7 @@ <string name="tethering_hardware_offload_summary" msgid="7801345335142803029">"Se disponível, utilizar a aceleração de hardware para ligação (à Internet) via telemóvel"</string> <string name="adb_warning_title" msgid="7708653449506485728">"Permitir depuração USB?"</string> <string name="adb_warning_message" msgid="8145270656419669221">"A depuração USB é utilizada apenas para fins de programação. Utilize-a para copiar dados entre o computador e o aparelho, instalar aplicações no aparelho sem notificação e ler dados de registo."</string> - <string name="adbwifi_warning_title" msgid="727104571653031865">"Pretende permitir a depuração sem fios?"</string> + <string name="adbwifi_warning_title" msgid="727104571653031865">"Permitir a depuração sem fios?"</string> <string name="adbwifi_warning_message" msgid="8005936574322702388">"A depuração sem fios é utilizada apenas para fins de programação. Utilize-a para copiar dados entre o computador e o dispositivo, instalar apps no dispositivo sem notificação e ler dados de registo."</string> <string name="adb_keys_warning_message" msgid="2968555274488101220">"Revogar acesso à depuração USB de todos os computadores anteriormente autorizados?"</string> <string name="dev_settings_warning_title" msgid="8251234890169074553">"Permitir definições de programação?"</string> @@ -371,6 +373,8 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"Mostrar caixa de diálogo A aplicação não está a responder para aplicações em segundo plano"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"Mostrar avisos do canal de notificações"</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"Mostra um aviso no ecrã quando uma aplicação publica uma notificação sem o canal ser válido"</string> + <string name="enforce_shortcuts_for_conversations" msgid="7040735163945040763">"Aplicar atalhos para notificações de conversas"</string> + <string name="enforce_shortcuts_for_conversations_summary" msgid="1860168037282467862">"Solicitar cópia de seg. das notif. por atalho de partilha de longa duração p/ apresentação na secção de conversas"</string> <string name="force_allow_on_external" msgid="9187902444231637880">"Forçar permissão de apps no armazenamento externo"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Torna qualquer aplicação elegível para ser gravada no armazenamento externo, independentemente dos valores do manifesto"</string> <string name="force_resizable_activities" msgid="7143612144399959606">"Forçar as atividades a serem redimensionáveis"</string> @@ -451,7 +455,7 @@ <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Carregamento lento"</string> <string name="battery_info_status_discharging" msgid="6962689305413556485">"Não está a carregar"</string> <string name="battery_info_status_not_charging" msgid="8330015078868707899">"Ligada à corrente, não é possível carregar neste momento"</string> - <string name="battery_info_status_full" msgid="4443168946046847468">"Completo"</string> + <string name="battery_info_status_full" msgid="4443168946046847468">"Carregada"</string> <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Controlado pelo gestor"</string> <string name="disabled" msgid="8017887509554714950">"Desativada"</string> <string name="external_source_trusted" msgid="1146522036773132905">"Autorizada"</string> diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml index d98c9ff071bf..845433df6d96 100644 --- a/packages/SettingsLib/res/values-pt/strings.xml +++ b/packages/SettingsLib/res/values-pt/strings.xml @@ -212,7 +212,7 @@ <string name="adb_wireless_settings" msgid="2295017847215680229">"Depuração por Wi-Fi"</string> <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Para ver e usar dispositivos disponíveis, ative a depuração por Wi-Fi"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"Parear o dispositivo com um código QR"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"Parear novos dispositivos usando um leitor de código QR"</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"Parear novos dispositivos usando um leitor de código QR"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"Parear o dispositivo com um código de pareamento"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"Parear novos dispositivos usando um código de seis dígitos"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"Dispositivos pareados"</string> @@ -231,7 +231,7 @@ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"Falha ao parear o dispositivo. O código QR está incorreto ou o dispositivo não está conectado à mesma rede."</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"Endereço IP e porta"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"Ler código QR"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"Parear dispositivo na rede Wi‑Fi fazendo a leitura do código QR"</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Parear dispositivo na rede Wi‑Fi fazendo a leitura do código QR"</string> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Conecte-se a uma rede Wi-Fi"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, debug, dev"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"Atalho para relatório de bugs"</string> @@ -251,6 +251,7 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"Certificação de Display sem fio"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"Ativar registro detalhado de Wi-Fi"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"Limitar busca por Wi-Fi"</string> + <string name="wifi_enhanced_mac_randomization" msgid="5437378364995776979">"MAC aleatório melhorado por Wi-Fi"</string> <string name="mobile_data_always_on" msgid="8275958101875563572">"Dados móveis sempre ativos"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"Aceleração de hardware de tethering"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"Mostrar dispositivos Bluetooth sem nomes"</string> @@ -283,6 +284,7 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"Mostrar opções de certificação de Display sem fio"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Aumentar o nível de registro de Wi-Fi; mostrar conforme o RSSI do SSID no seletor de Wi-Fi"</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"Reduz o consumo de bateria e melhora o desempenho da rede"</string> + <string name="wifi_enhanced_mac_randomization_summary" msgid="7925425746373704991">"Essa opção afeta o comportamento de ordem aleatória de MAC somente para o modo cliente.\nQuando esse modo é ativado, todas as redes que tiverem a ordem aleatória de MAC ativada poderão ter a ordem aleatória refeita durante a associação, dependendo de quando o cliente se desconectou da rede pela última vez. A ordem aleatória não será refeita se o dispositivo se reconectar em até quatro horas."</string> <string name="wifi_metered_label" msgid="8737187690304098638">"Limitada"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"Ilimitada"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"Tamanhos de buffer de logger"</string> @@ -300,8 +302,8 @@ <string name="tethering_hardware_offload_summary" msgid="7801345335142803029">"Usar aceleração de hardware de tethering quando disponível"</string> <string name="adb_warning_title" msgid="7708653449506485728">"Permitir a depuração USB?"</string> <string name="adb_warning_message" msgid="8145270656419669221">"A depuração USB serve apenas para fins de desenvolvimento. Use-a para copiar dados entre o computador e o dispositivo, instalar apps no seu aparelho sem notificação e ler dados de registro."</string> - <string name="adbwifi_warning_title" msgid="727104571653031865">"Permitir a depuração sem fio?"</string> - <string name="adbwifi_warning_message" msgid="8005936574322702388">"A depuração sem fio serve apenas para fins de desenvolvimento. Use-a para copiar dados entre o computador e o dispositivo, instalar apps no seu aparelho sem notificação e ler dados de registro."</string> + <string name="adbwifi_warning_title" msgid="727104571653031865">"Permitir a depuração por Wi-Fi?"</string> + <string name="adbwifi_warning_message" msgid="8005936574322702388">"A depuração por Wi-Fi serve apenas para fins de desenvolvimento. Use para copiar dados entre o computador e o dispositivo, instalar apps no seu aparelho sem notificação e ler dados de registro."</string> <string name="adb_keys_warning_message" msgid="2968555274488101220">"Revogar o acesso à depuração USB para todos os computadores autorizados?"</string> <string name="dev_settings_warning_title" msgid="8251234890169074553">"Ativar as configurações de desenvolvimento?"</string> <string name="dev_settings_warning_message" msgid="37741686486073668">"Essas configurações são destinadas apenas para o uso de desenvolvedores. Elas podem causar a desativação ou mau funcionamento do dispositivo e dos apps contidos nele."</string> @@ -371,6 +373,8 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"Exibir a caixa de diálogo \"App não responde\" para apps em segundo plano"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"Mostrar avisos de notificações"</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"Exibir aviso na tela quando um app posta notificação sem canal válido"</string> + <string name="enforce_shortcuts_for_conversations" msgid="7040735163945040763">"Usar atalhos para notificações de conversa"</string> + <string name="enforce_shortcuts_for_conversations_summary" msgid="1860168037282467862">"Exigir que as notificações sejam apoiadas por um atalho de compartilhamento de longa duração para que elas possam aparecer na seção de conversa"</string> <string name="force_allow_on_external" msgid="9187902444231637880">"Forçar permissão de apps em armazenamento externo"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Qualificar apps para gravação em armazenamento externo, independentemente de valores de manifestos"</string> <string name="force_resizable_activities" msgid="7143612144399959606">"Forçar atividades a serem redimensionáveis"</string> @@ -426,10 +430,10 @@ <string name="power_discharging_duration_enhanced" msgid="1800465736237672323">"Tempo restante aproximado, com base no seu uso: <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <!-- no translation found for power_remaining_duration_only_short (7438846066602840588) --> <skip /> - <string name="power_discharge_by_enhanced" msgid="563438403581662942">"Deve durar até cerca de <xliff:g id="TIME">%1$s</xliff:g> com base no seu uso (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_discharge_by_only_enhanced" msgid="3268796172652988877">"Deve durar até cerca de <xliff:g id="TIME">%1$s</xliff:g> com base no seu uso"</string> - <string name="power_discharge_by" msgid="4113180890060388350">"Deve durar até cerca de <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_discharge_by_only" msgid="92545648425937000">"Deve durar até cerca de <xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="power_discharge_by_enhanced" msgid="563438403581662942">"Deve durar até por volta de <xliff:g id="TIME">%1$s</xliff:g> com base no seu uso (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_discharge_by_only_enhanced" msgid="3268796172652988877">"Deve durar até por volta de <xliff:g id="TIME">%1$s</xliff:g> com base no seu uso"</string> + <string name="power_discharge_by" msgid="4113180890060388350">"Deve durar até por volta de <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_discharge_by_only" msgid="92545648425937000">"Deve durar até por volta de <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Até <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"A bateria pode acabar neste horário: <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"Menos de <xliff:g id="THRESHOLD">%1$s</xliff:g> restante(s)"</string> diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml index 586040944b9e..b0d78cde0ae8 100644 --- a/packages/SettingsLib/res/values-ro/strings.xml +++ b/packages/SettingsLib/res/values-ro/strings.xml @@ -206,13 +206,13 @@ <string name="enable_adb" msgid="8072776357237289039">"Remedierea erorilor prin USB"</string> <string name="enable_adb_summary" msgid="3711526030096574316">"Mod de depanare când este conectat USB"</string> <string name="clear_adb_keys" msgid="3010148733140369917">"Revoc autorizații remediere a erorilor prin USB"</string> - <string name="enable_adb_wireless" msgid="6973226350963971018">"Remedierea erorilor prin wireless"</string> + <string name="enable_adb_wireless" msgid="6973226350963971018">"Remedierea erorilor wireless"</string> <string name="enable_adb_wireless_summary" msgid="7344391423657093011">"Modul de remediere a erorilor când rețeaua Wi-Fi este conectată"</string> <string name="adb_wireless_error" msgid="721958772149779856">"Eroare"</string> - <string name="adb_wireless_settings" msgid="2295017847215680229">"Remedierea erorilor prin wireless"</string> + <string name="adb_wireless_settings" msgid="2295017847215680229">"Remedierea erorilor wireless"</string> <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Activați remedierea erorilor wireless pentru a vedea și a folosi dispozitivele disponibile"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"Asociați dispozitivul folosind codul QR"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"Asociați dispozitive noi folosind scannerul de coduri QR"</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"Asociați dispozitive noi folosind scannerul de coduri QR"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"Asociați dispozitivul folosind codul de conectare"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"Asociați dispozitive noi folosind codul din șase cifre"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"Dispozitive asociate"</string> @@ -231,7 +231,7 @@ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"Nu s-a asociat dispozitivul. Codul QR este incorect sau dispozitivul nu este conectat la aceeași rețea."</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"Adresa IP și portul"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"Scanați codul QR"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"Asociați dispozitivul prin Wi-Fi scanând un cod QR"</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Asociați dispozitivul prin Wi-Fi scanând un cod QR"</string> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Conectați-vă la o rețea Wi-Fi"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, remedierea erorilor, dev"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"Comandă rapidă pentru raportul de erori"</string> @@ -251,6 +251,7 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"Certificare Ecran wireless"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"Înregistrare prin Wi-Fi de volume mari de date"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"Limitare căutare de rețele Wi-Fi"</string> + <string name="wifi_enhanced_mac_randomization" msgid="5437378364995776979">"Randomizare MAC îmbunătățită prin Wi-Fi"</string> <string name="mobile_data_always_on" msgid="8275958101875563572">"Date mobile permanent active"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"Accelerare hardware pentru tethering"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"Afișați dispozitivele Bluetooth fără nume"</string> @@ -283,6 +284,7 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"Afișați opțiunile pentru certificarea Ecran wireless"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Măriți niv. de înr. prin Wi‑Fi, afișați în fcț. de SSID RSSI în Selectorul Wi‑Fi"</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"Reduce descărcarea bateriei și îmbunătățește performanța rețelei"</string> + <string name="wifi_enhanced_mac_randomization_summary" msgid="7925425746373704991">"Acest comutator influențează comportamentul de randomizare a adresei MAC numai pentru modul client.\nCând este activat acest mod, toate rețelele care au activată randomizarea adresei MAC pot randomiza din nou adresele MAC în timpul asocierii, în funcție de ora ultimei deconectări a clientului de la rețea. Randomizarea nu se repetă dacă dispozitivul se reconectează în decurs de 4 ore."</string> <string name="wifi_metered_label" msgid="8737187690304098638">"Contorizată"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"Necontorizată"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"Dimensiunile memoriei temporare a jurnalului"</string> @@ -300,8 +302,8 @@ <string name="tethering_hardware_offload_summary" msgid="7801345335142803029">"Folosiți accelerarea hardware pentru tethering, dacă este disponibilă"</string> <string name="adb_warning_title" msgid="7708653449506485728">"Permiteți remedierea erorilor prin USB?"</string> <string name="adb_warning_message" msgid="8145270656419669221">"Remedierea erorilor prin USB are exclusiv scopuri de dezvoltare. Utilizați-o pentru a copia date de pe computer pe dispozitiv, pentru a instala aplicații pe dispozitiv fără notificare și pentru a citi datele din jurnale."</string> - <string name="adbwifi_warning_title" msgid="727104571653031865">"Permiteți remedierea erorilor prin wireless?"</string> - <string name="adbwifi_warning_message" msgid="8005936574322702388">"Remedierea erorilor prin wireless are exclusiv scopuri de dezvoltare. Folosiți-o pentru a copia date de pe computer pe dispozitiv, pentru a instala aplicații pe dispozitiv fără notificare și pentru a citi datele din jurnale."</string> + <string name="adbwifi_warning_title" msgid="727104571653031865">"Permiteți remedierea erorilor wireless?"</string> + <string name="adbwifi_warning_message" msgid="8005936574322702388">"Remedierea erorilor wireless are exclusiv scopuri de dezvoltare. Folosiți-o pentru a copia date de pe computer pe dispozitiv, pentru a instala aplicații pe dispozitiv fără notificare și pentru a citi datele din jurnale."</string> <string name="adb_keys_warning_message" msgid="2968555274488101220">"Revocați accesul la remedierea erorilor prin USB de pe toate computerele pe care le-ați autorizat anterior?"</string> <string name="dev_settings_warning_title" msgid="8251234890169074553">"Permiteți setările pentru dezvoltare?"</string> <string name="dev_settings_warning_message" msgid="37741686486073668">"Aceste setări sunt destinate exclusiv utilizării pentru dezvoltare. Din cauza lor, este posibil ca dispozitivul dvs. și aplicațiile de pe acesta să nu mai funcționeze sau să funcționeze necorespunzător."</string> @@ -371,6 +373,8 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"Afișați dialogul Aplicația nu răspunde pentru aplicațiile din fundal"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"Afișați avertismentele de pe canalul de notificări"</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"Afișați avertisment pe ecran când o aplicație postează o notificare fără canal valid"</string> + <string name="enforce_shortcuts_for_conversations" msgid="7040735163945040763">"Comenzi rapide pt. notif. de conversație"</string> + <string name="enforce_shortcuts_for_conversations_summary" msgid="1860168037282467862">"Notificările trebuie susținute de o comandă rapidă veche de trimitere ca să apară în secțiunea conversației"</string> <string name="force_allow_on_external" msgid="9187902444231637880">"Forțați accesul aplicațiilor la stocarea externă"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Faceți ca orice aplicație eligibilă să fie scrisă în stocarea externă, indiferent de valorile manifestului"</string> <string name="force_resizable_activities" msgid="7143612144399959606">"Forțați redimensionarea activităților"</string> diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml index ab230b768f20..57f980f74211 100644 --- a/packages/SettingsLib/res/values-ru/strings.xml +++ b/packages/SettingsLib/res/values-ru/strings.xml @@ -112,7 +112,7 @@ <string name="bluetooth_opp_profile_summary_use_for" msgid="461981154387015457">"Используется для передачи файлов"</string> <string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"Использовать для ввода"</string> <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="7689393730163320483">"Использовать для слухового аппарата"</string> - <string name="bluetooth_pairing_accept" msgid="2054232610815498004">"Подключить"</string> + <string name="bluetooth_pairing_accept" msgid="2054232610815498004">"Добавить"</string> <string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"ДОБАВИТЬ"</string> <string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Отмена"</string> <string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"Установление соединения обеспечивает доступ к вашим контактам и журналу звонков при подключении."</string> @@ -194,8 +194,8 @@ <item msgid="581904787661470707">"Максимальная"</item> </string-array> <string name="choose_profile" msgid="343803890897657450">"Выбор профиля"</string> - <string name="category_personal" msgid="6236798763159385225">"Личные данные"</string> - <string name="category_work" msgid="4014193632325996115">"Работа"</string> + <string name="category_personal" msgid="6236798763159385225">"Личный профиль"</string> + <string name="category_work" msgid="4014193632325996115">"Рабочий профиль"</string> <string name="development_settings_title" msgid="140296922921597393">"Для разработчиков"</string> <string name="development_settings_enable" msgid="4285094651288242183">"Включить параметры для разработчиков"</string> <string name="development_settings_summary" msgid="8718917813868735095">"Настройка параметров для разработчиков"</string> @@ -212,7 +212,7 @@ <string name="adb_wireless_settings" msgid="2295017847215680229">"Отладка по Wi-Fi"</string> <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Чтобы посмотреть и использовать доступные устройства, включите отладку по Wi-Fi"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"Подключить устройство с помощью QR-кода"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"Подключение новых устройств с помощью сканера QR-кодов"</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"Подключение новых устройств с помощью сканера QR-кодов"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"Подключить устройство с помощью кода подключения"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"Подключение новых устройств с помощью шестизначного кода"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"Подключенные устройства"</string> @@ -230,8 +230,8 @@ <string name="adb_wireless_verifying_qrcode_text" msgid="6123192424916029207">"Подключение устройства…"</string> <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"Не удалось подключить устройство. QR-код неверный, или устройство находится в другой сети."</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP-адрес и порт"</string> - <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"Сканировать QR-код"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"Подключение устройства через Wi‑Fi с использованием QR-кода"</string> + <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"Отсканируйте QR-код"</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Подключение устройства через Wi‑Fi с использованием QR-кода"</string> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Подключите устройство к сети Wi-Fi."</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, отладка, разработчик"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"Отчет об ошибке"</string> @@ -251,6 +251,7 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"Серт. беспроводн. мониторов"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"Подробный журнал Wi‑Fi"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"Ограничивать поиск сетей Wi‑Fi"</string> + <string name="wifi_enhanced_mac_randomization" msgid="5437378364995776979">"Случайные MAC-адреса в сети Wi-Fi"</string> <string name="mobile_data_always_on" msgid="8275958101875563572">"Не отключать мобильный Интернет"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"Аппаратное ускорение в режиме модема"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"Показывать Bluetooth-устройства без названий"</string> @@ -283,6 +284,7 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"Показывать параметры сертификации беспроводных мониторов"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Вести подробный журнал, показывать RSSI для каждого SSID при выборе сети"</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"Уменьшает расход заряда батареи и улучшает работу сети"</string> + <string name="wifi_enhanced_mac_randomization_summary" msgid="7925425746373704991">"Эта настройка влияет на использование случайных MAC-адресов только в клиентском режиме.\nВо время подключения к любой сети происходит повторное создание случайного MAC-адреса в зависимости от того, когда клиент последний раз отключался от сети. Это невозможно, если соединение возобновляется через четыре часа или раньше."</string> <string name="wifi_metered_label" msgid="8737187690304098638">"Сеть с тарификацией трафика"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"Сеть без тарификации трафика"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"Размер буфера журнала"</string> @@ -371,6 +373,8 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"Уведомлять о том, что приложение, запущенное в фоновом режиме, не отвечает"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"Показывать предупреждения канала передачи уведомлений"</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"Показывать предупреждение о новых уведомлениях приложения вне допустимого канала"</string> + <string name="enforce_shortcuts_for_conversations" msgid="7040735163945040763">"Принудительное использование ярлыков для уведомлений из чатов"</string> + <string name="enforce_shortcuts_for_conversations_summary" msgid="1860168037282467862">"Обязательно дублировать уведомления с помощью долго отображаемых ярлыков, чтобы уведомления появлялись в разделе чатов"</string> <string name="force_allow_on_external" msgid="9187902444231637880">"Разрешить сохранение на внешние накопители"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Разрешить сохранение приложений на внешних накопителях (независимо от значений в манифесте)"</string> <string name="force_resizable_activities" msgid="7143612144399959606">"Изменение размера в многооконном режиме"</string> diff --git a/packages/SettingsLib/res/values-si/strings.xml b/packages/SettingsLib/res/values-si/strings.xml index d87e2884ceb0..d22a643a7856 100644 --- a/packages/SettingsLib/res/values-si/strings.xml +++ b/packages/SettingsLib/res/values-si/strings.xml @@ -212,7 +212,7 @@ <string name="adb_wireless_settings" msgid="2295017847215680229">"නොරැහැන් දෝෂාවේක්ෂණය"</string> <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"ලබා ගත හැකි උපාංග බැලීමට, නොරැහැන් දෝෂාවේක්ෂණය ක්රියාත්මක කරන්න"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"QR කේතය සමගින් උපාංගය යුගල කරන්න"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"QR කේත ස්කෑනරය භාවිතයෙන් නව උපාංග යුගල කරන්න"</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"QR කේත ස්කෑනරය භාවිතයෙන් නව උපාංග යුගල කරන්න"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"යුගල කිරීමේ කේතය සමගින් උපාංගය යුගල කරන්න"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"ඉලක්කම් හයක කේතය භාවිතයෙන් නව උපාංග යුගල කරන්න"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"යුගල කළ උපාංග"</string> @@ -231,7 +231,7 @@ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"උපාංගය යුගල කිරීමට අසමත් විය. QR කේතය වැරදිය නැතහොත් එකම ජාලයට සම්බන්ධ කර නැත."</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP ලිපිනය & තොට"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"QR කේතය ස්කෑන් කරන්න"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"QR කේතය ස්කෑන් කිරීමෙන් Wi‑Fi හරහා උපාංගය යුගල කරන්න"</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"QR කේතය ස්කෑන් කිරීමෙන් Wi‑Fi හරහා උපාංගය යුගල කරන්න"</string> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"කරුණාකර Wi-Fi ජාලයකට සම්බන්ධ වන්න"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, දෝෂාවෙක්ෂණ, dev"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"දෝෂය වාර්තා කිරීමේ කෙටිමඟ"</string> @@ -251,6 +251,7 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"නොරැහැන් සංදර්ශක සහතිකය"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"විස්තරාත්මක Wi‑Fi ලොග් කිරීම සබල කරන්න"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"Wi‑Fi ස්කෑන් අවකරණය"</string> + <string name="wifi_enhanced_mac_randomization" msgid="5437378364995776979">"Wi-Fi‑වැඩිදියුණු කළ MAC සසම්භාවීකරණය"</string> <string name="mobile_data_always_on" msgid="8275958101875563572">"ජංගම දත්ත සැමවිට ක්රියාකාරීය"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"ටෙදරින් දෘඪාංග ත්වරණය"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"නම් නොමැති බ්ලූටූත් උපාංග පෙන්වන්න"</string> @@ -283,6 +284,7 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"නොරැහැන් සංදර්ශක සහතිකය සඳහා විකල්ප පෙන්වන්න"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Wi‑Fi ලොග් මට්ටම වැඩි කරන්න, Wi‑Fi තෝරනයෙහි SSID RSSI අනුව පෙන්වන්න"</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"බැටරි බැසීම අඩු කරන අතර ජාල කාර්ය සාධනය වැඩි දියුණු කරයි"</string> + <string name="wifi_enhanced_mac_randomization_summary" msgid="7925425746373704991">"මෙම ටොගලය සේවාලාභී ප්රකාරය සඳහා පමණක් MAC සසම්භාවීකරණ හැසිරීමට බලපායි.\nමෙම ප්රකාරය සක්රිය කර ඇති විට, MAC සසම්භාවීකරණය සබල කර ඇති ඕනෑම ජාලයකට, සේවාලාභියා අවසන් වරට ජාලයෙන් විසන්ධි වූයේ කවදාද යන්න මත පදනම්ව සම්බන්ධය අතරතුර ඔවුන්ගේ MAC ලිපින යළි සසම්භාවිකරණය කර තිබිය හැකිය. උපාංගය පැය 4කින් හෝ ඊට අඩු කාලයකදී නැවත සම්බන්ධ වන්නේ නම් යළි සසම්භාවිකරණය සිදු නොවේ."</string> <string name="wifi_metered_label" msgid="8737187690304098638">"මනිනු ලැබේ"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"මනින්නේ නැත"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"ලෝගයේ අන්තරාවක ප්රමාණය"</string> @@ -371,6 +373,8 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"පසුබිම් යෙදුම්වලට යෙදුම ප්රතිචාර නොදක්වයි කවුළුව සංදර්ශනය කරන්න"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"දැනුම්දීම් නාලිකා අනතුරු ඇඟවීම් පෙන්."</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"යෙදුමක් වලංගු නාලිකාවකින් තොරව දැනුම්දීමක් පළ කරන විට තිරය-මත අනතුරු ඇඟවීමක් සංදර්ශනය කරයි."</string> + <string name="enforce_shortcuts_for_conversations" msgid="7040735163945040763">"සංවාද දැනුම් දීම් සඳහා කෙටිමං බලාත්මක කරන්න"</string> + <string name="enforce_shortcuts_for_conversations_summary" msgid="1860168037282467862">"සංවාද කොටසේ පෙනී සිටීම පිණිස දිගු කාලයක් පවතින බෙදා ගැනීමේ කෙටිමඟක් මඟින් දැනුම් දීම් අවහිර කිරීමට අවශ්ය වේ"</string> <string name="force_allow_on_external" msgid="9187902444231637880">"බාහිර මත යෙදුම් ඉඩ දීම බල කරන්න"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"මැනිෆෙස්ට් අගයන් නොසලකා, ඕනෑම යෙදුමක් බාහිර ගබඩාවට ලිවීමට සුදුසුකම් ලබා දෙයි"</string> <string name="force_resizable_activities" msgid="7143612144399959606">"ක්රියාකාරකම් ප්රතිප්රමාණ කළ හැකි බවට බල කරන්න"</string> diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml index 73cfce1d73d7..79a9c2443a9a 100644 --- a/packages/SettingsLib/res/values-sk/strings.xml +++ b/packages/SettingsLib/res/values-sk/strings.xml @@ -212,7 +212,7 @@ <string name="adb_wireless_settings" msgid="2295017847215680229">"Bezdrôtové ladenie"</string> <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Ak chcete zobraziť a používať dostupné zariadenia, zapnite bezdrôtové ladenie"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"Spárovať zariadenie pomocou QR kódu"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"Spárujte nové zariadenia pomocou skenera QR kódov"</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"Spárujte nové zariadenia pomocou skenera QR kódov"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"Spárovať zariadenie pomocou párovacieho kódu"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"Spárujte nové zariadenia pomocou šesťmiestneho kódu"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"Spárované zariadenia"</string> @@ -231,7 +231,7 @@ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"Zariadenie sa nepodarilo spárovať. Buď bol QR kód nesprávny, alebo zariadenie nie je pripojené k rovnakej sieti."</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"Adresa IP a port"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"Naskenujte QR kód"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"Spárujte zariadenie cez sieť Wi-Fi naskenovaním QR kódu"</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Spárujte zariadenie cez sieť Wi-Fi naskenovaním QR kódu"</string> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Pripojte sa k sieti Wi‑Fi"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, ladenie, dev"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"Skratka hlásenia chyby"</string> @@ -251,6 +251,8 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"Certifikácia bezdrôtového zobrazenia"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"Podrobné denníky Wi‑Fi"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"Pribrzdenie vyhľadávania sietí Wi‑Fi"</string> + <!-- no translation found for wifi_enhanced_mac_randomization (5437378364995776979) --> + <skip /> <string name="mobile_data_always_on" msgid="8275958101875563572">"Mobilné dáta ponechať vždy aktívne"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"Hardvérová akcelerácia tetheringu"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"Zobrazovať zariadenia Bluetooth bez názvov"</string> @@ -277,12 +279,14 @@ <string name="select_private_dns_configuration_dialog_title" msgid="3731422918335951912">"Výber súkromného režimu DNS"</string> <string name="private_dns_mode_off" msgid="7065962499349997041">"Vypnuté"</string> <string name="private_dns_mode_opportunistic" msgid="1947864819060442354">"Automaticky"</string> - <string name="private_dns_mode_provider" msgid="3619040641762557028">"Súkromný názov hostiteľa poskytovateľa DNS"</string> + <string name="private_dns_mode_provider" msgid="3619040641762557028">"Názov hostiteľa poskytovateľa súkromného DNS"</string> <string name="private_dns_mode_provider_hostname_hint" msgid="6564868953748514595">"Zadajte názov hostiteľa poskytovateľa DNS"</string> <string name="private_dns_mode_provider_failure" msgid="8356259467861515108">"Nepodarilo sa pripojiť"</string> <string name="wifi_display_certification_summary" msgid="8111151348106907513">"Zobraziť možnosti certifikácie bezdrôtového zobrazenia"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Zvýšiť úroveň denníkov Wi‑Fi, zobrazovať podľa SSID RSSI pri výbere siete Wi‑Fi"</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"Znižuje používanie batérie a zlepšuje výkon siete"</string> + <!-- no translation found for wifi_enhanced_mac_randomization_summary (7925425746373704991) --> + <skip /> <string name="wifi_metered_label" msgid="8737187690304098638">"Merané"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"Bez merania dát"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"Vyrovnávacia pamäť nástroja denníkov"</string> @@ -371,6 +375,8 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"Zobrazovať dialógové okno „Aplikácia nereaguje“ pre aplikácie na pozadí"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"Zobraziť hlásenia kanála upozornení"</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"Zobrazuje varovné hlásenie na obrazovke, keď aplikácia zverejní upozornenie bez platného kanála"</string> + <string name="enforce_shortcuts_for_conversations" msgid="7040735163945040763">"Vynútiť skratky pre upozornenia na konverzácie"</string> + <string name="enforce_shortcuts_for_conversations_summary" msgid="1860168037282467862">"Vyžadovať zastúpenie upozornení dlhodobou skratkou na zdieľanie, aby sa zobrazili v sekcii konverzácie"</string> <string name="force_allow_on_external" msgid="9187902444231637880">"Vynútiť povolenie aplikácií na externom úložisku"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Umožňuje zapísať akúkoľvek aplikáciu do externého úložiska bez ohľadu na hodnoty v manifeste"</string> <string name="force_resizable_activities" msgid="7143612144399959606">"Vynútiť možnosť zmeny veľkosti aktivít"</string> diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml index 8e3782c1b11c..4ff27db97aaf 100644 --- a/packages/SettingsLib/res/values-sl/strings.xml +++ b/packages/SettingsLib/res/values-sl/strings.xml @@ -78,7 +78,7 @@ <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="8477440576953067242">"Povezano (brez telefona ali predstavnosti), raven napolnjenosti akumulatorja je <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> <xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_active_battery_level" msgid="3450745316700494425">"Aktivna, akumulator na <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> <string name="bluetooth_active_battery_level_untethered" msgid="2706188607604205362">"Aktivno, L: napolnjenost akumulatorja je <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, D: napolnjenost akumulatorja je <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>"</string> - <string name="bluetooth_battery_level" msgid="2893696778200201555">"Akumulator na <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> + <string name="bluetooth_battery_level" msgid="2893696778200201555">"Baterija na <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string> <string name="bluetooth_battery_level_untethered" msgid="4002282355111504349">"L: napolnjenost akumulatorja je <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>, D: napolnjenost akumulatorja je <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>"</string> <string name="bluetooth_active_no_battery_level" msgid="4155462233006205630">"Aktivna"</string> <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Zvok predstavnosti"</string> @@ -86,7 +86,7 @@ <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Prenos datoteke"</string> <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Vnosna naprava"</string> <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Internetni dostop"</string> - <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Dajanje stikov v skupno rabo"</string> + <string name="bluetooth_profile_pbap" msgid="7064307749579335765">"Deljenje stikov"</string> <string name="bluetooth_profile_pbap_summary" msgid="2955819694801952056">"Uporabi za dajanje stikov v skupno rabo"</string> <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Skupna raba internetne povezave"</string> <string name="bluetooth_profile_map" msgid="8907204701162107271">"Sporočila SMS"</string> @@ -212,7 +212,7 @@ <string name="adb_wireless_settings" msgid="2295017847215680229">"Brezžično odpravljanje napak"</string> <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Če si želite ogledati in uporabljati razpoložljive naprave, vklopite brezžično odpravljanje napak"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"Seznanjanje naprave s kodo QR"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"Seznanjanje novih naprav z optičnim bralnikom kod QR"</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"Seznanitev novih naprav z optičnim bralnikom kod QR"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"Seznanjanje naprave s kodo za seznanjanje"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"Seznanjanje novih naprav s šestmestno kodo"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"Seznanjene naprave"</string> @@ -231,7 +231,7 @@ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"Seznanitev naprave ni uspela. Koda QR je nepravilna ali pa naprava ni povezana v isto omrežje."</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"Naslov IP in vrata"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"Optično branje kode QR"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"Seznanitev naprave prek Wi‑Fi-ja z optičnim branjem kode QR"</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Seznanitev naprave prek Wi‑Fi-ja z optičnim branjem kode QR"</string> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Vzpostavite povezavo z omrežjem Wi-Fi"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, odpravljanje napak, razvoj"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"Bližnjica za poročanje o napakah"</string> @@ -251,6 +251,7 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"Potrdilo brezžičnega zaslona"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"Omogoči podrobno zapisovanje dnevnika za Wi-Fi"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"Omejevanje iskanja omrežij Wi-Fi"</string> + <string name="wifi_enhanced_mac_randomization" msgid="5437378364995776979">"Naključen naslov MAC s podporo Wi‑Fi‑ja"</string> <string name="mobile_data_always_on" msgid="8275958101875563572">"Prenos podatkov v mobilnem omrežju je vedno aktiven"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"Strojno pospeševanje za internetno povezavo prek mobilnega telefona"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"Prikaži naprave Bluetooth brez imen"</string> @@ -283,6 +284,7 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"Pokaži možnosti za potrdilo brezžičnega zaslona"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Povečaj raven zapisovanja dnevnika za Wi-Fi; v izbirniku Wi‑Fi-ja pokaži glede na SSID RSSI"</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"Zmanjša porabo energije akumulatorja in izboljša delovanje omrežja"</string> + <string name="wifi_enhanced_mac_randomization_summary" msgid="7925425746373704991">"To stikalo vpliva na dodeljevanje naključnega naslova MAC samo v načinu odjemalca.\nKo je ta način aktiviran, se omrežjem, pri katerih je omogočeno naključno dodeljevanje naslova MAC, med povezovanjem morda dodeli nov naključen naslov MAC, kar je odvisno od tega, kdaj je odjemalec nazadnje prekinil povezavo z omrežjem. Dodelitev novega naključnega naslova se ne izvede, če naprava znova vzpostavi povezavo po največ štirih urah."</string> <string name="wifi_metered_label" msgid="8737187690304098638">"Omejen prenos podatkov"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"Z neomejenim prenosom podatkov"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"Velikosti medpomnilnikov zapisovalnika dnevnika"</string> @@ -371,6 +373,8 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"Prikaz pogovornega okna za neodzivanje aplikacij v ozadju"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"Pokaži opozorila kanala za obvestila"</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"Na zaslonu se pokaže opozorilo, ko aplikacija objavi obvestilo brez veljavnega kanala"</string> + <string name="enforce_shortcuts_for_conversations" msgid="7040735163945040763">"Uveljavitev bližnjic za obvestila pogovora"</string> + <string name="enforce_shortcuts_for_conversations_summary" msgid="1860168037282467862">"Zahteva, da obvestila podpira dolgotrajna bližnjica za deljenje, da se prikažejo v razdelku s pogovorom"</string> <string name="force_allow_on_external" msgid="9187902444231637880">"Vsili omogočanje aplikacij v zunanji shrambi"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Poskrbi, da je ne glede na vrednosti v manifestu mogoče vsako aplikacijo zapisati v zunanjo shrambo"</string> <string name="force_resizable_activities" msgid="7143612144399959606">"Vsili spremembo velikosti za aktivnosti"</string> diff --git a/packages/SettingsLib/res/values-sq/strings.xml b/packages/SettingsLib/res/values-sq/strings.xml index 6d1e80a0f341..2a50f5854eac 100644 --- a/packages/SettingsLib/res/values-sq/strings.xml +++ b/packages/SettingsLib/res/values-sq/strings.xml @@ -206,13 +206,13 @@ <string name="enable_adb" msgid="8072776357237289039">"Korrigjimi i USB-së"</string> <string name="enable_adb_summary" msgid="3711526030096574316">"Korrigjo gabimet e modalitetit kur UBS-ja është e lidhur"</string> <string name="clear_adb_keys" msgid="3010148733140369917">"Anulo autorizimet e korrigjimeve të gabimeve të USB-së"</string> - <string name="enable_adb_wireless" msgid="6973226350963971018">"Korrigjimi me valë"</string> + <string name="enable_adb_wireless" msgid="6973226350963971018">"Korrigjimi përmes Wi-Fi"</string> <string name="enable_adb_wireless_summary" msgid="7344391423657093011">"Regjimi i korrigjimit kur Wi‑Fi është i lidhur"</string> <string name="adb_wireless_error" msgid="721958772149779856">"Gabim"</string> - <string name="adb_wireless_settings" msgid="2295017847215680229">"Korrigjimi me valë"</string> - <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Për të parë dhe përdorur pajisjet e disponueshme, aktivizo korrigjimin me valë"</string> + <string name="adb_wireless_settings" msgid="2295017847215680229">"Korrigjimi përmes Wi-Fi"</string> + <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Për të parë dhe përdorur pajisjet e disponueshme, aktivizo korrigjimin përmes Wi-Fi"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"Çifto pajisjen me kod QR"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"Çifto pajisjet e reja duke përdorur skanerin e kodeve QR"</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"Çifto pajisjet e reja duke përdorur skanerin e kodeve QR"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"Çifto pajisjen me kodin e çiftimit"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"Çifto pajisjet e reja duke përdorur kodin me gjashtë shifra"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"Pajisjet e çiftuara"</string> @@ -231,7 +231,7 @@ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"Çiftimi i pajisjes dështoi. Ose kodi QR nuk ishte i saktë, ose pajisja nuk është e lidhur me të njëjtin rrjet."</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"Adresa e IP-së dhe porta"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"Skano kodin QR"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"Çifto pajisjen përmes Wi‑Fi duke skanuar një kod QR"</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Çifto pajisjen përmes Wi‑Fi duke skanuar një kod QR"</string> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Lidhu me një rrjet Wi-Fi"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, korrigjimi, zhvilluesi"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"Shkurtorja e raportit të defektit në kod"</string> @@ -251,6 +251,7 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"Certifikimi i ekranit valor"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"Aktivizo hyrjen Wi-Fi Verbose"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"Përshpejtimi i skanimit të Wi‑Fi"</string> + <string name="wifi_enhanced_mac_randomization" msgid="5437378364995776979">"Renditja e rastësishme e adresave MAC të përmirësuara me Wi-Fi"</string> <string name="mobile_data_always_on" msgid="8275958101875563572">"Të dhënat celulare gjithmonë aktive"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"Përshpejtimi i harduerit për ndarjen e lidhjes (internet)"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"Shfaq pajisjet me Bluetooth pa emra"</string> @@ -283,6 +284,7 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"Shfaq opsionet për certifikimin e ekranit valor"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Rrit nivelin regjistrues të Wi‑Fi duke shfaqur SSID RSSI-në te Zgjedhësi i Wi‑Fi"</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"Zvogëlon shkarkimin e baterisë dhe përmirëson cilësinë e funksionimit të rrjetit"</string> + <string name="wifi_enhanced_mac_randomization_summary" msgid="7925425746373704991">"Ky ndryshim ndikon te sjellja e renditjes së rastësishme të adresave MAC vetëm për modalitetin e klientit.\nKur aktivizohet ky modalitet, çdo rrjet që ka të aktivizuar renditjen e rastësishme të adresave MAC mund t\'i rirendisë adresat e veta MAC gjatë shoqërimit, në varësi të kohës kur është shkëputur klienti për herë të fundit nga rrjeti. Rirenditja e rastësishme nuk ndodh nëse pajisja lidhet brenda 4 orëve ose më pak."</string> <string name="wifi_metered_label" msgid="8737187690304098638">"Me matje"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"Pa matje"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"Madhësitë e regjistruesit"</string> @@ -300,8 +302,8 @@ <string name="tethering_hardware_offload_summary" msgid="7801345335142803029">"Përdor përshpejtimin e harduerit për ndarjen e lidhjes (internet) nëse është i disponueshëm"</string> <string name="adb_warning_title" msgid="7708653449506485728">"Të lejohet korrigjimi i USB-së?"</string> <string name="adb_warning_message" msgid="8145270656419669221">"Korrigjuesi i USB-së është vetëm për qëllime zhvillimore. Përdore për të kopjuar të dhëna mes kompjuterit dhe pajisjes tënde, për të instaluar aplikacione në pajisjen tënde pa asnjë njoftim si dhe për të lexuar të dhënat e ditarit."</string> - <string name="adbwifi_warning_title" msgid="727104571653031865">"Të lejohet korrigjimi me valë?"</string> - <string name="adbwifi_warning_message" msgid="8005936574322702388">"Korrigjimi me valë është vetëm për qëllime zhvillimore. Përdore për të kopjuar të dhëna mes kompjuterit dhe pajisjes sate, për të instaluar aplikacione në pajisjen tënde pa asnjë njoftim si dhe për të lexuar të dhënat e regjistrit."</string> + <string name="adbwifi_warning_title" msgid="727104571653031865">"Të lejohet korrigjimi përmes Wi-Fi?"</string> + <string name="adbwifi_warning_message" msgid="8005936574322702388">"Korrigjimin përmes Wi-Fi është vetëm për qëllime zhvillimore. Përdore për të kopjuar të dhëna mes kompjuterit dhe pajisjes sate, për të instaluar aplikacione në pajisjen tënde pa asnjë njoftim si dhe për të lexuar të dhënat e regjistrit."</string> <string name="adb_keys_warning_message" msgid="2968555274488101220">"Të bllokohet qasja për korrigjim të USB-së nga të gjithë kompjuterët që ke autorizuar më parë?"</string> <string name="dev_settings_warning_title" msgid="8251234890169074553">"Të lejohen cilësimet e zhvillimit?"</string> <string name="dev_settings_warning_message" msgid="37741686486073668">"Këto cilësime janë të projektuara vetëm për përdorim në programim. Ato mund të shkaktojnë që pajisja dhe aplikacionet në të, të mos punojnë ose të veprojnë në mënyrë të gabuar."</string> @@ -371,6 +373,8 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"Shfaq raportet ANR (Aplikacioni nuk përgjigjet) për aplikacionet në sfond"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"Shfaq paralajmërimet e kanalit të njoftimeve"</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"Shfaq paralajmërimin në ekran kur një aplikacion poston një njoftim pa një kanal të vlefshëm"</string> + <string name="enforce_shortcuts_for_conversations" msgid="7040735163945040763">"Zbato shkurtoret për njoftimet e bisedave"</string> + <string name="enforce_shortcuts_for_conversations_summary" msgid="1860168037282467862">"Kërko që informacionet të mbështeten nga një shkurtore ndarjeje afatgjatë që ato të shfaqen në seksionin e bashkëbisedimit"</string> <string name="force_allow_on_external" msgid="9187902444231637880">"Detyro lejimin në hapësirën e jashtme"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Bën që çdo aplikacion të jetë i përshtatshëm për t\'u shkruar në hapësirën ruajtëse të jashtme, pavarësisht nga vlerat e manifestit"</string> <string name="force_resizable_activities" msgid="7143612144399959606">"Detyro madhësinë e ndryshueshme për aktivitetet"</string> @@ -443,7 +447,7 @@ <string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7703677921000858479">"Tableti mund të fiket së shpejti (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string> <string name="power_remaining_duration_shutdown_imminent" product="device" msgid="4374784375644214578">"Pajisja mund të fiket së shpejti (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string> <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string> - <string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"<xliff:g id="TIME">%1$s</xliff:g> të mbetura për karikimin"</string> + <string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"<xliff:g id="TIME">%1$s</xliff:g> të mbetura deri në karikim"</string> <string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> deri sa të karikohen"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"I panjohur"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"Po karikohet"</string> diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml index 775b7d504e1e..45dbd365ba6d 100644 --- a/packages/SettingsLib/res/values-sr/strings.xml +++ b/packages/SettingsLib/res/values-sr/strings.xml @@ -212,7 +212,7 @@ <string name="adb_wireless_settings" msgid="2295017847215680229">"Бежично отклањање грешака"</string> <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Да бисте видели и користили доступне уређаје, укључите бежично отклањање грешака"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"Упарите уређај помоћу QR кода"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"Упарите нове уређаје помоћу читача QR кода"</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"Упарите нове уређаје помоћу читача QR кода"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"Упарите уређај помоћу кода за упаривање"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"Упарите нове уређаје помоћу шестоцифреног кода"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"Упарени уређаји"</string> @@ -231,7 +231,7 @@ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"Упаривање уређаја није успело. QR кôд је погрешан или уређај није повезан са истом мрежом."</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP адреса и порт"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"Скенирај QR кôд"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"Упарите уређај помоћу Wi‑Fi мреже или тако што ћете скенирати QR кôд"</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Упарите уређај помоћу Wi‑Fi мреже тако што ћете скенирати QR кôд"</string> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Повежите се на Wi-Fi мрежу"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, отклањање грешака, програмер"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"Пречица за извештај о грешкама"</string> @@ -251,6 +251,7 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"Сертификација бежичног екрана"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"Омогући детаљнију евиденцију за Wi‑Fi"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"Успоравање Wi-Fi скенирања"</string> + <string name="wifi_enhanced_mac_randomization" msgid="5437378364995776979">"Насумично MAC разврставање по Wi‑Fi‑ју"</string> <string name="mobile_data_always_on" msgid="8275958101875563572">"Мобилни подаци су увек активни"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"Хардверско убрзање привезивања"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"Прикажи Bluetooth уређаје без назива"</string> @@ -283,6 +284,7 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"Приказ опција за сертификацију бежичног екрана"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Повећава ниво евидентирања за Wi‑Fi. Приказ по SSID RSSI-у у бирачу Wi‑Fi мреже"</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"Смањује потрошњу батерије и побољшава учинак мреже"</string> + <string name="wifi_enhanced_mac_randomization_summary" msgid="7925425746373704991">"Овај прекидач утиче на понашање насумичног разврставања MAC адреса само за режим клијента.\nКада се овај режим активира, за мреже на којима је омогућено насумично разврставање MAC адреса може да дође до поновног насумичног разврставања MAC адреса током повезивања, у зависности од тога када се клијент пре тога искључио са мреже. До поновног насумичног разврставања не долази ако се уређај поново повеже за 4 сата или мање."</string> <string name="wifi_metered_label" msgid="8737187690304098638">"Са ограничењем"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"Без ограничења"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"Величине бафера података у програму за евидентирање"</string> @@ -371,6 +373,8 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"Прикажи дијалог Апликација не реагује за апликације у позадини"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"Приказуј упозорења због канала за обавештења"</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"Приказује упозорење на екрану када апликација постави обавештење без важећег канала"</string> + <string name="enforce_shortcuts_for_conversations" msgid="7040735163945040763">"Примењуј пречице за обавештења о конверзацијама"</string> + <string name="enforce_shortcuts_for_conversations_summary" msgid="1860168037282467862">"Захтева да обавештења имају и дугорочну пречицу за дељење како би се појављивала у одељку за конверзације"</string> <string name="force_allow_on_external" msgid="9187902444231637880">"Принудно дозволи апликације у спољној"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Омогућава уписивање свих апликација у спољну меморију, без обзира на вредности манифеста"</string> <string name="force_resizable_activities" msgid="7143612144399959606">"Принудно омогући промену величине активности"</string> diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml index e40ba29eadc1..92ec6369afbe 100644 --- a/packages/SettingsLib/res/values-sv/strings.xml +++ b/packages/SettingsLib/res/values-sv/strings.xml @@ -212,7 +212,7 @@ <string name="adb_wireless_settings" msgid="2295017847215680229">"Trådlös felsökning"</string> <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Aktivera trådlös felsökning om du vill se tillgängliga enheter"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"Parkoppla enheten med en QR-kod"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"Koppla nya enheter med QR-kodsläsare"</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"Parkoppla nya enheter med QR-kodsläsare"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"Koppla enheten med en kopplingskod"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"Koppla nya enheter med en sexsiffrig kod"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"Kopplade enheter"</string> @@ -231,7 +231,7 @@ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"Det gick inte att parkoppla enheten. Antingen var det fel QR-kod eller är enheten inte ansluten till samma nätverk."</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP-adress och port"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"Skanna QR-kod"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"Parkoppla enheten via Wi-Fi genom att skanna en QR-kod"</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Parkoppla enheten via Wi-Fi genom att skanna en QR-kod"</string> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Anslut till ett Wi-Fi-nätverk"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, debug, dev, felsöka, felsökning"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"Genväg till felrapport"</string> @@ -251,6 +251,7 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"Certifiering för Wi-Fi-skärmdelning"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"Aktivera utförlig loggning för Wi-Fi"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"Begränsning av Wi-Fi-sökning"</string> + <string name="wifi_enhanced_mac_randomization" msgid="5437378364995776979">"Wi‑Fi‑förstärkt MAC-slumpgenerering"</string> <string name="mobile_data_always_on" msgid="8275958101875563572">"Mobildata alltid aktiverad"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"Maskinvaruacceleration för internetdelning"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"Visa namnlösa Bluetooth-enheter"</string> @@ -283,6 +284,7 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"Visa certifieringsalternativ för Wi-Fi-skärmdelning"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Öka loggningsnivån för Wi-Fi, visa per SSID RSSI i Wi‑Fi Picker"</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"Sänker batteriförbrukningen och förbättrar nätverksprestandan"</string> + <string name="wifi_enhanced_mac_randomization_summary" msgid="7925425746373704991">"Detta läge påverkar endast MAC-slumpgenereringens beteende för klientläget.\nNär läget aktiveras kan alla nätverk som har MAC-slumpgenerering aktiverat få sina adresser slumpgenererade på nytt under kopplingen, beroende på när klienten senast kopplade från nätverket. Det sker ingen ny slumpgenerering om enheten återansluter inom fyra timmar."</string> <string name="wifi_metered_label" msgid="8737187690304098638">"Med datapriser"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"Utan datapriser"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"Buffertstorlekar för logg"</string> @@ -371,6 +373,8 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"Visa dialogrutan om att appen inte svarar för bakgrundsappar"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"Visa varningar om aviseringskanal"</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"Visa varningar på skärmen när en app lägger upp en avisering utan en giltig kanal"</string> + <string name="enforce_shortcuts_for_conversations" msgid="7040735163945040763">"Kräv genvägar för konversationsaviseringar"</string> + <string name="enforce_shortcuts_for_conversations_summary" msgid="1860168037282467862">"Kräv att aviseringar har en långlivad delningsgenväg för att få visas i konversationsavsnittet"</string> <string name="force_allow_on_external" msgid="9187902444231637880">"Tillåt appar i externt lagringsutrymme"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Allar appar kan skrivas till extern lagring, oavsett manifestvärden"</string> <string name="force_resizable_activities" msgid="7143612144399959606">"Framtvinga storleksanpassning för aktiviteter"</string> diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml index 815896df5512..2a093525b8a1 100644 --- a/packages/SettingsLib/res/values-sw/strings.xml +++ b/packages/SettingsLib/res/values-sw/strings.xml @@ -212,7 +212,7 @@ <string name="adb_wireless_settings" msgid="2295017847215680229">"Utatuzi usiotumia waya"</string> <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Ili kungalia na kutumia vifaa vinavyopatikana, washa utatuzi usiotumia waya"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"Oanisha kifaa ukitumia msimbo wa QR"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"Oanisha vifaa vipya ukitumia Kichanganuzi cha Msimbo wa QR"</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"Oanisha vifaa vipya ukitumia kichanganuzi cha Msimbo wa QR"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"Oanisha kifaa ukitumia msimbo wa kuoanisha"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"Oanisha vifaa vipya ukitumia msimbo wa tarakimu sita"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"Vifaa vilivyooanishwa"</string> @@ -231,7 +231,7 @@ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"Imeshindwa kuoanisha kifaa. Huenda msimbo wa QR haukuwa sahihi au kifaa hakijaunganishwa kwenye mtandao mmoja."</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"Anwani ya IP na Mlango"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"Changanua msimbo wa QR"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"Oanisha kifaa kupitia Wi-Fi kwa kuchanganua Msimbo wa QR"</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Oanisha kifaa kupitia Wi-Fi kwa kuchanganua msimbo wa QR"</string> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Tafadhali unganisha kwenye mtandao wa Wi-Fi"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, tatua, dev"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"Njia ya mkato ya kuripoti hitilafu"</string> @@ -251,6 +251,7 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"Chaguo za cheti cha kuonyesha pasiwaya"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"Washa Uwekaji kumbukumbu za WiFi kutumia Sauti"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"Kudhibiti utafutaji wa Wi-Fi"</string> + <string name="wifi_enhanced_mac_randomization" msgid="5437378364995776979">"Kuweka nasibu kwenye MAC iliyoimarishwa na Wi-Fi"</string> <string name="mobile_data_always_on" msgid="8275958101875563572">"Iendelee kutumia data ya simu"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"Kuongeza kasi kwa kutumia maunzi ili kusambaza mtandao"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"Onyesha vifaa vya Bluetooth visivyo na majina"</string> @@ -283,6 +284,7 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"Onyesha chaguo za cheti cha kuonyesha pasiwaya"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Ongeza hatua ya uwekaji kumbukumbu ya Wi-Fi, onyesha kwa kila SSID RSSI kwenye Kichukuzi cha Wi-Fi"</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"Hupunguza matumizi ya chaji ya betri na kuboresha utendaji wa mtandao"</string> + <string name="wifi_enhanced_mac_randomization_summary" msgid="7925425746373704991">"Hali hii ya kugeuza huathiri utendaji wa kuweka nasibu kwenye anwani ya MAC katika hali ya kiteja pekee.\nWakati hali hii imewashwa, mitandao yoyote ambapo kipengele cha unasibu wa MAC kimewashwa inaweza kuruhusu anwani zao za MAC kuwekwa nasibu tena wakati wa ushirikiano, kulingana na mara ya mwisho kiteja kilipoacha kuunganisha kwenye mtandao. Tukio la kuweka unasibu tena halitokei ikiwa kifaa kitaunganisha tena baada ya muda usiozidi saa nne."</string> <string name="wifi_metered_label" msgid="8737187690304098638">"Mtandao unapima data"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"Mtandao usiopima data"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"Ukubwa wa kiweka bafa ya kumbukumbu"</string> @@ -371,6 +373,8 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"Onyesha kidirisha cha Programu Kutorejesha Majibu kwa programu zinazotumika chinichini"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"Onyesha arifa za maonyo ya kituo"</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"Huonyesha onyo kwenye skrini programu inapochapisha arifa bila kituo sahihi."</string> + <string name="enforce_shortcuts_for_conversations" msgid="7040735163945040763">"Tekeleza njia za mkato za arifa za mazungumzo"</string> + <string name="enforce_shortcuts_for_conversations_summary" msgid="1860168037282467862">"Weka mipangilio ili nakala za arifa zihifadhiwe kwa njia ya zamani ya mkato ya kushiriki ili zionekane katika sehemu ya mazungumzo"</string> <string name="force_allow_on_external" msgid="9187902444231637880">"Lazima uruhusu programu kwenye hifadhi ya nje"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Huruhusu programu yoyote iwekwe kwenye hifadhi ya nje, bila kujali thamani za faili ya maelezo"</string> <string name="force_resizable_activities" msgid="7143612144399959606">"Lazimisha shughuli ziweze kubadilishwa ukubwa"</string> @@ -443,8 +447,8 @@ <string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7703677921000858479">"Huenda kompyuta kibao ikazima hivi karibuni (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string> <string name="power_remaining_duration_shutdown_imminent" product="device" msgid="4374784375644214578">"Huenda kifaa kikazima hivi karibuni (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string> <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string> - <string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"Zimesalia <xliff:g id="TIME">%1$s</xliff:g> hadi ijae chaji"</string> - <string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> hadi ijae chaji"</string> + <string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"Imebakisha <xliff:g id="TIME">%1$s</xliff:g> ijae chaji"</string> + <string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ijae chaji"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"Haijulikani"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"Inachaji"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Inachaji kwa kasi"</string> diff --git a/packages/SettingsLib/res/values-ta/strings.xml b/packages/SettingsLib/res/values-ta/strings.xml index 5080c31c27d7..16f5f12bf3ef 100644 --- a/packages/SettingsLib/res/values-ta/strings.xml +++ b/packages/SettingsLib/res/values-ta/strings.xml @@ -206,13 +206,14 @@ <string name="enable_adb" msgid="8072776357237289039">"USB பிழைதிருத்தம்"</string> <string name="enable_adb_summary" msgid="3711526030096574316">"USB இணைக்கப்பட்டிருக்கும்போது பிழைத்திருத்தப் பயன்முறையை அமை"</string> <string name="clear_adb_keys" msgid="3010148733140369917">"USB பிழைத்திருத்த அங்கீகரிப்புகளை நிராகரி"</string> - <string name="enable_adb_wireless" msgid="6973226350963971018">"வயர்லெஸ் பிழைதிருத்தம்"</string> + <string name="enable_adb_wireless" msgid="6973226350963971018">"வைஃபை பிழைதிருத்தம்"</string> <string name="enable_adb_wireless_summary" msgid="7344391423657093011">"வைஃபையை இணைக்கும்போது பிழைதிருத்தப் பயன்முறை இயக்கப்படும்"</string> <string name="adb_wireless_error" msgid="721958772149779856">"பிழை"</string> - <string name="adb_wireless_settings" msgid="2295017847215680229">"வயர்லெஸ் பிழைதிருத்தம்"</string> - <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"கிடைக்கும் சாதனங்களைப் பார்க்கவும் பயன்படுத்தவும் வயர்லெஸ் பிழைதிருத்தத்தை ஆன் செய்யவும்"</string> + <string name="adb_wireless_settings" msgid="2295017847215680229">"வைஃபை பிழைதிருத்தம்"</string> + <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"கிடைக்கும் சாதனங்களைப் பார்க்கவும் பயன்படுத்தவும் வைஃபை பிழைதிருத்தத்தை ஆன் செய்யவும்"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"QR குறியீட்டின் மூலம் சாதனத்தை இணைத்தல்"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"QR குறியீடு ஸ்கேனரைப் பயன்படுத்தி புதிய சாதனங்களை இணைக்கலாம்"</string> + <!-- no translation found for adb_pair_method_qrcode_summary (7130694277228970888) --> + <skip /> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"இணைத்தல் குறியீட்டின் மூலம் சாதனத்தை இணைத்தல்"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"ஆறு இலக்கக் குறியீட்டைப் பயன்படுத்தி புதிய சாதனங்களை இணைக்கலாம்"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"இணைக்கப்பட்ட சாதனங்கள்"</string> @@ -231,9 +232,9 @@ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"சாதனத்துடன் இணைக்க முடியவில்லை. தவறான QR குறியீடாகவோ சாதனம் அதே நெர்வொர்க்குடன் இணைக்கப்படாமலோ இருக்கலாம்."</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP முகவரி & போர்ட்"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"QR குறியீட்டை ஸ்கேன் செய்தல்"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"QR குறியீட்டை ஸ்கேன் செய்வதன் மூலம் சாதனத்தை வைஃபை மூலம் இணைக்கலாம்"</string> - <!-- no translation found for adb_wireless_no_network_msg (2365795244718494658) --> + <!-- no translation found for adb_wireless_qrcode_pairing_description (6014121407143607851) --> <skip /> + <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"வைஃபை நெட்வொர்க்குடன் இணைக்கவும்"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, debug, dev"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"பிழைப் புகாருக்கான ஷார்ட்கட்"</string> <string name="bugreport_in_power_summary" msgid="1885529649381831775">"பிழை அறிக்கையைப் பெற பவர் மெனுவில் விருப்பத்தைக் காட்டு"</string> @@ -252,6 +253,8 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"வயர்லெஸ் காட்சிக்கான சான்றிதழ்"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"வைஃபை அதிவிவர நுழைவை இயக்கு"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"வைஃபை ஸ்கேனிங்கை வரம்பிடுதல்"</string> + <!-- no translation found for wifi_enhanced_mac_randomization (5437378364995776979) --> + <skip /> <string name="mobile_data_always_on" msgid="8275958101875563572">"மொபைல் டேட்டாவை எப்போதும் இயக்கத்திலேயே வை"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"வன்பொருள் விரைவுப்படுத்துதல் இணைப்பு முறை"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"பெயர்கள் இல்லாத புளூடூத் சாதனங்களைக் காட்டு"</string> @@ -284,6 +287,8 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"வயர்லெஸ் காட்சி சான்றுக்கான விருப்பங்களைக் காட்டு"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"வைஃபை நுழைவு அளவை அதிகரித்து, வைஃபை தேர்வுக் கருவியில் ஒவ்வொன்றிற்கும் SSID RSSI ஐ காட்டுக"</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"பேட்டரி தீர்ந்துபோவதைக் குறைத்து நெட்வொர்க்கின் செயல்திறனை மேம்படுத்தும்"</string> + <!-- no translation found for wifi_enhanced_mac_randomization_summary (7925425746373704991) --> + <skip /> <string name="wifi_metered_label" msgid="8737187690304098638">"கட்டண நெட்வொர்க்"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"கட்டணமில்லா நெட்வொர்க்"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"லாகர் பஃபர் அளவுகள்"</string> @@ -301,8 +306,8 @@ <string name="tethering_hardware_offload_summary" msgid="7801345335142803029">"வன்பொருள் விரைவுப்படுத்துதல் இணைப்பு முறை கிடைக்கும் போது, அதைப் பயன்படுத்தும்"</string> <string name="adb_warning_title" msgid="7708653449506485728">"USB பிழைதிருத்தத்தை அனுமதிக்கவா?"</string> <string name="adb_warning_message" msgid="8145270656419669221">"USB பிழைதிருத்தம் மேம்படுத்தல் நோக்கங்களுக்காக மட்டுமே. அதை உங்கள் கணினி மற்றும் சாதனத்திற்கு இடையில் தரவை நகலெடுக்கவும், அறிவிப்பு இல்லாமல் உங்கள் சாதனத்தில் ஆப்ஸை நிறுவவும், பதிவு தரவைப் படிக்கவும் பயன்படுத்தவும்."</string> - <string name="adbwifi_warning_title" msgid="727104571653031865">"வயர்லெஸ் பிழைதிருத்தத்தை அனுமதிக்கவா?"</string> - <string name="adbwifi_warning_message" msgid="8005936574322702388">"\'வயர்லெஸ் பிழைதிருத்தம்\' டெவெலப்மெண்ட் நோக்கங்களுக்காக மட்டுமே. அதை உங்கள் கம்ப்யூட்டருக்கும் சாதனத்திற்கும் இடையே தரவை நகலெடுக்கவும், உங்கள் சாதனத்தில் அறிவிப்பின்றி ஆப்ஸை நிறுவவும், பதிவுத் தரவைப் படிக்கவும் பயன்படுத்தவும்."</string> + <string name="adbwifi_warning_title" msgid="727104571653031865">"வைஃபை பிழைதிருத்தத்தை அனுமதிக்கவா?"</string> + <string name="adbwifi_warning_message" msgid="8005936574322702388">"\'வைஃபை பிழைதிருத்தம்\' டெவெலப்மெண்ட் நோக்கங்களுக்காக மட்டுமே. அதை உங்கள் கம்ப்யூட்டருக்கும் சாதனத்திற்கும் இடையே தரவை நகலெடுக்கவும், உங்கள் சாதனத்தில் அறிவிப்பின்றி ஆப்ஸை நிறுவவும், பதிவுத் தரவைப் படிக்கவும் பயன்படுத்தவும்."</string> <string name="adb_keys_warning_message" msgid="2968555274488101220">"நீங்கள் ஏற்கனவே அனுமதித்த எல்லா கணினிகளிலிருந்தும் USB பிழைத்திருத்தத்திற்கான அணுகலைத் திரும்பப்பெற வேண்டுமா?"</string> <string name="dev_settings_warning_title" msgid="8251234890169074553">"மேம்பட்ட அமைப்புகளை அனுமதிக்கவா?"</string> <string name="dev_settings_warning_message" msgid="37741686486073668">"இந்த அமைப்பு மேம்பட்டப் பயன்பாட்டிற்காக மட்டுமே. உங்கள் சாதனம் மற்றும் அதில் உள்ள பயன்பாடுகளைச் சிதைக்கும் அல்லது தவறாகச் செயல்படும் வகையில் பாதிப்பை ஏற்படுத்தும்."</string> @@ -372,6 +377,10 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"பின்புல ஆப்ஸுக்கு, ஆப்ஸ் பதிலளிக்கவில்லை என்ற செய்தியைக் காட்டும்"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"அறிவிப்புச் சேனல் எச்சரிக்கைகளைக் காட்டு"</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"ஆப்ஸானது சரியான சேனல் இல்லாமல் அறிவிப்பை இடுகையிடும் போது, திரையில் எச்சரிக்கையைக் காட்டும்"</string> + <!-- no translation found for enforce_shortcuts_for_conversations (7040735163945040763) --> + <skip /> + <!-- no translation found for enforce_shortcuts_for_conversations_summary (1860168037282467862) --> + <skip /> <string name="force_allow_on_external" msgid="9187902444231637880">"ஆப்ஸை வெளிப்புறச் சேமிப்பிடத்தில் அனுமதி"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"மேனிஃபெஸ்ட் மதிப்புகளைப் பொருட்படுத்தாமல், எல்லா ஆப்ஸையும் வெளிப்புறச் சேமிப்பிடத்தில் எழுத அனுமதிக்கும்"</string> <string name="force_resizable_activities" msgid="7143612144399959606">"செயல்பாடுகளை அளவுமாறக்கூடியதாக அமை"</string> @@ -418,7 +427,7 @@ <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"நிறம் அடையாளங்காண முடியாமை (சிவப்பு-பச்சை)"</string> <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"நிறம் அடையாளங்காண முடியாமை (நீலம்-மஞ்சள்)"</string> <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"வண்ணத்திருத்தம்"</string> - <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1284746051652993443">"வண்ணத் திருத்தத்தைப் பயன்படுத்தி உங்கள் சாதனத்தில் வண்ணம் காண்பிக்கப்படும் விதத்தைச் சரிசெய்யலாம்"</string> + <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1284746051652993443">"கலர் கரெக்ஷனைப் பயன்படுத்தி உங்கள் சாதனத்தில் வண்ணங்கள் காண்பிக்கப்படும் விதத்தைச் சரிசெய்யலாம்"</string> <string name="daltonizer_type_overridden" msgid="4509604753672535721">"<xliff:g id="TITLE">%1$s</xliff:g> மூலம் மேலெழுதப்பட்டது"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="8264199158671531431">"கிட்டத்தட்ட <xliff:g id="TIME_REMAINING">%1$s</xliff:g> மீதமுள்ளது"</string> @@ -432,8 +441,7 @@ <string name="power_discharge_by" msgid="4113180890060388350">"<xliff:g id="TIME">%1$s</xliff:g> வரை பயன்படுத்த முடியும் (<xliff:g id="LEVEL">%2$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> - <!-- no translation found for power_suggestion_battery_run_out (6332089307827787087) --> - <skip /> + <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="5802195288324091585">"<xliff:g id="THRESHOLD">%1$s</xliff:g>க்கும் குறைவாகவே பயன்படுத்த முடியும்"</string> <string name="power_remaining_less_than_duration" msgid="1812668275239801236">"<xliff:g id="THRESHOLD">%1$s</xliff:g>க்கும் குறைவாகவே பயன்படுத்த முடியும் (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="7919119719242734848">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g>க்கும் மேல் பயன்படுத்த முடியும் (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -511,32 +519,21 @@ <string name="media_transfer_this_device_name" msgid="2716555073132169240">"மொபைல் ஸ்பீக்கர்"</string> <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"இணைப்பதில் சிக்கல். சாதனத்தை ஆஃப் செய்து மீண்டும் ஆன் செய்யவும்"</string> <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"வயருடன்கூடிய ஆடியோ சாதனம்"</string> - <!-- no translation found for help_label (3528360748637781274) --> - <skip /> - <!-- no translation found for storage_category (2287342585424631813) --> - <skip /> - <!-- no translation found for shared_data_title (1017034836800864953) --> - <skip /> - <!-- no translation found for shared_data_summary (5516326713822885652) --> - <skip /> + <string name="help_label" msgid="3528360748637781274">"உதவியும் கருத்தும்"</string> + <string name="storage_category" msgid="2287342585424631813">"சேமிப்பகம்"</string> + <string name="shared_data_title" msgid="1017034836800864953">"பகிரப்பட்ட தரவு"</string> + <string name="shared_data_summary" msgid="5516326713822885652">"பகிரப்பட்ட தரவைப் பார்க்கலாம், மாற்றலாம்"</string> <string name="shared_data_no_blobs_text" msgid="3108114670341737434">"இந்தப் பயனருடன் பகிரப்பட்ட தரவு எதுவும் இல்லை."</string> <string name="shared_data_query_failure_text" msgid="3489828881998773687">"பகிரப்பட்ட தரவைப் பெறுவதில் பிழை. மீண்டும் முயலவும்."</string> - <!-- no translation found for blob_id_text (8680078988996308061) --> - <skip /> - <!-- no translation found for blob_expires_text (7882727111491739331) --> - <skip /> + <string name="blob_id_text" msgid="8680078988996308061">"பகிர்ந்த தரவு ஐடி: <xliff:g id="BLOB_ID">%d</xliff:g>"</string> + <string name="blob_expires_text" msgid="7882727111491739331">"<xliff:g id="DATE">%s</xliff:g> அன்று காலாவதியாகும்"</string> <string name="shared_data_delete_failure_text" msgid="3842701391009628947">"பகிரப்பட்ட தரவை நீக்குவதில் பிழை."</string> <string name="shared_data_no_accessors_dialog_text" msgid="8903738462570715315">"இந்தப் பகிரப்பட்ட தரவிற்காகப் பெறப்பட்ட ஒப்பந்தங்கள் எதுவும் இல்லை. இதை நீக்க விரும்புகிறீர்களா?"</string> - <!-- no translation found for accessor_info_title (8289823651512477787) --> - <skip /> - <!-- no translation found for accessor_no_description_text (7510967452505591456) --> - <skip /> - <!-- no translation found for accessor_expires_text (4625619273236786252) --> - <skip /> - <!-- no translation found for delete_blob_text (2819192607255625697) --> - <skip /> - <!-- no translation found for delete_blob_confirmation_text (7807446938920827280) --> - <skip /> + <string name="accessor_info_title" msgid="8289823651512477787">"தரவைப் பகிர்ந்துகொள்ளும் ஆப்ஸ்"</string> + <string name="accessor_no_description_text" msgid="7510967452505591456">"ஆப்ஸ் எந்த விளக்கத்தையும் வழங்கவில்லை."</string> + <string name="accessor_expires_text" msgid="4625619273236786252">"<xliff:g id="DATE">%s</xliff:g> அன்று குத்தகை காலாவதியாகும்"</string> + <string name="delete_blob_text" msgid="2819192607255625697">"பகிரப்பட்ட தரவை நீக்கு"</string> + <string name="delete_blob_confirmation_text" msgid="7807446938920827280">"பகிரப்பட்ட இந்தத் தரவை நிச்சயமாக நீக்க வேண்டுமா?"</string> <string name="user_add_user_item_summary" msgid="5748424612724703400">"பயனர்கள் தங்களுக்குச் சொந்தமான ஆப்ஸ் மற்றும் உள்ளடக்கத்தை வைத்திருக்க வேண்டும்"</string> <string name="user_add_profile_item_summary" msgid="5418602404308968028">"உங்கள் கணக்கிலிருந்து ஆப்ஸ் மற்றும் உள்ளடக்கத்திற்கான அணுகலை நீங்கள் வரையறுக்கலாம்"</string> <string name="user_add_user_item_title" msgid="2394272381086965029">"பயனர்"</string> @@ -556,12 +553,8 @@ <string name="profile_info_settings_title" msgid="105699672534365099">"சுயவிவரத் தகவல்"</string> <string name="user_need_lock_message" msgid="4311424336209509301">"நீங்கள் வரையறுக்கப்பட்டச் சுயவிவரத்தை உருவாக்குவதற்கு முன்பு, உங்கள் ஆப்ஸ் மற்றும் தனிப்பட்ட தரவைப் பாதுகாக்கும் வகையில் நீங்கள் திரைப் பூட்டை அமைக்க வேண்டும்."</string> <string name="user_set_lock_button" msgid="1427128184982594856">"பூட்டை அமை"</string> - <!-- no translation found for user_switch_to_user (6975428297154968543) --> - <skip /> - <!-- no translation found for guest_new_guest (3482026122932643557) --> - <skip /> - <!-- no translation found for guest_exit_guest (5908239569510734136) --> - <skip /> - <!-- no translation found for guest_nickname (6332276931583337261) --> - <skip /> + <string name="user_switch_to_user" msgid="6975428297154968543">"<xliff:g id="USER_NAME">%s</xliff:g>க்கு மாறு"</string> + <string name="guest_new_guest" msgid="3482026122932643557">"கெஸ்ட்டைச் சேர்"</string> + <string name="guest_exit_guest" msgid="5908239569510734136">"கெஸ்ட்டை அகற்று"</string> + <string name="guest_nickname" msgid="6332276931583337261">"கெஸ்ட்"</string> </resources> diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml index 0e763ddc7207..cead9dfc53a7 100644 --- a/packages/SettingsLib/res/values-te/strings.xml +++ b/packages/SettingsLib/res/values-te/strings.xml @@ -212,7 +212,7 @@ <string name="adb_wireless_settings" msgid="2295017847215680229">"వైర్లెస్ డీబగ్గింగ్"</string> <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"అందుబాటులో వున్న పరికరాలను చూడటానికి, ఉపయోగించడానికి, వైర్లెస్ డీబగ్గింగ్ను ఆన్ చేయండి"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"QR కోడ్తో పరికరాన్ని పెయిర్ చేయండి"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"QR కోడ్ స్కానర్ను ఉపయోగించి కొత్త పరికరాలను పెయిర్ చేయండి"</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"QR కోడ్ స్కానర్ను ఉపయోగించి కొత్త పరికరాలను పెయిర్ చేయండి"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"పెయిరింగ్ కోడ్తో పరికరాన్ని పెయిర్ చేయండి"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"ఆరు అంకెల కోడ్ను ఉపయోగించి కొత్త పరికరాలను పెయిర్ చేయండి"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"పెయిర్ చేయబడిన పరికరాలు"</string> @@ -231,7 +231,7 @@ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"పరికరాన్ని పెయిర్ చేయడం విఫలమైంది. QR కోడ్ తప్పుగా ఉండడం గాని, లేదా పరికరం అదే నెట్వర్క్కు కనెక్ట్ అయి లేకపోవడం గాని జరిగింది."</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP చిరునామా & పోర్ట్"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"QR కోడ్ను స్కాన్ చేయండి"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"పరికరాన్ని Wi-Fi ద్వారా పెయిర్ చేయడానికి QR కోడ్ను స్కాన్ చేయండి"</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"QR కోడ్ను స్కాన్ చేయడం ద్వారా Wi-Fiని ఉపయోగించి పరికరాన్ని పెయిర్ చెయ్యండి"</string> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"దయచేసి Wi-Fi నెట్వర్క్కు కనెక్ట్ చేయండి"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, డీబగ్, dev"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"బగ్ నివేదిక షార్ట్కట్"</string> @@ -251,6 +251,8 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"వైర్లెస్ ప్రదర్శన ప్రామాణీకరణ"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"Wi‑Fi విశదీకృత లాగింగ్ను ప్రారంభించండి"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"Wi‑Fi స్కాన్ కుదింపు"</string> + <!-- no translation found for wifi_enhanced_mac_randomization (5437378364995776979) --> + <skip /> <string name="mobile_data_always_on" msgid="8275958101875563572">"మొబైల్ డేటాని ఎల్లప్పుడూ యాక్టివ్గా ఉంచు"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"టెథెరింగ్ హార్డ్వేర్ వేగవృద్ధి"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"పేర్లు లేని బ్లూటూత్ పరికరాలు చూపించు"</string> @@ -283,6 +285,8 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"వైర్లెస్ ప్రదర్శన సర్టిఫికెట్ కోసం ఎంపికలను చూపు"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Wi‑Fi ఎంపికలో SSID RSSI ప్రకారం చూపబడే Wi‑Fi లాగింగ్ స్థాయిని పెంచండి"</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"బ్యాటరీ శక్తి వినియోగాన్ని తగ్గించి & నెట్వర్క్ పనితీరును మెరుగుపరుస్తుంది"</string> + <!-- no translation found for wifi_enhanced_mac_randomization_summary (7925425746373704991) --> + <skip /> <string name="wifi_metered_label" msgid="8737187690304098638">"గణించబడుతోంది"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"గణించబడటం లేదు"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"లాగర్ బఫర్ పరిమాణాలు"</string> @@ -371,6 +375,8 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"నేపథ్య యాప్ల కోసం యాప్ ప్రతిస్పందించడం లేదు అనే డైలాగ్ను చూపు"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"ఛానెల్ హెచ్చరికల నోటిఫికేషన్ను చూపు"</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"చెల్లుబాటు అయ్యే ఛానెల్ లేకుండా యాప్ నోటిఫికేషన్ను పోస్ట్ చేస్తున్నప్పుడు స్క్రీన్పై హెచ్చరికను చూపిస్తుంది"</string> + <string name="enforce_shortcuts_for_conversations" msgid="7040735163945040763">"సంభాషణ నోటిఫికేషన్లకు షార్ట్కట్ల అమలు"</string> + <string name="enforce_shortcuts_for_conversations_summary" msgid="1860168037282467862">"సంభాషణల విభాగంలో కనిపించడానికి చిరకాలం నిలిచిపోయే భాగస్వామ్య సత్వరమార్గం ద్వారా నోటిఫికేషన్లకు మద్దతు ఉండాలి."</string> <string name="force_allow_on_external" msgid="9187902444231637880">"యాప్లను బాహ్య నిల్వలో తప్పనిసరిగా అనుమతించు"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"ఏ యాప్ని అయినా మానిఫెస్ట్ విలువలతో సంబంధం లేకుండా బాహ్య నిల్వలో సేవ్ చేయడానికి అనుమతిస్తుంది"</string> <string name="force_resizable_activities" msgid="7143612144399959606">"కార్యకలాపాల విండోల పరిమాణం మార్చగలిగేలా నిర్బంధించు"</string> diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml index b24f006ddbe6..64fa9fb68c7d 100644 --- a/packages/SettingsLib/res/values-th/strings.xml +++ b/packages/SettingsLib/res/values-th/strings.xml @@ -23,7 +23,7 @@ <string name="wifi_fail_to_scan" msgid="2333336097603822490">"ไม่สามารถสแกนหาเครือข่าย"</string> <string name="wifi_security_none" msgid="7392696451280611452">"ไม่มี"</string> <string name="wifi_remembered" msgid="3266709779723179188">"บันทึกแล้ว"</string> - <string name="wifi_disconnected" msgid="7054450256284661757">"เลิกเชื่อมต่อแล้ว"</string> + <string name="wifi_disconnected" msgid="7054450256284661757">"ยกเลิกการเชื่อมต่อแล้ว"</string> <string name="wifi_disabled_generic" msgid="2651916945380294607">"ปิดอยู่"</string> <string name="wifi_disabled_network_failure" msgid="2660396183242399585">"การกำหนดค่า IP ล้มเหลว"</string> <string name="wifi_disabled_by_recommendation_provider" msgid="1302938248432705534">"ไม่ได้เชื่อมต่อเนื่องจากเครือข่ายคุณภาพต่ำ"</string> @@ -35,7 +35,7 @@ <string name="wifi_not_in_range" msgid="1541760821805777772">"ไม่อยู่ในพื้นที่ให้บริการ"</string> <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"จะไม่เชื่อมต่อโดยอัตโนมัติ"</string> <string name="wifi_no_internet" msgid="1774198889176926299">"เข้าถึงอินเทอร์เน็ตไม่ได้"</string> - <string name="saved_network" msgid="7143698034077223645">"บันทึกโดย <xliff:g id="NAME">%1$s</xliff:g> แล้ว"</string> + <string name="saved_network" msgid="7143698034077223645">"บันทึกโดย<xliff:g id="NAME">%1$s</xliff:g> แล้ว"</string> <string name="connected_via_network_scorer" msgid="7665725527352893558">"เชื่อมต่ออัตโนมัติผ่าน %1$s แล้ว"</string> <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"เชื่อมต่ออัตโนมัติผ่านผู้ให้บริการการจัดอันดับเครือข่าย"</string> <string name="connected_via_passpoint" msgid="7735442932429075684">"เชื่อมต่อผ่าน %1$s แล้ว"</string> @@ -155,7 +155,7 @@ <string name="launch_defaults_some" msgid="3631650616557252926">"ตั้งค่าเริ่มต้นไว้บางส่วน"</string> <string name="launch_defaults_none" msgid="8049374306261262709">"ไม่ได้ตั้งค่าเริ่มต้น"</string> <string name="tts_settings" msgid="8130616705989351312">"การตั้งค่าการอ่านออกเสียงข้อความ"</string> - <string name="tts_settings_title" msgid="7602210956640483039">"เอาต์พุตการอ่านออกเสียง"</string> + <string name="tts_settings_title" msgid="7602210956640483039">"เอาต์พุตการอ่านออกเสียงข้อความ"</string> <string name="tts_default_rate_title" msgid="3964187817364304022">"ความเร็วของคำพูด"</string> <string name="tts_default_rate_summary" msgid="3781937042151716987">"ความเร็วในการพูดข้อความ"</string> <string name="tts_default_pitch_title" msgid="6988592215554485479">"ความสูง-ต่ำของเสียง"</string> @@ -196,7 +196,7 @@ <string name="choose_profile" msgid="343803890897657450">"เลือกโปรไฟล์"</string> <string name="category_personal" msgid="6236798763159385225">"ส่วนตัว"</string> <string name="category_work" msgid="4014193632325996115">"ที่ทำงาน"</string> - <string name="development_settings_title" msgid="140296922921597393">"สำหรับนักพัฒนาซอฟต์แวร์"</string> + <string name="development_settings_title" msgid="140296922921597393">"ตัวเลือกสำหรับนักพัฒนาซอฟต์แวร์"</string> <string name="development_settings_enable" msgid="4285094651288242183">"เปิดใช้ตัวเลือกสำหรับนักพัฒนาซอฟต์แวร์"</string> <string name="development_settings_summary" msgid="8718917813868735095">"ตั้งค่าตัวเลือกสำหรับการพัฒนาแอปพลิเคชัน"</string> <string name="development_settings_not_available" msgid="355070198089140951">"ตัวเลือกสำหรับนักพัฒนาซอฟต์แวร์ไม่สามารถใช้ได้สำหรับผู้ใช้นี้"</string> @@ -212,7 +212,7 @@ <string name="adb_wireless_settings" msgid="2295017847215680229">"การแก้ไขข้อบกพร่องผ่าน Wi-Fi"</string> <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"หากต้องการดูและใช้อุปกรณ์ที่มีอยู่ ให้เปิดการแก้ไขข้อบกพร่องผ่าน Wi-Fi"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"จับคู่อุปกรณ์ด้วยคิวอาร์โค้ด"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"จับคู่อุปกรณ์เครื่องใหม่โดยใช้เครื่องมือสแกนคิวอาร์โค้ด"</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"จับคู่อุปกรณ์เครื่องใหม่โดยใช้เครื่องมือสแกนคิวอาร์โค้ด"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"จับคู่อุปกรณ์ด้วยรหัสการจับคู่"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"จับคู่อุปกรณ์เครื่องใหม่โดยใช้รหัสตัวเลข 6 หลัก"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"อุปกรณ์ที่จับคู่"</string> @@ -231,7 +231,7 @@ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"จับคู่อุปกรณ์ไม่สำเร็จ คิวอาร์โค้ดไม่ถูกต้อง หรืออุปกรณ์ไม่ได้เชื่อมต่อกับเครือข่ายเดียวกัน"</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"ที่อยู่ IP และพอร์ต"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"สแกนคิวอาร์โค้ด"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"จับคู่อุปกรณ์ผ่าน Wi‑Fi ด้วยการสแกนคิวอาร์โค้ด"</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"จับคู่อุปกรณ์ผ่าน Wi‑Fi ด้วยการสแกนคิวอาร์โค้ด"</string> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"โปรดเชื่อมต่อกับเครือข่าย Wi-Fi"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, แก้ไขข้อบกพร่อง, พัฒนา"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"ทางลัดรายงานข้อบกพร่อง"</string> @@ -251,6 +251,7 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"การรับรองการแสดงผลแบบไร้สาย"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"เปิดใช้การบันทึกรายละเอียด Wi-Fi"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"การควบคุมการสแกนหา Wi‑Fi"</string> + <string name="wifi_enhanced_mac_randomization" msgid="5437378364995776979">"การสุ่ม MAC เพื่อเพิ่มความปลอดภัย Wi-Fi"</string> <string name="mobile_data_always_on" msgid="8275958101875563572">"เปิดใช้เน็ตมือถือเสมอ"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"การเร่งฮาร์ดแวร์การเชื่อมต่ออินเทอร์เน็ตผ่านมือถือ"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"แสดงอุปกรณ์บลูทูธที่ไม่มีชื่อ"</string> @@ -283,6 +284,7 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"แสดงตัวเลือกสำหรับการรับรองการแสดงผล แบบไร้สาย"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"เพิ่มระดับการบันทึก Wi‑Fi แสดงต่อ SSID RSSI ในตัวเลือก Wi‑Fi"</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"ลดการเปลืองแบตเตอรี่และเพิ่มประสิทธิภาพเครือข่าย"</string> + <string name="wifi_enhanced_mac_randomization_summary" msgid="7925425746373704991">"การตั้งค่านี้ส่งผลต่อลักษณะการสุ่ม MAC ในโหมดไคลเอ็นต์เท่านั้น\nเมื่อเปิดใช้งานโหมดนี้ ทุกเครือข่ายที่มีการเปิดใช้การสุ่ม MAC อาจสุ่มที่อยู่ MAC ซ้ำในระหว่างการเชื่อมโยง ทั้งนี้ขึ้นอยู่กับว่าไคลเอ็นต์ยกเลิกการเชื่อมต่อกับเครือข่ายครั้งสุดท้ายเมื่อใด การสุ่มซ้ำจะไม่เกิดขึ้นหากอุปกรณ์เชื่อมต่ออีกครั้งภายในไม่เกิน 4 ชั่วโมง"</string> <string name="wifi_metered_label" msgid="8737187690304098638">"มีการวัดปริมาณอินเทอร์เน็ต"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"ไม่มีการวัดปริมาณอินเทอร์เน็ต"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"ขนาดบัฟเฟอร์ของตัวบันทึก"</string> @@ -371,6 +373,8 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"แสดงกล่องโต้ตอบ \"แอปไม่ตอบสนอง\" สำหรับแอปพื้นหลัง"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"แสดงคำเตือนจากช่องทางการแจ้งเตือน"</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"แสดงคำเตือนบนหน้าจอเมื่อแอปโพสต์การแจ้งเตือนโดยไม่มีช่องทางที่ถูกต้อง"</string> + <string name="enforce_shortcuts_for_conversations" msgid="7040735163945040763">"บังคับใช้ทางลัดสำหรับการแจ้งเตือนการสนทนา"</string> + <string name="enforce_shortcuts_for_conversations_summary" msgid="1860168037282467862">"ต้องทำให้การแจ้งเตือนปรากฏในส่วนการสนทนาได้อีกถ้ามีการปิดไปโดยใช้ทางลัดการแชร์ที่แสดงอยู่ตลอด"</string> <string name="force_allow_on_external" msgid="9187902444231637880">"บังคับให้แอปสามารถใช้ที่เก็บภายนอก"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"เขียนแอปในพื้นที่เก็บข้อมูลภายนอกได้ โดยไม่คำนึงถึงค่าไฟล์ Manifest"</string> <string name="force_resizable_activities" msgid="7143612144399959606">"บังคับให้กิจกรรมปรับขนาดได้"</string> @@ -443,11 +447,11 @@ <string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7703677921000858479">"แท็บเล็ตอาจปิดเครื่องในไม่ช้า (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string> <string name="power_remaining_duration_shutdown_imminent" product="device" msgid="4374784375644214578">"อุปกรณ์อาจปิดเครื่องในไม่ช้า (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string> <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string> - <string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"เหลือ <xliff:g id="TIME">%1$s</xliff:g> จนกว่าจะชาร์จ"</string> + <string name="power_remaining_charging_duration_only" msgid="7415639699283965818">"เหลือ <xliff:g id="TIME">%1$s</xliff:g> จนกว่าจะชาร์จเต็ม"</string> <string name="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> จนกว่าจะชาร์จ"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"ไม่ทราบ"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"กำลังชาร์จ"</string> - <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"กำลังชาร์จเร็ว"</string> + <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"กำลังชาร์จอย่างเร็ว"</string> <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"กำลังชาร์จอย่างช้าๆ"</string> <string name="battery_info_status_discharging" msgid="6962689305413556485">"ไม่ได้ชาร์จ"</string> <string name="battery_info_status_not_charging" msgid="8330015078868707899">"เสียบอยู่ ไม่สามารถชาร์จได้ในขณะนี้"</string> diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml index 8d70718c98c3..d3af3984789f 100644 --- a/packages/SettingsLib/res/values-tl/strings.xml +++ b/packages/SettingsLib/res/values-tl/strings.xml @@ -112,7 +112,7 @@ <string name="bluetooth_opp_profile_summary_use_for" msgid="461981154387015457">"Ginagamit para sa paglilipat ng file"</string> <string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"Gamitin para sa input"</string> <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="7689393730163320483">"Gamitin para sa Mga Hearing Aid"</string> - <string name="bluetooth_pairing_accept" msgid="2054232610815498004">"Pares"</string> + <string name="bluetooth_pairing_accept" msgid="2054232610815498004">"Ipares"</string> <string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"IPARES"</string> <string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Kanselahin"</string> <string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"Nagbibigay ang pagpapares ng access sa iyong mga contact at history ng tawag kapag nakakonekta."</string> @@ -212,7 +212,7 @@ <string name="adb_wireless_settings" msgid="2295017847215680229">"Wireless na pag-debug"</string> <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Para makita at magamit ang mga available na device, i-on ang wireless na pag-debug"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"Magpares ng device gamit ang QR code"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"Magpares ng mga bagong device gamit ang QR code Scanner"</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"Magpares ng mga bagong device gamit ang pang-scan ng QR code"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"Pinapares ang device gamit ang code ng pagpapares"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"Magpares ng mga bagong device gamit ang six digit na code"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"Mga nakapares na device"</string> @@ -231,7 +231,7 @@ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"Hindi nagawang ipares ang device. Hindi tama ang QR code, o hindi nakakonekta ang device sa parehong network."</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP address at Port"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"I-scan ang QR code"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"Ipares ang device gamit ang Wi‑Fi sa pamamagitan ng pag-scan ng isang QR Code"</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Magpares ng device gamit ang Wi‑Fi sa pamamagitan ng pag-scan ng isang QR code"</string> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Kumonekta sa Wi-Fi network"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, debug, dev"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"Shortcut ng ulat sa bug"</string> @@ -251,6 +251,7 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"Certification ng wireless display"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"I-enable ang Pagla-log sa Wi‑Fi Verbose"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"Pag-throttle ng pag-scan ng Wi‑Fi"</string> + <string name="wifi_enhanced_mac_randomization" msgid="5437378364995776979">"MAC randomization na pinahusay ng Wi‑Fi"</string> <string name="mobile_data_always_on" msgid="8275958101875563572">"Palaging aktibo ang mobile data"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"Hardware acceleration para sa pag-tether"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"Ipakita ang mga Bluetooth device na walang pangalan"</string> @@ -283,6 +284,7 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"Ipakita ang mga opsyon para sa certification ng wireless display"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Pataasin ang antas ng Wi‑Fi logging, ipakita sa bawat SSID RSSI sa Wi‑Fi Picker"</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"Binabawasan ang pagkaubos ng baterya at pinapahusay ang performance ng network"</string> + <string name="wifi_enhanced_mac_randomization_summary" msgid="7925425746373704991">"Nakakaapekto ang toggle na ito sa pag-kilos ng pag-randomize ng MAC para lang sa client mode.\nKapag na-activate ang mode na ito, baka ma-randomize ulit ang MAC address ng anumang network na naka-enable ang pag-randomize sa MAC habang nagaganap ang pag-uugnay, depende kung kailan huling nadiskonekta ang client sa network. Hindi nangyayari ang pag-randomize ulit kung kumonekta ulit ang device sa loob ng 4 na oras o mas maaga."</string> <string name="wifi_metered_label" msgid="8737187690304098638">"Nakametro"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"Hindi Nakametro"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"Mga laki ng buffer ng Logger"</string> @@ -371,6 +373,8 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"Ipakita ang dialog na Hindi Tumutugon ang App para sa mga app sa background"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"Ipakita ang mga babala sa notification channel"</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"Nagpapakita ng babala sa screen kapag nag-post ang app ng notification nang walang wastong channel"</string> + <string name="enforce_shortcuts_for_conversations" msgid="7040735163945040763">"Magpatupad ng mga shortcut para sa mga notification ng pag-uusap"</string> + <string name="enforce_shortcuts_for_conversations_summary" msgid="1860168037282467862">"Ipa-back up ang mga notification gamit ang long-lived na shortcut sa pagbabahagi para lumabas sa seksyong pag-uusap"</string> <string name="force_allow_on_external" msgid="9187902444231637880">"Puwersahang payagan ang mga app sa external"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Ginagawang kwalipikado ang anumang app na mailagay sa external na storage, anuman ang mga value ng manifest"</string> <string name="force_resizable_activities" msgid="7143612144399959606">"Sapilitang gawing resizable ang mga aktibidad"</string> diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml index 3579957fc00c..44238da73e30 100644 --- a/packages/SettingsLib/res/values-tr/strings.xml +++ b/packages/SettingsLib/res/values-tr/strings.xml @@ -212,7 +212,7 @@ <string name="adb_wireless_settings" msgid="2295017847215680229">"Kablosuz hata ayıklama"</string> <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Mevcut cihazları görmek ve kullanmak için kablosuz hata ayıklamayı açın"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"Cihazı QR kodu ile eşle"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"Yeni cihazları QR kodu Tarayıcıyı kullanarak eşleyin"</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"Yeni cihazları QR kodu tarayıcıyı kullanarak eşleyin"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"Eşleme kodu ile cihaz eşleme"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"Yeni cihazları altı basamaklı kodu kullanarak eşleyin"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"Eşlenen cihazlar"</string> @@ -231,7 +231,7 @@ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"Cihaz eşlenemedi. QR kodu hatalı ya da cihaz aynı ağa bağlı değil."</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP adresi ve Bağlantı noktası"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"QR kodunu tara"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"QR kodu tarayarak kablosuz ağ üzerinden cihaz eşleyin"</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"QR kodu tarayarak kablosuz ağ üzerinden cihaz eşleyin"</string> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Lütfen Kablosuz bir ağa bağlanın"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, hata ayıklama, dev"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"Hata raporu kısayolu"</string> @@ -251,6 +251,7 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"Kablosuz ekran sertifikası"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"Kablosuz Ayrıntılı Günlük Kaydını etkinleştir"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"Kablosuz ağ taramasını kısma"</string> + <string name="wifi_enhanced_mac_randomization" msgid="5437378364995776979">"Kablosuz için geliştirilmiş MAC rastgele seçimi"</string> <string name="mobile_data_always_on" msgid="8275958101875563572">"Mobil veri her zaman etkin"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"Tethering donanım hızlandırıcısı"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"Adsız Bluetooth cihazlarını göster"</string> @@ -283,6 +284,7 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"Kablosuz ekran sertifikası seçeneklerini göster"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Kablosuz günlük kaydı seviyesini artır. Kablosuz Seçici\'de her bir SSID RSSI için göster."</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"Pili daha az harcar ve ağ performansını iyileştirir"</string> + <string name="wifi_enhanced_mac_randomization_summary" msgid="7925425746373704991">"Bu geçiş, yalnızca istemci modu için MAC rastgele hale getirme davranışını etkiler.\nBu mod etkinleştirildiğinde, MAC rastgele seçimi etkin olan tüm ağların MAC adresleri, istemcinin ağla bağlantısının en son kesildiği zamana bağlı olarak ilişkilendirme sırasında yeniden rastgele seçilebilir. Cihaz 4 saat veya daha kısa süre içinde tekrar bağlanırsa yeniden rastgele hale getirme gerçekleşmez."</string> <string name="wifi_metered_label" msgid="8737187690304098638">"Sayaçlı"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"Sayaçsız"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"Günlük Kaydedici arabellek boyutları"</string> @@ -371,6 +373,8 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"Arka plan uygulamalar için Uygulama Yanıt Vermiyor mesajını göster"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"Bildirim kanalı uyarılarını göster"</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"Bir uygulama geçerli kanal olmadan bildirim yayınladığında ekranda uyarı gösterir"</string> + <string name="enforce_shortcuts_for_conversations" msgid="7040735163945040763">"Görüşme bildirimleri için kısayolları zorunlu kıl"</string> + <string name="enforce_shortcuts_for_conversations_summary" msgid="1860168037282467862">"Bildirimlerin, görüşme bölümünde görünebilmesi için uzun ömürlü paylaşma kısayolu ile desteklenmesini gerektir"</string> <string name="force_allow_on_external" msgid="9187902444231637880">"Harici birimdeki uygulamalara izin vermeye zorla"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Manifest değerlerinden bağımsız olarak uygulamaları harici depolamaya yazmak için uygun hale getirir"</string> <string name="force_resizable_activities" msgid="7143612144399959606">"Etkinlikleri yeniden boyutlandırılabilmeye zorla"</string> diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml index 5dae4f0a63c6..60aa1a9abaaa 100644 --- a/packages/SettingsLib/res/values-uk/strings.xml +++ b/packages/SettingsLib/res/values-uk/strings.xml @@ -206,13 +206,13 @@ <string name="enable_adb" msgid="8072776357237289039">"Налагодження USB"</string> <string name="enable_adb_summary" msgid="3711526030096574316">"Вмикати налагодження, коли телефон підключено через USB"</string> <string name="clear_adb_keys" msgid="3010148733140369917">"Скасувати доступ до налагодження USB"</string> - <string name="enable_adb_wireless" msgid="6973226350963971018">"Бездротове налагодження"</string> + <string name="enable_adb_wireless" msgid="6973226350963971018">"Налагодження через Wi-Fi"</string> <string name="enable_adb_wireless_summary" msgid="7344391423657093011">"Вмикати режим налагодження, коли пристрій підключено до мережі Wi-Fi"</string> <string name="adb_wireless_error" msgid="721958772149779856">"Помилка"</string> - <string name="adb_wireless_settings" msgid="2295017847215680229">"Бездротове налагодження"</string> - <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Щоб переглядати та використовувати доступні пристрої, увімкніть бездротове налагодження"</string> + <string name="adb_wireless_settings" msgid="2295017847215680229">"Налагодження через Wi-Fi"</string> + <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Щоб переглядати та використовувати доступні пристрої, увімкніть налагодження через Wi-Fi"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"Підключати пристрій за допомогою QR-коду"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"Підключати нові пристрої за допомогою сканера QR-кодів"</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"Підключати нові пристрої за допомогою сканера QR-кодів"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"Підключати пристрій за допомогою коду підключення"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"Підключати нові пристрої за допомогою шестизначного коду"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"Підключені пристрої"</string> @@ -231,7 +231,7 @@ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"Не вдалося підключитися до пристрою. Надано неправильний QR-код або пристрій не підключено до тієї ж мережі."</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP-адреса та порт"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"Сканувати QR-код"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"Підключати пристрій через Wi‑Fi за допомогою QR-коду"</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Підключати пристрій через Wi‑Fi за допомогою QR-коду"</string> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Підключіть пристрій до мережі Wi-Fi"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, налагодження, розробка"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"Ярлик звіту про помилки"</string> @@ -251,6 +251,7 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"Сертифікація бездрот. екрана"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"Докладний запис у журнал Wi-Fi"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"Зменшити радіус пошуку мереж Wi‑Fi"</string> + <string name="wifi_enhanced_mac_randomization" msgid="5437378364995776979">"Довільний вибір MAC-адрес із Wi‑Fi"</string> <string name="mobile_data_always_on" msgid="8275958101875563572">"Не вимикати мобільне передавання даних"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"Апаратне прискорення під час використання телефона в режимі модема"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"Показувати пристрої Bluetooth без назв"</string> @@ -273,16 +274,17 @@ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3233402355917446304">"Кодек для аудіо Bluetooth LDAC: якість відтворення"</string> <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="7274396574659784285">"Активувати LDAC для аудіо Bluetooth\nВибір кодека: якість відтворення"</string> <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="2040810756832027227">"Трансляція: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string> - <string name="select_private_dns_configuration_title" msgid="7887550926056143018">"Приватна DNS"</string> - <string name="select_private_dns_configuration_dialog_title" msgid="3731422918335951912">"Режим приватної системи DNS"</string> + <string name="select_private_dns_configuration_title" msgid="7887550926056143018">"Приватний DNS-сервер"</string> + <string name="select_private_dns_configuration_dialog_title" msgid="3731422918335951912">"Режим приватного DNS-сервера"</string> <string name="private_dns_mode_off" msgid="7065962499349997041">"Вимкнено"</string> <string name="private_dns_mode_opportunistic" msgid="1947864819060442354">"Автоматично"</string> - <string name="private_dns_mode_provider" msgid="3619040641762557028">"Ім’я хосту приватного постачальника послуг DNS"</string> + <string name="private_dns_mode_provider" msgid="3619040641762557028">"Ім’я хосту постачальника приватного DNS-сервера"</string> <string name="private_dns_mode_provider_hostname_hint" msgid="6564868953748514595">"Введіть ім’я хосту постачальника послуг DNS"</string> <string name="private_dns_mode_provider_failure" msgid="8356259467861515108">"Не вдалося під’єднатися"</string> <string name="wifi_display_certification_summary" msgid="8111151348106907513">"Показати параметри сертифікації бездротового екрана"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Показувати в журналі RSSI для кожного SSID під час вибору Wi-Fi"</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"Зменшує споживання заряду акумулятора й підвищує ефективність роботи мережі"</string> + <string name="wifi_enhanced_mac_randomization_summary" msgid="7925425746373704991">"Цей перемикач впливає на поведінку довільного вибору MAC-адрес лише для клієнтського режиму.\nКоли цей режим активовано, MAC-адреси мереж із довільним вибором цих адрес переназначаються під час зв\'язування залежно від часу останнього відключення клієнта від мережі. Повторний довільний вибір адрес не відбувається, якщо пристрій знову підключається протягом 4 годин."</string> <string name="wifi_metered_label" msgid="8737187690304098638">"З тарифікацією трафіку"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"Без тарифікації трафіку"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"Розміри буфера журналу"</string> @@ -300,8 +302,8 @@ <string name="tethering_hardware_offload_summary" msgid="7801345335142803029">"Якщо доступно, вмикати апаратне прискорення під час використання телефона в режимі модема"</string> <string name="adb_warning_title" msgid="7708653449506485728">"Дозвол. налагодж. USB?"</string> <string name="adb_warning_message" msgid="8145270656419669221">"Налагодження USB застосовується лише з метою розробки. Його можна використовувати для копіювання даних між комп’ютером і пристроєм, встановлення програм на вашому пристрої без сповіщення та читання даних журналу."</string> - <string name="adbwifi_warning_title" msgid="727104571653031865">"Дозволити бездротове налагодження?"</string> - <string name="adbwifi_warning_message" msgid="8005936574322702388">"Бездротове налагодження застосовується лише з метою розробки. Його можна використовувати, щоб копіювати дані між комп\'ютером і пристроєм, встановлювати додатки на пристрої без сповіщення та переглядати дані журналу."</string> + <string name="adbwifi_warning_title" msgid="727104571653031865">"Дозволити налагодження через Wi-Fi?"</string> + <string name="adbwifi_warning_message" msgid="8005936574322702388">"Налагодження через Wi-Fi застосовується лише з метою розробки. Його можна використовувати, щоб копіювати дані між комп\'ютером і пристроєм, встановлювати додатки на пристрої без сповіщення та переглядати дані журналу."</string> <string name="adb_keys_warning_message" msgid="2968555274488101220">"Скасувати доступ до налагодження USB для всіх комп’ютерів, які раніше отримали таке право?"</string> <string name="dev_settings_warning_title" msgid="8251234890169074553">"Дозволити налаштування розробки?"</string> <string name="dev_settings_warning_message" msgid="37741686486073668">"Ці налаштування застосовуються лише з метою розробки. Вони можуть спричиняти вихід з ладу або неправильне функціонування вашого пристрою чи програм у ньому."</string> @@ -371,6 +373,8 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"Показувати вікно \"Додаток не відповідає\" для додатків у фоновому режимі"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"Показувати застереження про канал"</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"З’являється застереження, коли додаток надсилає сповіщення через недійсний канал"</string> + <string name="enforce_shortcuts_for_conversations" msgid="7040735163945040763">"Використовувати ярлики для сповіщень про чати"</string> + <string name="enforce_shortcuts_for_conversations_summary" msgid="1860168037282467862">"Вимагати для сповіщень постійних ярликів доступу, щоб показувати їх у розділі чатів"</string> <string name="force_allow_on_external" msgid="9187902444231637880">"Примусово записувати додатки в зовнішню пам’ять"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Можна записувати додатки в зовнішню пам’ять, незалежно від значень у маніфесті"</string> <string name="force_resizable_activities" msgid="7143612144399959606">"Примусово масштабувати активність"</string> diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml index ce25f2f83af4..ac56cf7dae13 100644 --- a/packages/SettingsLib/res/values-ur/strings.xml +++ b/packages/SettingsLib/res/values-ur/strings.xml @@ -212,7 +212,7 @@ <string name="adb_wireless_settings" msgid="2295017847215680229">"وائرلیس ڈیبگنگ"</string> <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"دستیاب آلات کو دیکھنے اور استعمال کرنے کے لیے، وائرلیس ڈیبگنگ آن کریں"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"QR کوڈ کے ذریعے آلہ کا جوڑا بنائیں"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"QR کوڈ اسکینر کا استعمال کر کے نئے آلہ کا جوڑا بنائیں"</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"QR کوڈ اسکینر کا استعمال کر کے نئے آلات کا جوڑا بنائیں"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"جوڑا بنانے کے کوڈ کے ذریعے آلہ کا جوڑا بنائیں"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"چھ ہندسوں کا کوڈ استعمال کر کے نئے آلات کا جوڑا بنائیں"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"جوڑا بنائے گئے آلات"</string> @@ -231,7 +231,7 @@ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"آلہ کا جوڑا بنانے میں ناکام۔ یا تو QR کوڈ غلط تھا، یا آلہ اسی نیٹ ورک سے منسلک نہیں ہے۔"</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP پتہ اور پورٹ"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"QR کوڈ اسکین کریں"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"QR کوڈ اسکین کر کے Wi-Fi پر آلہ کا جوڑا بنائیں"</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"QR کوڈ اسکین کر کے Wi-Fi پر آلہ کا جوڑا بنائیں"</string> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"براہ کرم ایک Wi-Fi نیٹ ورک سے منسلک ہوں"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb، ڈیبگ، dev"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"بگ رپورٹ کا شارٹ کٹ"</string> @@ -251,6 +251,7 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"وائرلیس ڈسپلے سرٹیفیکیشن"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"Wi‑Fi وربوس لاگنگ فعال کریں"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"Wi‑Fi اسکین کو زبردستی روکا جا رہا ہے"</string> + <string name="wifi_enhanced_mac_randomization" msgid="5437378364995776979">"بہتر Wi-Fi MAC رینڈمائزیشن"</string> <string name="mobile_data_always_on" msgid="8275958101875563572">"موبائل ڈیٹا ہمیشہ فعال رکھیں"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"ٹیدرنگ ہارڈویئر سرعت کاری"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"بغیر نام والے بلوٹوتھ آلات دکھائیں"</string> @@ -283,6 +284,7 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"وائرلیس ڈسپلے سرٹیفیکیشن کیلئے اختیارات دکھائیں"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Wi‑Fi لاگنگ لیول میں اضافہ کریں، Wi‑Fi منتخب کنندہ میں فی SSID RSSI دکھائیں"</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"بیٹری ڈرین کم کرتا ہے اور نیٹ ورک کارکردگی کو بہتر بناتا ہے"</string> + <string name="wifi_enhanced_mac_randomization_summary" msgid="7925425746373704991">"یہ ٹوگل صرف کلائنٹ وضع کے لئے MAC کی رینڈمائزیشن کو متاثر کرتا ہے۔\nجب یہ وضع فعال کی جاتی ہے، تو کسی بھی نیٹ ورکس میں جو MAC رینڈمائزیشن کو فعال کرتا ہے ان کے MAC ایڈریسز ایسوسی ایشن کے دوران دوبارہ رینڈمائز ہو سکتے ہیں، اس پر منحصر ہے کہ کلائنٹ کب آخری بار نیٹ ورک سے غیر منسلک ہوا۔ اگر آلہ 4 گھنٹوں یا اس سے کم وقت میں دوبارہ منسلک ہو، تو پھر دوبارہ رینڈمائزیشن کا امکان نہیں ہوتا ہے۔"</string> <string name="wifi_metered_label" msgid="8737187690304098638">"میٹرڈ"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"غیر میٹر شدہ"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"لاگر بفر کے سائز"</string> @@ -371,6 +373,8 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"پس منظر کی ایپس کیلئے \'ایپ جواب نہیں دے رہی ہے\' ڈائلاگ ڈسپلے کریں"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"چینل کی اطلاعی تنبیہات دکھائیں"</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"کسی ایپ کی طرف سے درست چینل کے بغیر اطلاع پوسٹ ہونے پر آن اسکرین تنبیہ ڈسپلے کرتا ہے"</string> + <string name="enforce_shortcuts_for_conversations" msgid="7040735163945040763">"بات چیت کی اطلاعات کے لیے شارٹ کٹس نافذ کریں"</string> + <string name="enforce_shortcuts_for_conversations_summary" msgid="1860168037282467862">"بات چیت کے سیکشن میں ظاہر ہونے کے لئے اطلاعات کو طویل مدت والے شیئرنگ شارٹ کٹ کے ذریعے حمایت کی ضرورت ہے"</string> <string name="force_allow_on_external" msgid="9187902444231637880">"بیرونی پر ایپس کو زبردستی اجازت دیں"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"manifest اقدار سے قطع نظر، کسی بھی ایپ کو بیرونی اسٹوریج پر لکھے جانے کا اہل بناتا ہے"</string> <string name="force_resizable_activities" msgid="7143612144399959606">"سرگرمیوں کو ری سائز ایبل بنائیں"</string> diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml index 07f3a6e9c5ba..ef5ae787a1e6 100644 --- a/packages/SettingsLib/res/values-uz/strings.xml +++ b/packages/SettingsLib/res/values-uz/strings.xml @@ -206,13 +206,13 @@ <string name="enable_adb" msgid="8072776357237289039">"USB orqali nosozliklarni aniqlash"</string> <string name="enable_adb_summary" msgid="3711526030096574316">"USB orqali kompyuterga ulanganda tuzatish rejimi yoqilsin"</string> <string name="clear_adb_keys" msgid="3010148733140369917">"USB orqali nosozliklarni tuzatishni taqiqlash"</string> - <string name="enable_adb_wireless" msgid="6973226350963971018">"Simsiz nosozliklarni aniqlash"</string> + <string name="enable_adb_wireless" msgid="6973226350963971018">"Wi-Fi orqali debagging"</string> <string name="enable_adb_wireless_summary" msgid="7344391423657093011">"Wi‑Fi tarmoqqa ulanganda nosozliklarni aniqlash rejimi"</string> <string name="adb_wireless_error" msgid="721958772149779856">"Xato"</string> - <string name="adb_wireless_settings" msgid="2295017847215680229">"Simsiz nosozliklarni aniqlash"</string> - <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Mavjud qurilmalarni koʻrish va ulardan foydalanish uchun simsiz nosozliklarni aniqlash funksiyasini yoqing"</string> + <string name="adb_wireless_settings" msgid="2295017847215680229">"Wi-Fi orqali debagging"</string> + <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Mavjud qurilmalarni koʻrish va ulardan foydalanish uchun Wi-Fi orqali debagging funksiyasini yoqing"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"QR kod yordamida qurilmani ulang"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"QR kod skaneri yordamida yangi qurilmalarni ulash mumkin"</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"QR kod skaneri yordamida yangi qurilmalarni ulash mumkin"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"Ulanish kodi yordamida qurilmani ulang"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"Olti xonali kod yordamida yangi qurilmalarni ulash mumkin"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"Ulangan qurilmalar"</string> @@ -231,7 +231,7 @@ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"Qurilma ulanmadi. QR kod xato yoki qurilma bir xil tarmoqqa ulanmagan."</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP manzil va port"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"QR kodni skanerlash"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"QR kodni skanerlab, Wi-Fi orqali qurilmani ulang"</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"QR kodni skanerlab, Wi-Fi orqali qurilmani ulang"</string> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Wi-Fi tarmoqqa ulaning"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, debag, dev"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"Xatoliklar hisoboti"</string> @@ -251,6 +251,8 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"Simsiz monitor sertifikatlari"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"Batafsil Wi-Fi jurnali"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"Wi‑Fi tarmoqni taqsimlab skanlash"</string> + <!-- no translation found for wifi_enhanced_mac_randomization (5437378364995776979) --> + <skip /> <string name="mobile_data_always_on" msgid="8275958101875563572">"Mobil internet doim yoniq tursin"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"Modem rejimida apparatli tezlashtirish"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"Bluetooth qurilmalarini nomlarisiz ko‘rsatish"</string> @@ -283,6 +285,8 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"Simsiz monitorlarni sertifikatlash parametrini ko‘rsatish"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Wi-Fi ulanishini tanlashda har bir SSID uchun jurnalda ko‘rsatilsin"</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"Batareya sarfini tejaydi va tarmoq samaradorligini oshiradi"</string> + <!-- no translation found for wifi_enhanced_mac_randomization_summary (7925425746373704991) --> + <skip /> <string name="wifi_metered_label" msgid="8737187690304098638">"Trafik hisoblanadigan tarmoq"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"Trafik hisobi yuritilmaydigan tarmoq"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"Jurnal buferi hajmi"</string> @@ -300,8 +304,8 @@ <string name="tethering_hardware_offload_summary" msgid="7801345335142803029">"Modem rejimida apparatli tezlashtirishdan foydalanish (agar mavjud bo‘lsa)"</string> <string name="adb_warning_title" msgid="7708653449506485728">"USB orqali nosozliklarni tuzatishga ruxsat berilsinmi?"</string> <string name="adb_warning_message" msgid="8145270656419669221">"USB orqali nosozliklarni aniqlash faqat dasturlash maqsadlarida yoqiladi. Undan maʼlumotlarni qurilmangiz va kompyuter o‘rtasida ko‘chirish, ilovalarni xabarnomasiz o‘rnatish va jurnal maʼlumotlarini o‘qish uchun foydalaniladi."</string> - <string name="adbwifi_warning_title" msgid="727104571653031865">"Simsiz nosozliklarni aniqlashga ruxsat berilsinmi?"</string> - <string name="adbwifi_warning_message" msgid="8005936574322702388">"Simsiz nosozliklarni aniqlash faqat dasturlash maqsadlarida yoqiladi. Undan maʼlumotlarni qurilmangiz va kompyuter oʻrtasida koʻchirish, ilovalarni bildirishnomasiz oʻrnatish va jurnal maʼlumotlarini oʻqish uchun foydalaniladi."</string> + <string name="adbwifi_warning_title" msgid="727104571653031865">"Wi-Fi orqali debagging uchun ruxsat berilsinmi?"</string> + <string name="adbwifi_warning_message" msgid="8005936574322702388">"Wi-Fi orqali debagging faqat dasturlash maqsadlarida yoqiladi. Undan maʼlumotlarni qurilmangiz va kompyuter oʻrtasida koʻchirish, ilovalarni bildirishnomasiz oʻrnatish va jurnal maʼlumotlarini oʻqish uchun foydalaniladi."</string> <string name="adb_keys_warning_message" msgid="2968555274488101220">"USB orqali nosozliklarni tuzatishga berilgan ruxsat siz hisobingizga kirgan barcha kompyuterlar uchun bekor qilinsinmi?"</string> <string name="dev_settings_warning_title" msgid="8251234890169074553">"Dasturlash sozlamalariga ruxsat berilsinmi?"</string> <string name="dev_settings_warning_message" msgid="37741686486073668">"Bu sozlamalar faqat dasturlash maqsadlariga mo‘ljallangan. Shuning uchun, ular qurilmangizga va undagi ilovalariga shikast yetkazib, noto‘g‘ri ishlashiga sabab bo‘lishi mumkin."</string> @@ -371,6 +375,8 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"Ilova javob bermayotgani haqida xabar qilish"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"Xabarlar kanali ogohlantirishlarini ko‘rsatish"</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"Yaroqli kanalsiz yuborilgan yangi ilova xabarnomalari haqida ogohlantirishlarni ko‘rsatish"</string> + <string name="enforce_shortcuts_for_conversations" msgid="7040735163945040763">"Suhbat bildirishnomalari uchun yorliqlardan majburiy foydalanish"</string> + <string name="enforce_shortcuts_for_conversations_summary" msgid="1860168037282467862">"Bildirishnoma suhbat qismida chiqishi uchun uzoq koʻrinadigan belgilar yordamida ularni nusxalash kerak"</string> <string name="force_allow_on_external" msgid="9187902444231637880">"Tashqi xotira qurilmasidagi ilova dasturlariga majburiy ruxsat berish"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Manifest qiymatidan qat’i nazar istalgan ilovani tashqi xotiraga saqlash imkonini beradi"</string> <string name="force_resizable_activities" msgid="7143612144399959606">"Harakatlarni moslashuvchan o‘lchamga keltirish"</string> diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml index 10ac60df77c0..b3e73fe41c00 100644 --- a/packages/SettingsLib/res/values-vi/strings.xml +++ b/packages/SettingsLib/res/values-vi/strings.xml @@ -99,7 +99,7 @@ <string name="bluetooth_headset_profile_summary_connected" msgid="2420981566026949688">"Đã kết nối với âm thanh điện thoại"</string> <string name="bluetooth_opp_profile_summary_connected" msgid="2393521801478157362">"Đã kết nối với máy chủ chuyển tệp"</string> <string name="bluetooth_map_profile_summary_connected" msgid="4141725591784669181">"Đã kết nối với bản đồ"</string> - <string name="bluetooth_sap_profile_summary_connected" msgid="1280297388033001037">"Được kết nối với SAP"</string> + <string name="bluetooth_sap_profile_summary_connected" msgid="1280297388033001037">"Đã kết nối với SAP"</string> <string name="bluetooth_opp_profile_summary_not_connected" msgid="3959741824627764954">"Chưa kết nối với máy chủ chuyển tệp"</string> <string name="bluetooth_hid_profile_summary_connected" msgid="3923653977051684833">"Đã kết nối với thiết bị nhập"</string> <string name="bluetooth_pan_user_profile_summary_connected" msgid="380469653827505727">"Đã kết nối với thiết bị để truy cập Internet"</string> @@ -143,11 +143,11 @@ <string name="data_usage_uninstalled_apps" msgid="1933665711856171491">"Ứng dụng đã xóa"</string> <string name="data_usage_uninstalled_apps_users" msgid="5533981546921913295">"Ứng dụng và người dùng bị xóa"</string> <string name="data_usage_ota" msgid="7984667793701597001">"Bản cập nhật hệ thống"</string> - <string name="tether_settings_title_usb" msgid="3728686573430917722">"Chia sẻ kết nối Internet qua USB"</string> + <string name="tether_settings_title_usb" msgid="3728686573430917722">"Chia sẻ Internet qua USB"</string> <string name="tether_settings_title_wifi" msgid="4803402057533895526">"Điểm phát sóng di động"</string> - <string name="tether_settings_title_bluetooth" msgid="916519902721399656">"Chia sẻ kết nối Internet qua Bluetooth"</string> - <string name="tether_settings_title_usb_bluetooth" msgid="1727111807207577322">"Đang dùng làm điểm truy cập Internet"</string> - <string name="tether_settings_title_all" msgid="8910259483383010470">"USB Internet & điểm truy cập di động"</string> + <string name="tether_settings_title_bluetooth" msgid="916519902721399656">"Chia sẻ Internet qua Bluetooth"</string> + <string name="tether_settings_title_usb_bluetooth" msgid="1727111807207577322">"Chia sẻ Internet"</string> + <string name="tether_settings_title_all" msgid="8910259483383010470">"Chia sẻ Internet và điểm phát sóng di động"</string> <string name="managed_user_title" msgid="449081789742645723">"Tất cả ứng dụng làm việc"</string> <string name="user_guest" msgid="6939192779649870792">"Khách"</string> <string name="unknown" msgid="3544487229740637809">"Không xác định"</string> @@ -201,7 +201,7 @@ <string name="development_settings_summary" msgid="8718917813868735095">"Đặt tùy chọn cho phát triển ứng dụng"</string> <string name="development_settings_not_available" msgid="355070198089140951">"Tùy chọn dành cho nhà phát triển không khả dụng cho người dùng này"</string> <string name="vpn_settings_not_available" msgid="2894137119965668920">"Cài đặt VPN không khả dụng cho người dùng này"</string> - <string name="tethering_settings_not_available" msgid="266821736434699780">"Cài đặt cách chia sẻ kết nối không khả dụng cho người dùng này"</string> + <string name="tethering_settings_not_available" msgid="266821736434699780">"Các tùy chọn cài đặt của tính năng chia sẻ Internet không có sẵn cho người dùng này"</string> <string name="apn_settings_not_available" msgid="1147111671403342300">"Cài đặt tên điểm truy cập không khả dụng cho người dùng này"</string> <string name="enable_adb" msgid="8072776357237289039">"Gỡ lỗi qua USB"</string> <string name="enable_adb_summary" msgid="3711526030096574316">"Bật chế độ gỡ lỗi khi kết nối USB"</string> @@ -212,7 +212,7 @@ <string name="adb_wireless_settings" msgid="2295017847215680229">"Gỡ lỗi qua Wi-Fi"</string> <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Để xem và sử dụng các thiết bị có sẵn, hãy bật tính năng gỡ lỗi qua Wi-Fi"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"Ghép nối thiết bị bằng mã QR"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"Ghép nối các thiết bị mới bằng Trình quét mã QR"</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"Ghép nối các thiết bị mới bằng trình quét mã QR"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"Ghép nối thiết bị bằng mã ghép nối"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"Ghép nối các thiết bị mới bằng mã gồm 6 chữ số"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"Thiết bị được ghép nối"</string> @@ -231,7 +231,7 @@ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"Không ghép nối được thiết bị. Mã QR không chính xác hoặc bạn không kết nối thiết bị với cùng một mạng."</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"Địa chỉ IP và cổng"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"Quét mã QR"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"Ghép nối thiết bị qua Wi-Fi bằng cách quét mã QR"</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Ghép nối thiết bị qua Wi-Fi bằng cách quét mã QR"</string> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Hãy kết nối mạng Wi-Fi"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, gỡ lỗi, nhà phát triển"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"Phím tắt báo cáo lỗi"</string> @@ -251,8 +251,9 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"Chứng nhận hiển thị không dây"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"Bật ghi nhật ký chi tiết Wi‑Fi"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"Hạn chế quét tìm Wi-Fi"</string> + <string name="wifi_enhanced_mac_randomization" msgid="5437378364995776979">"Sắp xếp ngẫu nhiên địa chỉ MAC tăng cường Wi‑Fi"</string> <string name="mobile_data_always_on" msgid="8275958101875563572">"Dữ liệu di động luôn hoạt động"</string> - <string name="tethering_hardware_offload" msgid="4116053719006939161">"Tăng tốc phần cứng khi chia sẻ kết nối"</string> + <string name="tethering_hardware_offload" msgid="4116053719006939161">"Tăng tốc phần cứng khi chia sẻ Internet"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"Hiển thị các thiết bị Bluetooth không có tên"</string> <string name="bluetooth_disable_absolute_volume" msgid="1452342324349203434">"Vô hiệu hóa âm lượng tuyệt đối"</string> <string name="bluetooth_enable_gabeldorsche" msgid="9131730396242883416">"Bật tính năng Gabeldorsche"</string> @@ -283,6 +284,7 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"Hiển thị tùy chọn chứng nhận hiển thị không dây"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Tăng mức ghi nhật ký Wi‑Fi, hiển thị mỗi SSID RSSI trong bộ chọn Wi‑Fi"</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"Giảm hao pin và cải thiện hiệu suất mạng"</string> + <string name="wifi_enhanced_mac_randomization_summary" msgid="7925425746373704991">"Thao tác bật/tắt này chỉ ảnh hưởng đến hành vi sắp xếp ngẫu nhiên địa chỉ MAC ở chế độ máy khách.\nKhi bạn kích hoạt chế độ này, tất cả các mạng đã bật tính năng sắp xếp ngẫu nhiên địa chỉ MAC có thể sắp xếp ngẫu nhiên lại địa chỉ MAC của họ trong quá trình liên kết, tùy thuộc vào lần gần đây nhất máy khách ngắt kết nối với mạng. Các mạng này sẽ không thể sắp xếp ngẫu nhiên lại nếu thiết bị kết nối lại trong vòng 4 giờ."</string> <string name="wifi_metered_label" msgid="8737187690304098638">"Đo lượng dữ liệu"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"Không đo lượng dữ liệu"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"Kích thước bộ đệm của trình ghi nhật ký"</string> @@ -297,7 +299,7 @@ <string name="allow_mock_location_summary" msgid="179780881081354579">"Cho phép vị trí mô phỏng"</string> <string name="debug_view_attributes" msgid="3539609843984208216">"Cho phép kiểm tra thuộc tính của chế độ xem"</string> <string name="mobile_data_always_on_summary" msgid="1112156365594371019">"Luôn bật dữ liệu di động ngay cả khi Wi-Fi đang hoạt động (để chuyển đổi mạng nhanh)."</string> - <string name="tethering_hardware_offload_summary" msgid="7801345335142803029">"Sử dụng tính năng tăng tốc phần cứng khi chia sẻ kết nối nếu có"</string> + <string name="tethering_hardware_offload_summary" msgid="7801345335142803029">"Sử dụng tính năng tăng tốc phần cứng khi chia sẻ Internet nếu có"</string> <string name="adb_warning_title" msgid="7708653449506485728">"Cho phép gỡ lỗi qua USB?"</string> <string name="adb_warning_message" msgid="8145270656419669221">"Gỡ lỗi USB chỉ dành cho mục đích phát triển. Hãy sử dụng tính năng này để sao chép dữ liệu giữa máy tính và thiết bị của bạn, cài đặt ứng dụng trên thiết bị của bạn mà không thông báo và đọc dữ liệu nhật ký."</string> <string name="adbwifi_warning_title" msgid="727104571653031865">"Bật tính năng gỡ lỗi qua Wi-Fi?"</string> @@ -371,6 +373,8 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"Hiện hộp thoại Ứng dụng không phản hồi cho các ứng dụng nền"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"Hiện cảnh báo kênh thông báo"</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"Hiện cảnh báo trên màn hình khi ứng dụng đăng thông báo mà không có kênh hợp lệ"</string> + <string name="enforce_shortcuts_for_conversations" msgid="7040735163945040763">"Áp dụng lối tắt cho thông báo của cuộc trò chuyện"</string> + <string name="enforce_shortcuts_for_conversations_summary" msgid="1860168037282467862">"Để xuất hiện trong phần cuộc trò chuyện, thông báo phải có sự hỗ trợ của lối tắt chia sẻ lâu dài"</string> <string name="force_allow_on_external" msgid="9187902444231637880">"Buộc cho phép các ứng dụng trên bộ nhớ ngoài"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Cho phép ghi mọi ứng dụng đủ điều kiện vào bộ nhớ ngoài, bất kể giá trị tệp kê khai là gì"</string> <string name="force_resizable_activities" msgid="7143612144399959606">"Buộc các hoạt động có thể thay đổi kích thước"</string> diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml index c24f72dbc072..d972cba8864c 100644 --- a/packages/SettingsLib/res/values-zh-rCN/strings.xml +++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml @@ -212,7 +212,7 @@ <string name="adb_wireless_settings" msgid="2295017847215680229">"无线调试"</string> <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"要查看和使用可用的设备,请开启无线调试"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"使用二维码配对设备"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"使用二维码扫描器配对新设备"</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"使用二维码扫描器配对新设备"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"使用配对码配对设备"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"使用六位数验证码配对新设备"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"已配对的设备"</string> @@ -231,7 +231,7 @@ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"无法配对设备。可能是因为二维码不正确,或者设备未连接到同一网络。"</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP 地址和端口"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"扫描二维码"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"扫描二维码即可通过 WLAN 配对设备"</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"扫描二维码即可通过 WLAN 配对设备"</string> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"请连接到 WLAN 网络"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, 调试, debug, 开发, dev"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"错误报告快捷方式"</string> @@ -251,6 +251,8 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"无线显示认证"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"启用 WLAN 详细日志记录功能"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"WLAN 扫描调节"</string> + <!-- no translation found for wifi_enhanced_mac_randomization (5437378364995776979) --> + <skip /> <string name="mobile_data_always_on" msgid="8275958101875563572">"始终开启移动数据网络"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"网络共享硬件加速"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"显示没有名称的蓝牙设备"</string> @@ -283,6 +285,8 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"显示无线显示认证选项"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"提升 WLAN 日志记录级别(在 WLAN 选择器中显示每个 SSID 的 RSSI)"</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"降低耗电量以及改善网络性能"</string> + <!-- no translation found for wifi_enhanced_mac_randomization_summary (7925425746373704991) --> + <skip /> <string name="wifi_metered_label" msgid="8737187690304098638">"按流量计费"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"不按流量计费"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"日志记录器缓冲区大小"</string> @@ -371,6 +375,8 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"为后台应用显示“应用无响应”对话框"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"显示通知渠道警告"</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"当应用未经有效渠道发布通知时,在屏幕上显示警告"</string> + <string name="enforce_shortcuts_for_conversations" msgid="7040735163945040763">"强制执行会话通知快捷方式"</string> + <string name="enforce_shortcuts_for_conversations_summary" msgid="1860168037282467862">"要求通知必须有长期共享快捷方式支持,才能显示在会话部分中"</string> <string name="force_allow_on_external" msgid="9187902444231637880">"强制允许将应用写入外部存储设备"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"允许将任何应用写入外部存储设备(无论清单值是什么)"</string> <string name="force_resizable_activities" msgid="7143612144399959606">"强制将活动设为可调整大小"</string> @@ -464,7 +470,7 @@ <item msgid="7529124349186240216">"100%"</item> </string-array> <string name="charge_length_format" msgid="6941645744588690932">"<xliff:g id="ID_1">%1$s</xliff:g>前"</string> - <string name="remaining_length_format" msgid="4310625772926171089">"还剩 <xliff:g id="ID_1">%1$s</xliff:g>"</string> + <string name="remaining_length_format" msgid="4310625772926171089">"还需 <xliff:g id="ID_1">%1$s</xliff:g>"</string> <string name="screen_zoom_summary_small" msgid="6050633151263074260">"小"</string> <string name="screen_zoom_summary_default" msgid="1888865694033865408">"默认"</string> <string name="screen_zoom_summary_large" msgid="4706951482598978984">"大"</string> diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml index a4c2336d6a02..74e3498bfe7e 100644 --- a/packages/SettingsLib/res/values-zh-rHK/strings.xml +++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml @@ -212,7 +212,7 @@ <string name="adb_wireless_settings" msgid="2295017847215680229">"無線偵錯"</string> <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"如要查看並使用可用的裝置,請開啟無線偵錯"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"使用二維條碼配對裝置"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"使用二維條碼掃瞄器配對新裝置"</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"使用二維條碼掃瞄器配對新裝置"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"使用配對碼配對裝置"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"使用六位數的配對碼配對新裝置"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"已配對的裝置"</string> @@ -231,7 +231,7 @@ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"無法配對裝置,可能是二維條碼錯誤,或裝置未連線至相同的網絡。"</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP 位址和連接埠"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"掃瞄二維條碼"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"掃瞄二維條碼即可透過 Wi-Fi 配對裝置"</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"掃瞄二維條碼即可透過 Wi-Fi 配對裝置"</string> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"請連線至 Wi-Fi 網絡"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"ADB, 偵錯, 開發"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"錯誤舉報捷徑"</string> @@ -251,6 +251,7 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"無線螢幕分享認證"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"啟用 Wi‑Fi 詳細記錄"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"Wi‑Fi 掃瞄限流"</string> + <string name="wifi_enhanced_mac_randomization" msgid="5437378364995776979">"Wi-Fi 強化 MAC 隨機處理"</string> <string name="mobile_data_always_on" msgid="8275958101875563572">"一律保持啟用流動數據"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"網絡共享硬件加速"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"顯示沒有名稱的藍牙裝置"</string> @@ -283,6 +284,7 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"顯示無線螢幕分享認證的選項"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"讓 Wi‑Fi 記錄功能升級,在 Wi‑Fi 選擇器中依每個 SSID RSSI 顯示 Wi‑Fi 詳細紀錄"</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"減低耗電量並改善網絡表現"</string> + <string name="wifi_enhanced_mac_randomization_summary" msgid="7925425746373704991">"此切換只會影響用戶端模式的 MAC 隨機處理。\n啟動此模式後,視乎用戶端上次中斷網絡連線的時間,系統可能會重新為任何已啟用 MAC 隨機處理的網絡在關聯期間隨機處理其 MAC 地址。如裝置在 4 小時或以內重新連線,系統便不會重新進行隨機處理。"</string> <string name="wifi_metered_label" msgid="8737187690304098638">"按用量收費"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"不限數據用量收費"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"記錄器緩衝區空間"</string> @@ -371,6 +373,8 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"為背景應用程式顯示「應用程式無回應」對話框"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"顯示通知渠道警告"</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"當應用程式未經有效渠道發佈通知時,在螢幕上顯示警告"</string> + <string name="enforce_shortcuts_for_conversations" msgid="7040735163945040763">"執行對話通知捷徑"</string> + <string name="enforce_shortcuts_for_conversations_summary" msgid="1860168037282467862">"通知必須採用永久共用捷徑,以便在對話部分中顯示"</string> <string name="force_allow_on_external" msgid="9187902444231637880">"強制允許應用程式寫入到外部儲存空間"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"在任何資訊清單值下,允許將所有符合資格的應用程式寫入到外部儲存完間"</string> <string name="force_resizable_activities" msgid="7143612144399959606">"強制將活動設為可調整尺寸"</string> @@ -429,7 +433,7 @@ <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="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$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" 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_suggestion_battery_run_out" msgid="6332089307827787087">"電池電量可能將於<xliff:g id="TIME">%1$s</xliff:g>耗盡"</string> <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"剩餘電量時間少於 <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml index 5183df3011e5..9337b59c258e 100644 --- a/packages/SettingsLib/res/values-zh-rTW/strings.xml +++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml @@ -212,7 +212,7 @@ <string name="adb_wireless_settings" msgid="2295017847215680229">"無線偵錯"</string> <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"如要查看並使用可用的裝置,請開啟無線偵錯"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"使用 QR 圖碼配對裝置"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"使用 QR 圖碼掃描器配對新裝置"</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"使用 QR 圖碼掃描器配對新裝置"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"使用配對碼配對裝置"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"使用六位數的配對碼配對新裝置"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"已配對的裝置"</string> @@ -231,7 +231,7 @@ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"無法配對裝置。可能是QR 圖碼錯誤,或是裝置未連上相同的網路。"</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"IP 位址和通訊埠"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"掃描 QR 圖碼"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"掃描 QR 圖碼即可透過 Wi-Fi 配對裝置"</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"掃描 QR 圖碼即可透過 Wi-Fi 配對裝置"</string> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"請連上 Wi-Fi 網路"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"ADB, 偵錯, 開發"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"錯誤回報捷徑"</string> @@ -251,6 +251,7 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"無線螢幕分享認證"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"啟用 Wi‑Fi 詳細記錄設定"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"Wi-Fi 掃描調節"</string> + <string name="wifi_enhanced_mac_randomization" msgid="5437378364995776979">"Wi‑Fi 加強型 MAC 隨機化"</string> <string name="mobile_data_always_on" msgid="8275958101875563572">"行動數據連線一律保持啟用狀態"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"數據連線硬體加速"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"顯示沒有名稱的藍牙裝置"</string> @@ -283,6 +284,7 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"顯示無線螢幕分享認證的選項"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"讓 Wi‑Fi 記錄功能升級,在 Wi‑Fi 選擇器中依每個 SSID RSSI 顯示 Wi‑Fi 詳細記錄"</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"降低耗電量以及改善網路效能"</string> + <string name="wifi_enhanced_mac_randomization_summary" msgid="7925425746373704991">"這個切換鈕只會影響用戶端模式的 MAC 隨機化行為。\n這個模式開啟時,任何已啟用 MAC 隨機化的網路可能會在建立關聯時重新將 MAC 位址隨機化 (取決於用戶端上次中斷連線的時間)。如果裝置在 4 個小時內重新連線,就不會進行重新隨機化作業。"</string> <string name="wifi_metered_label" msgid="8737187690304098638">"計量付費"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"非計量付費"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"記錄器緩衝區空間"</string> @@ -371,6 +373,8 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"為背景應用程式顯示「應用程式無回應」對話方塊"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"顯示通知管道警告"</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"當應用程式未經有效管道發布通知時,在畫面上顯示警告"</string> + <string name="enforce_shortcuts_for_conversations" msgid="7040735163945040763">"強制執行對話通知捷徑"</string> + <string name="enforce_shortcuts_for_conversations_summary" msgid="1860168037282467862">"要求通知必須有永久分享捷徑支援,才能顯示在對話部分中"</string> <string name="force_allow_on_external" msgid="9187902444231637880">"強制允許將應用程式寫入外部儲存空間"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"允許將任何應用程式寫入外部儲存空間 (無論資訊清單值為何)"</string> <string name="force_resizable_activities" msgid="7143612144399959606">"將活動強制設為可調整大小"</string> @@ -429,7 +433,7 @@ <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_only" msgid="92545648425937000">"預估還能持續使用到<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_suggestion_battery_run_out" msgid="6332089307827787087">"電池電力可能於<xliff:g id="TIME">%1$s</xliff:g> 前耗盡"</string> <string name="power_remaining_less_than_duration_only" msgid="5802195288324091585">"電池可用時間不到 <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml index eb4ace633bcb..a552446e6acf 100644 --- a/packages/SettingsLib/res/values-zu/strings.xml +++ b/packages/SettingsLib/res/values-zu/strings.xml @@ -212,7 +212,7 @@ <string name="adb_wireless_settings" msgid="2295017847215680229">"Ukulungisa amaphutha okungenantambo"</string> <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"Ukubona futhi usebenzise amadivayisi atholakalayo, vula ukulungisa amaphutha okungenantambo"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"Bhangqa idivayisi ngekhodi ye-QR"</string> - <string name="adb_pair_method_qrcode_summary" msgid="3729901496856458634">"Bhangqa amadivayisi amasha usebenzisa iskena sekhodi ye-QR"</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"Bhangqa amadivayisi amasha usebenzisa isiphequluli sekhodi ye-QR"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"Bhangqa idivayisi ngekhodi yokumatanisa"</string> <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"Bhangqa amadivayisi amasha usebenzisa ikhodi yamadijithi ayisithupha"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"Amadivaysi abhangqene"</string> @@ -231,7 +231,7 @@ <string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"Yehlulekile ukubhangqa idivayisi. Kungenzeka ukuthi ikhodi ye-QR kade ingalungile, noma idivayisi ayixhunyiwe kunethiwekhi efanayo."</string> <string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"Ikheli le-IP nembobo"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"Skena ikhodi ye-QR"</string> - <string name="adb_wireless_qrcode_pairing_description" msgid="8578868049289910131">"Bhangqa idivayisi nge-Wi‑Fi ngokuskena ikhodi ye-QR"</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Bhangqa idivayisi nge-Wi‑Fi ngokuskena ikhodi ye-QR"</string> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"Sicela uxhume kunethiwekhi ye-Wi-Fi"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"i-adb, ukulungisa amaphutha, i-dev"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"Isinqamuleli sombiko wesiphazamisi"</string> @@ -251,6 +251,7 @@ <string name="wifi_display_certification" msgid="1805579519992520381">"Ukunikezwa isitifiketi sokubukeka okungenantambo"</string> <string name="wifi_verbose_logging" msgid="1785910450009679371">"Nika amandlaukungena kwe-Wi-Fi Verbose"</string> <string name="wifi_scan_throttling" msgid="2985624788509913617">"I-throttling yokuskena kwe-Wi-Fi"</string> + <string name="wifi_enhanced_mac_randomization" msgid="5437378364995776979">"Okungahleliwe kwe-Wi-Fi ethuthukisiwe ye-MAC"</string> <string name="mobile_data_always_on" msgid="8275958101875563572">"Idatha yeselula ihlala isebenza"</string> <string name="tethering_hardware_offload" msgid="4116053719006939161">"I-Tethering hardware acceleration"</string> <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"Bonisa amadivayisi e-Bluetooth ngaphandle kwamagama"</string> @@ -283,6 +284,7 @@ <string name="wifi_display_certification_summary" msgid="8111151348106907513">"Bonisa izinketho zokunikeza isitifiketi ukubukeka okungenantambo"</string> <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"khuphula izinga lokungena le-Wi-Fi, bonisa nge-SSID RSSI engayodwana kusikhethi se-Wi-Fi"</string> <string name="wifi_scan_throttling_summary" msgid="2577105472017362814">"Yehlisa ukuphela kwebhethri futhi ithuthukise ukusebenza kwenethiwekhi"</string> + <string name="wifi_enhanced_mac_randomization_summary" msgid="7925425746373704991">"Lokhu kuguqula kuthinta ukuziphatha kokungahleliwe kwe-MAC kwemodi yeklayenti kuphela.\nLapho le modi yenziwe yasebenza, noma yimaphi amanethiwekhi anokungahleliwe kwe-MAC okunikwe amandla angase abe nekheli lawo le-MAC libe okungahleliwe kabusha phakathi nokuhlobana, kuya ngokuthi iklayenti igcine nini ukunqamula kusuka kunethiwekhi. Ukwenza kube okungahleliwe kabusha akuveli uma idivayisi ixhuma kabusha emahoreni angu-4 noma ngaphansi."</string> <string name="wifi_metered_label" msgid="8737187690304098638">"Kulinganisiwe"</string> <string name="wifi_unmetered_label" msgid="6174142840934095093">"Akulinganiselwa"</string> <string name="select_logd_size_title" msgid="1604578195914595173">"Amasayizi weloga ngebhafa"</string> @@ -371,6 +373,8 @@ <string name="show_all_anrs_summary" msgid="8562788834431971392">"Uhlelo lokusebenza lwesibonisi aluphenduli kungxoxo yezinhlelo zokusebenza zangemuva"</string> <string name="show_notification_channel_warnings" msgid="3448282400127597331">"Bonisa izexwayiso zesiteshi sesaziso"</string> <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"Ibonisa isexwayiso esikusikrini uma uhlelo lokusebenza luthumela isaziso ngaphandle kwesiteshi esivumelekile"</string> + <string name="enforce_shortcuts_for_conversations" msgid="7040735163945040763">"Phoqelela izinqamuleli zezaziso zengxoxo"</string> + <string name="enforce_shortcuts_for_conversations_summary" msgid="1860168037282467862">"Kudinga ukuba izaziso zisekelwe yisinqamuleli sokwabelana sesikhathi eside ukuze zivele esigabeni sengxoxo"</string> <string name="force_allow_on_external" msgid="9187902444231637880">"Phoqelela ukuvumela izinhlelo zokusebenza ngaphandle"</string> <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Yenza noma uluphi uhlelo lokusebenza lifaneleke ukuthi libhalwe kusitoreji sangaphandle, ngaphandle kwamavelu we-manifest"</string> <string name="force_resizable_activities" msgid="7143612144399959606">"Imisebenzi yamandla izonikezwa usayizi omusha"</string> diff --git a/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java b/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java index 3024b842c2be..a62d76f732da 100644 --- a/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java +++ b/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java @@ -401,6 +401,11 @@ public class LocalMediaManager implements BluetoothCallback { } private List<MediaDevice> buildDisconnectedBluetoothDevice() { + if (mBluetoothAdapter == null) { + Log.w(TAG, "buildDisconnectedBluetoothDevice() BluetoothAdapter is null"); + return new ArrayList<>(); + } + final List<BluetoothDevice> bluetoothDevices = mBluetoothAdapter.getMostRecentlyConnectedDevices(); final CachedBluetoothDeviceManager cachedDeviceManager = diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/LocalMediaManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/LocalMediaManagerTest.java index 7ddd64c15876..206c8590a952 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/LocalMediaManagerTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/LocalMediaManagerTest.java @@ -691,4 +691,28 @@ public class LocalMediaManagerTest { assertThat(mLocalMediaManager.mMediaDevices).hasSize(7); verify(mCallback).onDeviceListUpdate(any()); } + + @Test + public void onDeviceListAdded_bluetoothAdapterIsNull_noDisconnectedDeviceAdded() { + final List<MediaDevice> devices = new ArrayList<>(); + final MediaDevice device1 = mock(MediaDevice.class); + final MediaDevice device2 = mock(MediaDevice.class); + final MediaDevice device3 = mock(MediaDevice.class); + mLocalMediaManager.mPhoneDevice = mock(PhoneMediaDevice.class); + devices.add(device1); + devices.add(device2); + mLocalMediaManager.mMediaDevices.add(device3); + mLocalMediaManager.mMediaDevices.add(mLocalMediaManager.mPhoneDevice); + + mShadowBluetoothAdapter = null; + + when(mLocalMediaManager.mPhoneDevice.getId()).thenReturn("test_phone_id"); + + assertThat(mLocalMediaManager.mMediaDevices).hasSize(2); + mLocalMediaManager.registerCallback(mCallback); + mLocalMediaManager.mMediaDeviceCallback.onDeviceListAdded(devices); + + assertThat(mLocalMediaManager.mMediaDevices).hasSize(2); + verify(mCallback).onDeviceListUpdate(any()); + } } diff --git a/packages/SettingsProvider/res/values-ky/strings.xml b/packages/SettingsProvider/res/values-ky/strings.xml index e5b82c69a81e..8058b4da5634 100644 --- a/packages/SettingsProvider/res/values-ky/strings.xml +++ b/packages/SettingsProvider/res/values-ky/strings.xml @@ -20,6 +20,6 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4567566098528588863">"Жөндөөлөрдү сактоо"</string> - <string name="wifi_softap_config_change" msgid="5688373762357941645">"Хотспот жөндөөлөрү өзгөрдү"</string> + <string name="wifi_softap_config_change" msgid="5688373762357941645">"Байланыш түйүнү жөндөөлөрү өзгөрдү"</string> <string name="wifi_softap_config_change_summary" msgid="8946397286141531087">"Чоо-жайын билүү үчүн басыңыз"</string> </resources> diff --git a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java index 01a2b6952f2a..03f6df0d5d2d 100644 --- a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java +++ b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java @@ -101,7 +101,8 @@ public class SettingsBackupTest { Settings.System.MIN_REFRESH_RATE, // depends on hardware capabilities Settings.System.PEAK_REFRESH_RATE, // depends on hardware capabilities Settings.System.SCREEN_BRIGHTNESS_FLOAT, - Settings.System.SCREEN_BRIGHTNESS_FOR_VR_FLOAT + Settings.System.SCREEN_BRIGHTNESS_FOR_VR_FLOAT, + Settings.System.MULTI_AUDIO_FOCUS_ENABLED // form-factor/OEM specific ); private static final Set<String> BACKUP_BLACKLISTED_GLOBAL_SETTINGS = diff --git a/packages/SystemUI/res/anim/control_state_list_animator.xml b/packages/SystemUI/res/anim/control_state_list_animator.xml new file mode 100644 index 000000000000..a20a9255f86f --- /dev/null +++ b/packages/SystemUI/res/anim/control_state_list_animator.xml @@ -0,0 +1,51 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ 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. + --> +<selector xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:state_pressed="true"> + <set> + <objectAnimator + android:interpolator="@interpolator/control_state" + android:duration="50" + android:propertyName="scaleX" + android:valueTo="0.97" + android:valueType="floatType" /> + <objectAnimator + android:interpolator="@interpolator/control_state" + android:duration="50" + android:propertyName="scaleY" + android:valueTo="0.97" + android:valueType="floatType" /> + + </set> + </item> + <item> + <set> + <objectAnimator + android:interpolator="@interpolator/control_state" + android:duration="250" + android:propertyName="scaleX" + android:valueTo="1" + android:valueType="floatType" /> + <objectAnimator + android:interpolator="@interpolator/control_state" + android:duration="250" + android:propertyName="scaleY" + android:valueTo="1" + android:valueType="floatType" /> + </set> + </item> +</selector>
\ No newline at end of file diff --git a/packages/SystemUI/res/drawable/control_background.xml b/packages/SystemUI/res/drawable/control_background.xml index 29b4efa48fa1..cf298b70f3db 100644 --- a/packages/SystemUI/res/drawable/control_background.xml +++ b/packages/SystemUI/res/drawable/control_background.xml @@ -17,7 +17,8 @@ */ --> <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> - <item> + <item + android:id="@+id/background"> <shape> <solid android:color="@color/control_default_background" /> <corners android:radius="@dimen/control_corner_radius" /> diff --git a/packages/SystemUI/res/drawable/ic_create_bubble.xml b/packages/SystemUI/res/drawable/ic_create_bubble.xml index 1947f58f8f5e..d58e9a347a2f 100644 --- a/packages/SystemUI/res/drawable/ic_create_bubble.xml +++ b/packages/SystemUI/res/drawable/ic_create_bubble.xml @@ -14,16 +14,12 @@ 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" - android:viewportHeight="24"> - <path - android:pathData="M12,3c-4.97,0 -9,4.03 -9,9c0,1.39 0.32,2.69 0.88,3.86l1.53,-1.53C5.15,13.6 5,12.82 5,12c0,-3.86 3.14,-7 7,-7s7,3.14 7,7s-3.14,7 -7,7c-0.83,0 -1.62,-0.15 -2.35,-0.42l-1.53,1.53C9.3,20.67 10.61,21 12,21c4.97,0 9,-4.03 9,-9C21,7.03 16.97,3 12,3z" - android:fillColor="#000000"/> - <path - android:pathData="M12.99,15.99l2,0l0,-7l-7,0l0,2l3.59,0l-8.79,8.8l1.41,1.41l8.79,-8.79z" - android:fillColor="#000000"/> -</vector> + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24"> + <path + android:fillColor="#FF000000" + android:pathData="M22,12C22,12 22,12 22,12C22,12 22,12 22,12c0,0.56 -0.06,1.1 -0.15,1.64l-1.97,-0.33c0.15,-0.91 0.15,-1.84 -0.02,-2.75c-0.01,-0.03 -0.01,-0.07 -0.02,-0.1c-0.03,-0.18 -0.08,-0.36 -0.13,-0.54c-0.02,-0.08 -0.04,-0.16 -0.06,-0.24c-0.04,-0.14 -0.09,-0.27 -0.14,-0.41c-0.04,-0.12 -0.08,-0.24 -0.13,-0.35c-0.04,-0.09 -0.08,-0.18 -0.13,-0.27c-0.07,-0.15 -0.14,-0.3 -0.22,-0.45c-0.03,-0.05 -0.06,-0.09 -0.08,-0.14c-0.72,-1.26 -1.77,-2.31 -3.03,-3.03c-0.05,-0.03 -0.09,-0.06 -0.14,-0.08c-0.15,-0.08 -0.3,-0.15 -0.45,-0.22c-0.09,-0.04 -0.18,-0.09 -0.27,-0.13c-0.11,-0.05 -0.23,-0.09 -0.35,-0.13c-0.14,-0.05 -0.27,-0.1 -0.41,-0.14c-0.08,-0.02 -0.16,-0.04 -0.23,-0.06c-0.18,-0.05 -0.36,-0.1 -0.54,-0.13c-0.03,-0.01 -0.07,-0.01 -0.1,-0.01c-0.95,-0.17 -1.93,-0.17 -2.88,0c-0.03,0.01 -0.07,0.01 -0.1,0.01c-0.18,0.04 -0.36,0.08 -0.54,0.13C9.85,4.3 9.77,4.32 9.69,4.34C9.55,4.38 9.42,4.44 9.28,4.49C9.17,4.53 9.05,4.57 8.93,4.61C8.84,4.65 8.75,4.7 8.66,4.74c-0.15,0.07 -0.3,0.14 -0.45,0.22C8.16,4.98 8.12,5.01 8.07,5.04C5.64,6.42 4,9.02 4,12c0,2.74 1.39,5.16 3.49,6.6c0.01,0.01 0.03,0.02 0.04,0.03c0.16,0.11 0.33,0.2 0.49,0.3c0.06,0.04 0.12,0.08 0.19,0.11c0.13,0.07 0.27,0.13 0.4,0.19c0.11,0.05 0.21,0.1 0.32,0.15c0.1,0.04 0.2,0.07 0.29,0.11c0.15,0.06 0.31,0.11 0.46,0.16c0.05,0.02 0.11,0.03 0.17,0.04c1.11,0.31 2.27,0.35 3.4,0.18l0.35,1.98c-0.54,0.09 -1.08,0.14 -1.62,0.14V22c-0.65,0 -1.28,-0.07 -1.9,-0.19c-0.01,0 -0.01,0 -0.02,0c-0.25,-0.05 -0.49,-0.11 -0.73,-0.18c-0.08,-0.02 -0.16,-0.04 -0.23,-0.06c-0.19,-0.06 -0.37,-0.13 -0.55,-0.19c-0.13,-0.05 -0.26,-0.09 -0.39,-0.14c-0.13,-0.05 -0.25,-0.12 -0.38,-0.18c-0.18,-0.08 -0.35,-0.16 -0.53,-0.25c-0.07,-0.04 -0.14,-0.08 -0.21,-0.13c-0.22,-0.12 -0.43,-0.25 -0.64,-0.39c-0.01,-0.01 -0.02,-0.02 -0.04,-0.03c-0.51,-0.35 -1,-0.74 -1.45,-1.2l0,0C3.12,17.26 2,14.76 2,12c0,-2.76 1.12,-5.26 2.93,-7.07l0,0c0.45,-0.45 0.93,-0.84 1.44,-1.19C6.39,3.73 6.4,3.72 6.42,3.71c0.2,-0.14 0.41,-0.26 0.62,-0.38c0.08,-0.05 0.15,-0.09 0.23,-0.14c0.17,-0.09 0.33,-0.16 0.5,-0.24c0.13,-0.06 0.27,-0.13 0.4,-0.19C8.3,2.71 8.42,2.67 8.55,2.63c0.19,-0.07 0.38,-0.14 0.58,-0.2c0.07,-0.02 0.14,-0.03 0.21,-0.05C10.18,2.14 11.07,2 12,2c0.65,0 1.29,0.07 1.91,0.19c0,0 0,0 0,0c0.25,0.05 0.5,0.11 0.75,0.18c0.07,0.02 0.14,0.03 0.22,0.06c0.19,0.06 0.38,0.13 0.57,0.2c0.12,0.05 0.25,0.09 0.37,0.14c0.14,0.06 0.27,0.12 0.4,0.18c0.17,0.08 0.34,0.16 0.51,0.25c0.08,0.04 0.15,0.09 0.23,0.14c0.21,0.12 0.42,0.24 0.62,0.38c0.01,0.01 0.03,0.02 0.04,0.03c0.51,0.35 0.99,0.74 1.45,1.19c0.24,0.24 0.47,0.49 0.68,0.75c0.04,0.04 0.06,0.09 0.1,0.13c0.17,0.22 0.34,0.45 0.5,0.68c0.01,0.01 0.02,0.03 0.03,0.04c0.69,1.05 1.17,2.21 1.42,3.44c0,0 0,0.01 0,0.01c0.06,0.29 0.1,0.58 0.13,0.87c0.01,0.04 0.01,0.09 0.02,0.13C21.98,11.32 22,11.66 22,12zM18.5,15c-1.93,0 -3.5,1.57 -3.5,3.5s1.57,3.5 3.5,3.5s3.5,-1.57 3.5,-3.5S20.43,15 18.5,15z"/> +</vector>
\ No newline at end of file diff --git a/packages/SystemUI/res/drawable/ic_stop_bubble.xml b/packages/SystemUI/res/drawable/ic_stop_bubble.xml new file mode 100644 index 000000000000..11bc741a4f17 --- /dev/null +++ b/packages/SystemUI/res/drawable/ic_stop_bubble.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + 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. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24"> + <path + android:fillColor="#FF000000" + android:pathData="M21.98,18.32l-3.3,-3.3C20.47,15.11 21.89,16.53 21.98,18.32zM8.66,4.74C8.75,4.7 8.84,4.65 8.93,4.61c0.11,-0.05 0.23,-0.09 0.35,-0.13c0.14,-0.05 0.27,-0.1 0.41,-0.14C9.77,4.32 9.85,4.3 9.92,4.28c0.18,-0.05 0.36,-0.1 0.54,-0.13c0.03,-0.01 0.07,-0.01 0.1,-0.01c0.95,-0.17 1.93,-0.17 2.88,0c0.03,0.01 0.07,0.01 0.1,0.01c0.18,0.04 0.36,0.08 0.54,0.13c0.08,0.02 0.16,0.04 0.23,0.06c0.14,0.04 0.27,0.09 0.41,0.14c0.12,0.04 0.23,0.08 0.35,0.13c0.09,0.04 0.18,0.09 0.27,0.13c0.15,0.07 0.3,0.14 0.45,0.22c0.05,0.03 0.09,0.06 0.14,0.08c1.26,0.72 2.31,1.77 3.03,3.03c0.03,0.05 0.06,0.09 0.08,0.14c0.08,0.15 0.15,0.3 0.22,0.45c0.04,0.09 0.09,0.18 0.13,0.27c0.05,0.11 0.09,0.23 0.13,0.35c0.05,0.13 0.1,0.27 0.14,0.41c0.02,0.08 0.04,0.16 0.06,0.24c0.05,0.18 0.1,0.36 0.13,0.54c0.01,0.03 0.01,0.07 0.02,0.1c0.16,0.91 0.17,1.84 0.02,2.75l1.97,0.33C21.94,13.1 22,12.56 22,12c0,0 0,0 0,0s0,0 0,0c0,-0.34 -0.02,-0.68 -0.05,-1.01c0,-0.04 -0.01,-0.09 -0.02,-0.13c-0.03,-0.29 -0.07,-0.58 -0.13,-0.87c0,0 0,-0.01 0,-0.01c-0.25,-1.23 -0.73,-2.39 -1.42,-3.44c-0.01,-0.01 -0.02,-0.03 -0.03,-0.04c-0.15,-0.23 -0.32,-0.46 -0.5,-0.68c-0.03,-0.04 -0.06,-0.09 -0.1,-0.13c-0.21,-0.26 -0.44,-0.51 -0.68,-0.75c-0.45,-0.45 -0.94,-0.84 -1.45,-1.19c-0.01,-0.01 -0.03,-0.02 -0.04,-0.03c-0.2,-0.14 -0.41,-0.26 -0.62,-0.38c-0.08,-0.04 -0.15,-0.09 -0.23,-0.14c-0.17,-0.09 -0.34,-0.17 -0.51,-0.25c-0.13,-0.06 -0.26,-0.13 -0.4,-0.18c-0.12,-0.05 -0.25,-0.09 -0.37,-0.14c-0.19,-0.07 -0.38,-0.14 -0.57,-0.2c-0.07,-0.02 -0.14,-0.04 -0.22,-0.06c-0.25,-0.07 -0.5,-0.13 -0.75,-0.18c0,0 0,0 0,0C13.29,2.07 12.65,2 12,2c-0.93,0 -1.82,0.14 -2.67,0.37C9.26,2.39 9.19,2.41 9.12,2.43c-0.2,0.06 -0.39,0.13 -0.58,0.2C8.42,2.67 8.3,2.71 8.18,2.76c-0.14,0.06 -0.27,0.12 -0.4,0.19C7.61,3.03 7.44,3.1 7.27,3.19C7.19,3.24 7.12,3.29 7.04,3.33C7.03,3.34 7.02,3.34 7.01,3.35l1.48,1.48C8.55,4.8 8.6,4.77 8.66,4.74zM2.71,1.29L1.29,2.71l2.97,2.97C2.85,7.4 2,9.6 2,12c0,2.76 1.12,5.26 2.93,7.07l0,0c0.45,0.45 0.94,0.85 1.45,1.2c0.01,0.01 0.02,0.02 0.04,0.03c0.21,0.14 0.42,0.27 0.64,0.39c0.07,0.04 0.14,0.09 0.21,0.13c0.17,0.09 0.35,0.17 0.53,0.25c0.13,0.06 0.25,0.12 0.38,0.18c0.13,0.05 0.26,0.1 0.39,0.14c0.18,0.07 0.36,0.14 0.55,0.19c0.08,0.02 0.16,0.04 0.23,0.06c0.24,0.07 0.48,0.13 0.73,0.18c0.01,0 0.01,0 0.02,0C10.72,21.93 11.35,22 12,22v-0.01c0.54,0 1.08,-0.05 1.62,-0.14l-0.35,-1.98c-1.13,0.18 -2.29,0.13 -3.4,-0.18c-0.06,-0.02 -0.11,-0.03 -0.17,-0.04c-0.16,-0.05 -0.31,-0.11 -0.46,-0.16c-0.1,-0.04 -0.2,-0.07 -0.29,-0.11c-0.11,-0.05 -0.22,-0.1 -0.32,-0.15c-0.13,-0.06 -0.27,-0.12 -0.4,-0.19c-0.06,-0.03 -0.13,-0.08 -0.19,-0.11c-0.17,-0.1 -0.33,-0.19 -0.49,-0.3c-0.01,-0.01 -0.03,-0.02 -0.04,-0.03C5.39,17.16 4,14.74 4,12c0,-1.85 0.64,-3.54 1.7,-4.89l9.73,9.73C15.16,17.33 15,17.9 15,18.5c0,1.93 1.57,3.5 3.5,3.5c0.6,0 1.17,-0.16 1.66,-0.43l1.13,1.13l1.41,-1.41L2.71,1.29z"/> +</vector> diff --git a/packages/SystemUI/res/interpolator/control_state.xml b/packages/SystemUI/res/interpolator/control_state.xml new file mode 100644 index 000000000000..66106d48d507 --- /dev/null +++ b/packages/SystemUI/res/interpolator/control_state.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ 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. + --> +<pathInterpolator + xmlns:android="http://schemas.android.com/apk/res/android" + android:controlX1="0" + android:controlY1="0" + android:controlX2="1" + android:controlY2="1"/> diff --git a/packages/SystemUI/res/layout/controls_base_item.xml b/packages/SystemUI/res/layout/controls_base_item.xml index 55c9083e4147..6a8621398191 100644 --- a/packages/SystemUI/res/layout/controls_base_item.xml +++ b/packages/SystemUI/res/layout/controls_base_item.xml @@ -24,6 +24,7 @@ android:clickable="false" android:focusable="true" android:screenReaderFocusable="true" + android:stateListAnimator="@anim/control_state_list_animator" android:layout_marginLeft="@dimen/control_base_item_margin" android:layout_marginRight="@dimen/control_base_item_margin" android:background="@drawable/control_background"> diff --git a/packages/SystemUI/res/layout/controls_horizontal_divider_withEmpty.xml b/packages/SystemUI/res/layout/controls_horizontal_divider_with_empty.xml index 90b3398e3de2..90b3398e3de2 100644 --- a/packages/SystemUI/res/layout/controls_horizontal_divider_withEmpty.xml +++ b/packages/SystemUI/res/layout/controls_horizontal_divider_with_empty.xml diff --git a/packages/SystemUI/res/layout/global_actions_grid_item_v2.xml b/packages/SystemUI/res/layout/global_actions_grid_item_v2.xml index 72cc2ddba282..477ec6a1c72c 100644 --- a/packages/SystemUI/res/layout/global_actions_grid_item_v2.xml +++ b/packages/SystemUI/res/layout/global_actions_grid_item_v2.xml @@ -28,6 +28,7 @@ android:paddingRight="@dimen/global_actions_grid_item_side_margin" android:layout_marginRight="@dimen/control_base_item_margin" android:layout_marginLeft="@dimen/control_base_item_margin" + android:stateListAnimator="@anim/control_state_list_animator" android:background="@drawable/control_background"> <LinearLayout android:layout_width="@dimen/global_actions_grid_item_width" diff --git a/packages/SystemUI/res/layout/global_actions_grid_v2.xml b/packages/SystemUI/res/layout/global_actions_grid_v2.xml index 59c4d011166a..dba003aa82a9 100644 --- a/packages/SystemUI/res/layout/global_actions_grid_v2.xml +++ b/packages/SystemUI/res/layout/global_actions_grid_v2.xml @@ -12,34 +12,46 @@ android:layout_height="wrap_content" android:orientation="horizontal" android:theme="@style/qs_theme" - android:gravity="top" android:clipChildren="false" android:clipToPadding="false" android:layout_marginTop="@dimen/global_actions_top_margin" + android:layout_marginLeft="@dimen/global_actions_side_margin" + android:layout_marginRight="@dimen/global_actions_side_margin" > <LinearLayout android:id="@android:id/list" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginLeft="@dimen/global_actions_side_margin" - android:layout_marginRight="@dimen/global_actions_side_margin" android:paddingLeft="@dimen/global_actions_grid_horizontal_padding" android:paddingRight="@dimen/global_actions_grid_horizontal_padding" android:paddingTop="@dimen/global_actions_grid_vertical_padding" android:paddingBottom="@dimen/global_actions_grid_vertical_padding" android:orientation="horizontal" - android:gravity="left" + android:gravity="left | center_vertical" android:translationZ="@dimen/global_actions_translate" - /> + > + <RelativeLayout + android:id="@+id/global_actions_overflow_button" + android:layout_width="48dp" + android:layout_height="48dp" + > + <ImageView + android:src="@drawable/ic_more_vert" + android:layout_centerInParent="true" + android:layout_width="24dp" + android:layout_height="24dp" + android:tint="@color/control_more_vert" + /> + </RelativeLayout> + </LinearLayout> </com.android.systemui.globalactions.GlobalActionsFlatLayout> <com.android.systemui.globalactions.MinHeightScrollView - xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:paddingBottom="@dimen/global_actions_grid_container_shadow_offset" - android:layout_marginBottom="@dimen/global_actions_grid_container_negative_shadow_offset" - android:orientation="vertical" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:paddingBottom="@dimen/global_actions_grid_container_shadow_offset" + android:layout_marginBottom="@dimen/global_actions_grid_container_negative_shadow_offset" + android:orientation="vertical" > <LinearLayout android:id="@+id/global_actions_grid_root" diff --git a/packages/SystemUI/res/layout/photo_preview_overlay.xml b/packages/SystemUI/res/layout/photo_preview_overlay.xml new file mode 100644 index 000000000000..9210996fb9c6 --- /dev/null +++ b/packages/SystemUI/res/layout/photo_preview_overlay.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ 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. + --> + +<!-- empty stub --> +<merge />
\ No newline at end of file diff --git a/packages/SystemUI/res/layout/status_bar_expanded.xml b/packages/SystemUI/res/layout/status_bar_expanded.xml index 115b4a86b86d..1d4b98242519 100644 --- a/packages/SystemUI/res/layout/status_bar_expanded.xml +++ b/packages/SystemUI/res/layout/status_bar_expanded.xml @@ -66,6 +66,8 @@ <include layout="@layout/ambient_indication" android:id="@+id/ambient_indication_container" /> + <include layout="@layout/photo_preview_overlay" /> + <ViewStub android:id="@+id/keyguard_user_switcher" android:layout="@layout/keyguard_user_switcher" diff --git a/packages/SystemUI/res/values-land/config.xml b/packages/SystemUI/res/values-land/config.xml index da5819c50a7e..2f7fbaff4ed2 100644 --- a/packages/SystemUI/res/values-land/config.xml +++ b/packages/SystemUI/res/values-land/config.xml @@ -34,4 +34,7 @@ <!-- Max number of columns for quick controls area --> <integer name="controls_max_columns">4</integer> + + <!-- Max number of columns for power menu --> + <integer name="power_menu_max_columns">4</integer> </resources> diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml index f549a3253319..62335abd4329 100644 --- a/packages/SystemUI/res/values/config.xml +++ b/packages/SystemUI/res/values/config.xml @@ -536,6 +536,10 @@ <!-- Max number of columns for quick controls area --> <integer name="controls_max_columns">2</integer> + + <!-- Max number of columns for power menu --> + <integer name="power_menu_max_columns">3</integer> + <!-- If the dp width of the available space is <= this value, potentially adjust the number of columns--> <integer name="controls_max_columns_adjust_below_width_dp">320</integer> diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index e7ef8ccf4eba..622e4ccef487 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -1252,6 +1252,7 @@ <dimen name="control_status_expanded">18sp</dimen> <dimen name="control_base_item_margin">2dp</dimen> <dimen name="control_status_padding">3dp</dimen> + <fraction name="controls_toggle_bg_intensity">5%</fraction> <!-- Home Controls activity view detail panel--> <dimen name="controls_activity_view_top_padding">25dp</dimen> diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index 7c0b6054dddb..49420e8620d1 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -235,8 +235,8 @@ your organization</string> <!-- Content description indicating that tapping a button will dismiss the screenshots UI [CHAR LIMIT=NONE] --> <string name="screenshot_dismiss_ui_description">Dismiss screenshot</string> - <!-- Content description indicating that tapping will open an app to view/edit the screenshot. [CHAR LIMIT=NONE] --> - <string name="screenshot_preview_description">Open screenshot</string> + <!-- Content description indicating that the view is a preview of the screenshot that was just taken [CHAR LIMIT=NONE] --> + <string name="screenshot_preview_description">Screenshot preview</string> <!-- Notification title displayed for screen recording [CHAR LIMIT=50]--> <string name="screenrecord_name">Screen Recorder</string> @@ -1829,15 +1829,15 @@ <!-- [CHAR LIMIT=150] Notification Importance title: normal importance level summary --> <string name="notification_channel_summary_default">Gets your attention with sound or vibration.</string> + <!-- [CHAR LIMIT=150] Conversation Notification Importance title: normal conversation level, with bubbling summary --> + <string name="notification_channel_summary_default_with_bubbles">Gets your attention with sound or vibration. Conversations from <xliff:g id="app_name" example="YouTube">%1$s</xliff:g> bubble by default.</string> + <!-- [CHAR LIMIT=150] Notification Importance title: bubble level summary --> <string name="notification_channel_summary_bubble">Keeps your attention with a floating shortcut to this content.</string> <!-- [CHAR LIMIT=150] Notification Importance title: important conversation level summary --> <string name="notification_channel_summary_priority">Shows at top of conversation section and appears as a bubble.</string> - <!--[CHAR LIMIT=150] Conversation inline controls footer shown when all conversations from the app are allowed to show as bubbles --> - <string name="notification_conversation_channel_all_bubble">All conversations from <xliff:g id="app_name" example="YouTube">%1$s</xliff:g> bubble by default. Manage in <xliff:g id="app_name" example="Settings">%2$s</xliff:g>.</string> - <!--[CHAR LIMIT=30] Linkable text to Settings app --> <string name="notification_conversation_channel_settings">Settings</string> diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml index 118aa5b3f96a..7e24f5dbbd50 100644 --- a/packages/SystemUI/res/values/styles.xml +++ b/packages/SystemUI/res/values/styles.xml @@ -564,7 +564,7 @@ <style name="TextAppearance.NotificationImportanceButton"> <item name="android:textSize">@dimen/notification_importance_button_text</item> <item name="android:fontFamily">@*android:string/config_headlineFontFamilyMedium</item> - <item name="android:textColor">?android:attr/colorAccent</item> + <item name="android:textColor">@color/notification_guts_priority_contents</item> <item name="android:gravity">center</item> </style> diff --git a/packages/SystemUI/scripts/update_statsd_lib.sh b/packages/SystemUI/scripts/update_statsd_lib.sh new file mode 100755 index 000000000000..79b9497a5f3f --- /dev/null +++ b/packages/SystemUI/scripts/update_statsd_lib.sh @@ -0,0 +1,35 @@ +#!/bin/sh + +NUM_ARGS=$# +JAR_DESTINATION="$1/prebuilts/framework_intermediates/libs/systemui_statsd.jar" + +has_croot() { + declare -F croot > /dev/null + return $? +} + +check_environment() { + if ! has_croot; then + echo "Run script in a shell that has had envsetup run. Run '. update_statsd_lib.sh' from scripts directory" + return 1 + fi + + if [ $NUM_ARGS -ne 1 ]; then + echo "Usage: . update_statsd_lib.sh PATH_TO_UNBUNDLED_LAUNCER e.g. . update_statsd_lib ~/src/ub-launcher3-master" + return 1 + fi + return 0 +} + +main() { + if check_environment ; then + pushd . + croot + mma -j16 SystemUI-statsd + cp out/target/product/$TARGET_PRODUCT/obj/JAVA_LIBRARIES/SystemUI-statsd_intermediates/javalib.jar $JAR_DESTINATION + popd + fi +} + +main + diff --git a/packages/SystemUI/src/com/android/systemui/Interpolators.java b/packages/SystemUI/src/com/android/systemui/Interpolators.java index 6923079dd5c4..2eba9521b9e7 100644 --- a/packages/SystemUI/src/com/android/systemui/Interpolators.java +++ b/packages/SystemUI/src/com/android/systemui/Interpolators.java @@ -54,6 +54,11 @@ public class Interpolators { public static final Interpolator PANEL_CLOSE_ACCELERATED = new PathInterpolator(0.3f, 0, 0.5f, 1); public static final Interpolator BOUNCE = new BounceInterpolator(); + /** + * For state transitions on the control panel that lives in GlobalActions. + */ + public static final Interpolator CONTROL_STATE = new PathInterpolator(0.4f, 0f, 0.2f, + 1.0f); /** * Interpolator to be used when animating a move based on a click. Pair with enough duration. diff --git a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java index 8df3dd2ad845..922fb69b3fdc 100644 --- a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java +++ b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java @@ -54,8 +54,10 @@ import android.graphics.Region; import android.graphics.drawable.VectorDrawable; import android.hardware.display.DisplayManager; import android.os.Handler; +import android.os.HandlerExecutor; import android.os.HandlerThread; import android.os.SystemProperties; +import android.os.UserHandle; import android.provider.Settings.Secure; import android.util.DisplayMetrics; import android.util.Log; @@ -298,13 +300,15 @@ public class ScreenDecorations extends SystemUI implements Tunable { updateColorInversion(value); } }; + + mColorInversionSetting.setListening(true); + mColorInversionSetting.onChange(false); } - mColorInversionSetting.setListening(true); - mColorInversionSetting.onChange(false); IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_USER_SWITCHED); - mBroadcastDispatcher.registerReceiverWithHandler(mIntentReceiver, filter, mHandler); + mBroadcastDispatcher.registerReceiver(mUserSwitchIntentReceiver, filter, + new HandlerExecutor(mHandler), UserHandle.ALL); mIsRegistered = true; } else { mMainHandler.post(() -> mTunerService.removeTunable(this)); @@ -313,7 +317,7 @@ public class ScreenDecorations extends SystemUI implements Tunable { mColorInversionSetting.setListening(false); } - mBroadcastDispatcher.unregisterReceiver(mIntentReceiver); + mBroadcastDispatcher.unregisterReceiver(mUserSwitchIntentReceiver); mIsRegistered = false; } } @@ -503,17 +507,16 @@ public class ScreenDecorations extends SystemUI implements Tunable { } } - private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() { + private final BroadcastReceiver mUserSwitchIntentReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { - String action = intent.getAction(); - if (action.equals(Intent.ACTION_USER_SWITCHED)) { - int newUserId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, - ActivityManager.getCurrentUser()); - // update color inversion setting to the new user - mColorInversionSetting.setUserId(newUserId); - updateColorInversion(mColorInversionSetting.getValue()); + int newUserId = ActivityManager.getCurrentUser(); + if (DEBUG) { + Log.d(TAG, "UserSwitched newUserId=" + newUserId); } + // update color inversion setting to the new user + mColorInversionSetting.setUserId(newUserId); + updateColorInversion(mColorInversionSetting.getValue()); } }; diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java index 669a86b8a742..da5c2968c6ac 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java @@ -17,6 +17,8 @@ package com.android.systemui.bubbles; import static android.app.Notification.FLAG_BUBBLE; +import static android.app.NotificationManager.BUBBLE_PREFERENCE_NONE; +import static android.app.NotificationManager.BUBBLE_PREFERENCE_SELECTED; import static android.service.notification.NotificationListenerService.REASON_APP_CANCEL; import static android.service.notification.NotificationListenerService.REASON_APP_CANCEL_ALL; import static android.service.notification.NotificationListenerService.REASON_CANCEL; @@ -30,7 +32,6 @@ import static android.view.View.VISIBLE; import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; import static com.android.systemui.bubbles.BubbleDebugConfig.DEBUG_BUBBLE_CONTROLLER; -import static com.android.systemui.bubbles.BubbleDebugConfig.DEBUG_EXPERIMENTS; import static com.android.systemui.bubbles.BubbleDebugConfig.TAG_BUBBLES; import static com.android.systemui.bubbles.BubbleDebugConfig.TAG_WITH_CLASS_NAME; import static com.android.systemui.statusbar.StatusBarState.SHADE; @@ -43,6 +44,9 @@ import static java.lang.annotation.RetentionPolicy.SOURCE; import android.annotation.UserIdInt; import android.app.ActivityManager.RunningTaskInfo; +import android.app.INotificationManager; +import android.app.Notification; +import android.app.NotificationChannel; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.Context; @@ -83,6 +87,7 @@ import com.android.systemui.shared.system.WindowManagerWrapper; import com.android.systemui.statusbar.FeatureFlags; import com.android.systemui.statusbar.NotificationLockscreenUserManager; import com.android.systemui.statusbar.NotificationRemoveInterceptor; +import com.android.systemui.statusbar.notification.NotificationChannelHelper; import com.android.systemui.statusbar.notification.NotificationEntryListener; import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.collection.NotifCollection; @@ -169,6 +174,7 @@ public class BubbleController implements ConfigurationController.ConfigurationLi private final NotificationShadeWindowController mNotificationShadeWindowController; private final ZenModeController mZenModeController; private StatusBarStateListener mStatusBarStateListener; + private INotificationManager mINotificationManager; // Callback that updates BubbleOverflowActivity on data change. @Nullable private Runnable mOverflowCallback = null; @@ -293,11 +299,13 @@ public class BubbleController implements ConfigurationController.ConfigurationLi FeatureFlags featureFlags, DumpManager dumpManager, FloatingContentCoordinator floatingContentCoordinator, - SysUiState sysUiState) { + SysUiState sysUiState, + INotificationManager notificationManager) { this(context, notificationShadeWindowController, statusBarStateController, shadeController, data, null /* synchronizer */, configurationController, interruptionStateProvider, zenModeController, notifUserManager, groupManager, entryManager, - notifPipeline, featureFlags, dumpManager, floatingContentCoordinator, sysUiState); + notifPipeline, featureFlags, dumpManager, floatingContentCoordinator, sysUiState, + notificationManager); } /** @@ -319,7 +327,8 @@ public class BubbleController implements ConfigurationController.ConfigurationLi FeatureFlags featureFlags, DumpManager dumpManager, FloatingContentCoordinator floatingContentCoordinator, - SysUiState sysUiState) { + SysUiState sysUiState, + INotificationManager notificationManager) { dumpManager.registerDumpable(TAG, this); mContext = context; mShadeController = shadeController; @@ -327,6 +336,7 @@ public class BubbleController implements ConfigurationController.ConfigurationLi mNotifUserManager = notifUserManager; mZenModeController = zenModeController; mFloatingContentCoordinator = floatingContentCoordinator; + mINotificationManager = notificationManager; mZenModeController.addCallback(new ZenModeController.Callback() { @Override public void onZenChanged(int zen) { @@ -809,37 +819,43 @@ public class BubbleController implements ConfigurationController.ConfigurationLi * This method will collapse the shade, create the bubble without a flyout or dot, and suppress * the notification from appearing in the shade. * - * @param entry the notification to show as a bubble. + * @param entry the notification to change bubble state for. + * @param shouldBubble whether the notification should show as a bubble or not. */ - public void onUserCreatedBubbleFromNotification(NotificationEntry entry) { - if (DEBUG_EXPERIMENTS || DEBUG_BUBBLE_CONTROLLER) { - Log.d(TAG, "onUserCreatedBubble: " + entry.getKey()); + public void onUserChangedBubble(NotificationEntry entry, boolean shouldBubble) { + NotificationChannel channel = entry.getChannel(); + final String appPkg = entry.getSbn().getPackageName(); + final int appUid = entry.getSbn().getUid(); + if (channel == null || appPkg == null) { + return; } - mShadeController.collapsePanel(true); - entry.setFlagBubble(true); - updateBubble(entry, true /* suppressFlyout */, false /* showInShade */); - mUserCreatedBubbles.add(entry.getKey()); - mUserBlockedBubbles.remove(entry.getKey()); - } - /** - * Called when a user has indicated that an active notification appearing as a bubble should - * no longer be shown as a bubble. - * - * @param entry the notification to no longer show as a bubble. - */ - public void onUserDemotedBubbleFromNotification(NotificationEntry entry) { - if (DEBUG_EXPERIMENTS || DEBUG_BUBBLE_CONTROLLER) { - Log.d(TAG, "onUserDemotedBubble: " + entry.getKey()); + // Update the state in NotificationManagerService + try { + int flags = Notification.BubbleMetadata.FLAG_SUPPRESS_NOTIFICATION; + mBarService.onNotificationBubbleChanged(entry.getKey(), shouldBubble, flags); + } catch (RemoteException e) { } - entry.setFlagBubble(false); - removeBubble(entry, DISMISS_BLOCKED); - mUserCreatedBubbles.remove(entry.getKey()); - if (BubbleExperimentConfig.isPackageWhitelistedToAutoBubble( - mContext, entry.getSbn().getPackageName())) { - // This package is whitelist but user demoted the bubble, let's save it so we don't - // auto-bubble for the whitelist again. - mUserBlockedBubbles.add(entry.getKey()); + + // Change the settings + channel = NotificationChannelHelper.createConversationChannelIfNeeded(mContext, + mINotificationManager, entry, channel); + channel.setAllowBubbles(shouldBubble); + try { + int currentPref = mINotificationManager.getBubblePreferenceForPackage(appPkg, appUid); + if (shouldBubble && currentPref == BUBBLE_PREFERENCE_NONE) { + mINotificationManager.setBubblesAllowed(appPkg, appUid, BUBBLE_PREFERENCE_SELECTED); + } + mINotificationManager.updateNotificationChannelForPackage(appPkg, appUid, channel); + } catch (RemoteException e) { + Log.e(TAG, e.getMessage()); + } + + if (shouldBubble) { + mShadeController.collapsePanel(true); + if (entry.getRow() != null) { + entry.getRow().updateBubbleButton(); + } } } @@ -987,14 +1003,15 @@ public class BubbleController implements ConfigurationController.ConfigurationLi } else { // Update the flag for SysUI bubble.getEntry().getSbn().getNotification().flags &= ~FLAG_BUBBLE; + if (bubble.getEntry().getRow() != null) { + bubble.getEntry().getRow().updateBubbleButton(); + } - // Make sure NoMan knows it's not a bubble anymore so anyone querying it - // will get right result back + // Update the state in NotificationManagerService try { mBarService.onNotificationBubbleChanged(bubble.getKey(), - false /* isBubble */); + false /* isBubble */, 0 /* flags */); } catch (RemoteException e) { - // Bad things have happened } } diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java index 4c149ddd3939..a1393cddc9f6 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java @@ -120,6 +120,7 @@ public class BubbleData { /** Bubbles that are being loaded but haven't been added to the stack just yet. */ private final List<Bubble> mPendingBubbles; private Bubble mSelectedBubble; + private boolean mShowingOverflow; private boolean mExpanded; private final int mMaxBubbles; private final int mMaxOverflowBubbles; @@ -215,6 +216,10 @@ public class BubbleData { dispatchPendingChanges(); } + void setShowingOverflow(boolean showingOverflow) { + mShowingOverflow = showingOverflow; + } + private void moveOverflowBubbleToPending(Bubble b) { // Preserve new order for next repack, which sorts by last updated time. b.markUpdatedAt(mTimeSource.currentTimeMillis()); @@ -513,9 +518,11 @@ public class BubbleData { if (DEBUG_BUBBLE_DATA) { Log.d(TAG, "setSelectedBubbleInternal: " + bubble); } - if (Objects.equals(bubble, mSelectedBubble)) { + if (!mShowingOverflow && Objects.equals(bubble, mSelectedBubble)) { return; } + // Otherwise, if we are showing the overflow menu, return to the previously selected bubble. + if (bubble != null && !mBubbles.contains(bubble) && !mOverflowBubbles.contains(bubble)) { Log.e(TAG, "Cannot select bubble which doesn't exist!" + " (" + bubble + ") bubbles=" + mBubbles); @@ -559,6 +566,10 @@ public class BubbleData { mStateChange.orderChanged |= repackAll(); // Save the state which should be returned to when expanded (with no other changes) + if (mShowingOverflow) { + // Show previously selected bubble instead of overflow menu on next expansion. + setSelectedBubbleInternal(mSelectedBubble); + } if (mBubbles.indexOf(mSelectedBubble) > 0) { // Move the selected bubble to the top while collapsed. if (!mSelectedBubble.isOngoing() && mBubbles.get(0).isOngoing()) { diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java index 71dbbbc9da50..1cabe221bef1 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java @@ -442,8 +442,8 @@ public class BubbleStackView extends FrameLayout { // that means overflow was previously expanded. Set the selected bubble // internally without going through BubbleData (which would ignore it since it's // already selected). + mBubbleData.setShowingOverflow(true); setSelectedBubble(clickedBubble); - } } else { // Otherwise, we either tapped the stack (which means we're collapsed @@ -1232,8 +1232,12 @@ public class BubbleStackView extends FrameLayout { if (mExpandedBubble != null && mExpandedBubble.equals(bubbleToSelect)) { return; } + if (bubbleToSelect == null || bubbleToSelect.getKey() != BubbleOverflow.KEY) { + mBubbleData.setShowingOverflow(false); + } final BubbleViewProvider previouslySelected = mExpandedBubble; mExpandedBubble = bubbleToSelect; + updatePointerPosition(); if (mIsExpanded) { // Make the container of the expanded view transparent before removing the expanded view @@ -1243,7 +1247,6 @@ public class BubbleStackView extends FrameLayout { mSurfaceSynchronizer.syncSurfaceAndRun(() -> { previouslySelected.setContentVisibility(false); updateExpandedBubble(); - updatePointerPosition(); requestUpdate(); logBubbleEvent(previouslySelected, diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/dagger/BubbleModule.java b/packages/SystemUI/src/com/android/systemui/bubbles/dagger/BubbleModule.java index e84e932c9e61..72d646e0554d 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/dagger/BubbleModule.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/dagger/BubbleModule.java @@ -16,6 +16,7 @@ package com.android.systemui.bubbles.dagger; +import android.app.INotificationManager; import android.content.Context; import com.android.systemui.bubbles.BubbleController; @@ -64,14 +65,15 @@ public interface BubbleModule { FeatureFlags featureFlags, DumpManager dumpManager, FloatingContentCoordinator floatingContentCoordinator, - SysUiState sysUiState) { + SysUiState sysUiState, + INotificationManager notifManager) { return new BubbleController( context, notificationShadeWindowController, statusBarStateController, shadeController, data, - /* synchronizer */null, + null /* synchronizer */, configurationController, interruptionStateProvider, zenModeController, @@ -82,6 +84,7 @@ public interface BubbleModule { featureFlags, dumpManager, floatingContentCoordinator, - sysUiState); + sysUiState, + notifManager); } } diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt index 607934c3bae7..03ca3931e68c 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt @@ -81,7 +81,7 @@ class ControlAdapter( } TYPE_DIVIDER -> { DividerHolder(layoutInflater.inflate( - R.layout.controls_horizontal_divider_withEmpty, parent, false)) + R.layout.controls_horizontal_divider_with_empty, parent, false)) } else -> throw IllegalStateException("Wrong viewType: $viewType") } diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinator.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinator.kt index ad86eeb089c8..2c1a91dca225 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinator.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinator.kt @@ -24,12 +24,11 @@ import android.service.controls.actions.BooleanAction import android.service.controls.actions.CommandAction import android.util.Log import android.view.HapticFeedbackConstants - import com.android.systemui.R object ControlActionCoordinator { - public const val MIN_LEVEL = 0 - public const val MAX_LEVEL = 10000 + const val MIN_LEVEL = 0 + const val MAX_LEVEL = 10000 private var dialog: Dialog? = null @@ -40,9 +39,6 @@ object ControlActionCoordinator { fun toggle(cvh: ControlViewHolder, templateId: String, isChecked: Boolean) { cvh.action(BooleanAction(templateId, !isChecked)) - - val nextLevel = if (isChecked) MIN_LEVEL else MAX_LEVEL - cvh.clipLayer.setLevel(nextLevel) } fun touch(cvh: ControlViewHolder, templateId: String, control: Control) { diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt index 0eb6cb100933..93e1bd444938 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt @@ -16,6 +16,9 @@ package com.android.systemui.controls.ui +import android.animation.Animator +import android.animation.AnimatorListenerAdapter +import android.animation.ValueAnimator import android.content.Context import android.graphics.drawable.ClipDrawable import android.graphics.drawable.GradientDrawable @@ -32,11 +35,11 @@ import android.view.View import android.view.ViewGroup import android.widget.ImageView import android.widget.TextView - +import com.android.internal.graphics.ColorUtils +import com.android.systemui.Interpolators +import com.android.systemui.R import com.android.systemui.controls.controller.ControlsController import com.android.systemui.util.concurrency.DelayableExecutor -import com.android.systemui.R - import kotlin.reflect.KClass /** @@ -53,15 +56,20 @@ class ControlViewHolder( ) { companion object { + const val STATE_ANIMATION_DURATION = 700L private const val UPDATE_DELAY_IN_MILLIS = 3000L private const val ALPHA_ENABLED = (255.0 * 0.2).toInt() - private const val ALPHA_DISABLED = 255 + private const val ALPHA_DISABLED = 0 private val FORCE_PANEL_DEVICES = setOf( DeviceTypes.TYPE_THERMOSTAT, DeviceTypes.TYPE_CAMERA ) } + private val toggleBackgroundIntensity: Float = layout.context.resources + .getFraction(R.fraction.controls_toggle_bg_intensity, 1, 1) + private var stateAnimator: ValueAnimator? = null + private val baseLayer: GradientDrawable val icon: ImageView = layout.requireViewById(R.id.icon) val status: TextView = layout.requireViewById(R.id.status) val title: TextView = layout.requireViewById(R.id.title) @@ -79,6 +87,8 @@ class ControlViewHolder( val ld = layout.getBackground() as LayerDrawable ld.mutate() clipLayer = ld.findDrawableByLayerId(R.id.clip_layer) as ClipDrawable + clipLayer.alpha = ALPHA_DISABLED + baseLayer = ld.findDrawableByLayerId(R.id.background) as GradientDrawable // needed for marquee to start status.setSelected(true) } @@ -160,30 +170,59 @@ class ControlViewHolder( } } - internal fun applyRenderInfo(enabled: Boolean, offset: Int = 0) { + internal fun applyRenderInfo(enabled: Boolean, offset: Int = 0, animated: Boolean = true) { setEnabled(enabled) val ri = RenderInfo.lookup(context, cws.componentName, deviceType, enabled, offset) - val fg = context.getResources().getColorStateList(ri.foreground, context.getTheme()) - val (bg, alpha) = if (enabled) { - Pair(ri.enabledBackground, ALPHA_ENABLED) + val fg = context.resources.getColorStateList(ri.foreground, context.theme) + val bg = context.resources.getColor(R.color.control_default_background, context.theme) + val (clip, newAlpha) = if (enabled) { + listOf(ri.enabledBackground, ALPHA_ENABLED) } else { - Pair(R.color.control_default_background, ALPHA_DISABLED) + listOf(R.color.control_default_background, ALPHA_DISABLED) } status.setTextColor(fg) - icon.setImageDrawable(ri.icon) // do not color app icons if (deviceType != DeviceTypes.TYPE_ROUTINE) { - icon.setImageTintList(fg) + icon.imageTintList = fg } (clipLayer.getDrawable() as GradientDrawable).apply { - setColor(context.getResources().getColor(bg, context.getTheme())) - setAlpha(alpha) + val newClipColor = context.resources.getColor(clip, context.theme) + val newBaseColor = if (behavior is ToggleRangeBehavior) { + ColorUtils.blendARGB(bg, newClipColor, toggleBackgroundIntensity) + } else { + bg + } + stateAnimator?.cancel() + if (animated) { + val oldColor = color?.defaultColor ?: newClipColor + val oldBaseColor = baseLayer.color?.defaultColor ?: newBaseColor + stateAnimator = ValueAnimator.ofInt(clipLayer.alpha, newAlpha).apply { + addUpdateListener { + alpha = it.animatedValue as Int + setColor(ColorUtils.blendARGB(oldColor, newClipColor, it.animatedFraction)) + baseLayer.setColor(ColorUtils.blendARGB(oldBaseColor, + newBaseColor, it.animatedFraction)) + } + addListener(object : AnimatorListenerAdapter() { + override fun onAnimationEnd(animation: Animator?) { + stateAnimator = null + } + }) + duration = STATE_ANIMATION_DURATION + interpolator = Interpolators.CONTROL_STATE + start() + } + } else { + alpha = newAlpha + setColor(newClipColor) + baseLayer.setColor(newBaseColor) + } } } diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ToggleBehavior.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ToggleBehavior.kt index a3368ef77a56..368d1399971d 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/ui/ToggleBehavior.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ToggleBehavior.kt @@ -18,12 +18,10 @@ package com.android.systemui.controls.ui import android.graphics.drawable.Drawable import android.graphics.drawable.LayerDrawable -import android.view.View import android.service.controls.Control import android.service.controls.templates.ToggleTemplate - +import android.view.View import com.android.systemui.R -import com.android.systemui.controls.ui.ControlActionCoordinator.MIN_LEVEL import com.android.systemui.controls.ui.ControlActionCoordinator.MAX_LEVEL class ToggleBehavior : Behavior { @@ -34,7 +32,7 @@ class ToggleBehavior : Behavior { override fun initialize(cvh: ControlViewHolder) { this.cvh = cvh - cvh.applyRenderInfo(false) + cvh.applyRenderInfo(false /* enabled */, 0 /* offset */, false /* animated */) cvh.layout.setOnClickListener(View.OnClickListener() { ControlActionCoordinator.toggle(cvh, template.getTemplateId(), template.isChecked()) @@ -49,9 +47,9 @@ class ToggleBehavior : Behavior { val ld = cvh.layout.getBackground() as LayerDrawable clipLayer = ld.findDrawableByLayerId(R.id.clip_layer) + clipLayer.level = MAX_LEVEL val checked = template.isChecked() - clipLayer.setLevel(if (checked) MAX_LEVEL else MIN_LEVEL) cvh.applyRenderInfo(checked) } } diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ToggleRangeBehavior.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ToggleRangeBehavior.kt index 5a956653285c..d8b26e2e68d8 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/ui/ToggleRangeBehavior.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ToggleRangeBehavior.kt @@ -16,11 +16,20 @@ package com.android.systemui.controls.ui -import android.os.Bundle +import android.animation.Animator +import android.animation.AnimatorListenerAdapter +import android.animation.ValueAnimator import android.content.Context import android.graphics.drawable.Drawable import android.graphics.drawable.LayerDrawable +import android.os.Bundle +import android.service.controls.Control +import android.service.controls.actions.FloatAction +import android.service.controls.templates.RangeTemplate +import android.service.controls.templates.ToggleRangeTemplate import android.util.Log +import android.util.MathUtils +import android.util.TypedValue import android.view.GestureDetector import android.view.GestureDetector.SimpleOnGestureListener import android.view.MotionEvent @@ -29,19 +38,14 @@ import android.view.ViewGroup import android.view.accessibility.AccessibilityEvent import android.view.accessibility.AccessibilityNodeInfo import android.widget.TextView -import android.service.controls.Control -import android.service.controls.actions.FloatAction -import android.service.controls.templates.RangeTemplate -import android.service.controls.templates.ToggleRangeTemplate -import android.util.TypedValue - +import com.android.systemui.Interpolators import com.android.systemui.R -import com.android.systemui.controls.ui.ControlActionCoordinator.MIN_LEVEL import com.android.systemui.controls.ui.ControlActionCoordinator.MAX_LEVEL - +import com.android.systemui.controls.ui.ControlActionCoordinator.MIN_LEVEL import java.util.IllegalFormatException class ToggleRangeBehavior : Behavior { + private var rangeAnimator: ValueAnimator? = null lateinit var clipLayer: Drawable lateinit var template: ToggleRangeTemplate lateinit var control: Control @@ -61,20 +65,21 @@ class ToggleRangeBehavior : Behavior { status = cvh.status context = status.getContext() - cvh.applyRenderInfo(false) + cvh.applyRenderInfo(false /* enabled */, 0 /* offset */, false /* animated */) val gestureListener = ToggleRangeGestureListener(cvh.layout) val gestureDetector = GestureDetector(context, gestureListener) cvh.layout.setOnTouchListener { v: View, e: MotionEvent -> if (gestureDetector.onTouchEvent(e)) { - return@setOnTouchListener true + // Don't return true to let the state list change to "pressed" + return@setOnTouchListener false } if (e.getAction() == MotionEvent.ACTION_UP && gestureListener.isDragging) { v.getParent().requestDisallowInterceptTouchEvent(false) gestureListener.isDragging = false endUpdateRange() - return@setOnTouchListener true + return@setOnTouchListener false } return@setOnTouchListener false @@ -87,17 +92,18 @@ class ToggleRangeBehavior : Behavior { currentStatusText = control.getStatusText() status.setText(currentStatusText) + // ControlViewHolder sets a long click listener, but we want to handle touch in + // here instead, otherwise we'll have state conflicts. + cvh.layout.setOnLongClickListener(null) + val ld = cvh.layout.getBackground() as LayerDrawable clipLayer = ld.findDrawableByLayerId(R.id.clip_layer) - clipLayer.setLevel(MIN_LEVEL) template = control.getControlTemplate() as ToggleRangeTemplate rangeTemplate = template.getRange() val checked = template.isChecked() - val currentRatio = rangeTemplate.getCurrentValue() / - (rangeTemplate.getMaxValue() - rangeTemplate.getMinValue()) - updateRange(currentRatio, checked, /* isDragging */ false) + updateRange(rangeToLevelValue(rangeTemplate.currentValue), checked, /* isDragging */ false) cvh.applyRenderInfo(checked) @@ -146,9 +152,8 @@ class ToggleRangeBehavior : Behavior { } else { val value = arguments.getFloat( AccessibilityNodeInfo.ACTION_ARGUMENT_PROGRESS_VALUE) - val ratioDiff = (value - rangeTemplate.getCurrentValue()) / - (rangeTemplate.getMaxValue() - rangeTemplate.getMinValue()) - updateRange(ratioDiff, template.isChecked(), /* isDragging */ false) + val level = rangeToLevelValue(value - rangeTemplate.getCurrentValue()) + updateRange(level, template.isChecked(), /* isDragging */ false) endUpdateRange() true } @@ -172,13 +177,30 @@ class ToggleRangeBehavior : Behavior { .getDimensionPixelSize(R.dimen.control_status_expanded).toFloat()) } - fun updateRange(ratioDiff: Float, checked: Boolean, isDragging: Boolean) { - val changeAmount = if (checked) (MAX_LEVEL * ratioDiff).toInt() else MIN_LEVEL - val newLevel = Math.max(MIN_LEVEL, Math.min(MAX_LEVEL, clipLayer.getLevel() + changeAmount)) - clipLayer.setLevel(newLevel) + fun updateRange(level: Int, checked: Boolean, isDragging: Boolean) { + val newLevel = if (checked) Math.max(MIN_LEVEL, Math.min(MAX_LEVEL, level)) else MIN_LEVEL + + rangeAnimator?.cancel() + if (isDragging) { + clipLayer.level = newLevel + } else { + rangeAnimator = ValueAnimator.ofInt(cvh.clipLayer.level, newLevel).apply { + addUpdateListener { + cvh.clipLayer.level = it.animatedValue as Int + } + addListener(object : AnimatorListenerAdapter() { + override fun onAnimationEnd(animation: Animator?) { + rangeAnimator = null + } + }) + duration = ControlViewHolder.STATE_ANIMATION_DURATION + interpolator = Interpolators.CONTROL_STATE + start() + } + } if (checked) { - val newValue = levelToRangeValue(clipLayer.getLevel()) + val newValue = levelToRangeValue(newLevel) currentRangeValue = format(rangeTemplate.getFormatString().toString(), DEFAULT_FORMAT, newValue) val text = if (isDragging) { @@ -206,9 +228,13 @@ class ToggleRangeBehavior : Behavior { } private fun levelToRangeValue(i: Int): Float { - val ratio = i.toFloat() / MAX_LEVEL - return rangeTemplate.getMinValue() + - (ratio * (rangeTemplate.getMaxValue() - rangeTemplate.getMinValue())) + return MathUtils.constrainedMap(rangeTemplate.minValue, rangeTemplate.maxValue, + MIN_LEVEL.toFloat(), MAX_LEVEL.toFloat(), i.toFloat()) + } + + private fun rangeToLevelValue(i: Float): Int { + return MathUtils.constrainedMap(MIN_LEVEL.toFloat(), MAX_LEVEL.toFloat(), + rangeTemplate.minValue, rangeTemplate.maxValue, i).toInt() } fun endUpdateRange() { @@ -247,6 +273,9 @@ class ToggleRangeBehavior : Behavior { } override fun onLongPress(e: MotionEvent) { + if (isDragging) { + return + } ControlActionCoordinator.longPress(this@ToggleRangeBehavior.cvh) } @@ -256,14 +285,19 @@ class ToggleRangeBehavior : Behavior { xDiff: Float, yDiff: Float ): Boolean { + if (!template.isChecked) { + return false + } if (!isDragging) { v.getParent().requestDisallowInterceptTouchEvent(true) this@ToggleRangeBehavior.beginUpdateRange() isDragging = true } - this@ToggleRangeBehavior.updateRange(-xDiff / v.getWidth(), - /* checked */ true, /* isDragging */ true) + val ratioDiff = -xDiff / v.width + val changeAmount = ((MAX_LEVEL - MIN_LEVEL) * ratioDiff).toInt() + this@ToggleRangeBehavior.updateRange(clipLayer.level + changeAmount, + checked = true, isDragging = true) return true } diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/TouchBehavior.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/TouchBehavior.kt index b02c9c8972fc..fd96cea1541e 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/ui/TouchBehavior.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/ui/TouchBehavior.kt @@ -37,7 +37,7 @@ class TouchBehavior : Behavior { override fun initialize(cvh: ControlViewHolder) { this.cvh = cvh - cvh.applyRenderInfo(false) + cvh.applyRenderInfo(false /* enabled */, 0 /* offset */, false /* animated */) cvh.layout.setOnClickListener(View.OnClickListener() { ControlActionCoordinator.touch(cvh, template.getTemplateId(), control) diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java index 4db5374cd566..2c080b8efc63 100644 --- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java +++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java @@ -43,7 +43,6 @@ import android.content.res.ColorStateList; import android.content.res.Resources; import android.database.ContentObserver; import android.graphics.Color; -import android.graphics.Insets; import android.graphics.drawable.Drawable; import android.media.AudioManager; import android.net.ConnectivityManager; @@ -75,9 +74,12 @@ import android.view.Window; import android.view.WindowInsets; import android.view.WindowManager; import android.view.accessibility.AccessibilityEvent; +import android.widget.BaseAdapter; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.ImageView.ScaleType; +import android.widget.ListPopupWindow; +import android.widget.ListView; import android.widget.TextView; import androidx.annotation.NonNull; @@ -151,19 +153,20 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, /* Valid settings for global actions keys. * see config.xml config_globalActionList */ - private static final String GLOBAL_ACTION_KEY_POWER = "power"; - private static final String GLOBAL_ACTION_KEY_AIRPLANE = "airplane"; - private static final String GLOBAL_ACTION_KEY_BUGREPORT = "bugreport"; - private static final String GLOBAL_ACTION_KEY_SILENT = "silent"; - private static final String GLOBAL_ACTION_KEY_USERS = "users"; - private static final String GLOBAL_ACTION_KEY_SETTINGS = "settings"; - private static final String GLOBAL_ACTION_KEY_LOCKDOWN = "lockdown"; - private static final String GLOBAL_ACTION_KEY_VOICEASSIST = "voiceassist"; - private static final String GLOBAL_ACTION_KEY_ASSIST = "assist"; - private static final String GLOBAL_ACTION_KEY_RESTART = "restart"; - private static final String GLOBAL_ACTION_KEY_LOGOUT = "logout"; - private static final String GLOBAL_ACTION_KEY_EMERGENCY = "emergency"; - private static final String GLOBAL_ACTION_KEY_SCREENSHOT = "screenshot"; + @VisibleForTesting + protected static final String GLOBAL_ACTION_KEY_POWER = "power"; + protected static final String GLOBAL_ACTION_KEY_AIRPLANE = "airplane"; + protected static final String GLOBAL_ACTION_KEY_BUGREPORT = "bugreport"; + protected static final String GLOBAL_ACTION_KEY_SILENT = "silent"; + protected static final String GLOBAL_ACTION_KEY_USERS = "users"; + protected static final String GLOBAL_ACTION_KEY_SETTINGS = "settings"; + protected static final String GLOBAL_ACTION_KEY_LOCKDOWN = "lockdown"; + protected static final String GLOBAL_ACTION_KEY_VOICEASSIST = "voiceassist"; + protected static final String GLOBAL_ACTION_KEY_ASSIST = "assist"; + protected static final String GLOBAL_ACTION_KEY_RESTART = "restart"; + protected static final String GLOBAL_ACTION_KEY_LOGOUT = "logout"; + protected static final String GLOBAL_ACTION_KEY_EMERGENCY = "emergency"; + protected static final String GLOBAL_ACTION_KEY_SCREENSHOT = "screenshot"; private static final String PREFS_CONTROLS_SEEDING_COMPLETED = "ControlsSeedingCompleted"; private static final String PREFS_CONTROLS_FILE = "controls_prefs"; @@ -191,13 +194,18 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, // Used for RingerModeTracker private final LifecycleRegistry mLifecycle = new LifecycleRegistry(this); - private ArrayList<Action> mItems; + @VisibleForTesting + protected ArrayList<Action> mItems; + @VisibleForTesting + protected ArrayList<Action> mOverflowItems; + private ActionsDialog mDialog; private Action mSilentModeAction; private ToggleAction mAirplaneModeOn; private MyAdapter mAdapter; + private MyOverflowAdapter mOverflowAdapter; private boolean mKeyguardShowing = false; private boolean mDeviceProvisioned = false; @@ -459,12 +467,51 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, } } + @VisibleForTesting + protected boolean shouldShowAction(Action action) { + if (mKeyguardShowing && !action.showDuringKeyguard()) { + return false; + } + if (!mDeviceProvisioned && !action.showBeforeProvisioning()) { + return false; + } + return true; + } + /** - * Create the global actions dialog. - * - * @return A new dialog. + * Returns the maximum number of power menu items to show based on which GlobalActions + * layout is being used. */ - private ActionsDialog createDialog() { + @VisibleForTesting + protected int getMaxShownPowerItems() { + if (shouldShowControls()) { + return mResources.getInteger(com.android.systemui.R.integer.power_menu_max_columns); + } else { + return Integer.MAX_VALUE; + } + } + + /** + * Add a power menu action item for to either the main or overflow items lists, depending on + * whether controls are enabled and whether the max number of shown items has been reached. + */ + private void addActionItem(Action action) { + if (mItems != null && shouldShowAction(action)) { + if (mItems.size() < getMaxShownPowerItems()) { + mItems.add(action); + } else if (mOverflowItems != null) { + mOverflowItems.add(action); + } + } + } + + @VisibleForTesting + protected String[] getDefaultActions() { + return mResources.getStringArray(R.array.config_globalActionsList); + } + + @VisibleForTesting + protected void createActionItems() { // Simple toggle style if there's no vibrator, otherwise use a tri-state if (!mHasVibrator) { mSilentModeAction = new SilentModeToggleAction(); @@ -475,7 +522,13 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, onAirplaneModeChanged(); mItems = new ArrayList<Action>(); - String[] defaultActions = mResources.getStringArray(R.array.config_globalActionsList); + mOverflowItems = new ArrayList<Action>(); + String[] defaultActions = getDefaultActions(); + + // make sure emergency affordance action is first, if needed + if (mEmergencyAffordanceManager.needsEmergencyAffordance()) { + addActionItem(new EmergencyAffordanceAction()); + } ArraySet<String> addedKeys = new ArraySet<String>(); for (int i = 0; i < defaultActions.length; i++) { @@ -485,46 +538,46 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, continue; } if (GLOBAL_ACTION_KEY_POWER.equals(actionKey)) { - mItems.add(new PowerAction()); + addActionItem(new PowerAction()); } else if (GLOBAL_ACTION_KEY_AIRPLANE.equals(actionKey)) { - mItems.add(mAirplaneModeOn); + addActionItem(mAirplaneModeOn); } else if (GLOBAL_ACTION_KEY_BUGREPORT.equals(actionKey)) { if (Settings.Global.getInt(mContentResolver, Settings.Global.BUGREPORT_IN_POWER_MENU, 0) != 0 && isCurrentUserOwner()) { - mItems.add(new BugReportAction()); + addActionItem(new BugReportAction()); } } else if (GLOBAL_ACTION_KEY_SILENT.equals(actionKey)) { if (mShowSilentToggle) { - mItems.add(mSilentModeAction); + addActionItem(mSilentModeAction); } } else if (GLOBAL_ACTION_KEY_USERS.equals(actionKey)) { if (SystemProperties.getBoolean("fw.power_user_switcher", false)) { - addUsersToMenu(mItems); + addUsersToMenu(); } } else if (GLOBAL_ACTION_KEY_SETTINGS.equals(actionKey)) { - mItems.add(getSettingsAction()); + addActionItem(getSettingsAction()); } else if (GLOBAL_ACTION_KEY_LOCKDOWN.equals(actionKey)) { if (Settings.Secure.getIntForUser(mContentResolver, Settings.Secure.LOCKDOWN_IN_POWER_MENU, 0, getCurrentUser().id) != 0 && shouldDisplayLockdown()) { - mItems.add(getLockdownAction()); + addActionItem(getLockdownAction()); } } else if (GLOBAL_ACTION_KEY_VOICEASSIST.equals(actionKey)) { - mItems.add(getVoiceAssistAction()); + addActionItem(getVoiceAssistAction()); } else if (GLOBAL_ACTION_KEY_ASSIST.equals(actionKey)) { - mItems.add(getAssistAction()); + addActionItem(getAssistAction()); } else if (GLOBAL_ACTION_KEY_RESTART.equals(actionKey)) { - mItems.add(new RestartAction()); + addActionItem(new RestartAction()); } else if (GLOBAL_ACTION_KEY_SCREENSHOT.equals(actionKey)) { - mItems.add(new ScreenshotAction()); + addActionItem(new ScreenshotAction()); } else if (GLOBAL_ACTION_KEY_LOGOUT.equals(actionKey)) { if (mDevicePolicyManager.isLogoutEnabled() && getCurrentUser().id != UserHandle.USER_SYSTEM) { - mItems.add(new LogoutAction()); + addActionItem(new LogoutAction()); } } else if (GLOBAL_ACTION_KEY_EMERGENCY.equals(actionKey)) { if (!mEmergencyAffordanceManager.needsEmergencyAffordance()) { - mItems.add(new EmergencyDialerAction()); + addActionItem(new EmergencyDialerAction()); } } else { Log.e(TAG, "Invalid global action key " + actionKey); @@ -532,17 +585,23 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, // Add here so we don't add more than one. addedKeys.add(actionKey); } + } - if (mEmergencyAffordanceManager.needsEmergencyAffordance()) { - mItems.add(new EmergencyAffordanceAction()); - } + /** + * Create the global actions dialog. + * + * @return A new dialog. + */ + private ActionsDialog createDialog() { + createActionItems(); mAdapter = new MyAdapter(); + mOverflowAdapter = new MyOverflowAdapter(); mDepthController.setShowingHomeControls(shouldShowControls()); - ActionsDialog dialog = new ActionsDialog(mContext, mAdapter, getWalletPanelViewController(), - mDepthController, mSysuiColorExtractor, mStatusBarService, - mNotificationShadeWindowController, + ActionsDialog dialog = new ActionsDialog(mContext, mAdapter, mOverflowAdapter, + getWalletPanelViewController(), mDepthController, mSysuiColorExtractor, + mStatusBarService, mNotificationShadeWindowController, shouldShowControls() ? mControlsUiController : null, mBlurUtils); dialog.setCanceledOnTouchOutside(false); // Handled by the custom class. dialog.setKeyguardShowing(mKeyguardShowing); @@ -1020,7 +1079,7 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, return currentUser == null || currentUser.isPrimary(); } - private void addUsersToMenu(ArrayList<Action> items) { + private void addUsersToMenu() { if (mUserManager.isUserSwitcherEnabled()) { List<UserInfo> users = mUserManager.getUsers(); UserInfo currentUser = getCurrentUser(); @@ -1050,7 +1109,7 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, return false; } }; - items.add(switchToUser); + addActionItem(switchToUser); } } } @@ -1099,11 +1158,7 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, } /** - * The adapter used for the list within the global actions dialog, taking into account whether - * the keyguard is showing via - * {@link com.android.systemui.globalactions.GlobalActionsDialog#mKeyguardShowing} - * and whether the device is provisioned via - * {@link com.android.systemui.globalactions.GlobalActionsDialog#mDeviceProvisioned}. + * The adapter used for power menu items shown in the global actions dialog. */ public class MyAdapter extends MultiListAdapter { private int countItems(boolean separated) { @@ -1111,23 +1166,13 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, for (int i = 0; i < mItems.size(); i++) { final Action action = mItems.get(i); - if (shouldBeShown(action) && action.shouldBeSeparated() == separated) { + if (action.shouldBeSeparated() == separated) { count++; } } return count; } - private boolean shouldBeShown(Action action) { - if (mKeyguardShowing && !action.showDuringKeyguard()) { - return false; - } - if (!mDeviceProvisioned && !action.showBeforeProvisioning()) { - return false; - } - return true; - } - @Override public int countSeparatedItems() { return countItems(true); @@ -1158,7 +1203,7 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, int filteredPos = 0; for (int i = 0; i < mItems.size(); i++) { final Action action = mItems.get(i); - if (!shouldBeShown(action)) { + if (!shouldShowAction(action)) { continue; } if (filteredPos == position) { @@ -1223,6 +1268,79 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, } } + /** + * The adapter used for items in the overflow menu. + */ + public class MyOverflowAdapter extends BaseAdapter { + @Override + public int getCount() { + return mOverflowItems != null ? mOverflowItems.size() : 0; + } + + @Override + public Action getItem(int position) { + return mOverflowItems != null ? mOverflowItems.get(position) : null; + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + Action action = getItem(position); + if (action == null) { + Log.w(TAG, "No overflow action found at position: " + position); + return null; + } + int viewLayoutResource = com.android.systemui.R.layout.controls_more_item; + View view = convertView != null ? convertView + : LayoutInflater.from(mContext).inflate(viewLayoutResource, parent, false); + TextView textView = (TextView) view; + textView.setOnClickListener(v -> onClickItem(position)); + if (action.getMessageResId() != 0) { + textView.setText(action.getMessageResId()); + } else { + textView.setText(action.getMessage()); + } + + if (action instanceof LongPressAction) { + textView.setOnLongClickListener(v -> onLongClickItem(position)); + } else { + textView.setOnLongClickListener(null); + } + return textView; + } + + private boolean onLongClickItem(int position) { + final Action action = getItem(position); + if (action instanceof LongPressAction) { + if (mDialog != null) { + mDialog.hidePowerOverflowMenu(); + mDialog.dismiss(); + } else { + Log.w(TAG, "Action long-clicked while mDialog is null."); + } + return ((LongPressAction) action).onLongPress(); + } + return false; + } + + private void onClickItem(int position) { + Action item = getItem(position); + if (!(item instanceof SilentModeTriStateAction)) { + if (mDialog != null) { + mDialog.hidePowerOverflowMenu(); + mDialog.dismiss(); + } else { + Log.w(TAG, "Action clicked while mDialog is null."); + } + item.onPress(); + } + } + } + // note: the scheme below made more sense when we were planning on having // 8 different things in the global actions dialog. seems overkill with // only 3 items now, but may as well keep this flexible approach so it will @@ -1248,8 +1366,8 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, boolean showDuringKeyguard(); /** - * @return whether this action should appear in the dialog before the device is - * provisioned.onlongpress + * @return whether this action should appear in the dialog before the + * device is provisioned.f */ boolean showBeforeProvisioning(); @@ -1258,6 +1376,18 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, default boolean shouldBeSeparated() { return false; } + + /** + * Return the id of the message associated with this action, or 0 if it doesn't have one. + * @return + */ + int getMessageResId(); + + /** + * Return the message associated with this action, or null if it doesn't have one. + * @return + */ + CharSequence getMessage(); } /** @@ -1309,6 +1439,15 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, } } + + public int getMessageResId() { + return mMessageResId; + } + + public CharSequence getMessage() { + return mMessage; + } + public View create( Context context, View convertView, ViewGroup parent, LayoutInflater inflater) { View v = inflater.inflate(getActionLayoutId(), parent, false /* attach */); @@ -1396,6 +1535,23 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, return context.getString(mMessageResId); } + private boolean isOn() { + return mState == ToggleState.On || mState == ToggleState.TurningOn; + } + + @Override + public CharSequence getMessage() { + return null; + } + @Override + public int getMessageResId() { + return isOn() ? mEnabledStatusMessageResId : mDisabledStatusMessageResId; + } + + private int getIconResId() { + return isOn() ? mEnabledIconResId : mDisabledIconResid; + } + public View create(Context context, View convertView, ViewGroup parent, LayoutInflater inflater) { willCreate(); @@ -1405,17 +1561,15 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, ImageView icon = (ImageView) v.findViewById(R.id.icon); TextView messageView = (TextView) v.findViewById(R.id.message); final boolean enabled = isEnabled(); - boolean on = ((mState == ToggleState.On) || (mState == ToggleState.TurningOn)); if (messageView != null) { - messageView.setText(on ? mEnabledStatusMessageResId : mDisabledStatusMessageResId); + messageView.setText(getMessageResId()); messageView.setEnabled(enabled); messageView.setSelected(true); // necessary for marquee to work } if (icon != null) { - icon.setImageDrawable(context.getDrawable( - (on ? mEnabledIconResId : mDisabledIconResid))); + icon.setImageDrawable(context.getDrawable(getIconResId())); icon.setEnabled(enabled); } @@ -1553,6 +1707,16 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, return null; } + @Override + public int getMessageResId() { + return 0; + } + + @Override + public CharSequence getMessage() { + return null; + } + public View create(Context context, View convertView, ViewGroup parent, LayoutInflater inflater) { View v = inflater.inflate(R.layout.global_actions_silent_mode, parent, false); @@ -1708,6 +1872,7 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, private final Context mContext; private final MyAdapter mAdapter; + private final MyOverflowAdapter mOverflowAdapter; private final IStatusBarService mStatusBarService; private final IBinder mToken = new Binder(); private MultiListLayout mGlobalActionsLayout; @@ -1722,11 +1887,12 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, private final NotificationShadeWindowController mNotificationShadeWindowController; private final NotificationShadeDepthController mDepthController; private final BlurUtils mBlurUtils; + private ListPopupWindow mOverflowPopup; private ControlsUiController mControlsUiController; private ViewGroup mControlsView; - ActionsDialog(Context context, MyAdapter adapter, + ActionsDialog(Context context, MyAdapter adapter, MyOverflowAdapter overflowAdapter, GlobalActionsPanelPlugin.PanelViewController plugin, NotificationShadeDepthController depthController, SysuiColorExtractor sysuiColorExtractor, IStatusBarService statusBarService, @@ -1735,6 +1901,7 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, super(context, com.android.systemui.R.style.Theme_SystemUI_Dialog_GlobalActions); mContext = context; mAdapter = adapter; + mOverflowAdapter = overflowAdapter; mDepthController = depthController; mColorExtractor = sysuiColorExtractor; mStatusBarService = statusBarService; @@ -1817,6 +1984,45 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, } } + private ListPopupWindow createPowerOverflowPopup() { + ListPopupWindow popup = new ListPopupWindow(new ContextThemeWrapper( + mContext, com.android.systemui.R.style.Control_ListPopupWindow)); + popup.setWindowLayoutType(WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY); + View overflowButton = + findViewById(com.android.systemui.R.id.global_actions_overflow_button); + popup.setAnchorView(overflowButton); + int parentWidth = mGlobalActionsLayout.getWidth(); + // arbitrarily set the menu width to half of parent + // TODO: Logic for menu sizing based on contents. + int halfParentWidth = Math.round(parentWidth * 0.5f); + popup.setContentWidth(halfParentWidth); + popup.setAdapter(mOverflowAdapter); + popup.setModal(true); + return popup; + } + + private void showPowerOverflowMenu() { + mOverflowPopup.show(); + + // Width is fixed to slightly more than half of the GlobalActionsLayout container. + // TODO: Resize the width of this dialog based on the sizes of the items in it. + int width = Math.round(mGlobalActionsLayout.getWidth() * 0.6f); + + ListView listView = mOverflowPopup.getListView(); + listView.setDividerHeight(mContext.getResources() + .getDimensionPixelSize(com.android.systemui.R.dimen.control_list_divider)); + listView.setDivider(mContext.getResources().getDrawable( + com.android.systemui.R.drawable.controls_list_divider)); + mOverflowPopup.setWidth(width); + mOverflowPopup.setHorizontalOffset(-width + mOverflowPopup.getAnchorView().getWidth()); + mOverflowPopup.setVerticalOffset(mOverflowPopup.getAnchorView().getHeight()); + mOverflowPopup.show(); + } + + private void hidePowerOverflowMenu() { + mOverflowPopup.dismiss(); + } + private void initializeLayout() { setContentView(getGlobalActionsLayoutId(mContext)); fixNavBarClipping(); @@ -1835,6 +2041,18 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, mGlobalActionsLayout.setRotationListener(this::onRotate); mGlobalActionsLayout.setAdapter(mAdapter); + mOverflowPopup = createPowerOverflowPopup(); + + View overflowButton = findViewById( + com.android.systemui.R.id.global_actions_overflow_button); + if (overflowButton != null) { + if (mOverflowAdapter.getCount() > 0) { + overflowButton.setOnClickListener((view) -> showPowerOverflowMenu()); + } else { + overflowButton.setVisibility(View.GONE); + } + } + View globalActionsParent = (View) mGlobalActionsLayout.getParent(); globalActionsParent.setOnClickListener(v -> dismiss()); @@ -1959,8 +2177,10 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, ViewGroup root = (ViewGroup) mGlobalActionsLayout.getRootView(); root.setOnApplyWindowInsetsListener((v, windowInsets) -> { if (mControlsUiController != null) { - Insets insets = windowInsets.getInsets(WindowInsets.Type.all()); - root.setPadding(insets.left, insets.top, insets.right, insets.bottom); + root.setPadding(windowInsets.getStableInsetLeft(), + windowInsets.getStableInsetTop(), + windowInsets.getStableInsetRight(), + windowInsets.getStableInsetBottom()); } return WindowInsets.CONSUMED; }); @@ -2090,9 +2310,10 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, return isPanelDebugModeEnabled(context); } - private boolean shouldShowControls() { + @VisibleForTesting + protected boolean shouldShowControls() { return mKeyguardStateController.isUnlocked() && mControlsUiController.getAvailable() && !mControlsServiceInfos.isEmpty(); } -} +}
\ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsFlatLayout.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsFlatLayout.java index f1025615783b..2f32d972449e 100644 --- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsFlatLayout.java +++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsFlatLayout.java @@ -32,7 +32,6 @@ import com.android.systemui.R; * Flat, single-row implementation of the button layout created by the global actions dialog. */ public class GlobalActionsFlatLayout extends GlobalActionsLayout { - private static final int MAX_ITEMS = 4; public GlobalActionsFlatLayout(Context context, AttributeSet attrs) { super(context, attrs); } @@ -54,11 +53,28 @@ public class GlobalActionsFlatLayout extends GlobalActionsLayout { return null; } + private View getOverflowButton() { + return findViewById(com.android.systemui.R.id.global_actions_overflow_button); + } + @Override protected void addToListView(View v, boolean reverse) { - // only add items to the list view if we haven't hit our max yet - if (getListView().getChildCount() < MAX_ITEMS) { - super.addToListView(v, reverse); + super.addToListView(v, reverse); + View overflowButton = getOverflowButton(); + // if there's an overflow button, make sure it stays at the end + if (overflowButton != null) { + getListView().removeView(overflowButton); + super.addToListView(overflowButton, reverse); + } + } + + @Override + protected void removeAllListViews() { + View overflowButton = getOverflowButton(); + super.removeAllListViews(); + // if there's an overflow button, add it back after clearing the list views + if (overflowButton != null) { + super.addToListView(overflowButton, false); } } diff --git a/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java b/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java index a95d6b7a73cd..0125153542c1 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java +++ b/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java @@ -126,7 +126,7 @@ public class PipTaskOrganizer extends TaskOrganizer { }; @SuppressWarnings("unchecked") - private Handler.Callback mUpdateCallbacks = (msg) -> { + private final Handler.Callback mUpdateCallbacks = (msg) -> { SomeArgs args = (SomeArgs) msg.obj; Consumer<Rect> updateBoundsCallback = (Consumer<Rect>) args.arg1; switch (msg.what) { @@ -282,7 +282,7 @@ public class PipTaskOrganizer extends TaskOrganizer { */ @Override public void onTaskVanished(ActivityManager.RunningTaskInfo info) { - WindowContainerToken token = info.token; + final WindowContainerToken token = info.token; Objects.requireNonNull(token, "Requires valid WindowContainerToken"); if (token.asBinder() != mToken.asBinder()) { Log.wtf(TAG, "Unrecognized token: " + token); @@ -297,6 +297,7 @@ public class PipTaskOrganizer extends TaskOrganizer { @Override public void onTaskInfoChanged(ActivityManager.RunningTaskInfo info) { + Objects.requireNonNull(mToken, "onTaskInfoChanged requires valid existing mToken"); final PictureInPictureParams newParams = info.pictureInPictureParams; if (!shouldUpdateDestinationBounds(newParams)) { Log.d(TAG, "Ignored onTaskInfoChanged with PiP param: " + newParams); @@ -321,13 +322,19 @@ public class PipTaskOrganizer extends TaskOrganizer { * @param destinationBoundsOut the current destination bounds will be populated to this param */ @SuppressWarnings("unchecked") - public void onMovementBoundsChanged(Rect destinationBoundsOut, + public void onMovementBoundsChanged(Rect destinationBoundsOut, boolean fromRotation, boolean fromImeAdjustment, boolean fromShelfAdjustment) { final PipAnimationController.PipTransitionAnimator animator = mPipAnimationController.getCurrentAnimator(); - destinationBoundsOut.set(mLastReportedBounds); if (animator == null || !animator.isRunning() || animator.getTransitionDirection() != TRANSITION_DIRECTION_TO_PIP) { + if (mInPip && fromRotation) { + // this could happen if rotation finishes before the animation + mLastReportedBounds.set(destinationBoundsOut); + scheduleFinishResizePip(mLastReportedBounds); + } else if (!mLastReportedBounds.isEmpty()) { + destinationBoundsOut.set(mLastReportedBounds); + } return; } @@ -375,7 +382,7 @@ public class PipTaskOrganizer extends TaskOrganizer { @PipAnimationController.TransitionDirection int direction, int durationMs, Consumer<Rect> updateBoundsCallback) { if (!mInPip) { - // Ignore animation when we are no longer in PIP + // can be initiated in other component, ignore if we are no longer in PIP return; } SomeArgs args = SomeArgs.obtain(); @@ -427,6 +434,10 @@ public class PipTaskOrganizer extends TaskOrganizer { private void scheduleFinishResizePip(SurfaceControl.Transaction tx, Rect destinationBounds, @PipAnimationController.TransitionDirection int direction, Consumer<Rect> updateBoundsCallback) { + if (!mInPip) { + // can be initiated in other component, ignore if we are no longer in PIP + return; + } SomeArgs args = SomeArgs.obtain(); args.arg1 = updateBoundsCallback; args.arg2 = tx; @@ -441,7 +452,7 @@ public class PipTaskOrganizer extends TaskOrganizer { public void scheduleOffsetPip(Rect originalBounds, int offset, int duration, Consumer<Rect> updateBoundsCallback) { if (!mInPip) { - // Ignore offsets when we are no longer in PIP + // can be initiated in other component, ignore if we are no longer in PIP return; } SomeArgs args = SomeArgs.obtain(); diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java index a2667d9a4c74..c3779efcf4b2 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java +++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java @@ -97,8 +97,8 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio final boolean changed = mPipBoundsHandler.onDisplayRotationChanged(mTmpNormalBounds, displayId, fromRotation, toRotation, t); if (changed) { - updateMovementBounds(mTmpNormalBounds, false /* fromImeAdjustment */, - false /* fromShelfAdjustment */); + updateMovementBounds(mTmpNormalBounds, true /* fromRotation */, + false /* fromImeAdjustment */, false /* fromShelfAdjustment */); } }; @@ -163,7 +163,7 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio @Override public void onMovementBoundsChanged(boolean fromImeAdjustment) { mHandler.post(() -> updateMovementBounds(null /* toBounds */, - fromImeAdjustment, false /* fromShelfAdjustment */)); + false /* fromRotation */, fromImeAdjustment, false /* fromShelfAdjustment */)); } @Override @@ -294,7 +294,8 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio if (changed) { mTouchHandler.onShelfVisibilityChanged(visible, height); updateMovementBounds(mPipBoundsHandler.getLastDestinationBounds(), - false /* fromImeAdjustment */, true /* fromShelfAdjustment */); + false /* fromRotation */, false /* fromImeAdjustment */, + true /* fromShelfAdjustment */); } }); } @@ -353,7 +354,7 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio mMenuController.onPinnedStackAnimationEnded(); } - private void updateMovementBounds(@Nullable Rect toBounds, + private void updateMovementBounds(@Nullable Rect toBounds, boolean fromRotation, boolean fromImeAdjustment, boolean fromShelfAdjustment) { // Populate inset / normal bounds and DisplayInfo from mPipBoundsHandler before // passing to mTouchHandler/mPipTaskOrganizer @@ -361,7 +362,7 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio mPipBoundsHandler.onMovementBoundsChanged(mTmpInsetBounds, mTmpNormalBounds, outBounds, mTmpDisplayInfo); // mTouchHandler would rely on the bounds populated from mPipTaskOrganizer - mPipTaskOrganizer.onMovementBoundsChanged(outBounds, + mPipTaskOrganizer.onMovementBoundsChanged(outBounds, fromRotation, fromImeAdjustment, fromShelfAdjustment); mTouchHandler.onMovementBoundsChanged(mTmpInsetBounds, mTmpNormalBounds, outBounds, fromImeAdjustment, fromShelfAdjustment, diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java index ddba9eab7766..79d2eddfaec4 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java +++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java @@ -266,6 +266,10 @@ public class PipTouchHandler { mMagnetizedPip = mMotionHelper.getMagnetizedPip(); mMagneticTarget = mMagnetizedPip.addTarget(mTargetView, 0); + + // Set the magnetic field radius equal to twice the size of the target. + mMagneticTarget.setMagneticFieldRadiusPx(targetSize * 2); + mMagnetizedPip.setPhysicsAnimatorUpdateListener(mMotionHelper.mResizePipUpdateListener); mMagnetizedPip.setMagnetListener(new MagnetizedObject.MagnetListener() { @Override @@ -321,7 +325,7 @@ public class PipTouchHandler { } public void onActivityPinned() { - createDismissTargetMaybe(); + createOrUpdateDismissTarget(); mShowPipMenuOnAnimationEnd = true; mPipResizeGestureHandler.onActivityPinned(); @@ -357,8 +361,7 @@ public class PipTouchHandler { mMotionHelper.synchronizePinnedStackBounds(); // Recreate the dismiss target for the new orientation. - cleanUpDismissTarget(); - createDismissTargetMaybe(); + createOrUpdateDismissTarget(); } public void onImeVisibilityChanged(boolean imeVisible, int imeHeight) { @@ -454,43 +457,57 @@ public class PipTouchHandler { } /** Adds the magnetic target view to the WindowManager so it's ready to be animated in. */ - private void createDismissTargetMaybe() { + private void createOrUpdateDismissTarget() { if (!mTargetViewContainer.isAttachedToWindow()) { mHandler.removeCallbacks(mShowTargetAction); mMagneticTargetAnimator.cancel(); - final Point windowSize = new Point(); - mWindowManager.getDefaultDisplay().getRealSize(windowSize); - WindowManager.LayoutParams lp = new WindowManager.LayoutParams( - WindowManager.LayoutParams.MATCH_PARENT, - mDismissAreaHeight, - 0, windowSize.y - mDismissAreaHeight, - WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL, - WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN - | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE - | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, - PixelFormat.TRANSLUCENT); - lp.setTitle("pip-dismiss-overlay"); - lp.privateFlags |= WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS; - lp.setFitInsetsTypes(0 /* types */); - mTargetViewContainer.setVisibility(View.INVISIBLE); - mWindowManager.addView(mTargetViewContainer, lp); + + try { + mWindowManager.addView(mTargetViewContainer, getDismissTargetLayoutParams()); + } catch (IllegalStateException e) { + // This shouldn't happen, but if the target is already added, just update its layout + // params. + mWindowManager.updateViewLayout( + mTargetViewContainer, getDismissTargetLayoutParams()); + } + } else { + mWindowManager.updateViewLayout(mTargetViewContainer, getDismissTargetLayoutParams()); } } + /** Returns layout params for the dismiss target, using the latest display metrics. */ + private WindowManager.LayoutParams getDismissTargetLayoutParams() { + final Point windowSize = new Point(); + mWindowManager.getDefaultDisplay().getRealSize(windowSize); + + final WindowManager.LayoutParams lp = new WindowManager.LayoutParams( + WindowManager.LayoutParams.MATCH_PARENT, + mDismissAreaHeight, + 0, windowSize.y - mDismissAreaHeight, + WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL, + WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN + | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE + | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, + PixelFormat.TRANSLUCENT); + + lp.setTitle("pip-dismiss-overlay"); + lp.privateFlags |= WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS; + lp.setFitInsetsTypes(0 /* types */); + + return lp; + } + /** Makes the dismiss target visible and animates it in, if it isn't already visible. */ private void showDismissTargetMaybe() { - createDismissTargetMaybe(); + createOrUpdateDismissTarget(); if (mTargetViewContainer.getVisibility() != View.VISIBLE) { mTargetView.setTranslationY(mTargetViewContainer.getHeight()); mTargetViewContainer.setVisibility(View.VISIBLE); - // Set the magnetic field radius to half of PIP's width. - mMagneticTarget.setMagneticFieldRadiusPx(mMotionHelper.getBounds().width()); - // Cancel in case we were in the middle of animating it out. mMagneticTargetAnimator.cancel(); mMagneticTargetAnimator diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java index 666323766c12..9cee7e7ccba4 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java @@ -72,6 +72,7 @@ public class ScreenRecordTile extends QSTileImpl<QSTile.BooleanState> state.value = isRecording || isStarting; state.state = (isRecording || isStarting) ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE; + state.label = mContext.getString(R.string.quick_settings_screen_record_label); if (isRecording) { state.icon = ResourceIcon.get(R.drawable.ic_qs_screenrecord); diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java index 1780fb1848e7..e1cc0b0c90c2 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java @@ -422,6 +422,8 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset mDismissButton.setVisibility(View.GONE); mScreenshotView.setVisibility(View.GONE); mScreenshotView.setLayerType(View.LAYER_TYPE_NONE, null); + mScreenshotView.setContentDescription( + mContext.getResources().getString(R.string.screenshot_preview_description)); } /** @@ -606,6 +608,7 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset Log.e(TAG, "Intent cancelled", e); } }); + mScreenshotView.setContentDescription(action.title); } mActionsView.addView(actionChip); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt index 0d7715958995..25f1a974bc36 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt @@ -250,7 +250,8 @@ class NotificationShadeDepthController @Inject constructor( private fun updateShadeBlur() { var newBlur = 0 val state = statusBarStateController.state - if (state == StatusBarState.SHADE || state == StatusBarState.SHADE_LOCKED) { + if ((state == StatusBarState.SHADE || state == StatusBarState.SHADE_LOCKED) && + !keyguardStateController.isKeyguardFadingAway) { newBlur = blurUtils.blurRadiusOfRatio(shadeExpansion) } shadeSpring.animateTo(newBlur) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationChannelHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationChannelHelper.java new file mode 100644 index 000000000000..ff945d15a4ed --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationChannelHelper.java @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.statusbar.notification; + +import android.app.INotificationManager; +import android.app.Notification; +import android.app.NotificationChannel; +import android.content.Context; +import android.os.Bundle; +import android.os.RemoteException; +import android.os.UserHandle; +import android.text.TextUtils; +import android.util.Slog; + +import com.android.systemui.R; +import com.android.systemui.statusbar.notification.collection.NotificationEntry; + +/** + * Helps SystemUI create notification channels. + */ +public class NotificationChannelHelper { + private static final String TAG = "NotificationChannelHelper"; + + /** Creates a conversation channel based on the shortcut info or notification title. */ + public static NotificationChannel createConversationChannelIfNeeded( + Context context, + INotificationManager notificationManager, + NotificationEntry entry, + NotificationChannel channel) { + if (!TextUtils.isEmpty(channel.getConversationId())) { + return channel; + } + final String conversationId = entry.getSbn().getShortcutId(context); + final String pkg = entry.getSbn().getPackageName(); + final int appUid = entry.getSbn().getUid(); + if (TextUtils.isEmpty(conversationId) || TextUtils.isEmpty(pkg)) { + return channel; + } + + String name; + if (entry.getRanking().getShortcutInfo() != null) { + name = entry.getRanking().getShortcutInfo().getShortLabel().toString(); + } else { + Bundle extras = entry.getSbn().getNotification().extras; + String nameString = extras.getString(Notification.EXTRA_CONVERSATION_TITLE); + if (TextUtils.isEmpty(nameString)) { + nameString = extras.getString(Notification.EXTRA_TITLE); + } + name = nameString; + } + + // If this channel is not already a customized conversation channel, create + // a custom channel + try { + // TODO: When shortcuts are enforced remove this and use the shortcut label for naming + channel.setName(context.getString( + R.string.notification_summary_message_format, + name, channel.getName())); + notificationManager.createConversationNotificationChannelForPackage( + pkg, appUid, entry.getSbn().getKey(), channel, + conversationId); + channel = notificationManager.getConversationNotificationChannel( + context.getOpPackageName(), UserHandle.getUserId(appUid), pkg, + channel.getId(), false, conversationId); + } catch (RemoteException e) { + Slog.e(TAG, "Could not create conversation channel", e); + } + return channel; + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java index 998230f205ab..85090dcbf748 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java @@ -70,6 +70,7 @@ import com.android.internal.widget.CachingIconView; import com.android.systemui.Dependency; import com.android.systemui.Interpolators; import com.android.systemui.R; +import com.android.systemui.bubbles.BubbleController; import com.android.systemui.plugins.FalsingManager; import com.android.systemui.plugins.PluginListener; import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin; @@ -579,6 +580,13 @@ public class ExpandableNotificationRow extends ActivatableNotificationView } } + /** Call when bubble state has changed and the button on the notification should be updated. */ + public void updateBubbleButton() { + for (NotificationContentView l : mLayouts) { + l.updateBubbleButton(mEntry); + } + } + @VisibleForTesting void updateShelfIconColor() { StatusBarIconView expandedIcon = mEntry.getIcons().getShelfIcon(); @@ -1086,6 +1094,18 @@ public class ExpandableNotificationRow extends ActivatableNotificationView updateClickAndFocus(); } + /** The click listener for the bubble button. */ + public View.OnClickListener getBubbleClickListener() { + return new View.OnClickListener() { + @Override + public void onClick(View v) { + Dependency.get(BubbleController.class) + .onUserChangedBubble(mEntry, !mEntry.isBubble() /* createBubble */); + mHeadsUpManager.removeNotification(mEntry.getKey(), true /* releaseImmediately */); + } + }; + } + private void updateClickAndFocus() { boolean normalChild = !isChildInGroup() || isGroupExpanded(); boolean clickable = mOnClickListener != null && normalChild; @@ -1267,7 +1287,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView return mNotificationColor; } - private void updateNotificationColor() { + public void updateNotificationColor() { Configuration currentConfig = getResources().getConfiguration(); boolean nightMode = (currentConfig.uiMode & Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES; @@ -1613,6 +1633,9 @@ public class ExpandableNotificationRow extends ActivatableNotificationView mFalsingManager = falsingManager; mStatusbarStateController = statusBarStateController; mPeopleNotificationIdentifier = peopleNotificationIdentifier; + for (NotificationContentView l : mLayouts) { + l.setPeopleNotificationIdentifier(mPeopleNotificationIdentifier); + } } private void initDimens() { 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 3c3f1b21fb3c..bd1745eaa028 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 @@ -16,13 +16,18 @@ package com.android.systemui.statusbar.notification.row; + +import static android.provider.Settings.Global.NOTIFICATION_BUBBLES; + import android.annotation.NonNull; import android.annotation.Nullable; import android.app.Notification; import android.app.PendingIntent; import android.content.Context; import android.graphics.Rect; +import android.graphics.drawable.Drawable; import android.os.Build; +import android.provider.Settings; import android.service.notification.StatusBarNotification; import android.util.ArrayMap; import android.util.ArraySet; @@ -47,6 +52,7 @@ import com.android.systemui.statusbar.SmartReplyController; import com.android.systemui.statusbar.TransformableView; import com.android.systemui.statusbar.notification.NotificationUtils; import com.android.systemui.statusbar.notification.collection.NotificationEntry; +import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier; import com.android.systemui.statusbar.notification.row.wrapper.NotificationCustomViewWrapper; import com.android.systemui.statusbar.notification.row.wrapper.NotificationViewWrapper; import com.android.systemui.statusbar.phone.NotificationGroupManager; @@ -118,6 +124,7 @@ public class NotificationContentView extends FrameLayout { private NotificationGroupManager mGroupManager; private RemoteInputController mRemoteInputController; private Runnable mExpandedVisibleListener; + private PeopleNotificationIdentifier mPeopleIdentifier; /** * List of listeners for when content views become inactive (i.e. not the showing view). */ @@ -454,6 +461,9 @@ public class NotificationContentView extends FrameLayout { mExpandedChild = child; mExpandedWrapper = NotificationViewWrapper.wrap(getContext(), child, mContainingNotification); + if (mContainingNotification != null) { + applyBubbleAction(mExpandedChild, mContainingNotification.getEntry()); + } } /** @@ -493,6 +503,9 @@ public class NotificationContentView extends FrameLayout { mHeadsUpChild = child; mHeadsUpWrapper = NotificationViewWrapper.wrap(getContext(), child, mContainingNotification); + if (mContainingNotification != null) { + applyBubbleAction(mHeadsUpChild, mContainingNotification.getEntry()); + } } @Override @@ -1138,6 +1151,8 @@ public class NotificationContentView extends FrameLayout { mForceSelectNextLayout = true; mPreviousExpandedRemoteInputIntent = null; mPreviousHeadsUpRemoteInputIntent = null; + applyBubbleAction(mExpandedChild, entry); + applyBubbleAction(mHeadsUpChild, entry); } private void updateAllSingleLineViews() { @@ -1308,6 +1323,58 @@ public class NotificationContentView extends FrameLayout { return null; } + /** + * Call to update state of the bubble button (i.e. does it show bubble or unbubble or no + * icon at all). + * + * @param entry the new entry to use. + */ + public void updateBubbleButton(NotificationEntry entry) { + applyBubbleAction(mExpandedChild, entry); + } + + private boolean isBubblesEnabled() { + return Settings.Global.getInt(mContext.getContentResolver(), + NOTIFICATION_BUBBLES, 0) == 1; + } + + private void applyBubbleAction(View layout, NotificationEntry entry) { + if (layout == null || mContainingNotification == null || mPeopleIdentifier == null) { + return; + } + ImageView bubbleButton = layout.findViewById(com.android.internal.R.id.bubble_button); + View actionContainer = layout.findViewById(com.android.internal.R.id.actions_container); + if (bubbleButton == null || actionContainer == null) { + return; + } + boolean isPerson = + mPeopleIdentifier.getPeopleNotificationType(entry.getSbn(), entry.getRanking()) + != PeopleNotificationIdentifier.TYPE_NON_PERSON; + boolean showButton = isBubblesEnabled() + && isPerson + && entry.getBubbleMetadata() != null; + if (showButton) { + Drawable d = mContext.getResources().getDrawable(entry.isBubble() + ? R.drawable.ic_stop_bubble + : R.drawable.ic_create_bubble); + mContainingNotification.updateNotificationColor(); + final int tint = mContainingNotification.getNotificationColor(); + d.setTint(tint); + + String contentDescription = mContext.getResources().getString(entry.isBubble() + ? R.string.notification_conversation_unbubble + : R.string.notification_conversation_bubble); + + bubbleButton.setContentDescription(contentDescription); + bubbleButton.setImageDrawable(d); + bubbleButton.setOnClickListener(mContainingNotification.getBubbleClickListener()); + bubbleButton.setVisibility(VISIBLE); + actionContainer.setVisibility(VISIBLE); + } else { + bubbleButton.setVisibility(GONE); + } + } + private void applySmartReplyView( SmartRepliesAndActions smartRepliesAndActions, NotificationEntry entry) { @@ -1512,6 +1579,10 @@ public class NotificationContentView extends FrameLayout { mContainingNotification = containingNotification; } + public void setPeopleNotificationIdentifier(PeopleNotificationIdentifier peopleIdentifier) { + mPeopleIdentifier = peopleIdentifier; + } + public void requestSelectLayout(boolean needsAnimation) { selectLayout(needsAnimation, false); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java index 6fc1264d69e2..ab2cffa57c3e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java @@ -17,6 +17,9 @@ package com.android.systemui.statusbar.notification.row; import static android.app.Notification.EXTRA_IS_GROUP_CONVERSATION; +import static android.app.NotificationManager.BUBBLE_PREFERENCE_ALL; +import static android.app.NotificationManager.BUBBLE_PREFERENCE_NONE; +import static android.app.NotificationManager.BUBBLE_PREFERENCE_SELECTED; import static android.app.NotificationManager.IMPORTANCE_DEFAULT; import static android.app.NotificationManager.IMPORTANCE_LOW; import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED; @@ -31,6 +34,7 @@ import android.app.INotificationManager; import android.app.Notification; import android.app.NotificationChannel; import android.app.NotificationChannelGroup; +import android.app.NotificationManager; import android.content.Context; import android.content.Intent; import android.content.pm.ApplicationInfo; @@ -38,11 +42,9 @@ import android.content.pm.PackageManager; import android.content.pm.ShortcutInfo; import android.content.pm.ShortcutManager; import android.graphics.drawable.Icon; -import android.os.Bundle; import android.os.Handler; import android.os.Parcelable; import android.os.RemoteException; -import android.os.UserHandle; import android.service.notification.StatusBarNotification; import android.text.TextUtils; import android.transition.ChangeBounds; @@ -62,6 +64,7 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.settingslib.notification.ConversationIconFactory; import com.android.systemui.Dependency; import com.android.systemui.R; +import com.android.systemui.statusbar.notification.NotificationChannelHelper; import com.android.systemui.statusbar.notification.VisualStabilityManager; import com.android.systemui.statusbar.notification.collection.NotificationEntry; @@ -91,6 +94,7 @@ public class NotificationConversationInfo extends LinearLayout implements private String mConversationId; private StatusBarNotification mSbn; private boolean mIsDeviceProvisioned; + private int mAppBubble; private TextView mPriorityDescriptionView; private TextView mDefaultDescriptionView; @@ -203,7 +207,15 @@ public class NotificationConversationInfo extends LinearLayout implements } mShortcutInfo = entry.getRanking().getShortcutInfo(); - createConversationChannelIfNeeded(); + mNotificationChannel = NotificationChannelHelper.createConversationChannelIfNeeded( + getContext(), mINotificationManager, entry, mNotificationChannel); + + try { + mAppBubble = mINotificationManager.getBubblePreferenceForPackage(mPackageName, mAppUid); + } catch (RemoteException e) { + Slog.e(TAG, "can't reach OS", e); + mAppBubble = BUBBLE_PREFERENCE_SELECTED; + } bindHeader(); bindActions(); @@ -212,27 +224,6 @@ public class NotificationConversationInfo extends LinearLayout implements done.setOnClickListener(mOnDone); } - void createConversationChannelIfNeeded() { - // If this channel is not already a customized conversation channel, create - // a custom channel - if (TextUtils.isEmpty(mNotificationChannel.getConversationId())) { - try { - // TODO: remove - mNotificationChannel.setName(mContext.getString( - R.string.notification_summary_message_format, - getName(), mNotificationChannel.getName())); - mINotificationManager.createConversationNotificationChannelForPackage( - mPackageName, mAppUid, mSbn.getKey(), mNotificationChannel, - mConversationId); - mNotificationChannel = mINotificationManager.getConversationNotificationChannel( - mContext.getOpPackageName(), UserHandle.getUserId(mAppUid), mPackageName, - mNotificationChannel.getId(), false, mConversationId); - } catch (RemoteException e) { - Slog.e(TAG, "Could not create conversation channel", e); - } - } - } - private void bindActions() { // TODO: b/152050825 @@ -247,6 +238,11 @@ public class NotificationConversationInfo extends LinearLayout implements snooze.setOnClickListener(mOnSnoozeClick); */ + if (mAppBubble == BUBBLE_PREFERENCE_ALL) { + ((TextView) findViewById(R.id.default_summary)).setText(getResources().getString( + R.string.notification_channel_summary_default_with_bubbles, mAppName)); + } + findViewById(R.id.priority).setOnClickListener(mOnFavoriteClick); findViewById(R.id.default_behavior).setOnClickListener(mOnDefaultClick); findViewById(R.id.silence).setOnClickListener(mOnMuteClick); @@ -284,7 +280,6 @@ public class NotificationConversationInfo extends LinearLayout implements // bindName(); bindPackage(); bindIcon(mNotificationChannel.isImportantConversation()); - } private void bindIcon(boolean important) { @@ -316,24 +311,6 @@ public class NotificationConversationInfo extends LinearLayout implements } } - private void bindName() { - TextView name = findViewById(R.id.name); - name.setText(getName()); - } - - private String getName() { - if (mShortcutInfo != null) { - return mShortcutInfo.getShortLabel().toString(); - } else { - Bundle extras = mSbn.getNotification().extras; - String nameString = extras.getString(Notification.EXTRA_CONVERSATION_TITLE); - if (TextUtils.isEmpty(nameString)) { - nameString = extras.getString(Notification.EXTRA_TITLE); - } - return nameString; - } - } - private void bindPackage() { ApplicationInfo info; try { @@ -598,6 +575,10 @@ public class NotificationConversationInfo extends LinearLayout implements !mChannelToUpdate.isImportantConversation()); if (mChannelToUpdate.isImportantConversation()) { mChannelToUpdate.setAllowBubbles(true); + if (mAppBubble == BUBBLE_PREFERENCE_NONE) { + mINotificationManager.setBubblesAllowed(mAppPkg, mAppUid, + BUBBLE_PREFERENCE_SELECTED); + } } mChannelToUpdate.setImportance(Math.max( mChannelToUpdate.getOriginalImportance(), IMPORTANCE_DEFAULT)); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/EdgeBackGestureHandler.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/EdgeBackGestureHandler.java index f103bd01fc3f..7d422e3c15a2 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/EdgeBackGestureHandler.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/EdgeBackGestureHandler.java @@ -312,7 +312,7 @@ public class EdgeBackGestureHandler implements DisplayListener, WindowManagerGlobal.getWindowManagerService() .unregisterSystemGestureExclusionListener( mGestureExclusionListener, mDisplayId); - } catch (RemoteException e) { + } catch (RemoteException | IllegalArgumentException e) { Log.e(TAG, "Failed to unregister window manager callbacks", e); } @@ -326,7 +326,7 @@ public class EdgeBackGestureHandler implements DisplayListener, WindowManagerGlobal.getWindowManagerService() .registerSystemGestureExclusionListener( mGestureExclusionListener, mDisplayId); - } catch (RemoteException e) { + } catch (RemoteException | IllegalArgumentException e) { Log.e(TAG, "Failed to register window manager callbacks", e); } diff --git a/packages/SystemUI/src/com/android/systemui/util/magnetictarget/MagnetizedObject.kt b/packages/SystemUI/src/com/android/systemui/util/magnetictarget/MagnetizedObject.kt index f27bdbfbeda0..e905e6772074 100644 --- a/packages/SystemUI/src/com/android/systemui/util/magnetictarget/MagnetizedObject.kt +++ b/packages/SystemUI/src/com/android/systemui/util/magnetictarget/MagnetizedObject.kt @@ -27,6 +27,7 @@ import android.provider.Settings import android.view.MotionEvent import android.view.VelocityTracker import android.view.View +import android.view.ViewConfiguration import androidx.dynamicanimation.animation.DynamicAnimation import androidx.dynamicanimation.animation.FloatPropertyCompat import androidx.dynamicanimation.animation.SpringForce @@ -146,6 +147,10 @@ abstract class MagnetizedObject<T : Any>( private val velocityTracker: VelocityTracker = VelocityTracker.obtain() private val vibrator: Vibrator = context.getSystemService(Context.VIBRATOR_SERVICE) as Vibrator + private var touchDown = PointF() + private var touchSlop = 0 + private var movedBeyondSlop = false + /** Whether touch events are presently occurring within the magnetic field area of a target. */ val objectStuckToTarget: Boolean get() = targetObjectIsStuckTo != null @@ -324,15 +329,32 @@ abstract class MagnetizedObject<T : Any>( // When a gesture begins, recalculate target views' positions on the screen in case they // have changed. Also, clear state. if (ev.action == MotionEvent.ACTION_DOWN) { - updateTargetViewLocations() + updateTargetViews() - // Clear the velocity tracker and assume we're not stuck to a target yet. + // Clear the velocity tracker and stuck target. velocityTracker.clear() targetObjectIsStuckTo = null + + // Set the touch down coordinates and reset movedBeyondSlop. + touchDown.set(ev.rawX, ev.rawY) + movedBeyondSlop = false } + // Always pass events to the VelocityTracker. addMovement(ev) + // If we haven't yet moved beyond the slop distance, check if we have. + if (!movedBeyondSlop) { + val dragDistance = hypot(ev.rawX - touchDown.x, ev.rawY - touchDown.y) + if (dragDistance > touchSlop) { + // If we're beyond the slop distance, save that and continue. + movedBeyondSlop = true + } else { + // Otherwise, don't do anything yet. + return false + } + } + val targetObjectIsInMagneticFieldOf = associatedTargets.firstOrNull { target -> val distanceFromTargetCenter = hypot( ev.rawX - target.centerOnScreen.x, @@ -559,8 +581,14 @@ abstract class MagnetizedObject<T : Any>( } /** Updates the locations on screen of all of the [associatedTargets]. */ - internal fun updateTargetViewLocations() { + internal fun updateTargetViews() { associatedTargets.forEach { it.updateLocationOnScreen() } + + // Update the touch slop, since the configuration may have changed. + if (associatedTargets.size > 0) { + touchSlop = + ViewConfiguration.get(associatedTargets[0].targetView.context).scaledTouchSlop + } } /** diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java index e472de349466..2f5ef00056fb 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java @@ -42,6 +42,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.app.IActivityManager; +import android.app.INotificationManager; import android.app.Notification; import android.app.PendingIntent; import android.content.res.Resources; @@ -273,7 +274,8 @@ public class BubbleControllerTest extends SysuiTestCase { mFeatureFlagsOldPipeline, mDumpManager, mFloatingContentCoordinator, - mSysUiState); + mSysUiState, + mock(INotificationManager.class)); mBubbleController.setBubbleStateChangeListener(mBubbleStateChangeListener); mBubbleController.setExpandListener(mBubbleExpandListener); diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/NewNotifPipelineBubbleControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/NewNotifPipelineBubbleControllerTest.java index 5f4f2ef04c1d..9da160c3820c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/NewNotifPipelineBubbleControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/NewNotifPipelineBubbleControllerTest.java @@ -38,6 +38,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.app.IActivityManager; +import android.app.INotificationManager; import android.app.Notification; import android.app.PendingIntent; import android.content.res.Resources; @@ -250,7 +251,8 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase { mFeatureFlagsNewPipeline, mDumpManager, mFloatingContentCoordinator, - mSysUiState); + mSysUiState, + mock(INotificationManager.class)); mBubbleController.addNotifCallback(mNotifCallback); mBubbleController.setBubbleStateChangeListener(mBubbleStateChangeListener); mBubbleController.setExpandListener(mBubbleExpandListener); diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/TestableBubbleController.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/TestableBubbleController.java index f4861028e81a..7815ae78823a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/TestableBubbleController.java +++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/TestableBubbleController.java @@ -16,6 +16,7 @@ package com.android.systemui.bubbles; +import android.app.INotificationManager; import android.content.Context; import com.android.systemui.dump.DumpManager; @@ -54,12 +55,14 @@ public class TestableBubbleController extends BubbleController { FeatureFlags featureFlags, DumpManager dumpManager, FloatingContentCoordinator floatingContentCoordinator, - SysUiState sysUiState) { + SysUiState sysUiState, + INotificationManager notificationManager) { super(context, notificationShadeWindowController, statusBarStateController, shadeController, data, Runnable::run, configurationController, interruptionStateProvider, zenModeController, lockscreenUserManager, groupManager, entryManager, - notifPipeline, featureFlags, dumpManager, floatingContentCoordinator, sysUiState); + notifPipeline, featureFlags, dumpManager, floatingContentCoordinator, sysUiState, + notificationManager); setInflateSynchronously(true); } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogTest.java index 3af164db4b80..b44b23a9f51e 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogTest.java @@ -16,6 +16,11 @@ package com.android.systemui.globalactions; +import static junit.framework.Assert.assertEquals; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -200,4 +205,63 @@ public class GlobalActionsDialogTest extends SysuiTestCase { verify(mUiEventLogger, times(1)) .log(event); } + + @Test + public void testCreateActionItems_maxThree() { + mGlobalActionsDialog = spy(mGlobalActionsDialog); + // allow 3 items to be shown + doReturn(3).when(mGlobalActionsDialog).getMaxShownPowerItems(); + // ensure items are not blocked by keyguard or device provisioning + doReturn(true).when(mGlobalActionsDialog).shouldShowAction(any()); + String[] actions = { + GlobalActionsDialog.GLOBAL_ACTION_KEY_EMERGENCY, + GlobalActionsDialog.GLOBAL_ACTION_KEY_POWER, + GlobalActionsDialog.GLOBAL_ACTION_KEY_RESTART, + GlobalActionsDialog.GLOBAL_ACTION_KEY_SCREENSHOT, + }; + doReturn(actions).when(mGlobalActionsDialog).getDefaultActions(); + mGlobalActionsDialog.createActionItems(); + + assertEquals(3, mGlobalActionsDialog.mItems.size()); + assertEquals(1, mGlobalActionsDialog.mOverflowItems.size()); + } + + @Test + public void testCreateActionItems_maxAny() { + mGlobalActionsDialog = spy(mGlobalActionsDialog); + // allow any number of power menu items to be shown + doReturn(Integer.MAX_VALUE).when(mGlobalActionsDialog).getMaxShownPowerItems(); + // ensure items are not blocked by keyguard or device provisioning + doReturn(true).when(mGlobalActionsDialog).shouldShowAction(any()); + String[] actions = { + GlobalActionsDialog.GLOBAL_ACTION_KEY_EMERGENCY, + GlobalActionsDialog.GLOBAL_ACTION_KEY_POWER, + GlobalActionsDialog.GLOBAL_ACTION_KEY_RESTART, + GlobalActionsDialog.GLOBAL_ACTION_KEY_SCREENSHOT, + }; + doReturn(actions).when(mGlobalActionsDialog).getDefaultActions(); + mGlobalActionsDialog.createActionItems(); + + assertEquals(4, mGlobalActionsDialog.mItems.size()); + assertEquals(0, mGlobalActionsDialog.mOverflowItems.size()); + } + + @Test + public void testCreateActionItems_maxThree_itemNotShown() { + mGlobalActionsDialog = spy(mGlobalActionsDialog); + // allow only 3 items to be shown + doReturn(3).when(mGlobalActionsDialog).getMaxShownPowerItems(); + String[] actions = { + GlobalActionsDialog.GLOBAL_ACTION_KEY_EMERGENCY, + // screenshot blocked because device not provisioned + GlobalActionsDialog.GLOBAL_ACTION_KEY_SCREENSHOT, + GlobalActionsDialog.GLOBAL_ACTION_KEY_POWER, + GlobalActionsDialog.GLOBAL_ACTION_KEY_RESTART, + }; + doReturn(actions).when(mGlobalActionsDialog).getDefaultActions(); + mGlobalActionsDialog.createActionItems(); + + assertEquals(3, mGlobalActionsDialog.mItems.size()); + assertEquals(0, mGlobalActionsDialog.mOverflowItems.size()); + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java index b6bd5e213dd4..6bcaee100496 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java @@ -17,6 +17,8 @@ package com.android.systemui.statusbar.notification.row; import static android.app.Notification.FLAG_BUBBLE; +import static android.app.NotificationManager.BUBBLE_PREFERENCE_ALL; +import static android.app.NotificationManager.BUBBLE_PREFERENCE_SELECTED; import static android.app.NotificationManager.IMPORTANCE_DEFAULT; import static android.app.NotificationManager.IMPORTANCE_HIGH; import static android.app.NotificationManager.IMPORTANCE_LOW; @@ -458,7 +460,9 @@ public class NotificationConversationInfoTest extends SysuiTestCase { } @Test - public void testBindNotification_defaultSelected_notFave_notSilent() { + public void testBindNotification_defaultSelected_notFave_notSilent() throws Exception { + when(mMockINotificationManager.getBubblePreferenceForPackage(anyString(), anyInt())) + .thenReturn(BUBBLE_PREFERENCE_SELECTED); mConversationChannel.setImportance(IMPORTANCE_HIGH); mConversationChannel.setImportantConversation(false); mConversationChannel.setAllowBubbles(true); @@ -476,6 +480,35 @@ public class NotificationConversationInfoTest extends SysuiTestCase { true); View view = mNotificationInfo.findViewById(R.id.default_behavior); assertThat(view.isSelected()).isTrue(); + assertThat(((TextView) view.findViewById(R.id.default_summary)).getText()).isEqualTo( + mContext.getString(R.string.notification_channel_summary_default)); + } + + @Test + public void testBindNotification_default_allCanBubble() throws Exception { + when(mMockINotificationManager.getBubblePreferenceForPackage(anyString(), anyInt())) + .thenReturn(BUBBLE_PREFERENCE_ALL); + when(mMockPackageManager.getApplicationLabel(any())).thenReturn("App Name"); + mConversationChannel.setImportance(IMPORTANCE_HIGH); + mConversationChannel.setImportantConversation(false); + mConversationChannel.setAllowBubbles(true); + mNotificationInfo.bindNotification( + mShortcutManager, + mMockPackageManager, + mMockINotificationManager, + mVisualStabilityManager, + TEST_PACKAGE_NAME, + mNotificationChannel, + mEntry, + null, + null, + mIconFactory, + true); + View view = mNotificationInfo.findViewById(R.id.default_behavior); + assertThat(view.isSelected()).isTrue(); + assertThat(((TextView) view.findViewById(R.id.default_summary)).getText()).isEqualTo( + mContext.getString(R.string.notification_channel_summary_default_with_bubbles, + "App Name")); } @Test diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/animation/PhysicsAnimatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/util/animation/PhysicsAnimatorTest.kt index 950f70fcda46..eb435f9314e7 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/util/animation/PhysicsAnimatorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/util/animation/PhysicsAnimatorTest.kt @@ -134,6 +134,7 @@ class PhysicsAnimatorTest : SysuiTestCase() { @Test @Throws(InterruptedException::class) + @Ignore("Increasingly flaky") fun testEndListenersAndActions() { PhysicsAnimatorTestUtils.setAllAnimationsBlock(false) animator diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/magnetictarget/MagnetizedObjectTest.kt b/packages/SystemUI/tests/src/com/android/systemui/util/magnetictarget/MagnetizedObjectTest.kt index f6b7b74d4bfc..251ca9c8dcb2 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/util/magnetictarget/MagnetizedObjectTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/util/magnetictarget/MagnetizedObjectTest.kt @@ -186,8 +186,8 @@ class MagnetizedObjectTest : SysuiTestCase() { @Test fun testMotionEventConsumption_downInMagneticField() { - // We should consume DOWN events if they occur in the field. - assertTrue(magnetizedObject.maybeConsumeMotionEvent(getMotionEvent( + // We should not consume DOWN events even if they occur in the field. + assertFalse(magnetizedObject.maybeConsumeMotionEvent(getMotionEvent( x = targetCenterX, y = targetCenterY, action = MotionEvent.ACTION_DOWN))) } @@ -342,10 +342,14 @@ class MagnetizedObjectTest : SysuiTestCase() { // Trigger the magnet animation, and block the test until it ends. PhysicsAnimatorTestUtils.setAllAnimationsBlock(true) magnetizedObject.maybeConsumeMotionEvent(getMotionEvent( - x = targetCenterX, - y = targetCenterY, + x = targetCenterX - 250, + y = targetCenterY - 250, action = MotionEvent.ACTION_DOWN)) + magnetizedObject.maybeConsumeMotionEvent(getMotionEvent( + x = targetCenterX, + y = targetCenterY)) + // The object's (top-left) position should now position it centered over the target. assertEquals(targetCenterX - objectSize / 2, objectX) assertEquals(targetCenterY - objectSize / 2, objectY) diff --git a/packages/Tethering/AndroidManifest.xml b/packages/Tethering/AndroidManifest.xml index 9328611f5d3f..1dc8227e81f4 100644 --- a/packages/Tethering/AndroidManifest.xml +++ b/packages/Tethering/AndroidManifest.xml @@ -43,8 +43,9 @@ android:process="com.android.networkstack.process" android:extractNativeLibs="false" android:persistent="true"> - <service android:name="com.android.server.connectivity.tethering.TetheringService" - android:permission="android.permission.MAINLINE_NETWORK_STACK"> + <service android:name="com.android.networkstack.tethering.TetheringService" + android:permission="android.permission.MAINLINE_NETWORK_STACK" + android:exported="true"> <intent-filter> <action android:name="android.net.ITetheringConnector"/> </intent-filter> diff --git a/packages/Tethering/AndroidManifest_InProcess.xml b/packages/Tethering/AndroidManifest_InProcess.xml index 02ea551254b9..b1f124097c79 100644 --- a/packages/Tethering/AndroidManifest_InProcess.xml +++ b/packages/Tethering/AndroidManifest_InProcess.xml @@ -22,9 +22,10 @@ android:process="system"> <uses-sdk android:minSdkVersion="29" android:targetSdkVersion="29" /> <application> - <service android:name="com.android.server.connectivity.tethering.TetheringService" + <service android:name="com.android.networkstack.tethering.TetheringService" android:process="system" - android:permission="android.permission.MAINLINE_NETWORK_STACK"> + android:permission="android.permission.MAINLINE_NETWORK_STACK" + android:exported="true"> <intent-filter> <action android:name="android.net.ITetheringConnector.InProcess"/> </intent-filter> diff --git a/packages/Tethering/proguard.flags b/packages/Tethering/proguard.flags index 1f83a663827c..051fbd19fc6c 100644 --- a/packages/Tethering/proguard.flags +++ b/packages/Tethering/proguard.flags @@ -1,5 +1,5 @@ # Keep class's integer static field for MessageUtils to parsing their name. --keep class com.android.server.connectivity.tethering.Tethering$TetherMasterSM { +-keep class com.android.networkstack.tethering.Tethering$TetherMasterSM { static final int CMD_*; static final int EVENT_*; } diff --git a/packages/Tethering/res/values-mcc204-mnc04/strings.xml b/packages/Tethering/res/values-mcc204-mnc04/strings.xml index a996b4247a0e..9dadd49cf8a4 100644 --- a/packages/Tethering/res/values-mcc204-mnc04/strings.xml +++ b/packages/Tethering/res/values-mcc204-mnc04/strings.xml @@ -15,16 +15,16 @@ --> <resources> <!-- String for no upstream notification title [CHAR LIMIT=200] --> - <string name="no_upstream_notification_title">Hotspot has no internet</string> + <string name="no_upstream_notification_title">Tethering has no internet</string> <!-- String for no upstream notification title [CHAR LIMIT=200] --> - <string name="no_upstream_notification_message">Devices can\u2019t connect to internet</string> - <!-- String for cellular roaming notification disable button [CHAR LIMIT=200] --> - <string name="no_upstream_notification_disable_button">Turn off hotspot</string> + <string name="no_upstream_notification_message">Devices can\u2019t connect</string> + <!-- String for no upstream notification disable button [CHAR LIMIT=200] --> + <string name="no_upstream_notification_disable_button">Turn off tethering</string> - <!-- String for cellular roaming notification title [CHAR LIMIT=200] --> - <string name="upstream_roaming_notification_title">Hotspot is on</string> - <!-- String for cellular roaming notification message [CHAR LIMIT=500] --> + <!-- String for cellular roaming notification title [CHAR LIMIT=200] --> + <string name="upstream_roaming_notification_title">Hotspot or tethering is on</string> + <!-- String for cellular roaming notification message [CHAR LIMIT=500] --> <string name="upstream_roaming_notification_message">Additional charges may apply while roaming</string> - <!-- String for cellular roaming notification continue button [CHAR LIMIT=200] --> + <!-- String for cellular roaming notification continue button [CHAR LIMIT=200] --> <string name="upstream_roaming_notification_continue_button">Continue</string> </resources> diff --git a/packages/Tethering/res/values-mcc310-mnc004/strings.xml b/packages/Tethering/res/values-mcc310-mnc004/strings.xml index a996b4247a0e..9dadd49cf8a4 100644 --- a/packages/Tethering/res/values-mcc310-mnc004/strings.xml +++ b/packages/Tethering/res/values-mcc310-mnc004/strings.xml @@ -15,16 +15,16 @@ --> <resources> <!-- String for no upstream notification title [CHAR LIMIT=200] --> - <string name="no_upstream_notification_title">Hotspot has no internet</string> + <string name="no_upstream_notification_title">Tethering has no internet</string> <!-- String for no upstream notification title [CHAR LIMIT=200] --> - <string name="no_upstream_notification_message">Devices can\u2019t connect to internet</string> - <!-- String for cellular roaming notification disable button [CHAR LIMIT=200] --> - <string name="no_upstream_notification_disable_button">Turn off hotspot</string> + <string name="no_upstream_notification_message">Devices can\u2019t connect</string> + <!-- String for no upstream notification disable button [CHAR LIMIT=200] --> + <string name="no_upstream_notification_disable_button">Turn off tethering</string> - <!-- String for cellular roaming notification title [CHAR LIMIT=200] --> - <string name="upstream_roaming_notification_title">Hotspot is on</string> - <!-- String for cellular roaming notification message [CHAR LIMIT=500] --> + <!-- String for cellular roaming notification title [CHAR LIMIT=200] --> + <string name="upstream_roaming_notification_title">Hotspot or tethering is on</string> + <!-- String for cellular roaming notification message [CHAR LIMIT=500] --> <string name="upstream_roaming_notification_message">Additional charges may apply while roaming</string> - <!-- String for cellular roaming notification continue button [CHAR LIMIT=200] --> + <!-- String for cellular roaming notification continue button [CHAR LIMIT=200] --> <string name="upstream_roaming_notification_continue_button">Continue</string> </resources> diff --git a/packages/Tethering/res/values-mcc311-mnc480/strings.xml b/packages/Tethering/res/values-mcc311-mnc480/strings.xml index a996b4247a0e..9dadd49cf8a4 100644 --- a/packages/Tethering/res/values-mcc311-mnc480/strings.xml +++ b/packages/Tethering/res/values-mcc311-mnc480/strings.xml @@ -15,16 +15,16 @@ --> <resources> <!-- String for no upstream notification title [CHAR LIMIT=200] --> - <string name="no_upstream_notification_title">Hotspot has no internet</string> + <string name="no_upstream_notification_title">Tethering has no internet</string> <!-- String for no upstream notification title [CHAR LIMIT=200] --> - <string name="no_upstream_notification_message">Devices can\u2019t connect to internet</string> - <!-- String for cellular roaming notification disable button [CHAR LIMIT=200] --> - <string name="no_upstream_notification_disable_button">Turn off hotspot</string> + <string name="no_upstream_notification_message">Devices can\u2019t connect</string> + <!-- String for no upstream notification disable button [CHAR LIMIT=200] --> + <string name="no_upstream_notification_disable_button">Turn off tethering</string> - <!-- String for cellular roaming notification title [CHAR LIMIT=200] --> - <string name="upstream_roaming_notification_title">Hotspot is on</string> - <!-- String for cellular roaming notification message [CHAR LIMIT=500] --> + <!-- String for cellular roaming notification title [CHAR LIMIT=200] --> + <string name="upstream_roaming_notification_title">Hotspot or tethering is on</string> + <!-- String for cellular roaming notification message [CHAR LIMIT=500] --> <string name="upstream_roaming_notification_message">Additional charges may apply while roaming</string> - <!-- String for cellular roaming notification continue button [CHAR LIMIT=200] --> + <!-- String for cellular roaming notification continue button [CHAR LIMIT=200] --> <string name="upstream_roaming_notification_continue_button">Continue</string> </resources> diff --git a/packages/Tethering/res/values/config.xml b/packages/Tethering/res/values/config.xml index 04d6215dce96..430fdc42284d 100644 --- a/packages/Tethering/res/values/config.xml +++ b/packages/Tethering/res/values/config.xml @@ -89,7 +89,7 @@ TYPE_MOBILE_HIPRI is appended. For other changes applied to this list, now and in the future, see - com.android.server.connectivity.tethering.TetheringConfiguration. + com.android.networkstack.tethering.TetheringConfiguration. Note also: the order of this is important. The first upstream type for which a satisfying network exists is used. diff --git a/packages/Tethering/res/values/strings.xml b/packages/Tethering/res/values/strings.xml index 52a16545c22f..4fa60d412566 100644 --- a/packages/Tethering/res/values/strings.xml +++ b/packages/Tethering/res/values/strings.xml @@ -40,13 +40,13 @@ <string name="no_upstream_notification_title"></string> <!-- String for no upstream notification message [CHAR LIMIT=200] --> <string name="no_upstream_notification_message"></string> - <!-- String for cellular roaming notification disable button [CHAR LIMIT=200] --> + <!-- String for no upstream notification disable button [CHAR LIMIT=200] --> <string name="no_upstream_notification_disable_button"></string> - <!-- String for cellular roaming notification title [CHAR LIMIT=200] --> + <!-- String for cellular roaming notification title [CHAR LIMIT=200] --> <string name="upstream_roaming_notification_title"></string> - <!-- String for cellular roaming notification message [CHAR LIMIT=500] --> + <!-- String for cellular roaming notification message [CHAR LIMIT=500] --> <string name="upstream_roaming_notification_message"></string> - <!-- String for cellular roaming notification continue button [CHAR LIMIT=200] --> + <!-- String for cellular roaming notification continue button [CHAR LIMIT=200] --> <string name="upstream_roaming_notification_continue_button"></string> </resources> diff --git a/packages/Tethering/src/android/net/ip/IpServer.java b/packages/Tethering/src/android/net/ip/IpServer.java index 1dac5b784649..83727bcdc67e 100644 --- a/packages/Tethering/src/android/net/ip/IpServer.java +++ b/packages/Tethering/src/android/net/ip/IpServer.java @@ -122,6 +122,8 @@ public class IpServer extends StateMachine { // TODO: have this configurable private static final int DHCP_LEASE_TIME_SECS = 3600; + private static final MacAddress NULL_MAC_ADDRESS = MacAddress.fromString("00:00:00:00:00:00"); + private static final String TAG = "IpServer"; private static final boolean DBG = false; private static final boolean VDBG = false; @@ -902,9 +904,12 @@ public class IpServer extends StateMachine { return; } + // When deleting rules, we still need to pass a non-null MAC, even though it's ignored. + // Do this here instead of in the Ipv6ForwardingRule constructor to ensure that we never + // add rules with a null MAC, only delete them. + MacAddress dstMac = e.isValid() ? e.macAddr : NULL_MAC_ADDRESS; Ipv6ForwardingRule rule = new Ipv6ForwardingRule(upstreamIfindex, - mInterfaceParams.index, (Inet6Address) e.ip, mInterfaceParams.macAddr, - e.macAddr); + mInterfaceParams.index, (Inet6Address) e.ip, mInterfaceParams.macAddr, dstMac); if (e.isValid()) { addIpv6ForwardingRule(rule); } else { diff --git a/packages/Tethering/src/com/android/server/connectivity/tethering/ConnectedClientsTracker.java b/packages/Tethering/src/com/android/networkstack/tethering/ConnectedClientsTracker.java index cdd1a5d97823..8a96988ae1d1 100644 --- a/packages/Tethering/src/com/android/server/connectivity/tethering/ConnectedClientsTracker.java +++ b/packages/Tethering/src/com/android/networkstack/tethering/ConnectedClientsTracker.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.server.connectivity.tethering; +package com.android.networkstack.tethering; import static android.net.TetheringManager.TETHERING_WIFI; diff --git a/packages/Tethering/src/com/android/server/connectivity/tethering/EntitlementManager.java b/packages/Tethering/src/com/android/networkstack/tethering/EntitlementManager.java index 639cf65d7936..4c7b2d49ee9a 100644 --- a/packages/Tethering/src/com/android/server/connectivity/tethering/EntitlementManager.java +++ b/packages/Tethering/src/com/android/networkstack/tethering/EntitlementManager.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.server.connectivity.tethering; +package com.android.networkstack.tethering; import static android.net.TetheringConstants.EXTRA_ADD_TETHER_TYPE; import static android.net.TetheringConstants.EXTRA_PROVISION_CALLBACK; @@ -52,7 +52,6 @@ import android.util.SparseIntArray; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.StateMachine; -import com.android.networkstack.tethering.R; import java.io.PrintWriter; @@ -71,7 +70,7 @@ public class EntitlementManager { @VisibleForTesting protected static final String DISABLE_PROVISIONING_SYSPROP_KEY = "net.tethering.noprovisioning"; private static final String ACTION_PROVISIONING_ALARM = - "com.android.server.connectivity.tethering.PROVISIONING_RECHECK_ALARM"; + "com.android.networkstack.tethering.PROVISIONING_RECHECK_ALARM"; private static final String EXTRA_SUBID = "subId"; private final ComponentName mSilentProvisioningService; diff --git a/packages/Tethering/src/com/android/server/connectivity/tethering/IPv6TetheringCoordinator.java b/packages/Tethering/src/com/android/networkstack/tethering/IPv6TetheringCoordinator.java index 66b9ade81019..d450c46de718 100644 --- a/packages/Tethering/src/com/android/server/connectivity/tethering/IPv6TetheringCoordinator.java +++ b/packages/Tethering/src/com/android/networkstack/tethering/IPv6TetheringCoordinator.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.server.connectivity.tethering; +package com.android.networkstack.tethering; import android.net.IpPrefix; import android.net.LinkAddress; diff --git a/packages/Tethering/src/com/android/server/connectivity/tethering/OffloadController.java b/packages/Tethering/src/com/android/networkstack/tethering/OffloadController.java index 15cdb6ad7a8e..c007c174fe4f 100644 --- a/packages/Tethering/src/com/android/server/connectivity/tethering/OffloadController.java +++ b/packages/Tethering/src/com/android/networkstack/tethering/OffloadController.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.server.connectivity.tethering; +package com.android.networkstack.tethering; import static android.net.NetworkStats.DEFAULT_NETWORK_NO; import static android.net.NetworkStats.METERED_NO; @@ -50,7 +50,7 @@ import android.util.Log; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.IndentingPrintWriter; -import com.android.server.connectivity.tethering.OffloadHardwareInterface.ForwardedStats; +import com.android.networkstack.tethering.OffloadHardwareInterface.ForwardedStats; import java.net.Inet4Address; import java.net.Inet6Address; diff --git a/packages/Tethering/src/com/android/server/connectivity/tethering/OffloadHardwareInterface.java b/packages/Tethering/src/com/android/networkstack/tethering/OffloadHardwareInterface.java index b54571720857..85a23fb83fb2 100644 --- a/packages/Tethering/src/com/android/server/connectivity/tethering/OffloadHardwareInterface.java +++ b/packages/Tethering/src/com/android/networkstack/tethering/OffloadHardwareInterface.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.server.connectivity.tethering; +package com.android.networkstack.tethering; import static android.net.util.TetheringUtils.uint16; diff --git a/packages/Tethering/src/com/android/server/connectivity/tethering/Tethering.java b/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java index 4b2c9215f7b7..f3cead92be7e 100644 --- a/packages/Tethering/src/com/android/server/connectivity/tethering/Tethering.java +++ b/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.server.connectivity.tethering; +package com.android.networkstack.tethering; import static android.Manifest.permission.NETWORK_SETTINGS; import static android.Manifest.permission.NETWORK_STACK; @@ -60,7 +60,7 @@ import static android.net.wifi.WifiManager.WIFI_AP_STATE_DISABLED; import static android.telephony.CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED; import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID; -import static com.android.server.connectivity.tethering.TetheringNotificationUpdater.DOWNSTREAM_NONE; +import static com.android.networkstack.tethering.TetheringNotificationUpdater.DOWNSTREAM_NONE; import android.app.usage.NetworkStatsManager; import android.bluetooth.BluetoothAdapter; diff --git a/packages/Tethering/src/com/android/server/connectivity/tethering/TetheringConfiguration.java b/packages/Tethering/src/com/android/networkstack/tethering/TetheringConfiguration.java index 7e9e26f5af40..aeac437e24e3 100644 --- a/packages/Tethering/src/com/android/server/connectivity/tethering/TetheringConfiguration.java +++ b/packages/Tethering/src/com/android/networkstack/tethering/TetheringConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.server.connectivity.tethering; +package com.android.networkstack.tethering; import static android.content.Context.TELEPHONY_SERVICE; import static android.net.ConnectivityManager.TYPE_ETHERNET; @@ -33,7 +33,6 @@ import android.telephony.TelephonyManager; import android.text.TextUtils; import com.android.internal.annotations.VisibleForTesting; -import com.android.networkstack.tethering.R; import java.io.PrintWriter; import java.util.ArrayList; diff --git a/packages/Tethering/src/com/android/server/connectivity/tethering/TetheringDependencies.java b/packages/Tethering/src/com/android/networkstack/tethering/TetheringDependencies.java index 0330dad6a1ae..893c5823dce1 100644 --- a/packages/Tethering/src/com/android/server/connectivity/tethering/TetheringDependencies.java +++ b/packages/Tethering/src/com/android/networkstack/tethering/TetheringDependencies.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.server.connectivity.tethering; +package com.android.networkstack.tethering; import android.bluetooth.BluetoothAdapter; import android.content.Context; diff --git a/packages/Tethering/src/com/android/server/connectivity/tethering/TetheringInterfaceUtils.java b/packages/Tethering/src/com/android/networkstack/tethering/TetheringInterfaceUtils.java index 4dd68301f9fa..ff38f717a121 100644 --- a/packages/Tethering/src/com/android/server/connectivity/tethering/TetheringInterfaceUtils.java +++ b/packages/Tethering/src/com/android/networkstack/tethering/TetheringInterfaceUtils.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.server.connectivity.tethering; +package com.android.networkstack.tethering; import android.annotation.Nullable; import android.net.LinkProperties; diff --git a/packages/Tethering/src/com/android/server/connectivity/tethering/TetheringNotificationUpdater.java b/packages/Tethering/src/com/android/networkstack/tethering/TetheringNotificationUpdater.java index 992cdd8de6a7..42870560cb5e 100644 --- a/packages/Tethering/src/com/android/server/connectivity/tethering/TetheringNotificationUpdater.java +++ b/packages/Tethering/src/com/android/networkstack/tethering/TetheringNotificationUpdater.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.server.connectivity.tethering; +package com.android.networkstack.tethering; import static android.net.TetheringManager.TETHERING_BLUETOOTH; import static android.net.TetheringManager.TETHERING_USB; @@ -41,7 +41,6 @@ import androidx.annotation.IntRange; import androidx.annotation.NonNull; import com.android.internal.annotations.VisibleForTesting; -import com.android.networkstack.tethering.R; /** * A class to display tethering-related notifications. diff --git a/packages/Tethering/src/com/android/server/connectivity/tethering/TetheringService.java b/packages/Tethering/src/com/android/networkstack/tethering/TetheringService.java index c30be25dbd22..3ed211520db6 100644 --- a/packages/Tethering/src/com/android/server/connectivity/tethering/TetheringService.java +++ b/packages/Tethering/src/com/android/networkstack/tethering/TetheringService.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.server.connectivity.tethering; +package com.android.networkstack.tethering; import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.net.TetheringManager.TETHER_ERROR_NO_ACCESS_TETHERING_PERMISSION; diff --git a/packages/Tethering/src/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java b/packages/Tethering/src/com/android/networkstack/tethering/UpstreamNetworkMonitor.java index 45bb4ab6e5f7..25ddce4404e4 100644 --- a/packages/Tethering/src/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java +++ b/packages/Tethering/src/com/android/networkstack/tethering/UpstreamNetworkMonitor.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.server.connectivity.tethering; +package com.android.networkstack.tethering; import static android.net.ConnectivityManager.TYPE_BLUETOOTH; import static android.net.ConnectivityManager.TYPE_ETHERNET; diff --git a/packages/Tethering/src/com/android/server/connectivity/tethering/UpstreamNetworkState.java b/packages/Tethering/src/com/android/networkstack/tethering/UpstreamNetworkState.java index 68bb83759368..bab9f84cf762 100644 --- a/packages/Tethering/src/com/android/server/connectivity/tethering/UpstreamNetworkState.java +++ b/packages/Tethering/src/com/android/networkstack/tethering/UpstreamNetworkState.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.android.server.connectivity.tethering; +package com.android.networkstack.tethering; import android.net.LinkProperties; import android.net.Network; diff --git a/packages/Tethering/tests/integration/Android.bp b/packages/Tethering/tests/integration/Android.bp index 620261b375d2..6b751afdf58b 100644 --- a/packages/Tethering/tests/integration/Android.bp +++ b/packages/Tethering/tests/integration/Android.bp @@ -13,19 +13,12 @@ // See the License for the specific language governing permissions and // limitations under the License. // - -android_test { - name: "TetheringIntegrationTests", - certificate: "platform", - platform_apis: true, +java_defaults { + name: "TetheringIntegrationTestsDefaults", srcs: [ "src/**/*.java", "src/**/*.kt", ], - test_suites: [ - "device-tests", - "mts", - ], static_libs: [ "NetworkStackApiStableLib", "androidx.test.rules", @@ -44,4 +37,49 @@ android_test { "libdexmakerjvmtiagent", "libstaticjvmtiagent", ], + jarjar_rules: ":NetworkStackJarJarRules", +} + +android_library { + name: "TetheringIntegrationTestsLib", + platform_apis: true, + defaults: ["TetheringIntegrationTestsDefaults"], + visibility: ["//cts/tests/tests/tethering"] +} + +android_test { + name: "TetheringIntegrationTests", + platform_apis: true, + defaults: ["TetheringIntegrationTestsDefaults"], + test_suites: [ + "device-tests", + "mts", + ], + compile_multilib: "both", } + +// Special version of the tethering tests that includes all tests necessary for code coverage +// purposes. This is currently the union of TetheringTests, TetheringIntegrationTests and +// NetworkStackTests. +android_test { + name: "TetheringCoverageTests", + certificate: "platform", + platform_apis: true, + test_suites: ["device-tests", "mts"], + test_config: "AndroidTest_Coverage.xml", + defaults: ["libnetworkstackutilsjni_deps"], + static_libs: [ + "NetworkStackTestsLib", + "TetheringTestsLib", + "TetheringIntegrationTestsLib", + ], + jni_libs: [ + // For mockito extended + "libdexmakerjvmtiagent", + "libstaticjvmtiagent", + // For NetworkStackUtils included in NetworkStackBase + "libnetworkstackutilsjni", + ], + compile_multilib: "both", + manifest: "AndroidManifest_coverage.xml", +}
\ No newline at end of file diff --git a/packages/Tethering/tests/integration/AndroidManifest.xml b/packages/Tethering/tests/integration/AndroidManifest.xml index 233ba40b5d35..fddfaad29f0f 100644 --- a/packages/Tethering/tests/integration/AndroidManifest.xml +++ b/packages/Tethering/tests/integration/AndroidManifest.xml @@ -17,7 +17,6 @@ package="com.android.networkstack.tethering.tests.integration"> <uses-permission android:name="android.permission.INTERNET"/> - <uses-permission android:name="android.permission.TETHER_PRIVILEGED"/> <application android:debuggable="true"> <uses-library android:name="android.test.runner" /> diff --git a/packages/Tethering/tests/integration/AndroidManifest_coverage.xml b/packages/Tethering/tests/integration/AndroidManifest_coverage.xml new file mode 100644 index 000000000000..06de00d78558 --- /dev/null +++ b/packages/Tethering/tests/integration/AndroidManifest_coverage.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- 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. +--> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + package="com.android.networkstack.tethering.tests.coverage"> + + <application tools:replace="android:label" + android:debuggable="true" + android:label="Tethering coverage tests"> + <uses-library android:name="android.test.runner" /> + </application> + <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner" + android:targetPackage="com.android.networkstack.tethering.tests.coverage" + android:label="Tethering coverage tests"> + </instrumentation> +</manifest> diff --git a/packages/Tethering/tests/integration/AndroidTest_Coverage.xml b/packages/Tethering/tests/integration/AndroidTest_Coverage.xml new file mode 100644 index 000000000000..3def2099e45f --- /dev/null +++ b/packages/Tethering/tests/integration/AndroidTest_Coverage.xml @@ -0,0 +1,12 @@ +<configuration description="Runs coverage tests for Tethering"> + <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup"> + <option name="test-file-name" value="TetheringCoverageTests.apk" /> + </target_preparer> + + <option name="test-tag" value="TetheringCoverageTests" /> + <test class="com.android.tradefed.testtype.AndroidJUnitTest" > + <option name="package" value="com.android.networkstack.tethering.tests.coverage" /> + <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" /> + <option name="hidden-api-checks" value="false"/> + </test> +</configuration>
\ No newline at end of file diff --git a/packages/Tethering/tests/integration/src/android/net/EthernetTetheringTest.java b/packages/Tethering/tests/integration/src/android/net/EthernetTetheringTest.java index b02bb23f9807..4bac9da9c3d2 100644 --- a/packages/Tethering/tests/integration/src/android/net/EthernetTetheringTest.java +++ b/packages/Tethering/tests/integration/src/android/net/EthernetTetheringTest.java @@ -18,6 +18,7 @@ package android.net; import static android.Manifest.permission.MANAGE_TEST_NETWORKS; import static android.Manifest.permission.NETWORK_SETTINGS; +import static android.Manifest.permission.TETHER_PRIVILEGED; import static android.net.TetheringManager.TETHERING_ETHERNET; import static org.junit.Assert.assertEquals; @@ -109,7 +110,8 @@ public class EthernetTetheringTest { mTetheredInterfaceRequester = new TetheredInterfaceRequester(mHandler, mEm); // Needed to create a TestNetworkInterface, to call requestTetheredInterface, and to receive // tethered client callbacks. - mUiAutomation.adoptShellPermissionIdentity(MANAGE_TEST_NETWORKS, NETWORK_SETTINGS); + mUiAutomation.adoptShellPermissionIdentity( + MANAGE_TEST_NETWORKS, NETWORK_SETTINGS, TETHER_PRIVILEGED); } private void cleanUp() throws Exception { diff --git a/packages/Tethering/tests/unit/Android.bp b/packages/Tethering/tests/unit/Android.bp index 59681e9eb56a..4849fd5d01f5 100644 --- a/packages/Tethering/tests/unit/Android.bp +++ b/packages/Tethering/tests/unit/Android.bp @@ -14,39 +14,33 @@ // limitations under the License. // -android_test { - name: "TetheringTests", - certificate: "platform", +java_defaults { + name: "TetheringTestsDefaults", srcs: [ "src/**/*.java", "src/**/*.kt", ], - test_suites: [ - "device-tests", - "mts", - ], - compile_multilib: "both", static_libs: [ + "TetheringApiCurrentLib", "androidx.test.rules", "frameworks-base-testutils", - "net-tests-utils", "mockito-target-extended-minus-junit4", - "TetheringApiCurrentLib", + "net-tests-utils", "testables", ], // TODO(b/147200698) change sdk_version to module-current and // remove framework-minus-apex, ext, and framework-res sdk_version: "core_platform", libs: [ - "framework-minus-apex", - "ext", - "framework-res", - "framework-wifi-stubs-module_libs_api", - "framework-telephony-stubs", "android.test.runner", "android.test.base", "android.test.mock", + "ext", + "framework-minus-apex", + "framework-res", + "framework-telephony-stubs", "framework-tethering", + "framework-wifi-stubs-module_libs_api", ], jni_libs: [ // For mockito extended @@ -55,3 +49,25 @@ android_test { ], jarjar_rules: "jarjar-rules.txt", } + +// Library containing the unit tests. This is used by the coverage test target to pull in the +// unit test code. It is not currently used by the tests themselves because all the build +// configuration needed by the tests is in the TetheringTestsDefaults rule. +android_library { + name: "TetheringTestsLib", + defaults: ["TetheringTestsDefaults"], + visibility: [ + "//frameworks/base/packages/Tethering/tests/integration", + ] +} + +android_test { + name: "TetheringTests", + certificate: "platform", + test_suites: [ + "device-tests", + "mts", + ], + defaults: ["TetheringTestsDefaults"], + compile_multilib: "both", +} diff --git a/packages/Tethering/tests/unit/AndroidManifest.xml b/packages/Tethering/tests/unit/AndroidManifest.xml index 4ff1d3777f25..55640db69324 100644 --- a/packages/Tethering/tests/unit/AndroidManifest.xml +++ b/packages/Tethering/tests/unit/AndroidManifest.xml @@ -21,11 +21,11 @@ <application android:debuggable="true"> <uses-library android:name="android.test.runner" /> <service - android:name="com.android.server.connectivity.tethering.MockTetheringService" + android:name="com.android.networkstack.tethering.MockTetheringService" android:permission="android.permission.TETHER_PRIVILEGED" android:exported="true"> <intent-filter> - <action android:name="com.android.server.connectivity.tethering.TetheringService"/> + <action android:name="com.android.networkstack.tethering.TetheringService"/> </intent-filter> </service> </application> diff --git a/packages/Tethering/tests/unit/src/android/net/ip/IpServerTest.java b/packages/Tethering/tests/unit/src/android/net/ip/IpServerTest.java index fdfdae837d51..f9be7b9d3664 100644 --- a/packages/Tethering/tests/unit/src/android/net/ip/IpServerTest.java +++ b/packages/Tethering/tests/unit/src/android/net/ip/IpServerTest.java @@ -587,6 +587,7 @@ public class IpServerTest { final InetAddress neighB = InetAddresses.parseNumericAddress("2001:db8::2"); final InetAddress neighLL = InetAddresses.parseNumericAddress("fe80::1"); final InetAddress neighMC = InetAddresses.parseNumericAddress("ff02::1234"); + final MacAddress macNull = MacAddress.fromString("00:00:00:00:00:00"); final MacAddress macA = MacAddress.fromString("00:00:00:00:00:0a"); final MacAddress macB = MacAddress.fromString("11:22:33:00:00:0b"); @@ -612,13 +613,14 @@ public class IpServerTest { verifyNoMoreInteractions(mNetd); // A neighbor that is no longer valid causes the rule to be removed. - recvNewNeigh(myIfindex, neighA, NUD_FAILED, macA); - verify(mNetd).tetherOffloadRuleRemove(matches(UPSTREAM_IFINDEX, neighA, macA)); + // NUD_FAILED events do not have a MAC address. + recvNewNeigh(myIfindex, neighA, NUD_FAILED, null); + verify(mNetd).tetherOffloadRuleRemove(matches(UPSTREAM_IFINDEX, neighA, macNull)); reset(mNetd); // A neighbor that is deleted causes the rule to be removed. recvDelNeigh(myIfindex, neighB, NUD_STALE, macB); - verify(mNetd).tetherOffloadRuleRemove(matches(UPSTREAM_IFINDEX, neighB, macB)); + verify(mNetd).tetherOffloadRuleRemove(matches(UPSTREAM_IFINDEX, neighB, macNull)); reset(mNetd); // Upstream changes result in deleting and re-adding the rules. diff --git a/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/ConnectedClientsTrackerTest.kt b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/ConnectedClientsTrackerTest.kt index 1cdc3bbb9933..d915354b0c37 100644 --- a/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/ConnectedClientsTrackerTest.kt +++ b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/ConnectedClientsTrackerTest.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.server.connectivity.tethering +package com.android.networkstack.tethering import android.net.LinkAddress import android.net.MacAddress @@ -159,4 +159,4 @@ class ConnectedClientsTrackerTest { return time } } -}
\ No newline at end of file +} diff --git a/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/EntitlementManagerTest.java b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/EntitlementManagerTest.java index 6695eed0ff65..8bd0edc2490d 100644 --- a/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/EntitlementManagerTest.java +++ b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/EntitlementManagerTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.server.connectivity.tethering; +package com.android.networkstack.tethering; import static android.net.TetheringManager.TETHERING_BLUETOOTH; import static android.net.TetheringManager.TETHERING_ETHERNET; @@ -59,7 +59,6 @@ import androidx.test.runner.AndroidJUnit4; import com.android.internal.util.State; import com.android.internal.util.StateMachine; import com.android.internal.util.test.BroadcastInterceptingContext; -import com.android.networkstack.tethering.R; import org.junit.After; import org.junit.Before; diff --git a/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/IPv6TetheringCoordinatorTest.java b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/IPv6TetheringCoordinatorTest.java index 912124357ca8..820f25514532 100644 --- a/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/IPv6TetheringCoordinatorTest.java +++ b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/IPv6TetheringCoordinatorTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.server.connectivity.tethering; +package com.android.networkstack.tethering; import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; import static android.net.RouteInfo.RTN_UNICAST; diff --git a/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/MockTetheringService.java b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/MockTetheringService.java index 355ece9a44a1..1c81c1247ded 100644 --- a/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/MockTetheringService.java +++ b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/MockTetheringService.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.android.server.connectivity.tethering; +package com.android.networkstack.tethering; import static org.mockito.Mockito.mock; diff --git a/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/OffloadControllerTest.java b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/OffloadControllerTest.java index fe840864fb99..65797200fa92 100644 --- a/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/OffloadControllerTest.java +++ b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/OffloadControllerTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.server.connectivity.tethering; +package com.android.networkstack.tethering; import static android.net.NetworkStats.DEFAULT_NETWORK_NO; import static android.net.NetworkStats.METERED_NO; @@ -26,9 +26,9 @@ import static android.net.NetworkStats.UID_TETHERING; import static android.net.RouteInfo.RTN_UNICAST; import static android.provider.Settings.Global.TETHER_OFFLOAD_DISABLED; -import static com.android.server.connectivity.tethering.OffloadController.StatsType.STATS_PER_IFACE; -import static com.android.server.connectivity.tethering.OffloadController.StatsType.STATS_PER_UID; -import static com.android.server.connectivity.tethering.OffloadHardwareInterface.ForwardedStats; +import static com.android.networkstack.tethering.OffloadController.StatsType.STATS_PER_IFACE; +import static com.android.networkstack.tethering.OffloadController.StatsType.STATS_PER_UID; +import static com.android.networkstack.tethering.OffloadHardwareInterface.ForwardedStats; import static com.android.testutils.MiscAssertsKt.assertContainsAll; import static com.android.testutils.MiscAssertsKt.assertThrows; import static com.android.testutils.NetworkStatsUtilsKt.orderInsensitiveEquals; diff --git a/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/TetheringConfigurationTest.java b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringConfigurationTest.java index 3635964dd6a6..07ddea43f4e8 100644 --- a/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/TetheringConfigurationTest.java +++ b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringConfigurationTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.server.connectivity.tethering; +package com.android.networkstack.tethering; import static android.net.ConnectivityManager.TYPE_ETHERNET; import static android.net.ConnectivityManager.TYPE_MOBILE; @@ -44,7 +44,6 @@ import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; import com.android.internal.util.test.BroadcastInterceptingContext; -import com.android.networkstack.tethering.R; import org.junit.After; import org.junit.Before; diff --git a/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/TetheringNotificationUpdaterTest.kt b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringNotificationUpdaterTest.kt index b86949185c69..7bff74b25d94 100644 --- a/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/TetheringNotificationUpdaterTest.kt +++ b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringNotificationUpdaterTest.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.server.connectivity.tethering +package com.android.networkstack.tethering import android.app.Notification import android.app.NotificationManager @@ -29,8 +29,7 @@ import androidx.test.platform.app.InstrumentationRegistry import androidx.test.filters.SmallTest import androidx.test.runner.AndroidJUnit4 import com.android.internal.util.test.BroadcastInterceptingContext -import com.android.networkstack.tethering.R -import com.android.server.connectivity.tethering.TetheringNotificationUpdater.DOWNSTREAM_NONE +import com.android.networkstack.tethering.TetheringNotificationUpdater.DOWNSTREAM_NONE import org.junit.Assert.assertEquals import org.junit.Before import org.junit.Test @@ -259,4 +258,4 @@ class TetheringNotificationUpdaterTest { notificationUpdater.notifyTetheringDisabledByRestriction() verifyNotification(R.drawable.stat_sys_tether_general, disallowTitle, disallowMessage) } -}
\ No newline at end of file +} diff --git a/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/TetheringServiceTest.java b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringServiceTest.java index d9d3e73eb4e3..51bad9af23ef 100644 --- a/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/TetheringServiceTest.java +++ b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringServiceTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.server.connectivity.tethering; +package com.android.networkstack.tethering; import static android.net.TetheringManager.TETHERING_WIFI; import static android.net.TetheringManager.TETHER_ERROR_NO_ERROR; @@ -37,7 +37,7 @@ import androidx.test.filters.SmallTest; import androidx.test.rule.ServiceTestRule; import androidx.test.runner.AndroidJUnit4; -import com.android.server.connectivity.tethering.MockTetheringService.MockTetheringConnector; +import com.android.networkstack.tethering.MockTetheringService.MockTetheringConnector; import org.junit.After; import org.junit.Before; diff --git a/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/TetheringTest.java b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java index 2955903c84f5..d4be3a26d958 100644 --- a/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/TetheringTest.java +++ b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.server.connectivity.tethering; +package com.android.networkstack.tethering; import static android.hardware.usb.UsbManager.USB_CONFIGURED; import static android.hardware.usb.UsbManager.USB_CONNECTED; @@ -47,7 +47,7 @@ import static android.net.wifi.WifiManager.IFACE_IP_MODE_TETHERED; import static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLED; import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID; -import static com.android.server.connectivity.tethering.TetheringNotificationUpdater.DOWNSTREAM_NONE; +import static com.android.networkstack.tethering.TetheringNotificationUpdater.DOWNSTREAM_NONE; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; @@ -137,7 +137,6 @@ import com.android.internal.util.ArrayUtils; import com.android.internal.util.StateMachine; import com.android.internal.util.test.BroadcastInterceptingContext; import com.android.internal.util.test.FakeSettingsProvider; -import com.android.networkstack.tethering.R; import com.android.testutils.MiscAssertsKt; import org.junit.After; diff --git a/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/UpstreamNetworkMonitorTest.java b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/UpstreamNetworkMonitorTest.java index 7c98f626a4d2..232588c7eec0 100644 --- a/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/UpstreamNetworkMonitorTest.java +++ b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/UpstreamNetworkMonitorTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.server.connectivity.tethering; +package com.android.networkstack.tethering; import static android.net.ConnectivityManager.TYPE_MOBILE_DUN; import static android.net.ConnectivityManager.TYPE_MOBILE_HIPRI; @@ -24,7 +24,7 @@ import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET; import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; import static android.net.NetworkCapabilities.TRANSPORT_WIFI; -import static com.android.server.connectivity.tethering.UpstreamNetworkMonitor.TYPE_NONE; +import static com.android.networkstack.tethering.UpstreamNetworkMonitor.TYPE_NONE; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; diff --git a/read-snapshot.txt b/read-snapshot.txt new file mode 100644 index 000000000000..e69de29bb2d1 --- /dev/null +++ b/read-snapshot.txt diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java index d1805d96cad8..1bc026cd3b19 100644 --- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java +++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java @@ -815,26 +815,27 @@ final class AutofillManagerServiceImpl } } - void logAugmentedAutofillSelected(int sessionId, @Nullable String suggestionId) { + void logAugmentedAutofillSelected(int sessionId, @Nullable String suggestionId, + @Nullable Bundle clientState) { synchronized (mLock) { if (mAugmentedAutofillEventHistory == null || mAugmentedAutofillEventHistory.getSessionId() != sessionId) { return; } mAugmentedAutofillEventHistory.addEvent( - new Event(Event.TYPE_DATASET_SELECTED, suggestionId, null, null, null, + new Event(Event.TYPE_DATASET_SELECTED, suggestionId, clientState, null, null, null, null, null, null, null, null)); } } - void logAugmentedAutofillShown(int sessionId) { + void logAugmentedAutofillShown(int sessionId, @Nullable Bundle clientState) { synchronized (mLock) { if (mAugmentedAutofillEventHistory == null || mAugmentedAutofillEventHistory.getSessionId() != sessionId) { return; } mAugmentedAutofillEventHistory.addEvent( - new Event(Event.TYPE_DATASETS_SHOWN, null, null, null, null, null, + new Event(Event.TYPE_DATASETS_SHOWN, null, clientState, null, null, null, null, null, null, null, null)); } @@ -1185,15 +1186,16 @@ final class AutofillManagerServiceImpl } @Override - public void logAugmentedAutofillShown(int sessionId) { - AutofillManagerServiceImpl.this.logAugmentedAutofillShown(sessionId); + public void logAugmentedAutofillShown(int sessionId, Bundle clientState) { + AutofillManagerServiceImpl.this.logAugmentedAutofillShown(sessionId, + clientState); } @Override public void logAugmentedAutofillSelected(int sessionId, - String suggestionId) { + String suggestionId, Bundle clientState) { AutofillManagerServiceImpl.this.logAugmentedAutofillSelected(sessionId, - suggestionId); + suggestionId, clientState); } @Override diff --git a/services/autofill/java/com/android/server/autofill/RemoteAugmentedAutofillService.java b/services/autofill/java/com/android/server/autofill/RemoteAugmentedAutofillService.java index b6bc7c5646a5..6cec8d82f9d4 100644 --- a/services/autofill/java/com/android/server/autofill/RemoteAugmentedAutofillService.java +++ b/services/autofill/java/com/android/server/autofill/RemoteAugmentedAutofillService.java @@ -168,12 +168,12 @@ final class RemoteAugmentedAutofillService focusedId, focusedValue, requestTime, inlineSuggestionsRequest, new IFillCallback.Stub() { @Override - public void onSuccess( - @Nullable List<Dataset> inlineSuggestionsData) { + public void onSuccess(@Nullable List<Dataset> inlineSuggestionsData, + @Nullable Bundle clientState) { mCallbacks.resetLastResponse(); maybeRequestShowInlineSuggestions(sessionId, inlineSuggestionsRequest, inlineSuggestionsData, - focusedId, inlineSuggestionsCallback, + clientState, focusedId, inlineSuggestionsCallback, client, onErrorCallback, remoteRenderService); requestAutofill.complete(null); } @@ -238,7 +238,8 @@ final class RemoteAugmentedAutofillService private void maybeRequestShowInlineSuggestions(int sessionId, @Nullable InlineSuggestionsRequest request, - @Nullable List<Dataset> inlineSuggestionsData, @NonNull AutofillId focusedId, + @Nullable List<Dataset> inlineSuggestionsData, @Nullable Bundle clientState, + @NonNull AutofillId focusedId, @Nullable Function<InlineSuggestionsResponse, Boolean> inlineSuggestionsCallback, @NonNull IAutoFillManagerClient client, @NonNull Runnable onErrorCallback, @Nullable RemoteInlineSuggestionRenderService remoteRenderService) { @@ -256,7 +257,7 @@ final class RemoteAugmentedAutofillService @Override public void autofill(Dataset dataset) { mCallbacks.logAugmentedAutofillSelected(sessionId, - dataset.getId()); + dataset.getId(), clientState); try { final ArrayList<AutofillId> fieldIds = dataset.getFieldIds(); final int size = fieldIds.size(); @@ -287,7 +288,7 @@ final class RemoteAugmentedAutofillService return; } if (inlineSuggestionsCallback.apply(inlineSuggestionsResponse)) { - mCallbacks.logAugmentedAutofillShown(sessionId); + mCallbacks.logAugmentedAutofillShown(sessionId, clientState); } } @@ -310,8 +311,9 @@ final class RemoteAugmentedAutofillService void setLastResponse(int sessionId); - void logAugmentedAutofillShown(int sessionId); + void logAugmentedAutofillShown(int sessionId, @Nullable Bundle clientState); - void logAugmentedAutofillSelected(int sessionId, @Nullable String suggestionId); + void logAugmentedAutofillSelected(int sessionId, @Nullable String suggestionId, + @Nullable Bundle clientState); } } diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index 51427c191aa7..1a58d6047bd7 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -2151,7 +2151,8 @@ public class ConnectivityService extends IConnectivityManager.Stub private boolean checkNetworkSignalStrengthWakeupPermission(int pid, int uid) { return checkAnyPermissionOf(pid, uid, android.Manifest.permission.NETWORK_SIGNAL_STRENGTH_WAKEUP, - NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK); + NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, + android.Manifest.permission.NETWORK_SETTINGS); } private void enforceConnectivityRestrictedNetworksPermission() { diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java index b0a586d122ea..14fe0c5e3c22 100644 --- a/services/core/java/com/android/server/StorageManagerService.java +++ b/services/core/java/com/android/server/StorageManagerService.java @@ -3215,10 +3215,14 @@ class StorageManagerService extends IStorageManager.Stub @Override public void unlockUserKey(int userId, int serialNumber, byte[] token, byte[] secret) { - Slog.d(TAG, "unlockUserKey: " + userId); + boolean isFsEncrypted = StorageManager.isFileEncryptedNativeOrEmulated(); + Slog.d(TAG, "unlockUserKey: " + userId + + " isFileEncryptedNativeOrEmulated: " + isFsEncrypted + + " hasToken: " + (token != null) + + " hasSecret: " + (secret != null)); enforcePermission(android.Manifest.permission.STORAGE_INTERNAL); - if (StorageManager.isFileEncryptedNativeOrEmulated()) { + if (isFsEncrypted) { try { mVold.unlockUserKey(userId, serialNumber, encodeBytes(token), encodeBytes(secret)); diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index e41ba0e1745d..2a9f503602ac 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -465,6 +465,8 @@ public class ActivityManagerService extends IActivityManager.Stub static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; + static final String SYSTEM_USER_HOME_NEEDED = "ro.system_user_home_needed"; + public static final String ANR_TRACE_DIR = "/data/anr"; // Maximum number of receivers an app can register. @@ -9592,7 +9594,8 @@ public class ActivityManagerService extends IActivityManager.Stub // to handle home activity in this case. if (UserManager.isSplitSystemUser() && Settings.Secure.getInt(mContext.getContentResolver(), - Settings.Secure.USER_SETUP_COMPLETE, 0) != 0) { + Settings.Secure.USER_SETUP_COMPLETE, 0) != 0 + || SystemProperties.getBoolean(SYSTEM_USER_HOME_NEEDED, false)) { t.traceBegin("enableHomeActivity"); ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class); try { diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java index 89fa02bbbd64..cce749d5a7ef 100644 --- a/services/core/java/com/android/server/am/ProcessList.java +++ b/services/core/java/com/android/server/am/ProcessList.java @@ -1668,6 +1668,33 @@ public final class ProcessList { return gidArray; } + private boolean shouldEnableTaggedPointers(ProcessRecord app) { + // Ensure we have platform + kernel support for TBI. + if (!Zygote.nativeSupportsTaggedPointers()) { + return false; + } + + // Check to ensure the app hasn't explicitly opted-out of TBI via. the manifest attribute. + if (!app.info.allowsNativeHeapPointerTagging()) { + return false; + } + + // Check to see that the compat feature for TBI is enabled. + if (!mPlatformCompat.isChangeEnabled(NATIVE_HEAP_POINTER_TAGGING, app.info)) { + return false; + } + + return true; + } + + private int decideTaggingLevel(ProcessRecord app) { + if (shouldEnableTaggedPointers(app)) { + return Zygote.MEMORY_TAG_LEVEL_TBI; + } + + return 0; + } + private int decideGwpAsanLevel(ProcessRecord app) { // Look at the process attribute first. if (app.processInfo != null @@ -1856,15 +1883,6 @@ public final class ProcessList { runtimeFlags |= Zygote.USE_APP_IMAGE_STARTUP_CACHE; } - if (Zygote.nativeSupportsTaggedPointers()) { - // Enable heap pointer tagging if supported by the kernel, unless disabled by the - // app manifest, target sdk level, or compat feature. - if (app.info.allowsNativeHeapPointerTagging() - && mPlatformCompat.isChangeEnabled(NATIVE_HEAP_POINTER_TAGGING, app.info)) { - runtimeFlags |= Zygote.MEMORY_TAG_LEVEL_TBI; - } - } - runtimeFlags |= decideGwpAsanLevel(app); String invokeWith = null; @@ -1895,6 +1913,20 @@ public final class ProcessList { app.setRequiredAbi(requiredAbi); app.instructionSet = instructionSet; + // If instructionSet is non-null, this indicates that the system_server is spawning a + // process with an ISA that may be different from its own. System (kernel and hardware) + // compatililty for these features is checked in the decideTaggingLevel in the + // system_server process (not the child process). As TBI is only supported in aarch64, + // we can simply ensure that the new process is also aarch64. This prevents the mismatch + // where a 64-bit system server spawns a 32-bit child that thinks it should enable some + // tagging variant. Theoretically, a 32-bit system server could exist that spawns 64-bit + // processes, in which case the new process won't get any tagging. This is fine as we + // haven't seen this configuration in practice, and we can reasonable assume that if + // tagging is desired, the system server will be 64-bit. + if (instructionSet == null || instructionSet.equals("arm64")) { + runtimeFlags |= decideTaggingLevel(app); + } + // the per-user SELinux context must be set if (TextUtils.isEmpty(app.info.seInfoUser)) { Slog.wtf(ActivityManagerService.TAG, "SELinux tag not defined", diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java index e02c6f9d5497..546025a2498f 100644 --- a/services/core/java/com/android/server/am/UserController.java +++ b/services/core/java/com/android/server/am/UserController.java @@ -40,6 +40,7 @@ import static com.android.server.am.UserState.STATE_RUNNING_LOCKED; import static com.android.server.am.UserState.STATE_RUNNING_UNLOCKED; import static com.android.server.am.UserState.STATE_RUNNING_UNLOCKING; +import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; @@ -89,6 +90,7 @@ import android.util.Pair; import android.util.Slog; import android.util.SparseArray; import android.util.SparseIntArray; +import android.util.SparseLongArray; import android.util.proto.ProtoOutputStream; import com.android.internal.R; @@ -112,6 +114,7 @@ import java.util.Arrays; import java.util.Iterator; import java.util.List; import java.util.Objects; +import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.atomic.AtomicInteger; /** @@ -162,6 +165,46 @@ class UserController implements Handler.Callback { // TODO(b/149604218): STOPSHIP remove this constant and the logcat private static final boolean TESTS_NEED_LOGCAT = true; + // Used for statsd logging with UserLifecycleJourneyReported + UserLifecycleEventOccurred atoms + private static final long INVALID_SESSION_ID = 0; + + // The various user journeys, defined in the UserLifecycleJourneyReported atom for statsd + private static final int USER_JOURNEY_UNKNOWN = + FrameworkStatsLog.USER_LIFECYCLE_JOURNEY_REPORTED__JOURNEY__UNKNOWN; + private static final int USER_JOURNEY_USER_SWITCH_FG = + FrameworkStatsLog.USER_LIFECYCLE_JOURNEY_REPORTED__JOURNEY__USER_SWITCH_FG; + private static final int USER_JOURNEY_USER_SWITCH_UI = + FrameworkStatsLog.USER_LIFECYCLE_JOURNEY_REPORTED__JOURNEY__USER_SWITCH_UI; + private static final int USER_JOURNEY_USER_START = + FrameworkStatsLog.USER_LIFECYCLE_JOURNEY_REPORTED__JOURNEY__USER_START; + private static final int USER_JOURNEY_USER_CREATE = + FrameworkStatsLog.USER_LIFECYCLE_JOURNEY_REPORTED__JOURNEY__USER_CREATE; + @IntDef(prefix = { "USER_JOURNEY" }, value = { + USER_JOURNEY_UNKNOWN, + USER_JOURNEY_USER_SWITCH_FG, + USER_JOURNEY_USER_SWITCH_UI, + USER_JOURNEY_USER_START, + USER_JOURNEY_USER_CREATE, + }) + @interface UserJourney {} + + // The various user lifecycle events, defined in the UserLifecycleEventOccurred atom for statsd + private static final int USER_LIFECYCLE_EVENT_UNKNOWN = + FrameworkStatsLog.USER_LIFECYCLE_EVENT_OCCURRED__EVENT__UNKNOWN; + private static final int USER_LIFECYCLE_EVENT_SWITCH_USER = + FrameworkStatsLog.USER_LIFECYCLE_EVENT_OCCURRED__EVENT__SWITCH_USER; + private static final int USER_LIFECYCLE_EVENT_START_USER = + FrameworkStatsLog.USER_LIFECYCLE_EVENT_OCCURRED__EVENT__START_USER; + private static final int USER_LIFECYCLE_EVENT_CREATE_USER = + FrameworkStatsLog.USER_LIFECYCLE_EVENT_OCCURRED__EVENT__CREATE_USER; + @IntDef(prefix = { "USER_LIFECYCLE_EVENT" }, value = { + USER_LIFECYCLE_EVENT_UNKNOWN, + USER_LIFECYCLE_EVENT_SWITCH_USER, + USER_LIFECYCLE_EVENT_START_USER, + USER_LIFECYCLE_EVENT_CREATE_USER, + }) + @interface UserLifecycleEvent {} + /** * Maximum number of users we allow to be running at a time, including system user. * @@ -270,6 +313,13 @@ class UserController implements Handler.Callback { @GuardedBy("mLock") private final ArrayList<Integer> mLastActiveUsers = new ArrayList<>(); + /** + * A per-user, journey to session id map, used for statsd logging for the + * UserLifecycleJourneyReported and UserLifecycleEventOccurred atoms. + */ + @GuardedBy("mUserJourneyToSessionIdMap") + private final SparseArray<SparseLongArray> mUserJourneyToSessionIdMap = new SparseArray<>(); + UserController(ActivityManagerService service) { this(new Injector(service)); } @@ -2349,6 +2399,10 @@ class UserController implements Handler.Callback { public boolean handleMessage(Message msg) { switch (msg.what) { case START_USER_SWITCH_FG_MSG: + logUserJourneyInfo(getUserInfo(getCurrentUserId()), getUserInfo(msg.arg1), + USER_JOURNEY_USER_SWITCH_FG); + logUserLifecycleEvent(msg.arg1, USER_JOURNEY_USER_SWITCH_FG, + USER_LIFECYCLE_EVENT_SWITCH_USER, true); startUserInForeground(msg.arg1); break; case REPORT_USER_SWITCH_MSG: @@ -2370,8 +2424,14 @@ class UserController implements Handler.Callback { mInjector.batteryStatsServiceNoteEvent( BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, Integer.toString(msg.arg1), msg.arg1); + logUserJourneyInfo(null, getUserInfo(msg.arg1), USER_JOURNEY_USER_START); + logUserLifecycleEvent(msg.arg1, USER_JOURNEY_USER_START, + USER_LIFECYCLE_EVENT_START_USER, true); mInjector.getSystemServiceManager().startUser(TimingsTraceAndSlog.newAsyncLog(), msg.arg1); + logUserLifecycleEvent(msg.arg1, USER_JOURNEY_USER_START, + USER_LIFECYCLE_EVENT_START_USER, false); + clearSessionId(msg.arg1, USER_JOURNEY_USER_START); break; case USER_UNLOCK_MSG: final int userId = msg.arg1; @@ -2400,17 +2460,94 @@ class UserController implements Handler.Callback { break; case REPORT_USER_SWITCH_COMPLETE_MSG: dispatchUserSwitchComplete(msg.arg1); + final int currentJourney = mUserSwitchUiEnabled ? USER_JOURNEY_USER_SWITCH_UI + : USER_JOURNEY_USER_SWITCH_FG; + logUserLifecycleEvent(msg.arg1, currentJourney, + USER_LIFECYCLE_EVENT_SWITCH_USER, false); + clearSessionId(msg.arg1, currentJourney); break; case REPORT_LOCKED_BOOT_COMPLETE_MSG: dispatchLockedBootComplete(msg.arg1); break; case START_USER_SWITCH_UI_MSG: - showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj); + final Pair<UserInfo, UserInfo> fromToUserPair = (Pair<UserInfo, UserInfo>) msg.obj; + logUserJourneyInfo(fromToUserPair.first, fromToUserPair.second, + USER_JOURNEY_USER_SWITCH_UI); + logUserLifecycleEvent(fromToUserPair.second.id, USER_JOURNEY_USER_SWITCH_UI, + USER_LIFECYCLE_EVENT_SWITCH_USER, true); + showUserSwitchDialog(fromToUserPair); break; } return false; } + /** + * statsd helper method for logging the start of a user journey via a UserLifecycleEventOccurred + * atom given the originating and targeting users for the journey. + * + * Note: these info atoms are currently logged more than once per journey since there is no + * state associated with the user's ongoing journey - this will be updated in a later CL. + */ + private void logUserJourneyInfo(UserInfo origin, UserInfo target, @UserJourney int journey) { + final long newSessionId = ThreadLocalRandom.current().nextLong(1, Long.MAX_VALUE); + synchronized (mUserJourneyToSessionIdMap) { + SparseLongArray userSessions = mUserJourneyToSessionIdMap.get(target.id); + if (userSessions == null) { + userSessions = new SparseLongArray(); + mUserJourneyToSessionIdMap.put(target.id, userSessions); + } + final long oldSessionId = userSessions.get(journey); + if (oldSessionId != INVALID_SESSION_ID) { + // potentially an incomplete or timed-out session + FrameworkStatsLog.write(FrameworkStatsLog.USER_LIFECYCLE_EVENT_OCCURRED, + oldSessionId, target.id, USER_LIFECYCLE_EVENT_UNKNOWN, + FrameworkStatsLog.USER_LIFECYCLE_EVENT_OCCURRED__STATE__NONE); + } + // update session id + userSessions.put(journey, newSessionId); + } + + FrameworkStatsLog.write(FrameworkStatsLog.USER_LIFECYCLE_JOURNEY_REPORTED, newSessionId, + journey, origin != null ? origin.id : -1, + target.id, UserManager.getUserTypeForStatsd(target.userType), target.flags); + } + + /** + * statsd helper method for logging the begin or finish of the given event for the + * UserLifecycleEventOccurred statsd atom. + * Note: This does not clear the user's journey session id - if this event represents the end of + * a particular journey, call {@link #clearSessionId} to indicate that the session is over. + */ + private void logUserLifecycleEvent(@UserIdInt int userId, @UserJourney int journey, + @UserLifecycleEvent int event, boolean begin) { + final long sessionId; + synchronized (mUserJourneyToSessionIdMap) { + final SparseLongArray eventToSessionMap = mUserJourneyToSessionIdMap.get(userId); + if (eventToSessionMap == null || eventToSessionMap.size() == 0) { + return; + } + sessionId = eventToSessionMap.get(journey); + if (sessionId == INVALID_SESSION_ID) { + return; + } + } + + FrameworkStatsLog.write(FrameworkStatsLog.USER_LIFECYCLE_EVENT_OCCURRED, sessionId, userId, + event, begin ? FrameworkStatsLog.USER_LIFECYCLE_EVENT_OCCURRED__STATE__BEGIN + : FrameworkStatsLog.USER_LIFECYCLE_EVENT_OCCURRED__STATE__FINISH); + } + + /** + * Clears the user's session id associated with the given UserJourney (for statsd). + */ + private void clearSessionId(@UserIdInt int userId, @UserJourney int journey) { + synchronized (mUserJourneyToSessionIdMap) { + if (mUserJourneyToSessionIdMap.get(userId) != null) { + mUserJourneyToSessionIdMap.get(userId).delete(journey); + } + } + } + private static class UserProgressListener extends IProgressListener.Stub { private volatile long mUnlockStarted; @Override diff --git a/services/core/java/com/android/server/appop/TEST_MAPPING b/services/core/java/com/android/server/appop/TEST_MAPPING index 9c03a3606e6c..604b9f1ead6d 100644 --- a/services/core/java/com/android/server/appop/TEST_MAPPING +++ b/services/core/java/com/android/server/appop/TEST_MAPPING @@ -38,6 +38,9 @@ }, { "name": "CtsAppTestCases:ActivityManagerApi29Test" + }, + { + "name": "UidAtomTests:testAppOps" } ] } diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index 02d8571c2dcd..f840f2d359d5 100644..100755 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -185,6 +185,9 @@ public class AudioService extends IAudioService.Stub private static final String TAG = "AS.AudioService"; + private final AudioSystemAdapter mAudioSystem; + private final SystemServerAdapter mSystemServer; + /** Debug audio mode */ protected static final boolean DEBUG_MODE = false; @@ -573,6 +576,8 @@ public class AudioService extends IAudioService.Stub private boolean mMicMuteFromSwitch; private boolean mMicMuteFromApi; private boolean mMicMuteFromRestrictions; + // caches the value returned by AudioSystem.isMicrophoneMuted() + private boolean mMicMuteFromSystemCached; @GuardedBy("mSettingsLock") private int mAssistantUid; @@ -647,10 +652,19 @@ public class AudioService extends IAudioService.Stub /** @hide */ public AudioService(Context context) { + this(context, AudioSystemAdapter.getDefaultAdapter(), + SystemServerAdapter.getDefaultAdapter(context)); + } + + public AudioService(Context context, AudioSystemAdapter audioSystem, + SystemServerAdapter systemServer) { mContext = context; mContentResolver = context.getContentResolver(); mAppOps = (AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE); + mAudioSystem = audioSystem; + mSystemServer = systemServer; + mPlatformType = AudioSystem.getPlatformType(context); mIsSingleVolume = AudioSystem.isSingleVolume(context); @@ -840,11 +854,13 @@ public class AudioService extends IAudioService.Stub context.registerReceiverAsUser(mReceiver, UserHandle.ALL, intentFilter, null, null); - LocalServices.addService(AudioManagerInternal.class, new AudioServiceInternal()); + if (mSystemServer.isPrivileged()) { + LocalServices.addService(AudioManagerInternal.class, new AudioServiceInternal()); - mUserManagerInternal.addUserRestrictionsListener(mUserRestrictionsListener); + mUserManagerInternal.addUserRestrictionsListener(mUserRestrictionsListener); - mRecordMonitor.initMonitor(); + mRecordMonitor.initMonitor(); + } final float[] preScale = new float[3]; preScale[0] = mContext.getResources().getFraction( @@ -933,6 +949,7 @@ public class AudioService extends IAudioService.Stub onIndicateSystemReady(); + mMicMuteFromSystemCached = mAudioSystem.isMicrophoneMuted(); setMicMuteFromSwitchInput(); } @@ -1126,6 +1143,7 @@ public class AudioService extends IAudioService.Stub sendMsg(mAudioHandler, MSG_DISPATCH_AUDIO_SERVER_STATE, SENDMSG_QUEUE, 1, 0, null, 0); + setMicrophoneMuteNoCallerCheck(getCurrentUserId()); // will also update the mic mute cache setMicMuteFromSwitchInput(); } @@ -1632,12 +1650,15 @@ public class AudioService extends IAudioService.Stub } if (currentImeUid != mCurrentImeUid || forceUpdate) { - AudioSystem.setCurrentImeUid(currentImeUid); + mAudioSystem.setCurrentImeUid(currentImeUid); mCurrentImeUid = currentImeUid; } } private void readPersistedSettings() { + if (!mSystemServer.isPrivileged()) { + return; + } final ContentResolver cr = mContentResolver; int ringerModeFromSettings = @@ -1708,6 +1729,9 @@ public class AudioService extends IAudioService.Stub } private void readUserRestrictions() { + if (!mSystemServer.isPrivileged()) { + return; + } final int currentUser = getCurrentUserId(); // Check the current user restriction. @@ -2778,6 +2802,9 @@ public class AudioService extends IAudioService.Stub } private void sendBroadcastToAll(Intent intent) { + if (!mSystemServer.isPrivileged()) { + return; + } intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); final long ident = Binder.clearCallingIdentity(); @@ -3151,21 +3178,41 @@ public class AudioService extends IAudioService.Stub } } + /** + * Returns the microphone mute state as seen from the native audio system + * @return true if microphone is reported as muted by primary HAL + */ public boolean isMicrophoneMuted() { + return mMicMuteFromSystemCached; + } + + private boolean isMicrophoneSupposedToBeMuted() { return mMicMuteFromSwitch || mMicMuteFromRestrictions || mMicMuteFromApi; } private void setMicrophoneMuteNoCallerCheck(int userId) { - final boolean muted = isMicrophoneMuted(); + final boolean muted = isMicrophoneSupposedToBeMuted(); if (DEBUG_VOL) { Log.d(TAG, String.format("Mic mute %b, user=%d", muted, userId)); } // only mute for the current user if (getCurrentUserId() == userId || userId == android.os.Process.SYSTEM_UID) { - final boolean currentMute = AudioSystem.isMicrophoneMuted(); + final boolean currentMute = mAudioSystem.isMicrophoneMuted(); final long identity = Binder.clearCallingIdentity(); - AudioSystem.muteMicrophone(muted); + final int ret = mAudioSystem.muteMicrophone(muted); + + // update cache with the real state independently from what was set + mMicMuteFromSystemCached = mAudioSystem.isMicrophoneMuted(); + if (ret != AudioSystem.AUDIO_STATUS_OK) { + Log.e(TAG, "Error changing mic mute state to " + muted + " current:" + + mMicMuteFromSystemCached); + } try { + // send the intent even if there was a failure to change the actual mute state: + // the AudioManager.setMicrophoneMute API doesn't have a return value to + // indicate if the call failed to successfully change the mute state, and receiving + // the intent may be the only time an application can resynchronize its mic mute + // state with the actual system mic mute state if (muted != currentMute) { sendMsg(mAudioHandler, MSG_BROADCAST_MICROPHONE_MUTE, SENDMSG_NOOP, 0, 0, null, 0); @@ -4494,6 +4541,9 @@ public class AudioService extends IAudioService.Stub } private void broadcastRingerMode(String action, int ringerMode) { + if (!mSystemServer.isPrivileged()) { + return; + } // Send sticky broadcast Intent broadcast = new Intent(action); broadcast.putExtra(AudioManager.EXTRA_RINGER_MODE, ringerMode); @@ -4503,6 +4553,9 @@ public class AudioService extends IAudioService.Stub } private void broadcastVibrateSetting(int vibrateType) { + if (!mSystemServer.isPrivileged()) { + return; + } // Send broadcast if (mActivityManagerInternal.isSystemReady()) { Intent broadcast = new Intent(AudioManager.VIBRATE_SETTING_CHANGED_ACTION); @@ -5234,6 +5287,9 @@ public class AudioService extends IAudioService.Stub } public int observeDevicesForStream_syncVSS(boolean checkOthers) { + if (!mSystemServer.isPrivileged()) { + return AudioSystem.DEVICE_NONE; + } final int devices = AudioSystem.getDevicesForStream(mStreamType); if (devices == mObservedDevices) { return devices; @@ -5974,10 +6030,7 @@ public class AudioService extends IAudioService.Stub break; case MSG_BROADCAST_MICROPHONE_MUTE: - mContext.sendBroadcastAsUser( - new Intent(AudioManager.ACTION_MICROPHONE_MUTE_CHANGED) - .setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY), - UserHandle.ALL); + mSystemServer.sendMicrophoneMuteChangedIntent(); break; } } @@ -6976,6 +7029,10 @@ public class AudioService extends IAudioService.Stub pw.print(" mHdmiTvClient="); pw.println(mHdmiTvClient); pw.print(" mHdmiSystemAudioSupported="); pw.println(mHdmiSystemAudioSupported); pw.print(" mIsCallScreeningModeSupported="); pw.println(mIsCallScreeningModeSupported); + pw.print(" mic mute FromSwitch=" + mMicMuteFromSwitch + + " FromRestrictions=" + mMicMuteFromRestrictions + + " FromApi=" + mMicMuteFromApi + + " from system=" + mMicMuteFromSystemCached); dumpAudioPolicies(pw); mDynPolicyLogger.dump(pw); @@ -8419,6 +8476,23 @@ public class AudioService extends IAudioService.Stub } //====================== + // Multi Audio Focus + //====================== + public void setMultiAudioFocusEnabled(boolean enabled) { + enforceModifyAudioRoutingPermission(); + if (mMediaFocusControl != null) { + boolean mafEnabled = mMediaFocusControl.getMultiAudioFocusEnabled(); + if (mafEnabled != enabled) { + mMediaFocusControl.updateMultiAudioFocus(enabled); + if (!enabled) { + mDeviceBroker.postBroadcastBecomingNoisy(); + } + } + } + } + + + //====================== // misc //====================== private final HashMap<IBinder, AudioPolicyProxy> mAudioPolicies = diff --git a/services/core/java/com/android/server/audio/AudioSystemAdapter.java b/services/core/java/com/android/server/audio/AudioSystemAdapter.java index 9f8f9f8fddde..40c13904fbc9 100644 --- a/services/core/java/com/android/server/audio/AudioSystemAdapter.java +++ b/services/core/java/com/android/server/audio/AudioSystemAdapter.java @@ -40,10 +40,11 @@ public class AudioSystemAdapter { /** * Create an adapter for AudioSystem that always succeeds, and does nothing. - * @return a no-op AudioSystem adapter + * Overridden methods can be configured + * @return a no-op AudioSystem adapter with configurable adapter */ - static final @NonNull AudioSystemAdapter getAlwaysOkAdapter() { - return new AudioSystemOkAdapter(); + static final @NonNull AudioSystemAdapter getConfigurableAdapter() { + return new AudioSystemConfigurableAdapter(); } /** @@ -113,10 +114,51 @@ public class AudioSystemAdapter { return AudioSystem.setParameters(keyValuePairs); } + /** + * Same as {@link AudioSystem#isMicrophoneMuted()}} + * Checks whether the microphone mute is on or off. + * @return true if microphone is muted, false if it's not + */ + public boolean isMicrophoneMuted() { + return AudioSystem.isMicrophoneMuted(); + } + + /** + * Same as {@link AudioSystem#muteMicrophone(boolean)} + * Sets the microphone mute on or off. + * + * @param on set <var>true</var> to mute the microphone; + * <var>false</var> to turn mute off + * @return command completion status see AUDIO_STATUS_OK, see AUDIO_STATUS_ERROR + */ + public int muteMicrophone(boolean on) { + return AudioSystem.muteMicrophone(on); + } + + /** + * Same as {@link AudioSystem#setCurrentImeUid(int)} + * Communicate UID of current InputMethodService to audio policy service. + */ + public int setCurrentImeUid(int uid) { + return AudioSystem.setCurrentImeUid(uid); + } + //-------------------------------------------------------------------- - protected static class AudioSystemOkAdapter extends AudioSystemAdapter { + protected static class AudioSystemConfigurableAdapter extends AudioSystemAdapter { private static final String TAG = "ASA"; + private boolean mIsMicMuted = false; + private boolean mMuteMicrophoneFails = false; + + public void configureIsMicrophoneMuted(boolean muted) { + mIsMicMuted = muted; + } + public void configureMuteMicrophoneToFail(boolean fail) { + mMuteMicrophoneFails = fail; + } + + //----------------------------------------------------------------- + // Overrides of AudioSystemAdapter @Override public int setDeviceConnectionState(int device, int state, String deviceAddress, String deviceName, int codecFormat) { @@ -152,5 +194,24 @@ public class AudioSystemAdapter { public int setParameters(String keyValuePairs) { return AudioSystem.AUDIO_STATUS_OK; } + + @Override + public boolean isMicrophoneMuted() { + return mIsMicMuted; + } + + @Override + public int muteMicrophone(boolean on) { + if (mMuteMicrophoneFails) { + return AudioSystem.AUDIO_STATUS_ERROR; + } + mIsMicMuted = on; + return AudioSystem.AUDIO_STATUS_OK; + } + + @Override + public int setCurrentImeUid(int uid) { + return AudioSystem.AUDIO_STATUS_OK; + } } } diff --git a/services/core/java/com/android/server/audio/MediaFocusControl.java b/services/core/java/com/android/server/audio/MediaFocusControl.java index 7bf2bc842176..bfab9919258c 100644..100755 --- a/services/core/java/com/android/server/audio/MediaFocusControl.java +++ b/services/core/java/com/android/server/audio/MediaFocusControl.java @@ -30,6 +30,7 @@ import android.os.Binder; import android.os.Build; import android.os.IBinder; import android.os.RemoteException; +import android.provider.Settings; import android.util.Log; import com.android.internal.annotations.GuardedBy; @@ -80,6 +81,7 @@ public class MediaFocusControl implements PlayerFocusEnforcer { private final Context mContext; private final AppOpsManager mAppOps; private PlayerFocusEnforcer mFocusEnforcer; // never null + private boolean mMultiAudioFocusEnabled = false; private boolean mRingOrCallActive = false; @@ -91,6 +93,8 @@ public class MediaFocusControl implements PlayerFocusEnforcer { mContext = cntxt; mAppOps = (AppOpsManager)mContext.getSystemService(Context.APP_OPS_SERVICE); mFocusEnforcer = pfe; + mMultiAudioFocusEnabled = Settings.System.getInt(mContext.getContentResolver(), + Settings.System.MULTI_AUDIO_FOCUS_ENABLED, 0) != 0; } protected void dump(PrintWriter pw) { @@ -100,6 +104,7 @@ public class MediaFocusControl implements PlayerFocusEnforcer { pw.println("\n"); // log mEventLogger.dump(pw); + dumpMultiAudioFocus(pw); } //================================================================= @@ -194,6 +199,14 @@ public class MediaFocusControl implements PlayerFocusEnforcer { mFocusStack.peek().handleFocusGain(AudioManager.AUDIOFOCUS_GAIN); } } + + if (mMultiAudioFocusEnabled && !mMultiAudioFocusList.isEmpty()) { + for (FocusRequester multifr : mMultiAudioFocusList) { + if (isLockedFocusOwner(multifr)) { + multifr.handleFocusGain(AudioManager.AUDIOFOCUS_GAIN); + } + } + } } /** @@ -203,17 +216,30 @@ public class MediaFocusControl implements PlayerFocusEnforcer { */ @GuardedBy("mAudioFocusLock") private void propagateFocusLossFromGain_syncAf(int focusGain, final FocusRequester fr, - boolean forceDuck) { + boolean forceDuck) { final List<String> clientsToRemove = new LinkedList<String>(); // going through the audio focus stack to signal new focus, traversing order doesn't // matter as all entries respond to the same external focus gain - for (FocusRequester focusLoser : mFocusStack) { - final boolean isDefinitiveLoss = - focusLoser.handleFocusLossFromGain(focusGain, fr, forceDuck); - if (isDefinitiveLoss) { - clientsToRemove.add(focusLoser.getClientId()); + if (!mFocusStack.empty()) { + for (FocusRequester focusLoser : mFocusStack) { + final boolean isDefinitiveLoss = + focusLoser.handleFocusLossFromGain(focusGain, fr, forceDuck); + if (isDefinitiveLoss) { + clientsToRemove.add(focusLoser.getClientId()); + } } } + + if (mMultiAudioFocusEnabled && !mMultiAudioFocusList.isEmpty()) { + for (FocusRequester multifocusLoser : mMultiAudioFocusList) { + final boolean isDefinitiveLoss = + multifocusLoser.handleFocusLossFromGain(focusGain, fr, forceDuck); + if (isDefinitiveLoss) { + clientsToRemove.add(multifocusLoser.getClientId()); + } + } + } + for (String clientToRemove : clientsToRemove) { removeFocusStackEntry(clientToRemove, false /*signal*/, true /*notifyFocusFollowers*/); @@ -222,6 +248,8 @@ public class MediaFocusControl implements PlayerFocusEnforcer { private final Stack<FocusRequester> mFocusStack = new Stack<FocusRequester>(); + ArrayList<FocusRequester> mMultiAudioFocusList = new ArrayList<FocusRequester>(); + /** * Helper function: * Display in the log the current entries in the audio focus stack @@ -287,6 +315,22 @@ public class MediaFocusControl implements PlayerFocusEnforcer { } } } + + if (mMultiAudioFocusEnabled && !mMultiAudioFocusList.isEmpty()) { + Iterator<FocusRequester> listIterator = mMultiAudioFocusList.iterator(); + while (listIterator.hasNext()) { + FocusRequester fr = listIterator.next(); + if (fr.hasSameClient(clientToRemove)) { + listIterator.remove(); + fr.release(); + } + } + + if (signal) { + // notify the new top of the stack it gained focus + notifyTopOfAudioFocusStack(); + } + } } /** @@ -410,6 +454,16 @@ public class MediaFocusControl implements PlayerFocusEnforcer { removeFocusEntryForExtPolicy(mCb); } else { removeFocusStackEntryOnDeath(mCb); + if (mMultiAudioFocusEnabled && !mMultiAudioFocusList.isEmpty()) { + Iterator<FocusRequester> listIterator = mMultiAudioFocusList.iterator(); + while (listIterator.hasNext()) { + FocusRequester fr = listIterator.next(); + if (fr.hasSameBinder(mCb)) { + listIterator.remove(); + fr.release(); + } + } + } } } } @@ -867,6 +921,35 @@ public class MediaFocusControl implements PlayerFocusEnforcer { final FocusRequester nfr = new FocusRequester(aa, focusChangeHint, flags, fd, cb, clientId, afdh, callingPackageName, Binder.getCallingUid(), this, sdk); + + if (mMultiAudioFocusEnabled + && (focusChangeHint == AudioManager.AUDIOFOCUS_GAIN)) { + if (enteringRingOrCall) { + if (!mMultiAudioFocusList.isEmpty()) { + for (FocusRequester multifr : mMultiAudioFocusList) { + multifr.handleFocusLossFromGain(focusChangeHint, nfr, forceDuck); + } + } + } else { + boolean needAdd = true; + if (!mMultiAudioFocusList.isEmpty()) { + for (FocusRequester multifr : mMultiAudioFocusList) { + if (multifr.getClientUid() == Binder.getCallingUid()) { + needAdd = false; + break; + } + } + } + if (needAdd) { + mMultiAudioFocusList.add(nfr); + } + nfr.handleFocusGainFromRequest(AudioManager.AUDIOFOCUS_REQUEST_GRANTED); + notifyExtPolicyFocusGrant_syncAf(nfr.toAudioFocusInfo(), + AudioManager.AUDIOFOCUS_REQUEST_GRANTED); + return AudioManager.AUDIOFOCUS_REQUEST_GRANTED; + } + } + if (focusGrantDelayed) { // focusGrantDelayed being true implies we can't reassign focus right now // which implies the focus stack is not empty. @@ -877,9 +960,7 @@ public class MediaFocusControl implements PlayerFocusEnforcer { return requestResult; } else { // propagate the focus change through the stack - if (!mFocusStack.empty()) { - propagateFocusLossFromGain_syncAf(focusChangeHint, nfr, forceDuck); - } + propagateFocusLossFromGain_syncAf(focusChangeHint, nfr, forceDuck); // push focus requester at the top of the audio focus stack mFocusStack.push(nfr); @@ -970,4 +1051,39 @@ public class MediaFocusControl implements PlayerFocusEnforcer { } }.start(); } + + public void updateMultiAudioFocus(boolean enabled) { + Log.d(TAG, "updateMultiAudioFocus( " + enabled + " )"); + mMultiAudioFocusEnabled = enabled; + Settings.System.putInt(mContext.getContentResolver(), + Settings.System.MULTI_AUDIO_FOCUS_ENABLED, enabled ? 1 : 0); + if (!mFocusStack.isEmpty()) { + final FocusRequester fr = mFocusStack.peek(); + fr.handleFocusLoss(AudioManager.AUDIOFOCUS_LOSS, null, false); + } + if (!enabled) { + if (!mMultiAudioFocusList.isEmpty()) { + for (FocusRequester multifr : mMultiAudioFocusList) { + multifr.handleFocusLoss(AudioManager.AUDIOFOCUS_LOSS, null, false); + } + mMultiAudioFocusList.clear(); + } + } + } + + public boolean getMultiAudioFocusEnabled() { + return mMultiAudioFocusEnabled; + } + + private void dumpMultiAudioFocus(PrintWriter pw) { + pw.println("Multi Audio Focus enabled :" + mMultiAudioFocusEnabled); + if (!mMultiAudioFocusList.isEmpty()) { + pw.println("Multi Audio Focus List:"); + pw.println("------------------------------"); + for (FocusRequester multifr : mMultiAudioFocusList) { + multifr.dump(pw); + } + pw.println("------------------------------"); + } + } } diff --git a/services/core/java/com/android/server/audio/SystemServerAdapter.java b/services/core/java/com/android/server/audio/SystemServerAdapter.java new file mode 100644 index 000000000000..509f6be76f17 --- /dev/null +++ b/services/core/java/com/android/server/audio/SystemServerAdapter.java @@ -0,0 +1,90 @@ +/* + * Copyright 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.server.audio; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.content.Context; +import android.content.Intent; +import android.media.AudioManager; +import android.os.UserHandle; + +/** + * Provides an adapter to access functionality reserved to components running in system_server + * Functionality such as sending privileged broadcasts is to be accessed through the default + * adapter, whereas tests can inject a no-op adapter. + */ +public class SystemServerAdapter { + + protected final Context mContext; + + private SystemServerAdapter(@Nullable Context context) { + mContext = context; + } + /** + * Create a wrapper around privileged functionality. + * @return the adapter + */ + static final @NonNull SystemServerAdapter getDefaultAdapter(Context context) { + return new SystemServerAdapter(context); + } + + /** + * Create an adapter that does nothing. + * Use for running non-privileged tests, such as unit tests + * @return a no-op adapter + */ + static final @NonNull SystemServerAdapter getNoOpAdapter() { + return new NoOpSystemServerAdapter(); + } + + /** + * @return true if this is supposed to be run in system_server, false otherwise (e.g. for a + * unit test) + */ + public boolean isPrivileged() { + return true; + } + + /** + * Broadcast ACTION_MICROPHONE_MUTE_CHANGED + */ + public void sendMicrophoneMuteChangedIntent() { + mContext.sendBroadcastAsUser( + new Intent(AudioManager.ACTION_MICROPHONE_MUTE_CHANGED) + .setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY), + UserHandle.ALL); + } + + //-------------------------------------------------------------------- + protected static class NoOpSystemServerAdapter extends SystemServerAdapter { + + NoOpSystemServerAdapter() { + super(null); + } + + @Override + public boolean isPrivileged() { + return false; + } + + @Override + public void sendMicrophoneMuteChangedIntent() { + // no-op + } + } +} diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java index f82ec82ce79b..48e30bf42c2d 100644 --- a/services/core/java/com/android/server/display/DisplayPowerController.java +++ b/services/core/java/com/android/server/display/DisplayPowerController.java @@ -42,6 +42,7 @@ import android.os.Message; import android.os.PowerManager; import android.os.RemoteException; import android.os.SystemClock; +import android.os.SystemProperties; import android.os.Trace; import android.os.UserHandle; import android.provider.Settings; @@ -389,6 +390,10 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call private ObjectAnimator mColorFadeOffAnimator; private RampAnimator<DisplayPowerState> mScreenBrightnessRampAnimator; + // The brightness synchronizer to allow changes in the int brightness value to be reflected in + // the float brightness value and vice versa. + @Nullable + private final BrightnessSynchronizer mBrightnessSynchronizer; /** * Creates the display power controller. @@ -405,6 +410,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call mWindowManagerPolicy = LocalServices.getService(WindowManagerPolicy.class); mBlanker = blanker; mContext = context; + mBrightnessSynchronizer = new BrightnessSynchronizer(context); mDisplayDevice = displayDevice; PowerManager pm = context.getSystemService(PowerManager.class); @@ -1243,6 +1249,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call if (!reportOnly) { Trace.traceCounter(Trace.TRACE_TAG_POWER, "ScreenState", state); + // TODO(b/153319140) remove when we can get this from the above trace invocation + SystemProperties.set("debug.tracing.screen_state", String.valueOf(state)); mPowerState.setScreenState(state); // Tell battery stats about the transition. try { @@ -1319,6 +1327,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call } if (mScreenBrightnessRampAnimator.animateTo(target, rate)) { Trace.traceCounter(Trace.TRACE_TAG_POWER, "TargetScreenBrightness", (int) target); + // TODO(b/153319140) remove when we can get this from the above trace invocation + SystemProperties.set("debug.tracing.screen_brightness", String.valueOf(target)); try { // TODO(brightnessfloat): change BatteryStats to use float mBatteryStats.noteScreenBrightness( diff --git a/services/core/java/com/android/server/hdmi/HdmiCecMessage.java b/services/core/java/com/android/server/hdmi/HdmiCecMessage.java index f8b39627f236..ff7da11340eb 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecMessage.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecMessage.java @@ -115,8 +115,12 @@ public final class HdmiCecMessage { s.append(String.format("<%s> %X%X:%02X", opcodeToString(mOpcode), mSource, mDestination, mOpcode)); if (mParams.length > 0) { - for (byte data : mParams) { - s.append(String.format(":%02X", data)); + if (filterMessageParameters(mOpcode)) { + s.append(String.format(" <Redacted len=%d>", mParams.length)); + } else { + for (byte data : mParams) { + s.append(String.format(":%02X", data)); + } } } return s.toString(); @@ -270,5 +274,21 @@ public final class HdmiCecMessage { return String.format("Opcode: %02X", opcode); } } + + private static boolean filterMessageParameters(int opcode) { + switch (opcode) { + case Constants.MESSAGE_USER_CONTROL_PRESSED: + case Constants.MESSAGE_USER_CONTROL_RELEASED: + case Constants.MESSAGE_SET_OSD_NAME: + case Constants.MESSAGE_SET_OSD_STRING: + case Constants.MESSAGE_VENDOR_COMMAND: + case Constants.MESSAGE_VENDOR_REMOTE_BUTTON_DOWN: + case Constants.MESSAGE_VENDOR_REMOTE_BUTTON_UP: + case Constants.MESSAGE_VENDOR_COMMAND_WITH_ID: + return true; + default: + return false; + } + } } diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java index e6cb37185d71..b949d6bcf2e2 100644 --- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java +++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java @@ -784,6 +784,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub private static final AtomicInteger sSequenceNumber = new AtomicInteger(0); private static final class Entry { + final int mSequenceNumber = sSequenceNumber.getAndIncrement(); final ClientState mClientState; @SoftInputModeFlags final int mFocusedWindowSoftInputMode; @@ -831,7 +832,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub continue; } pw.print(prefix); - pw.println("SoftInputShowHideHistory #" + sSequenceNumber.getAndIncrement() + ":"); + pw.println("SoftInputShowHideHistory #" + entry.mSequenceNumber + ":"); pw.print(prefix); pw.println(" time=" + dataFormat.format(new Date(entry.mWallTime)) diff --git a/services/core/java/com/android/server/location/AppOpsHelper.java b/services/core/java/com/android/server/location/AppOpsHelper.java index cb64c50bf11d..c598fb1dbe26 100644 --- a/services/core/java/com/android/server/location/AppOpsHelper.java +++ b/services/core/java/com/android/server/location/AppOpsHelper.java @@ -19,8 +19,8 @@ package com.android.server.location; import static android.app.AppOpsManager.OP_MONITOR_HIGH_POWER_LOCATION; import static android.app.AppOpsManager.OP_MONITOR_LOCATION; -import static com.android.server.LocationManagerService.D; -import static com.android.server.LocationManagerService.TAG; +import static com.android.server.location.LocationManagerService.D; +import static com.android.server.location.LocationManagerService.TAG; import android.annotation.Nullable; import android.app.AppOpsManager; diff --git a/services/core/java/com/android/server/LocationManagerService.java b/services/core/java/com/android/server/location/LocationManagerService.java index 7f25de6b3470..4f8708a7599a 100644 --- a/services/core/java/com/android/server/LocationManagerService.java +++ b/services/core/java/com/android/server/location/LocationManagerService.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007 The Android Open Source Project + * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.server; +package com.android.server.location; import static android.Manifest.permission.ACCESS_FINE_LOCATION; import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE; @@ -36,6 +36,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; import android.app.ActivityManager; +import android.app.AppOpsManager; import android.app.PendingIntent; import android.content.BroadcastReceiver; import android.content.Context; @@ -91,27 +92,14 @@ import com.android.internal.location.ProviderRequest; import com.android.internal.util.DumpUtils; import com.android.internal.util.IndentingPrintWriter; import com.android.internal.util.Preconditions; -import com.android.server.location.AbstractLocationProvider; +import com.android.server.FgThread; +import com.android.server.LocalServices; +import com.android.server.PendingIntentUtils; +import com.android.server.SystemService; import com.android.server.location.AbstractLocationProvider.State; -import com.android.server.location.AppForegroundHelper; -import com.android.server.location.AppOpsHelper; -import com.android.server.location.CallerIdentity; import com.android.server.location.CallerIdentity.PermissionLevel; -import com.android.server.location.GeocoderProxy; -import com.android.server.location.GeofenceManager; -import com.android.server.location.GeofenceProxy; -import com.android.server.location.HardwareActivityRecognitionProxy; -import com.android.server.location.LocationFudger; -import com.android.server.location.LocationProviderProxy; -import com.android.server.location.LocationRequestStatistics; import com.android.server.location.LocationRequestStatistics.PackageProviderKey; import com.android.server.location.LocationRequestStatistics.PackageStatistics; -import com.android.server.location.LocationUsageLogger; -import com.android.server.location.MockProvider; -import com.android.server.location.MockableLocationProvider; -import com.android.server.location.PassiveProvider; -import com.android.server.location.SettingsHelper; -import com.android.server.location.UserInfoHelper; import com.android.server.location.UserInfoHelper.UserListener; import com.android.server.location.gnss.GnssManagerService; import com.android.server.pm.permission.PermissionManagerServiceInternal; @@ -1620,8 +1608,8 @@ public class LocationManagerService extends ILocationManager.Stub { // For now, make sure callers have supplied an attribution tag for use with // AppOpsManager. This might be relaxed in the future. final List<WorkChain> workChains = workSource.getWorkChains(); - return workChains != null && !workChains.isEmpty() && - workChains.get(0).getAttributionTag() != null; + return workChains != null && !workChains.isEmpty() + && workChains.get(0).getAttributionTag() != null; } } @@ -1840,6 +1828,9 @@ public class LocationManagerService extends ILocationManager.Stub { if (request == null) { request = DEFAULT_LOCATION_REQUEST; } + if (listenerId == null && intent != null) { + listenerId = AppOpsManager.toReceiverId(intent); + } CallerIdentity identity = CallerIdentity.fromBinder(mContext, packageName, featureId, listenerId); @@ -2106,7 +2097,8 @@ public class LocationManagerService extends ILocationManager.Stub { request = DEFAULT_LOCATION_REQUEST; } - CallerIdentity identity = CallerIdentity.fromBinder(mContext, packageName, featureId); + CallerIdentity identity = CallerIdentity.fromBinder(mContext, packageName, featureId, + AppOpsManager.toReceiverId(intent)); identity.enforceLocationPermission(); Objects.requireNonNull(intent); diff --git a/services/core/java/com/android/server/LocationManagerServiceUtils.java b/services/core/java/com/android/server/location/LocationManagerServiceUtils.java index 9d0fe5e936bb..c33a70662cb5 100644 --- a/services/core/java/com/android/server/LocationManagerServiceUtils.java +++ b/services/core/java/com/android/server/location/LocationManagerServiceUtils.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 The Android Open Source Project + * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,15 +14,13 @@ * limitations under the License. */ -package com.android.server; +package com.android.server.location; import android.annotation.NonNull; import android.annotation.Nullable; import android.os.IBinder; import android.os.RemoteException; -import com.android.server.location.CallerIdentity; - import java.util.NoSuchElementException; import java.util.function.Consumer; diff --git a/services/core/java/com/android/server/location/LocationUsageLogger.java b/services/core/java/com/android/server/location/LocationUsageLogger.java index 93e19df01cf3..b325deb786d6 100644 --- a/services/core/java/com/android/server/location/LocationUsageLogger.java +++ b/services/core/java/com/android/server/location/LocationUsageLogger.java @@ -16,7 +16,7 @@ package com.android.server.location; -import static com.android.server.LocationManagerService.TAG; +import static com.android.server.location.LocationManagerService.TAG; import android.app.ActivityManager; import android.location.Geofence; diff --git a/services/core/java/com/android/server/location/SettingsHelper.java b/services/core/java/com/android/server/location/SettingsHelper.java index 7ab258c29b46..cbb06b86a291 100644 --- a/services/core/java/com/android/server/location/SettingsHelper.java +++ b/services/core/java/com/android/server/location/SettingsHelper.java @@ -26,8 +26,8 @@ import static android.provider.Settings.Secure.LOCATION_COARSE_ACCURACY_M; import static android.provider.Settings.Secure.LOCATION_MODE; import static android.provider.Settings.Secure.LOCATION_MODE_OFF; -import static com.android.server.LocationManagerService.D; -import static com.android.server.LocationManagerService.TAG; +import static com.android.server.location.LocationManagerService.D; +import static com.android.server.location.LocationManagerService.TAG; import android.app.ActivityManager; import android.content.Context; diff --git a/services/core/java/com/android/server/location/UserInfoHelper.java b/services/core/java/com/android/server/location/UserInfoHelper.java index 28f3f476847b..a3dcc40bdf2d 100644 --- a/services/core/java/com/android/server/location/UserInfoHelper.java +++ b/services/core/java/com/android/server/location/UserInfoHelper.java @@ -18,8 +18,8 @@ package com.android.server.location; import static android.os.UserManager.DISALLOW_SHARE_LOCATION; -import static com.android.server.LocationManagerService.D; -import static com.android.server.LocationManagerService.TAG; +import static com.android.server.location.LocationManagerService.D; +import static com.android.server.location.LocationManagerService.TAG; import android.annotation.IntDef; import android.annotation.Nullable; 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 711f45cb7d28..3c509c380374 100644 --- a/services/core/java/com/android/server/location/gnss/GnssManagerService.java +++ b/services/core/java/com/android/server/location/gnss/GnssManagerService.java @@ -46,11 +46,11 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.IndentingPrintWriter; import com.android.internal.util.Preconditions; import com.android.server.LocalServices; -import com.android.server.LocationManagerServiceUtils.LinkedListener; -import com.android.server.LocationManagerServiceUtils.LinkedListenerBase; import com.android.server.location.AppForegroundHelper; import com.android.server.location.AppOpsHelper; import com.android.server.location.CallerIdentity; +import com.android.server.location.LocationManagerServiceUtils.LinkedListener; +import com.android.server.location.LocationManagerServiceUtils.LinkedListenerBase; import com.android.server.location.LocationUsageLogger; import com.android.server.location.RemoteListenerHelper; import com.android.server.location.SettingsHelper; diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java index 9297a43b04aa..7972f247b46d 100644 --- a/services/core/java/com/android/server/locksettings/LockSettingsService.java +++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java @@ -366,10 +366,15 @@ public class LockSettingsService extends ILockSettings.Stub { if (mStorage.hasChildProfileLock(managedUserId)) { return; } - // Do not tie it to parent when parent does not have a screen lock + // If parent does not have a screen lock, simply clear credential from the managed profile, + // to maintain the invariant that unified profile should always have the same secure state + // as its parent. final int parentId = mUserManager.getProfileParent(managedUserId).id; - if (!isUserSecure(parentId)) { - if (DEBUG) Slog.v(TAG, "Parent does not have a screen lock"); + if (!isUserSecure(parentId) && !managedUserPassword.isNone()) { + if (DEBUG) Slog.v(TAG, "Parent does not have a screen lock but profile has one"); + + setLockCredentialInternal(LockscreenCredential.createNone(), managedUserPassword, + managedUserId, /* isLockTiedToParent= */ true); return; } // Do not tie when the parent has no SID (but does have a screen lock). @@ -3161,6 +3166,21 @@ public class LockSettingsService extends ILockSettings.Stub { return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(timestamp)); } + private static String credentialTypeToString(int credentialType) { + switch (credentialType) { + case CREDENTIAL_TYPE_NONE: + return "None"; + case CREDENTIAL_TYPE_PATTERN: + return "Pattern"; + case CREDENTIAL_TYPE_PIN: + return "Pin"; + case CREDENTIAL_TYPE_PASSWORD: + return "Password"; + default: + return "Unknown " + credentialType; + } + } + @Override protected void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) { if (!DumpUtils.checkDumpPermission(mContext, TAG, printWriter)) return; @@ -3192,7 +3212,8 @@ public class LockSettingsService extends ILockSettings.Stub { // It's OK to dump the password type since anyone with physical access can just // observe it from the keyguard directly. pw.println("Quality: " + getKeyguardStoredQuality(userId)); - pw.println("CredentialType: " + getCredentialTypeInternal(userId)); + pw.println("CredentialType: " + credentialTypeToString( + getCredentialTypeInternal(userId))); pw.println("SeparateChallenge: " + getSeparateProfileChallengeEnabledInternal(userId)); pw.println(String.format("Metrics: %s", getUserPasswordMetrics(userId) != null ? "known" : "unknown")); diff --git a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java index c3413e8d2934..0d899974cf93 100644 --- a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java +++ b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java @@ -622,6 +622,16 @@ class MediaRouter2ServiceImpl { return; } + if (route.isSystemRoute() && !routerRecord.mHasModifyAudioRoutingPermission + && !TextUtils.equals(route.getId(), + routerRecord.mUserRecord.mHandler.mSystemProvider.getDefaultRoute().getId())) { + Slog.w(TAG, "MODIFY_AUDIO_ROUTING permission is required to transfer to" + + route); + routerRecord.mUserRecord.mHandler.notifySessionCreationFailedToRouter( + routerRecord, requestId); + return; + } + long uniqueRequestId = toUniqueRequestId(routerRecord.mRouterId, requestId); routerRecord.mUserRecord.mHandler.sendMessage( obtainMessage(UserHandler::requestCreateSessionOnHandler, @@ -915,9 +925,6 @@ class MediaRouter2ServiceImpl { RouterRecord routerRecord = managerRecord.mUserRecord.mHandler .findRouterforSessionLocked(uniqueSessionId); - if (routerRecord == null) { - return; - } long uniqueRequestId = toUniqueRequestId(managerRecord.mManagerId, requestId); managerRecord.mUserRecord.mHandler.sendMessage( @@ -1272,15 +1279,6 @@ class MediaRouter2ServiceImpl { toOriginalRequestId(uniqueRequestId)); return; } - if (route.isSystemRoute() && !routerRecord.mHasModifyAudioRoutingPermission - && !TextUtils.equals(route.getId(), - mSystemProvider.getDefaultRoute().getId())) { - Slog.w(TAG, "MODIFY_AUDIO_ROUTING permission is required to transfer to" - + route); - notifySessionCreationFailedToRouter(routerRecord, - toOriginalRequestId(uniqueRequestId)); - return; - } SessionCreationRequest request = new SessionCreationRequest(routerRecord, uniqueRequestId, route, managerRecord); @@ -1404,11 +1402,11 @@ class MediaRouter2ServiceImpl { } private void releaseSessionOnHandler(long uniqueRequestId, - @NonNull RouterRecord routerRecord, @NonNull String uniqueSessionId) { + @Nullable RouterRecord routerRecord, @NonNull String uniqueSessionId) { final RouterRecord matchingRecord = mSessionToRouterMap.get(uniqueSessionId); if (matchingRecord != routerRecord) { - Slog.w(TAG, "Ignoring releasing session from non-matching router." - + " packageName=" + routerRecord.mPackageName + Slog.w(TAG, "Ignoring releasing session from non-matching router. packageName=" + + (routerRecord == null ? null : routerRecord.mPackageName) + " uniqueSessionId=" + uniqueSessionId); return; } diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java index d8264b36256d..f7d0d4ee16eb 100644 --- a/services/core/java/com/android/server/net/NetworkStatsService.java +++ b/services/core/java/com/android/server/net/NetworkStatsService.java @@ -46,7 +46,6 @@ import static android.net.NetworkStats.UID_ALL; import static android.net.NetworkStatsHistory.FIELD_ALL; import static android.net.NetworkTemplate.buildTemplateMobileWildcard; import static android.net.NetworkTemplate.buildTemplateWifiWildcard; -import static android.net.NetworkTemplate.getCollapsedRatType; import static android.net.TrafficStats.KB_IN_BYTES; import static android.net.TrafficStats.MB_IN_BYTES; import static android.os.Trace.TRACE_TAG_NETWORK; @@ -67,9 +66,6 @@ import static android.provider.Settings.Global.NETSTATS_UID_TAG_BUCKET_DURATION; import static android.provider.Settings.Global.NETSTATS_UID_TAG_DELETE_AGE; import static android.provider.Settings.Global.NETSTATS_UID_TAG_PERSIST_BYTES; import static android.provider.Settings.Global.NETSTATS_UID_TAG_ROTATE_AGE; -import static android.telephony.PhoneStateListener.LISTEN_NONE; -import static android.telephony.PhoneStateListener.LISTEN_SERVICE_STATE; -import static android.telephony.TelephonyManager.NETWORK_TYPE_UNKNOWN; import static android.text.format.DateUtils.DAY_IN_MILLIS; import static android.text.format.DateUtils.HOUR_IN_MILLIS; import static android.text.format.DateUtils.MINUTE_IN_MILLIS; @@ -133,9 +129,7 @@ import android.provider.Settings.Global; import android.service.NetworkInterfaceProto; import android.service.NetworkStatsServiceDumpProto; import android.telephony.PhoneStateListener; -import android.telephony.ServiceState; import android.telephony.SubscriptionPlan; -import android.telephony.TelephonyManager; import android.text.format.DateUtils; import android.util.ArrayMap; import android.util.ArraySet; @@ -206,7 +200,6 @@ public class NetworkStatsService extends INetworkStatsService.Stub { private final NetworkStatsFactory mStatsFactory; private final AlarmManager mAlarmManager; private final Clock mClock; - private final TelephonyManager mTeleManager; private final NetworkStatsSettings mSettings; private final NetworkStatsObservers mStatsObservers; @@ -352,6 +345,9 @@ public class NetworkStatsService extends INetworkStatsService.Stub { @NonNull private final Dependencies mDeps; + @NonNull + private final NetworkStatsSubscriptionsMonitor mNetworkStatsSubscriptionsMonitor; + private static @NonNull File getDefaultSystemDir() { return new File(Environment.getDataDirectory(), "system"); } @@ -401,8 +397,8 @@ public class NetworkStatsService extends INetworkStatsService.Stub { PowerManager.WakeLock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG); - NetworkStatsService service = new NetworkStatsService(context, networkManager, alarmManager, - wakeLock, getDefaultClock(), context.getSystemService(TelephonyManager.class), + final NetworkStatsService service = new NetworkStatsService(context, networkManager, + alarmManager, wakeLock, getDefaultClock(), new DefaultNetworkStatsSettings(context), new NetworkStatsFactory(), new NetworkStatsObservers(), getDefaultSystemDir(), getDefaultBaseDir(), new Dependencies()); @@ -416,16 +412,15 @@ public class NetworkStatsService extends INetworkStatsService.Stub { @VisibleForTesting NetworkStatsService(Context context, INetworkManagementService networkManager, AlarmManager alarmManager, PowerManager.WakeLock wakeLock, Clock clock, - TelephonyManager teleManager, NetworkStatsSettings settings, - NetworkStatsFactory factory, NetworkStatsObservers statsObservers, File systemDir, - File baseDir, @NonNull Dependencies deps) { + NetworkStatsSettings settings, NetworkStatsFactory factory, + NetworkStatsObservers statsObservers, File systemDir, File baseDir, + @NonNull Dependencies deps) { mContext = Objects.requireNonNull(context, "missing Context"); mNetworkManager = Objects.requireNonNull(networkManager, - "missing INetworkManagementService"); + "missing INetworkManagementService"); mAlarmManager = Objects.requireNonNull(alarmManager, "missing AlarmManager"); mClock = Objects.requireNonNull(clock, "missing Clock"); mSettings = Objects.requireNonNull(settings, "missing NetworkStatsSettings"); - mTeleManager = Objects.requireNonNull(teleManager, "missing TelephonyManager"); mWakeLock = Objects.requireNonNull(wakeLock, "missing WakeLock"); mStatsFactory = Objects.requireNonNull(factory, "missing factory"); mStatsObservers = Objects.requireNonNull(statsObservers, "missing NetworkStatsObservers"); @@ -437,7 +432,8 @@ public class NetworkStatsService extends INetworkStatsService.Stub { final HandlerThread handlerThread = mDeps.makeHandlerThread(); handlerThread.start(); mHandler = new NetworkStatsHandler(handlerThread.getLooper()); - mPhoneListener = new NetworkTypeListener(new HandlerExecutor(mHandler)); + mNetworkStatsSubscriptionsMonitor = deps.makeSubscriptionsMonitor(mContext, + new HandlerExecutor(mHandler), this); } /** @@ -453,6 +449,19 @@ public class NetworkStatsService extends INetworkStatsService.Stub { public HandlerThread makeHandlerThread() { return new HandlerThread(TAG); } + + /** + * Create a {@link NetworkStatsSubscriptionsMonitor}, can be used to monitor RAT change + * event in NetworkStatsService. + */ + @NonNull + public NetworkStatsSubscriptionsMonitor makeSubscriptionsMonitor(@NonNull Context context, + @NonNull Executor executor, @NonNull NetworkStatsService service) { + // TODO: Update RatType passively in NSS, instead of querying into the monitor + // when forceUpdateIface. + return new NetworkStatsSubscriptionsMonitor(context, executor, (subscriberId, type) -> + service.handleOnCollapsedRatTypeChanged()); + } } private void registerLocalService() { @@ -517,11 +526,10 @@ public class NetworkStatsService extends INetworkStatsService.Stub { mAlarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME, currentRealtime, mSettings.getPollInterval(), pollIntent); - // TODO: 1. listen to changes from all subscriptions. - // 2. listen to settings changed to support dynamically enable/disable. + // TODO: listen to settings changed to support dynamically enable/disable. // watch for networkType changes if (!mSettings.getCombineSubtypeEnabled()) { - mTeleManager.listen(mPhoneListener, LISTEN_SERVICE_STATE); + mNetworkStatsSubscriptionsMonitor.start(); } registerGlobalAlert(); @@ -544,7 +552,9 @@ public class NetworkStatsService extends INetworkStatsService.Stub { mContext.unregisterReceiver(mUserReceiver); mContext.unregisterReceiver(mShutdownReceiver); - mTeleManager.listen(mPhoneListener, LISTEN_NONE); + if (!mSettings.getCombineSubtypeEnabled()) { + mNetworkStatsSubscriptionsMonitor.stop(); + } final long currentTime = mClock.millis(); @@ -1197,35 +1207,14 @@ public class NetworkStatsService extends INetworkStatsService.Stub { }; /** - * Receiver that watches for {@link TelephonyManager} changes, such as - * transitioning between Radio Access Technology(RAT) types. + * Handle collapsed RAT type changed event. */ - @NonNull - private final NetworkTypeListener mPhoneListener; - - class NetworkTypeListener extends PhoneStateListener { - private volatile int mLastCollapsedRatType = NETWORK_TYPE_UNKNOWN; - - NetworkTypeListener(@NonNull Executor executor) { - super(executor); - } - - @Override - public void onServiceStateChanged(@NonNull ServiceState ss) { - final int networkType = ss.getDataNetworkType(); - final int collapsedRatType = getCollapsedRatType(networkType); - if (collapsedRatType == mLastCollapsedRatType) return; - - if (LOGD) { - Log.d(TAG, "subtype changed for mobile: " - + mLastCollapsedRatType + " -> " + collapsedRatType); - } - // Protect service from frequently updating. Remove pending messages if any. - mHandler.removeMessages(MSG_UPDATE_IFACES); - mLastCollapsedRatType = collapsedRatType; - mHandler.sendMessageDelayed( - mHandler.obtainMessage(MSG_UPDATE_IFACES), mSettings.getPollDelay()); - } + @VisibleForTesting + public void handleOnCollapsedRatTypeChanged() { + // Protect service from frequently updating. Remove pending messages if any. + mHandler.removeMessages(MSG_UPDATE_IFACES); + mHandler.sendMessageDelayed( + mHandler.obtainMessage(MSG_UPDATE_IFACES), mSettings.getPollDelay()); } private void updateIfaces( @@ -1352,8 +1341,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { return 0; } - // TODO: return different subType for different subscriptions. - return mPhoneListener.mLastCollapsedRatType; + return mNetworkStatsSubscriptionsMonitor.getRatTypeForSubscriberId(state.subscriberId); } private static <K> NetworkIdentitySet findOrCreateNetworkIdentitySet( diff --git a/services/core/java/com/android/server/notification/BubbleExtractor.java b/services/core/java/com/android/server/notification/BubbleExtractor.java index 2fa80cd8e4e4..27802ffc013d 100644 --- a/services/core/java/com/android/server/notification/BubbleExtractor.java +++ b/services/core/java/com/android/server/notification/BubbleExtractor.java @@ -16,12 +16,18 @@ package com.android.server.notification; import static android.app.Notification.FLAG_BUBBLE; +import static android.app.Notification.FLAG_FOREGROUND_SERVICE; +import static android.app.NotificationChannel.USER_LOCKED_ALLOW_BUBBLE; +import static android.app.NotificationManager.BUBBLE_PREFERENCE_ALL; +import static android.app.NotificationManager.BUBBLE_PREFERENCE_NONE; +import static android.app.NotificationManager.BUBBLE_PREFERENCE_SELECTED; import static com.android.internal.util.FrameworkStatsLog.BUBBLE_DEVELOPER_ERROR_REPORTED__ERROR__ACTIVITY_INFO_MISSING; import static com.android.internal.util.FrameworkStatsLog.BUBBLE_DEVELOPER_ERROR_REPORTED__ERROR__ACTIVITY_INFO_NOT_RESIZABLE; import android.app.ActivityManager; import android.app.Notification; +import android.app.NotificationChannel; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; @@ -32,13 +38,13 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.FrameworkStatsLog; /** - * Determines whether a bubble can be shown for this notification + * Determines whether a bubble can be shown for this notification. */ public class BubbleExtractor implements NotificationSignalExtractor { private static final String TAG = "BubbleExtractor"; private static final boolean DBG = false; - private BubbleChecker mBubbleChecker; + private ShortcutHelper mShortcutHelper; private RankingConfig mConfig; private ActivityManager mActivityManager; private Context mContext; @@ -60,24 +66,35 @@ public class BubbleExtractor implements NotificationSignalExtractor { return null; } - if (mBubbleChecker == null) { - if (DBG) Slog.d(TAG, "missing bubble checker"); + if (mShortcutHelper == null) { + if (DBG) Slog.d(TAG, "missing shortcut helper"); return null; } - boolean appCanShowBubble = - mConfig.areBubblesAllowed(record.getSbn().getPackageName(), record.getSbn().getUid()); - if (!mConfig.bubblesEnabled() || !appCanShowBubble) { + int bubblePreference = + mConfig.getBubblePreference( + record.getSbn().getPackageName(), record.getSbn().getUid()); + NotificationChannel recordChannel = record.getChannel(); + + if (!mConfig.bubblesEnabled() || bubblePreference == BUBBLE_PREFERENCE_NONE) { record.setAllowBubble(false); - } else { - if (record.getChannel() != null) { - record.setAllowBubble(record.getChannel().canBubble() && appCanShowBubble); - } else { - record.setAllowBubble(appCanShowBubble); - } + } else if (recordChannel == null) { + // the app is allowed but there's no channel to check + record.setAllowBubble(true); + } else if (bubblePreference == BUBBLE_PREFERENCE_ALL) { + // by default the channel is not allowed, only don't bubble if the user specified + boolean userLockedNoBubbles = !recordChannel.canBubble() + && (recordChannel.getUserLockedFields() & USER_LOCKED_ALLOW_BUBBLE) != 0; + record.setAllowBubble(!userLockedNoBubbles); + } else if (bubblePreference == BUBBLE_PREFERENCE_SELECTED) { + record.setAllowBubble(recordChannel.canBubble()); } - final boolean applyFlag = mBubbleChecker.isNotificationAppropriateToBubble(record) - && !record.isFlagBubbleRemoved(); + + final boolean fulfillsPolicy = record.canBubble() + && record.isConversation() + && !mActivityManager.isLowRamDevice() + && (record.getNotification().flags & FLAG_FOREGROUND_SERVICE) == 0; + final boolean applyFlag = fulfillsPolicy && canPresentAsBubble(record); if (applyFlag) { record.getNotification().flags |= FLAG_BUBBLE; } else { @@ -95,165 +112,95 @@ public class BubbleExtractor implements NotificationSignalExtractor { public void setZenHelper(ZenModeHelper helper) { } - /** - * Expected to be called after {@link #setConfig(RankingConfig)} has occurred. - */ - void setShortcutHelper(ShortcutHelper helper) { - if (mConfig == null) { - if (DBG) Slog.d(TAG, "setting shortcut helper prior to setConfig"); - return; - } - mBubbleChecker = new BubbleChecker(mContext, helper, mConfig, mActivityManager); + public void setShortcutHelper(ShortcutHelper helper) { + mShortcutHelper = helper; } @VisibleForTesting - void setBubbleChecker(BubbleChecker checker) { - mBubbleChecker = checker; + public void setActivityManager(ActivityManager manager) { + mActivityManager = manager; } /** - * Encapsulates special checks to see if a notification can be flagged as a bubble. This - * makes testing a bit easier. + * @return whether there is valid information for the notification to bubble. */ - public static class BubbleChecker { - - private ActivityManager mActivityManager; - private RankingConfig mRankingConfig; - private Context mContext; - private ShortcutHelper mShortcutHelper; - - BubbleChecker(Context context, ShortcutHelper helper, RankingConfig config, - ActivityManager activityManager) { - mContext = context; - mActivityManager = activityManager; - mShortcutHelper = helper; - mRankingConfig = config; + @VisibleForTesting + boolean canPresentAsBubble(NotificationRecord r) { + Notification notification = r.getNotification(); + Notification.BubbleMetadata metadata = notification.getBubbleMetadata(); + String pkg = r.getSbn().getPackageName(); + if (metadata == null) { + return false; } - /** - * @return whether the provided notification record is allowed to be represented as a - * bubble, accounting for user choice & policy. - */ - public boolean isNotificationAppropriateToBubble(NotificationRecord r) { - final String pkg = r.getSbn().getPackageName(); - final int userId = r.getSbn().getUser().getIdentifier(); - Notification notification = r.getNotification(); - if (!canBubble(r, pkg, userId)) { - // no log: canBubble has its own - return false; - } - - if (mActivityManager.isLowRamDevice()) { - logBubbleError(r.getKey(), "low ram device"); - return false; - } - - boolean isMessageStyle = Notification.MessagingStyle.class.equals( - notification.getNotificationStyle()); - if (!isMessageStyle) { - logBubbleError(r.getKey(), "must be Notification.MessageStyle"); - return false; - } + String shortcutId = metadata.getShortcutId(); + String notificationShortcutId = r.getShortcutInfo() != null + ? r.getShortcutInfo().getId() + : null; + boolean shortcutValid = false; + if (notificationShortcutId != null && shortcutId != null) { + // NoMan already checks validity of shortcut, just check if they match. + shortcutValid = shortcutId.equals(notificationShortcutId); + } else if (shortcutId != null) { + shortcutValid = + mShortcutHelper.getValidShortcutInfo(shortcutId, pkg, r.getUser()) != null; + } + if (metadata.getIntent() == null && !shortcutValid) { + // Should have a shortcut if intent is null + logBubbleError(r.getKey(), + "couldn't find valid shortcut for bubble with shortcutId: " + shortcutId); + return false; + } + if (shortcutValid) { + // TODO: check the shortcut intent / ensure it can show in activity view return true; } + return canLaunchInActivityView(mContext, metadata.getIntent(), pkg); + } - /** - * @return whether the user has enabled the provided notification to bubble, and if the - * developer has provided valid information for the notification to bubble. - */ - @VisibleForTesting - boolean canBubble(NotificationRecord r, String pkg, int userId) { - Notification notification = r.getNotification(); - Notification.BubbleMetadata metadata = notification.getBubbleMetadata(); - if (metadata == null) { - // no log: no need to inform dev if they didn't attach bubble metadata - return false; - } - if (!mRankingConfig.bubblesEnabled()) { - logBubbleError(r.getKey(), "bubbles disabled for user: " + userId); - return false; - } - if (!mRankingConfig.areBubblesAllowed(pkg, userId)) { - logBubbleError(r.getKey(), - "bubbles for package: " + pkg + " disabled for user: " + userId); - return false; - } - if (!r.getChannel().canBubble()) { - logBubbleError(r.getKey(), - "bubbles for channel " + r.getChannel().getId() + " disabled"); - return false; - } - - String shortcutId = metadata.getShortcutId(); - String notificationShortcutId = r.getShortcutInfo() != null - ? r.getShortcutInfo().getId() - : null; - boolean shortcutValid = false; - if (notificationShortcutId != null && shortcutId != null) { - // NoMan already checks validity of shortcut, just check if they match. - shortcutValid = shortcutId.equals(notificationShortcutId); - } else if (shortcutId != null) { - shortcutValid = - mShortcutHelper.getValidShortcutInfo(shortcutId, pkg, r.getUser()) != null; - } - if (metadata.getIntent() == null && !shortcutValid) { - // Should have a shortcut if intent is null - logBubbleError(r.getKey(), - "couldn't find valid shortcut for bubble with shortcutId: " + shortcutId); - return false; - } - if (shortcutValid) { - return true; - } - // no log: canLaunch method has the failure log - return canLaunchInActivityView(mContext, metadata.getIntent(), pkg); + /** + * Whether an intent is properly configured to display in an {@link + * android.app.ActivityView} for bubbling. + * + * @param context the context to use. + * @param pendingIntent the pending intent of the bubble. + * @param packageName the notification package name for this bubble. + */ + // Keep checks in sync with BubbleController#canLaunchInActivityView. + @VisibleForTesting + protected boolean canLaunchInActivityView(Context context, PendingIntent pendingIntent, + String packageName) { + if (pendingIntent == null) { + Slog.w(TAG, "Unable to create bubble -- no intent"); + return false; } - /** - * Whether an intent is properly configured to display in an {@link - * android.app.ActivityView}. - * - * @param context the context to use. - * @param pendingIntent the pending intent of the bubble. - * @param packageName the notification package name for this bubble. - */ - // Keep checks in sync with BubbleController#canLaunchInActivityView. - @VisibleForTesting - protected boolean canLaunchInActivityView(Context context, PendingIntent pendingIntent, - String packageName) { - if (pendingIntent == null) { - Slog.w(TAG, "Unable to create bubble -- no intent"); - return false; - } - - Intent intent = pendingIntent.getIntent(); - - ActivityInfo info = intent != null - ? intent.resolveActivityInfo(context.getPackageManager(), 0) - : null; - if (info == null) { - FrameworkStatsLog.write(FrameworkStatsLog.BUBBLE_DEVELOPER_ERROR_REPORTED, - packageName, - BUBBLE_DEVELOPER_ERROR_REPORTED__ERROR__ACTIVITY_INFO_MISSING); - Slog.w(TAG, "Unable to send as bubble -- couldn't find activity info for intent: " - + intent); - return false; - } - if (!ActivityInfo.isResizeableMode(info.resizeMode)) { - FrameworkStatsLog.write(FrameworkStatsLog.BUBBLE_DEVELOPER_ERROR_REPORTED, - packageName, - BUBBLE_DEVELOPER_ERROR_REPORTED__ERROR__ACTIVITY_INFO_NOT_RESIZABLE); - Slog.w(TAG, "Unable to send as bubble -- activity is not resizable for intent: " - + intent); - return false; - } - return true; + Intent intent = pendingIntent.getIntent(); + ActivityInfo info = intent != null + ? intent.resolveActivityInfo(context.getPackageManager(), 0) + : null; + if (info == null) { + FrameworkStatsLog.write(FrameworkStatsLog.BUBBLE_DEVELOPER_ERROR_REPORTED, + packageName, + BUBBLE_DEVELOPER_ERROR_REPORTED__ERROR__ACTIVITY_INFO_MISSING); + Slog.w(TAG, "Unable to send as bubble -- couldn't find activity info for intent: " + + intent); + return false; + } + if (!ActivityInfo.isResizeableMode(info.resizeMode)) { + FrameworkStatsLog.write(FrameworkStatsLog.BUBBLE_DEVELOPER_ERROR_REPORTED, + packageName, + BUBBLE_DEVELOPER_ERROR_REPORTED__ERROR__ACTIVITY_INFO_NOT_RESIZABLE); + Slog.w(TAG, "Unable to send as bubble -- activity is not resizable for intent: " + + intent); + return false; } + return true; + } - private void logBubbleError(String key, String failureMessage) { - if (DBG) { - Slog.w(TAG, "Bubble notification: " + key + " failed: " + failureMessage); - } + private void logBubbleError(String key, String failureMessage) { + if (DBG) { + Slog.w(TAG, "Bubble notification: " + key + " failed: " + failureMessage); } } } diff --git a/services/core/java/com/android/server/notification/NotificationDelegate.java b/services/core/java/com/android/server/notification/NotificationDelegate.java index b8140be2e266..1051423ea17f 100644 --- a/services/core/java/com/android/server/notification/NotificationDelegate.java +++ b/services/core/java/com/android/server/notification/NotificationDelegate.java @@ -51,7 +51,7 @@ public interface NotificationDelegate { /** * Called when the state of {@link Notification#FLAG_BUBBLE} is changed. */ - void onNotificationBubbleChanged(String key, boolean isBubble); + void onNotificationBubbleChanged(String key, boolean isBubble, int flags); /** * Called when the state of {@link Notification.BubbleMetadata#FLAG_SUPPRESS_NOTIFICATION} * changes. diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index f9fc82bf05b1..8eb41adc1585 100755 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -32,6 +32,7 @@ import static android.app.NotificationManager.ACTION_INTERRUPTION_FILTER_CHANGED import static android.app.NotificationManager.ACTION_NOTIFICATION_CHANNEL_BLOCK_STATE_CHANGED; import static android.app.NotificationManager.ACTION_NOTIFICATION_CHANNEL_GROUP_BLOCK_STATE_CHANGED; import static android.app.NotificationManager.ACTION_NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED; +import static android.app.NotificationManager.BUBBLE_PREFERENCE_ALL; import static android.app.NotificationManager.EXTRA_AUTOMATIC_ZEN_RULE_ID; import static android.app.NotificationManager.EXTRA_AUTOMATIC_ZEN_RULE_STATUS; import static android.app.NotificationManager.IMPORTANCE_LOW; @@ -107,6 +108,7 @@ import android.annotation.CallbackExecutor; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresPermission; +import android.annotation.UserIdInt; import android.annotation.WorkerThread; import android.app.ActivityManager; import android.app.ActivityManagerInternal; @@ -155,6 +157,7 @@ import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.PackageManagerInternal; import android.content.pm.ParceledListSlice; import android.content.pm.ShortcutInfo; +import android.content.pm.ShortcutServiceInternal; import android.content.pm.UserInfo; import android.content.res.Resources; import android.database.ContentObserver; @@ -219,6 +222,7 @@ import android.util.Log; import android.util.Pair; import android.util.Slog; import android.util.SparseArray; +import android.util.SparseArrayMap; import android.util.StatsEvent; import android.util.Xml; import android.util.proto.ProtoOutputStream; @@ -290,6 +294,7 @@ import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; +import java.util.LinkedList; import java.util.List; import java.util.Map.Entry; import java.util.Objects; @@ -527,13 +532,15 @@ public class NotificationManagerService extends SystemService { private NotificationRecordLogger mNotificationRecordLogger; private InstanceIdSequence mNotificationInstanceIdSequence; - private static class Archive { + static class Archive { + final SparseArray<Boolean> mEnabled; final int mBufferSize; - final ArrayDeque<Pair<StatusBarNotification, Integer>> mBuffer; + final LinkedList<Pair<StatusBarNotification, Integer>> mBuffer; public Archive(int size) { mBufferSize = size; - mBuffer = new ArrayDeque<>(mBufferSize); + mBuffer = new LinkedList<>(); + mEnabled = new SparseArray<>(); } public String toString() { @@ -546,7 +553,10 @@ public class NotificationManagerService extends SystemService { return sb.toString(); } - public void record(StatusBarNotification nr, int reason) { + public void record(StatusBarNotification sbn, int reason) { + if (!mEnabled.get(sbn.getNormalizedUserId(), false)) { + return; + } if (mBuffer.size() == mBufferSize) { mBuffer.removeFirst(); } @@ -554,7 +564,7 @@ public class NotificationManagerService extends SystemService { // We don't want to store the heavy bits of the notification in the archive, // but other clients in the system process might be using the object, so we // store a (lightened) copy. - mBuffer.addLast(new Pair<>(nr.cloneLight(), reason)); + mBuffer.addLast(new Pair<>(sbn.cloneLight(), reason)); } public Iterator<Pair<StatusBarNotification, Integer>> descendingIterator() { @@ -576,6 +586,17 @@ public class NotificationManagerService extends SystemService { return a.toArray(new StatusBarNotification[a.size()]); } + public void updateHistoryEnabled(@UserIdInt int userId, boolean enabled) { + mEnabled.put(userId, enabled); + + if (!enabled) { + for (int i = mBuffer.size() - 1; i >= 0; i--) { + if (userId == mBuffer.get(i).first.getNormalizedUserId()) { + mBuffer.remove(i); + } + } + } + } } void loadDefaultApprovedServices(int userId) { @@ -1195,14 +1216,7 @@ public class NotificationManagerService extends SystemService { } @Override - public void onNotificationBubbleChanged(String key, boolean isBubble) { - String pkg; - synchronized (mNotificationLock) { - NotificationRecord r = mNotificationsByKey.get(key); - pkg = r != null && r.getSbn() != null ? r.getSbn().getPackageName() : null; - } - boolean isAppForeground = pkg != null - && mActivityManager.getPackageImportance(pkg) == IMPORTANCE_FOREGROUND; + public void onNotificationBubbleChanged(String key, boolean isBubble, int flags) { synchronized (mNotificationLock) { NotificationRecord r = mNotificationsByKey.get(key); if (r != null) { @@ -1219,8 +1233,13 @@ public class NotificationManagerService extends SystemService { // be applied there. r.getNotification().flags |= FLAG_ONLY_ALERT_ONCE; r.setFlagBubbleRemoved(false); + if (r.getNotification().getBubbleMetadata() != null) { + r.getNotification().getBubbleMetadata().setFlags(flags); + } + // Force isAppForeground true here, because for sysui's purposes we + // want to adjust the flag behaviour. mHandler.post(new EnqueueNotificationRunnable(r.getUser().getIdentifier(), - r, isAppForeground)); + r, true /* isAppForeground*/)); } } } @@ -1639,6 +1658,9 @@ public class NotificationManagerService extends SystemService { = Settings.System.getUriFor(Settings.System.NOTIFICATION_LIGHT_PULSE); private final Uri NOTIFICATION_RATE_LIMIT_URI = Settings.Global.getUriFor(Settings.Global.MAX_NOTIFICATION_ENQUEUE_RATE); + private final Uri NOTIFICATION_HISTORY_ENABLED + = Settings.Secure.getUriFor(Settings.Secure.NOTIFICATION_HISTORY_ENABLED); + SettingsObserver(Handler handler) { super(handler); @@ -1654,10 +1676,12 @@ public class NotificationManagerService extends SystemService { false, this, UserHandle.USER_ALL); resolver.registerContentObserver(NOTIFICATION_BUBBLES_URI, false, this, UserHandle.USER_ALL); + resolver.registerContentObserver(NOTIFICATION_HISTORY_ENABLED, + false, this, UserHandle.USER_ALL); update(null); } - @Override public void onChange(boolean selfChange, Uri uri) { + @Override public void onChange(boolean selfChange, Uri uri, int userId) { update(uri); } @@ -1682,6 +1706,14 @@ public class NotificationManagerService extends SystemService { if (uri == null || NOTIFICATION_BUBBLES_URI.equals(uri)) { mPreferencesHelper.updateBubblesEnabled(); } + if (uri == null || NOTIFICATION_HISTORY_ENABLED.equals(uri)) { + final IntArray userIds = mUserProfiles.getCurrentProfileIds(); + + for (int i = 0; i < userIds.size(); i++) { + mArchive.updateHistoryEnabled(userIds.get(i), Settings.Secure.getInt(resolver, + Settings.Secure.NOTIFICATION_HISTORY_ENABLED, 0) == 1); + } + } } } @@ -1960,7 +1992,8 @@ public class NotificationManagerService extends SystemService { mPackageManagerClient, mRankingHandler, mZenModeHelper, - new NotificationChannelLoggerImpl()); + new NotificationChannelLoggerImpl(), + mAppOps); mRankingHelper = new RankingHelper(getContext(), mRankingHandler, mPreferencesHelper, @@ -2301,7 +2334,8 @@ public class NotificationManagerService extends SystemService { mRoleObserver.init(); LauncherApps launcherApps = (LauncherApps) getContext().getSystemService(Context.LAUNCHER_APPS_SERVICE); - mShortcutHelper = new ShortcutHelper(launcherApps, mShortcutListener); + mShortcutHelper = new ShortcutHelper(launcherApps, mShortcutListener, getLocalService( + ShortcutServiceInternal.class)); BubbleExtractor bubbsExtractor = mRankingHelper.findExtractor(BubbleExtractor.class); if (bubbsExtractor != null) { bubbsExtractor.setShortcutHelper(mShortcutHelper); @@ -3079,40 +3113,37 @@ public class NotificationManagerService extends SystemService { return mPreferencesHelper.getImportance(pkg, uid) != IMPORTANCE_NONE; } + /** + * @return true if and only if "all" bubbles are allowed from the provided package. + */ @Override public boolean areBubblesAllowed(String pkg) { - return areBubblesAllowedForPackage(pkg, Binder.getCallingUid()); + return getBubblePreferenceForPackage(pkg, Binder.getCallingUid()) + == BUBBLE_PREFERENCE_ALL; } @Override - public boolean areBubblesAllowedForPackage(String pkg, int uid) { + public int getBubblePreferenceForPackage(String pkg, int uid) { enforceSystemOrSystemUIOrSamePackage(pkg, "Caller not system or systemui or same package"); if (UserHandle.getCallingUserId() != UserHandle.getUserId(uid)) { getContext().enforceCallingPermission( android.Manifest.permission.INTERACT_ACROSS_USERS, - "canNotifyAsPackage for uid " + uid); + "getBubblePreferenceForPackage for uid " + uid); } - return mPreferencesHelper.areBubblesAllowed(pkg, uid); + return mPreferencesHelper.getBubblePreference(pkg, uid); } @Override - public void setBubblesAllowed(String pkg, int uid, boolean allowed) { - enforceSystemOrSystemUI("Caller not system or systemui"); - mPreferencesHelper.setBubblesAllowed(pkg, uid, allowed); + public void setBubblesAllowed(String pkg, int uid, int bubblePreference) { + checkCallerIsSystemOrSystemUiOrShell("Caller not system or sysui or shell"); + mPreferencesHelper.setBubblesAllowed(pkg, uid, bubblePreference); handleSavePolicyFile(); } @Override - public boolean hasUserApprovedBubblesForPackage(String pkg, int uid) { - enforceSystemOrSystemUI("Caller not system or systemui"); - int lockedFields = mPreferencesHelper.getAppLockedFields(pkg, uid); - return (lockedFields & PreferencesHelper.LockableAppFields.USER_LOCKED_BUBBLE) != 0; - } - - @Override public boolean shouldHideSilentStatusIcons(String callingPkg) { checkCallerIsSameApp(callingPkg); @@ -3308,7 +3339,7 @@ public class NotificationManagerService extends SystemService { String targetPkg, String channelId, boolean returnParentIfNoConversationChannel, String conversationId) { if (canNotifyAsPackage(callingPkg, targetPkg, userId) - || isCallerIsSystemOrSystemUi()) { + || isCallerIsSystemOrSysemUiOrShell()) { int targetUid = -1; try { targetUid = mPackageManagerClient.getPackageUidAsUser(targetPkg, userId); @@ -3418,7 +3449,7 @@ public class NotificationManagerService extends SystemService { @Override public void updateNotificationChannelForPackage(String pkg, int uid, NotificationChannel channel) { - enforceSystemOrSystemUI("Caller not system or systemui"); + checkCallerIsSystemOrSystemUiOrShell("Caller not system or sysui or shell"); Objects.requireNonNull(channel); updateNotificationChannelInt(pkg, uid, channel, false); } @@ -5848,6 +5879,7 @@ public class NotificationManagerService extends SystemService { synchronized (mNotificationLock) { NotificationRecord r = mNotificationsByKey.get(key); if (r != null) { + r.setShortcutInfo(null); // Enqueue will trigger resort & flag is updated that way. r.getNotification().flags |= FLAG_ONLY_ALERT_ONCE; mHandler.post( @@ -7210,7 +7242,10 @@ public class NotificationManagerService extends SystemService { boolean interruptiveChanged = record.canBubble() && (interruptiveBefore != record.isInterruptive()); - changed = indexChanged || interceptChanged || visibilityChanged || interruptiveChanged; + changed = indexChanged + || interceptChanged + || visibilityChanged + || interruptiveChanged; if (interceptBefore && !record.isIntercepted() && record.isNewEnoughForAlerting(System.currentTimeMillis())) { buzzBeepBlinkLocked(record); @@ -8248,6 +8283,14 @@ public class NotificationManagerService extends SystemService { == PERMISSION_GRANTED; } + private boolean isCallerIsSystemOrSysemUiOrShell() { + int callingUid = Binder.getCallingUid(); + if (callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID) { + return true; + } + return isCallerIsSystemOrSystemUi(); + } + private void checkCallerIsSystemOrShell() { int callingUid = Binder.getCallingUid(); if (callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID) { @@ -8264,6 +8307,10 @@ public class NotificationManagerService extends SystemService { } private void checkCallerIsSystemOrSystemUiOrShell() { + checkCallerIsSystemOrSystemUiOrShell(null); + } + + private void checkCallerIsSystemOrSystemUiOrShell(String message) { int callingUid = Binder.getCallingUid(); if (callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID) { return; @@ -8271,7 +8318,8 @@ public class NotificationManagerService extends SystemService { if (isCallerSystemOrPhone()) { return; } - getContext().enforceCallingPermission(android.Manifest.permission.STATUS_BAR_SERVICE, null); + getContext().enforceCallingPermission(android.Manifest.permission.STATUS_BAR_SERVICE, + message); } private void checkCallerIsSystemOrSameApp(String pkg) { diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java index 192df4139b37..2bbbffc203f4 100644 --- a/services/core/java/com/android/server/notification/NotificationRecord.java +++ b/services/core/java/com/android/server/notification/NotificationRecord.java @@ -590,6 +590,8 @@ public final class NotificationRecord { pw.println(prefix + "snoozeCriteria=" + TextUtils.join(",", getSnoozeCriteria())); } pw.println(prefix + "mAdjustments=" + mAdjustments); + pw.println(prefix + "shortcut=" + notification.getShortcutId() + + " found valid? " + (mShortcutInfo != null)); } @Override diff --git a/services/core/java/com/android/server/notification/NotificationShellCmd.java b/services/core/java/com/android/server/notification/NotificationShellCmd.java index 2b5ba2528429..e4a17740b0b7 100644 --- a/services/core/java/com/android/server/notification/NotificationShellCmd.java +++ b/services/core/java/com/android/server/notification/NotificationShellCmd.java @@ -38,7 +38,6 @@ import android.content.res.Resources; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.graphics.drawable.Icon; -import android.media.IRingtonePlayer; import android.net.Uri; import android.os.Binder; import android.os.Process; @@ -48,8 +47,6 @@ import android.os.UserHandle; import android.text.TextUtils; import android.util.Slog; -import com.android.internal.util.FunctionalUtils; - import java.io.PrintWriter; import java.net.URISyntaxException; import java.util.Collections; @@ -72,7 +69,11 @@ public class NotificationShellCmd extends ShellCommand { + " unsuspend_package PACKAGE\n" + " reset_assistant_user_set [user_id (current user if not specified)]\n" + " get_approved_assistant [user_id (current user if not specified)]\n" - + " post [--help | flags] TAG TEXT"; + + " post [--help | flags] TAG TEXT\n" + + " set_bubbles PACKAGE PREFERENCE (0=none 1=all 2=selected) " + + "[user_id (current user if not specified)]\n" + + " set_bubbles_channel PACKAGE CHANNEL_ID ALLOW " + + "[user_id (current user if not specified)]\n"; private static final String NOTIFY_USAGE = "usage: cmd notification post [flags] <tag> <text>\n\n" @@ -109,6 +110,7 @@ public class NotificationShellCmd extends ShellCommand { private final NotificationManagerService mDirectService; private final INotificationManager mBinderService; private final PackageManager mPm; + private NotificationChannel mChannel; public NotificationShellCmd(NotificationManagerService service) { mDirectService = service; @@ -276,6 +278,40 @@ public class NotificationShellCmd extends ShellCommand { } break; } + case "set_bubbles": { + // only use for testing + String packageName = getNextArgRequired(); + int preference = Integer.parseInt(getNextArgRequired()); + if (preference > 3 || preference < 0) { + pw.println("Invalid preference - must be between 0-3 " + + "(0=none 1=all 2=selected)"); + return -1; + } + int userId = ActivityManager.getCurrentUser(); + if (peekNextArg() != null) { + userId = Integer.parseInt(getNextArgRequired()); + } + int appUid = UserHandle.getUid(userId, mPm.getPackageUid(packageName, 0)); + mBinderService.setBubblesAllowed(packageName, appUid, preference); + break; + } + case "set_bubbles_channel": { + // only use for testing + String packageName = getNextArgRequired(); + String channelId = getNextArgRequired(); + boolean allow = Boolean.parseBoolean(getNextArgRequired()); + int userId = ActivityManager.getCurrentUser(); + if (peekNextArg() != null) { + userId = Integer.parseInt(getNextArgRequired()); + } + NotificationChannel channel = mBinderService.getNotificationChannel( + callingPackage, userId, packageName, channelId); + channel.setAllowBubbles(allow); + int appUid = UserHandle.getUid(userId, mPm.getPackageUid(packageName, 0)); + mBinderService.updateNotificationChannelForPackage(packageName, appUid, + channel); + break; + } case "post": case "notify": doNotify(pw, callingPackage, callingUid); diff --git a/services/core/java/com/android/server/notification/PreferencesHelper.java b/services/core/java/com/android/server/notification/PreferencesHelper.java index 8154988a4917..d432fc83b52a 100644 --- a/services/core/java/com/android/server/notification/PreferencesHelper.java +++ b/services/core/java/com/android/server/notification/PreferencesHelper.java @@ -16,7 +16,10 @@ package com.android.server.notification; +import static android.app.AppOpsManager.OP_SYSTEM_ALERT_WINDOW; import static android.app.NotificationChannel.PLACEHOLDER_CONVERSATION_ID; +import static android.app.NotificationManager.BUBBLE_PREFERENCE_ALL; +import static android.app.NotificationManager.BUBBLE_PREFERENCE_NONE; import static android.app.NotificationManager.IMPORTANCE_NONE; import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED; @@ -29,6 +32,7 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; +import android.app.AppOpsManager; import android.app.Notification; import android.app.NotificationChannel; import android.app.NotificationChannelGroup; @@ -78,7 +82,9 @@ import java.util.concurrent.ConcurrentHashMap; public class PreferencesHelper implements RankingConfig { private static final String TAG = "NotificationPrefHelper"; - private static final int XML_VERSION = 1; + private static final int XML_VERSION = 2; + /** What version to check to do the upgrade for bubbles. */ + private static final int XML_VERSION_BUBBLES_UPGRADE = 1; private static final int UNKNOWN_UID = UserHandle.USER_NULL; private static final String NON_BLOCKABLE_CHANNEL_DELIM = ":"; @@ -117,10 +123,14 @@ public class PreferencesHelper implements RankingConfig { @VisibleForTesting static final boolean DEFAULT_HIDE_SILENT_STATUS_BAR_ICONS = false; private static final boolean DEFAULT_SHOW_BADGE = true; - static final boolean DEFAULT_ALLOW_BUBBLE = true; + private static final boolean DEFAULT_OEM_LOCKED_IMPORTANCE = false; private static final boolean DEFAULT_APP_LOCKED_IMPORTANCE = false; + static final boolean DEFAULT_GLOBAL_ALLOW_BUBBLE = true; + @VisibleForTesting + static final int DEFAULT_BUBBLE_PREFERENCE = BUBBLE_PREFERENCE_NONE; + /** * Default value for what fields are user locked. See {@link LockableAppFields} for all lockable * fields. @@ -146,9 +156,10 @@ public class PreferencesHelper implements RankingConfig { private final RankingHandler mRankingHandler; private final ZenModeHelper mZenModeHelper; private final NotificationChannelLogger mNotificationChannelLogger; + private final AppOpsManager mAppOps; private SparseBooleanArray mBadgingEnabled; - private boolean mBubblesEnabled = DEFAULT_ALLOW_BUBBLE; + private boolean mBubblesEnabledGlobally = DEFAULT_GLOBAL_ALLOW_BUBBLE; private boolean mAreChannelsBypassingDnd; private boolean mHideSilentStatusBarIcons = DEFAULT_HIDE_SILENT_STATUS_BAR_ICONS; @@ -162,12 +173,14 @@ public class PreferencesHelper implements RankingConfig { } public PreferencesHelper(Context context, PackageManager pm, RankingHandler rankingHandler, - ZenModeHelper zenHelper, NotificationChannelLogger notificationChannelLogger) { + ZenModeHelper zenHelper, NotificationChannelLogger notificationChannelLogger, + AppOpsManager appOpsManager) { mContext = context; mZenModeHelper = zenHelper; mRankingHandler = rankingHandler; mPm = pm; mNotificationChannelLogger = notificationChannelLogger; + mAppOps = appOpsManager; // STOPSHIP (b/142218092) this should be removed before ship if (!wasBadgingForcedTrue(context)) { @@ -190,6 +203,15 @@ public class PreferencesHelper implements RankingConfig { if (type != XmlPullParser.START_TAG) return; String tag = parser.getName(); if (!TAG_RANKING.equals(tag)) return; + + boolean upgradeForBubbles = false; + if (parser.getAttributeCount() > 0) { + String attribute = parser.getAttributeName(0); + if (ATT_VERSION.equals(attribute)) { + int xmlVersion = Integer.parseInt(parser.getAttributeValue(0)); + upgradeForBubbles = xmlVersion == XML_VERSION_BUBBLES_UPGRADE; + } + } synchronized (mPackagePreferences) { while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) { tag = parser.getName(); @@ -215,6 +237,16 @@ public class PreferencesHelper implements RankingConfig { } } boolean skipWarningLogged = false; + boolean hasSAWPermission = false; + if (upgradeForBubbles) { + hasSAWPermission = mAppOps.noteOpNoThrow( + OP_SYSTEM_ALERT_WINDOW, uid, name, null, + "check-notif-bubble") == AppOpsManager.MODE_ALLOWED; + } + int bubblePref = hasSAWPermission + ? BUBBLE_PREFERENCE_ALL + : XmlUtils.readIntAttribute(parser, ATT_ALLOW_BUBBLE, + DEFAULT_BUBBLE_PREFERENCE); PackagePreferences r = getOrCreatePackagePreferencesLocked( name, userId, uid, @@ -226,8 +258,7 @@ public class PreferencesHelper implements RankingConfig { parser, ATT_VISIBILITY, DEFAULT_VISIBILITY), XmlUtils.readBooleanAttribute( parser, ATT_SHOW_BADGE, DEFAULT_SHOW_BADGE), - XmlUtils.readBooleanAttribute( - parser, ATT_ALLOW_BUBBLE, DEFAULT_ALLOW_BUBBLE)); + bubblePref); r.importance = XmlUtils.readIntAttribute( parser, ATT_IMPORTANCE, DEFAULT_IMPORTANCE); r.priority = XmlUtils.readIntAttribute( @@ -339,19 +370,19 @@ public class PreferencesHelper implements RankingConfig { int uid) { return getOrCreatePackagePreferencesLocked(pkg, UserHandle.getUserId(uid), uid, DEFAULT_IMPORTANCE, DEFAULT_PRIORITY, DEFAULT_VISIBILITY, DEFAULT_SHOW_BADGE, - DEFAULT_ALLOW_BUBBLE); + DEFAULT_BUBBLE_PREFERENCE); } private PackagePreferences getOrCreatePackagePreferencesLocked(String pkg, @UserIdInt int userId, int uid) { return getOrCreatePackagePreferencesLocked(pkg, userId, uid, DEFAULT_IMPORTANCE, DEFAULT_PRIORITY, DEFAULT_VISIBILITY, DEFAULT_SHOW_BADGE, - DEFAULT_ALLOW_BUBBLE); + DEFAULT_BUBBLE_PREFERENCE); } private PackagePreferences getOrCreatePackagePreferencesLocked(String pkg, @UserIdInt int userId, int uid, int importance, int priority, int visibility, - boolean showBadge, boolean allowBubble) { + boolean showBadge, int bubblePreference) { final String key = packagePreferencesKey(pkg, uid); PackagePreferences r = (uid == UNKNOWN_UID) @@ -365,7 +396,7 @@ public class PreferencesHelper implements RankingConfig { r.priority = priority; r.visibility = visibility; r.showBadge = showBadge; - r.allowBubble = allowBubble; + r.bubblePreference = bubblePreference; try { createDefaultChannelIfNeededLocked(r); @@ -479,7 +510,7 @@ public class PreferencesHelper implements RankingConfig { || r.channels.size() > 0 || r.groups.size() > 0 || r.delegate != null - || r.allowBubble != DEFAULT_ALLOW_BUBBLE; + || r.bubblePreference != DEFAULT_BUBBLE_PREFERENCE; if (hasNonDefaultSettings) { out.startTag(null, TAG_PACKAGE); out.attribute(null, ATT_NAME, r.pkg); @@ -492,8 +523,8 @@ public class PreferencesHelper implements RankingConfig { if (r.visibility != DEFAULT_VISIBILITY) { out.attribute(null, ATT_VISIBILITY, Integer.toString(r.visibility)); } - if (r.allowBubble != DEFAULT_ALLOW_BUBBLE) { - out.attribute(null, ATT_ALLOW_BUBBLE, Boolean.toString(r.allowBubble)); + if (r.bubblePreference != DEFAULT_BUBBLE_PREFERENCE) { + out.attribute(null, ATT_ALLOW_BUBBLE, Integer.toString(r.bubblePreference)); } out.attribute(null, ATT_SHOW_BADGE, Boolean.toString(r.showBadge)); out.attribute(null, ATT_APP_USER_LOCKED_FIELDS, @@ -544,14 +575,14 @@ public class PreferencesHelper implements RankingConfig { * * @param pkg the package to allow or not allow bubbles for. * @param uid the uid to allow or not allow bubbles for. - * @param allowed whether bubbles are allowed. + * @param bubblePreference whether bubbles are allowed. */ - public void setBubblesAllowed(String pkg, int uid, boolean allowed) { + public void setBubblesAllowed(String pkg, int uid, int bubblePreference) { boolean changed = false; synchronized (mPackagePreferences) { PackagePreferences p = getOrCreatePackagePreferencesLocked(pkg, uid); - changed = p.allowBubble != allowed; - p.allowBubble = allowed; + changed = p.bubblePreference != bubblePreference; + p.bubblePreference = bubblePreference; p.lockedAppFields = p.lockedAppFields | LockableAppFields.USER_LOCKED_BUBBLE; } if (changed) { @@ -567,9 +598,9 @@ public class PreferencesHelper implements RankingConfig { * @return whether bubbles are allowed. */ @Override - public boolean areBubblesAllowed(String pkg, int uid) { + public int getBubblePreference(String pkg, int uid) { synchronized (mPackagePreferences) { - return getOrCreatePackagePreferencesLocked(pkg, uid).allowBubble; + return getOrCreatePackagePreferencesLocked(pkg, uid).bubblePreference; } } @@ -788,6 +819,7 @@ public class PreferencesHelper implements RankingConfig { } if (fromTargetApp) { channel.setLockscreenVisibility(r.visibility); + channel.setAllowBubbles(existing != null && existing.canBubble()); } clearLockedFieldsLocked(channel); channel.setImportanceLockedByOEM(r.oemLockedImportance); @@ -2125,7 +2157,7 @@ public class PreferencesHelper implements RankingConfig { p.groups = new ArrayMap<>(); p.delegate = null; p.lockedAppFields = DEFAULT_LOCKED_APP_FIELDS; - p.allowBubble = DEFAULT_ALLOW_BUBBLE; + p.bubblePreference = DEFAULT_BUBBLE_PREFERENCE; p.importance = DEFAULT_IMPORTANCE; p.priority = DEFAULT_PRIORITY; p.visibility = DEFAULT_VISIBILITY; @@ -2165,15 +2197,15 @@ public class PreferencesHelper implements RankingConfig { public void updateBubblesEnabled() { final boolean newValue = Settings.Global.getInt(mContext.getContentResolver(), Settings.Global.NOTIFICATION_BUBBLES, - DEFAULT_ALLOW_BUBBLE ? 1 : 0) == 1; - if (newValue != mBubblesEnabled) { - mBubblesEnabled = newValue; + DEFAULT_GLOBAL_ALLOW_BUBBLE ? 1 : 0) == 1; + if (newValue != mBubblesEnabledGlobally) { + mBubblesEnabledGlobally = newValue; updateConfig(); } } public boolean bubblesEnabled() { - return mBubblesEnabled; + return mBubblesEnabledGlobally; } public void updateBadgingEnabled() { @@ -2229,7 +2261,7 @@ public class PreferencesHelper implements RankingConfig { int priority = DEFAULT_PRIORITY; int visibility = DEFAULT_VISIBILITY; boolean showBadge = DEFAULT_SHOW_BADGE; - boolean allowBubble = DEFAULT_ALLOW_BUBBLE; + int bubblePreference = DEFAULT_BUBBLE_PREFERENCE; int lockedAppFields = DEFAULT_LOCKED_APP_FIELDS; // these fields are loaded on boot from a different source of truth and so are not // written to notification policy xml diff --git a/services/core/java/com/android/server/notification/RankingConfig.java b/services/core/java/com/android/server/notification/RankingConfig.java index 7e98be7fe065..7fc79e6a9bf7 100644 --- a/services/core/java/com/android/server/notification/RankingConfig.java +++ b/services/core/java/com/android/server/notification/RankingConfig.java @@ -29,7 +29,7 @@ public interface RankingConfig { void setShowBadge(String packageName, int uid, boolean showBadge); boolean canShowBadge(String packageName, int uid); boolean badgingEnabled(UserHandle userHandle); - boolean areBubblesAllowed(String packageName, int uid); + int getBubblePreference(String packageName, int uid); boolean bubblesEnabled(); boolean isGroupBlocked(String packageName, int uid, String groupId); diff --git a/services/core/java/com/android/server/notification/ShortcutHelper.java b/services/core/java/com/android/server/notification/ShortcutHelper.java index f1ce3a7d9f48..1d4843822931 100644 --- a/services/core/java/com/android/server/notification/ShortcutHelper.java +++ b/services/core/java/com/android/server/notification/ShortcutHelper.java @@ -21,11 +21,15 @@ import static android.content.pm.LauncherApps.ShortcutQuery.FLAG_MATCH_DYNAMIC; import static android.content.pm.LauncherApps.ShortcutQuery.FLAG_MATCH_PINNED; import android.annotation.NonNull; +import android.content.Intent; +import android.content.IntentFilter; import android.content.pm.LauncherApps; import android.content.pm.ShortcutInfo; +import android.content.pm.ShortcutServiceInternal; import android.os.Binder; import android.os.Handler; import android.os.UserHandle; +import android.util.Slog; import com.android.internal.annotations.VisibleForTesting; @@ -38,6 +42,7 @@ import java.util.List; * Helper for querying shortcuts. */ class ShortcutHelper { + private static final String TAG = "ShortcutHelper"; /** * Listener to call when a shortcut we're tracking has been removed. @@ -48,6 +53,8 @@ class ShortcutHelper { private LauncherApps mLauncherAppsService; private ShortcutListener mShortcutListener; + private ShortcutServiceInternal mShortcutServiceInternal; + private IntentFilter mSharingFilter; // Key: packageName Value: <shortcutId, notifId> private HashMap<String, HashMap<String, String>> mActiveShortcutBubbles = new HashMap<>(); @@ -111,9 +118,17 @@ class ShortcutHelper { } }; - ShortcutHelper(LauncherApps launcherApps, ShortcutListener listener) { + ShortcutHelper(LauncherApps launcherApps, ShortcutListener listener, + ShortcutServiceInternal shortcutServiceInternal) { mLauncherAppsService = launcherApps; mShortcutListener = listener; + mSharingFilter = new IntentFilter(); + try { + mSharingFilter.addDataType("*/*"); + } catch (IntentFilter.MalformedMimeTypeException e) { + Slog.e(TAG, "Bad mime type", e); + } + mShortcutServiceInternal = shortcutServiceInternal; } @VisibleForTesting @@ -121,6 +136,11 @@ class ShortcutHelper { mLauncherAppsService = launcherApps; } + @VisibleForTesting + void setShortcutServiceInternal(ShortcutServiceInternal shortcutServiceInternal) { + mShortcutServiceInternal = shortcutServiceInternal; + } + /** * Only returns shortcut info if it's found and if it's {@link ShortcutInfo#isLongLived()}. */ @@ -141,7 +161,14 @@ class ShortcutHelper { ShortcutInfo info = shortcuts != null && shortcuts.size() > 0 ? shortcuts.get(0) : null; - return info != null && info.isLongLived() ? info : null; + if (info == null || !info.isLongLived() || !info.isEnabled()) { + return null; + } + if (mShortcutServiceInternal.isSharingShortcut(user.getIdentifier(), + "android", packageName, shortcutId, user.getIdentifier(), mSharingFilter)) { + return info; + } + return null; } finally { Binder.restoreCallingIdentity(token); } diff --git a/services/core/java/com/android/server/pm/BackgroundDexOptService.java b/services/core/java/com/android/server/pm/BackgroundDexOptService.java index dab4bfd4df5a..5415967c3bdc 100644 --- a/services/core/java/com/android/server/pm/BackgroundDexOptService.java +++ b/services/core/java/com/android/server/pm/BackgroundDexOptService.java @@ -17,6 +17,7 @@ package com.android.server.pm; import static com.android.server.pm.PackageManagerService.DEBUG_DEXOPT; +import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME; import android.annotation.Nullable; import android.app.job.JobInfo; @@ -434,7 +435,7 @@ public class BackgroundDexOptService extends JobService { | DexoptOptions.DEXOPT_DOWNGRADE; long package_size_before = getPackageSize(pm, pkg); - if (isForPrimaryDex) { + if (isForPrimaryDex || PLATFORM_PACKAGE_NAME.equals(pkg)) { // This applies for system apps or if packages location is not a directory, i.e. // monolithic install. if (!pm.canHaveOatDir(pkg)) { @@ -486,7 +487,9 @@ public class BackgroundDexOptService extends JobService { | DexoptOptions.DEXOPT_BOOT_COMPLETE | DexoptOptions.DEXOPT_IDLE_BACKGROUND_JOB; - return isForPrimaryDex + // System server share the same code path as primary dex files. + // PackageManagerService will select the right optimization path for it. + return (isForPrimaryDex || PLATFORM_PACKAGE_NAME.equals(pkg)) ? performDexOptPrimary(pm, pkg, reason, dexoptFlags) : performDexOptSecondary(pm, pkg, reason, dexoptFlags); } diff --git a/services/core/java/com/android/server/pm/DataLoaderManagerService.java b/services/core/java/com/android/server/pm/DataLoaderManagerService.java index 09baf6e0a817..ae9c38498b10 100644 --- a/services/core/java/com/android/server/pm/DataLoaderManagerService.java +++ b/services/core/java/com/android/server/pm/DataLoaderManagerService.java @@ -204,6 +204,12 @@ public class DataLoaderManagerService extends SystemService { @Override public void onServiceDisconnected(ComponentName arg0) { + if (mListener != null) { + try { + mListener.onStatusChanged(mId, IDataLoaderStatusListener.DATA_LOADER_DESTROYED); + } catch (RemoteException ignored) { + } + } remove(); } diff --git a/services/core/java/com/android/server/pm/PackageDexOptimizer.java b/services/core/java/com/android/server/pm/PackageDexOptimizer.java index 65b7cf3eabd1..1951e7417b2c 100644 --- a/services/core/java/com/android/server/pm/PackageDexOptimizer.java +++ b/services/core/java/com/android/server/pm/PackageDexOptimizer.java @@ -32,6 +32,7 @@ import static com.android.server.pm.Installer.DEXOPT_STORAGE_CE; import static com.android.server.pm.Installer.DEXOPT_STORAGE_DE; import static com.android.server.pm.InstructionSets.getAppDexInstructionSets; import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets; +import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME; import static com.android.server.pm.PackageManagerService.WATCHDOG_TIMEOUT; import static com.android.server.pm.PackageManagerServiceCompilerMapping.getReasonName; @@ -115,7 +116,9 @@ public class PackageDexOptimizer { static boolean canOptimizePackage(AndroidPackage pkg) { // We do not dexopt a package with no code. - if (!pkg.isHasCode()) { + // Note that the system package is marked as having no code, however we can + // still optimize it via dexoptSystemServerPath. + if (!PLATFORM_PACKAGE_NAME.equals(pkg.getPackageName()) && !pkg.isHasCode()) { return false; } @@ -132,6 +135,10 @@ public class PackageDexOptimizer { int performDexOpt(AndroidPackage pkg, @NonNull PackageSetting pkgSetting, String[] instructionSets, CompilerStats.PackageStats packageStats, PackageDexUsage.PackageUseInfo packageUseInfo, DexoptOptions options) { + if (PLATFORM_PACKAGE_NAME.equals(pkg.getPackageName())) { + throw new IllegalArgumentException("System server dexopting should be done via " + + " DexManager and PackageDexOptimizer#dexoptSystemServerPath"); + } if (pkg.getUid() == -1) { throw new IllegalArgumentException("Dexopt for " + pkg.getPackageName() + " has invalid uid."); diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java index 57908f3a4dac..4cfd1ab73c9e 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerService.java +++ b/services/core/java/com/android/server/pm/PackageInstallerService.java @@ -82,6 +82,7 @@ import com.android.internal.util.ImageUtils; import com.android.internal.util.IndentingPrintWriter; import com.android.server.IoThread; import com.android.server.LocalServices; +import com.android.server.SystemConfig; import com.android.server.pm.parsing.PackageParser2; import com.android.server.pm.permission.PermissionManagerServiceInternal; @@ -151,6 +152,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements private final Callbacks mCallbacks; private volatile boolean mOkToSendBroadcasts = false; + private volatile boolean mBypassNextStagedInstallerCheck = false; /** * File storing persisted {@link #mSessions} metadata. @@ -541,7 +543,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements } } - if (Build.IS_DEBUGGABLE || isDowngradeAllowedForCaller(callingUid)) { + if (Build.IS_DEBUGGABLE || isCalledBySystemOrShell(callingUid)) { params.installFlags |= PackageManager.INSTALL_ALLOW_DOWNGRADE; } else { params.installFlags &= ~PackageManager.INSTALL_ALLOW_DOWNGRADE; @@ -571,6 +573,14 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements } } + if (mBypassNextStagedInstallerCheck) { + mBypassNextStagedInstallerCheck = false; + } else if (params.isStaged + && !isCalledBySystemOrShell(callingUid) + && !isWhitelistedStagedInstaller(requestedInstallerPackageName)) { + throw new SecurityException("Installer not allowed to commit staged install"); + } + if (!params.isMultiPackage) { // Only system components can circumvent runtime permissions when installing. if ((params.installFlags & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0 @@ -683,11 +693,15 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements return sessionId; } - private boolean isDowngradeAllowedForCaller(int callingUid) { + private boolean isCalledBySystemOrShell(int callingUid) { return callingUid == Process.SYSTEM_UID || callingUid == Process.ROOT_UID || callingUid == Process.SHELL_UID; } + private boolean isWhitelistedStagedInstaller(String installerName) { + return SystemConfig.getInstance().getWhitelistedStagedInstallers().contains(installerName); + } + @Override public void updateSessionAppIcon(int sessionId, Bitmap appIcon) { synchronized (mSessions) { @@ -963,6 +977,11 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements } } + @Override + public void bypassNextStagedInstallerCheck(boolean value) { + mBypassNextStagedInstallerCheck = value; + } + private static int getSessionCount(SparseArray<PackageInstallerSession> sessions, int installerUid) { int count = 0; diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 59ac603875e2..12ee2f55e87f 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -94,6 +94,7 @@ import static android.content.pm.PackageManager.PERMISSION_DENIED; import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.content.pm.PackageManager.RESTRICTION_NONE; import static android.content.pm.PackageManager.UNINSTALL_REASON_UNKNOWN; +import static android.content.pm.PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V4; import static android.content.pm.PackageParser.isApkFile; import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER; import static android.os.incremental.IncrementalManager.isIncrementalPath; @@ -1820,10 +1821,12 @@ public class PackageManagerService extends IPackageManager.Stub state.setVerifierResponse(Binder.getCallingUid(), PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT); broadcastPackageVerified(verificationId, originUri, - PackageManager.VERIFICATION_ALLOW, user); + PackageManager.VERIFICATION_ALLOW, null, args.mDataLoaderType, + user); } else { broadcastPackageVerified(verificationId, originUri, - PackageManager.VERIFICATION_REJECT, user); + PackageManager.VERIFICATION_REJECT, null, args.mDataLoaderType, + user); params.setReturnCode( PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE); state.setVerifierResponse(Binder.getCallingUid(), @@ -1899,7 +1902,7 @@ public class PackageManagerService extends IPackageManager.Stub if (state.isInstallAllowed()) { broadcastPackageVerified(verificationId, originUri, - response.code, args.getUser()); + response.code, null, args.mDataLoaderType, args.getUser()); } else { params.setReturnCode( PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE); @@ -13575,12 +13578,17 @@ public class PackageManagerService extends IPackageManager.Stub } private void broadcastPackageVerified(int verificationId, Uri packageUri, - int verificationCode, UserHandle user) { + int verificationCode, @Nullable String rootHashString, int dataLoaderType, + UserHandle user) { final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED); intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE); intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId); intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode); + if (rootHashString != null) { + intent.putExtra(PackageManager.EXTRA_VERIFICATION_ROOT_HASH, rootHashString); + } + intent.putExtra(PackageInstaller.EXTRA_DATA_LOADER_TYPE, dataLoaderType); mContext.sendBroadcastAsUser(intent, user, android.Manifest.permission.PACKAGE_VERIFICATION_AGENT); @@ -14952,8 +14960,17 @@ public class PackageManagerService extends IPackageManager.Stub verificationState.setRequiredVerifierUid(requiredUid); final int installerUid = verificationInfo == null ? -1 : verificationInfo.installerUid; - if (!origin.existing && isVerificationEnabled(pkgLite, verifierUser.getIdentifier(), - installFlags, installerUid)) { + final boolean isVerificationEnabled = isVerificationEnabled( + pkgLite, verifierUser.getIdentifier(), installFlags, installerUid); + final boolean isV4Signed = + (mArgs.signingDetails.signatureSchemeVersion == SIGNING_BLOCK_V4); + final boolean isIncrementalInstall = + (mArgs.mDataLoaderType == DataLoaderType.INCREMENTAL); + // NOTE: We purposefully skip verification for only incremental installs when there's + // a v4 signature block. Otherwise, proceed with verification as usual. + if (!origin.existing + && isVerificationEnabled + && (!isIncrementalInstall || !isV4Signed)) { final Intent verification = new Intent( Intent.ACTION_PACKAGE_NEEDS_VERIFICATION); verification.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); @@ -16569,7 +16586,29 @@ public class PackageManagerService extends IPackageManager.Stub } executePostCommitSteps(commitRequest); } finally { - if (!success) { + if (success) { + for (InstallRequest request : requests) { + final InstallArgs args = request.args; + if (args.mDataLoaderType != DataLoaderType.INCREMENTAL) { + continue; + } + if (args.signingDetails.signatureSchemeVersion != SIGNING_BLOCK_V4) { + continue; + } + // For incremental installs, we bypass the verifier prior to install. Now + // that we know the package is valid, send a notice to the verifier with + // the root hash of the base.apk. + final String baseCodePath = request.installResult.pkg.getBaseCodePath(); + final String[] splitCodePaths = request.installResult.pkg.getSplitCodePaths(); + final Uri originUri = Uri.fromFile(args.origin.resolvedFile); + final int verificationId = mPendingVerificationToken++; + final String rootHashString = PackageManagerServiceUtils + .buildVerificationRootHashString(baseCodePath, splitCodePaths); + broadcastPackageVerified(verificationId, originUri, + PackageManager.VERIFICATION_ALLOW, rootHashString, + args.mDataLoaderType, args.getUser()); + } + } else { for (ScanResult result : preparedScans.values()) { if (createdAppId.getOrDefault(result.request.parsedPackage.getPackageName(), false)) { @@ -16911,7 +16950,6 @@ public class PackageManagerService extends IPackageManager.Stub if (args.signingDetails != PackageParser.SigningDetails.UNKNOWN) { parsedPackage.setSigningDetails(args.signingDetails); } else { - // TODO(b/136132412): skip for Incremental installation parsedPackage.setSigningDetails( ParsingPackageUtils.collectCertificates(parsedPackage, false /* skipVerify */)); } diff --git a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java index 91afd846a9c3..5c175a6ef847 100644 --- a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java +++ b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java @@ -32,7 +32,6 @@ import android.annotation.Nullable; import android.app.AppGlobals; import android.content.Context; import android.content.Intent; -import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfoLite; import android.content.pm.PackageManager; import android.content.pm.PackageManagerInternal; @@ -40,7 +39,6 @@ import android.content.pm.PackageParser; import android.content.pm.PackageParser.PackageParserException; import android.content.pm.ResolveInfo; import android.content.pm.Signature; -import android.content.pm.parsing.ParsingPackageUtils; import android.os.Build; import android.os.Debug; import android.os.Environment; @@ -50,6 +48,9 @@ import android.os.RemoteException; import android.os.SystemProperties; import android.os.UserHandle; import android.os.UserManagerInternal; +import android.os.incremental.IncrementalManager; +import android.os.incremental.V4Signature; +import android.os.incremental.V4Signature.HashingInfo; import android.service.pm.PackageServiceDumpProto; import android.system.ErrnoException; import android.system.Os; @@ -62,6 +63,7 @@ import com.android.internal.content.NativeLibraryHelper; import com.android.internal.content.PackageHelper; import com.android.internal.util.ArrayUtils; import com.android.internal.util.FastPrintWriter; +import com.android.internal.util.HexDump; import com.android.server.EventLogTags; import com.android.server.pm.dex.DexManager; import com.android.server.pm.dex.PackageDexUsage; @@ -94,8 +96,6 @@ import java.util.Collections; import java.util.Date; import java.util.LinkedList; import java.util.List; -import java.util.Map; -import java.util.Set; import java.util.function.Predicate; import java.util.zip.GZIPInputStream; @@ -943,4 +943,71 @@ public class PackageManagerServiceUtils { Os.chmod(currentDir.getAbsolutePath(), mode); } } + + /** + * Returns a string that's compatible with the verification root hash extra. + * @see PackageManager#EXTRA_VERIFICATION_ROOT_HASH + */ + @NonNull + public static String buildVerificationRootHashString(@NonNull String baseFilename, + @Nullable String[] splitFilenameArray) { + final StringBuilder sb = new StringBuilder(); + final String baseFilePath = + baseFilename.substring(baseFilename.lastIndexOf(File.separator) + 1); + sb.append(baseFilePath).append(":"); + final byte[] baseRootHash = getRootHash(baseFilename); + if (baseRootHash == null) { + sb.append("0"); + } else { + sb.append(HexDump.toHexString(baseRootHash)); + } + if (splitFilenameArray == null || splitFilenameArray.length == 0) { + return sb.toString(); + } + + for (int i = splitFilenameArray.length - 1; i >= 0; i--) { + final String splitFilename = splitFilenameArray[i]; + final String splitFilePath = + splitFilename.substring(splitFilename.lastIndexOf(File.separator) + 1); + final byte[] splitRootHash = getRootHash(splitFilename); + sb.append(";").append(splitFilePath).append(":"); + if (splitRootHash == null) { + sb.append("0"); + } else { + sb.append(HexDump.toHexString(splitRootHash)); + } + } + return sb.toString(); + } + + /** + * Returns the root has for the given file. + * <p>Otherwise, returns {@code null} if the root hash could not be found or calculated. + * <p>NOTE: This currently only works on files stored on the incremental file system. The + * eventual goal is that this hash [among others] can be retrieved for any file. + */ + @Nullable + private static byte[] getRootHash(String filename) { + try { + final byte[] baseFileSignature = + IncrementalManager.unsafeGetFileSignature(filename); + if (baseFileSignature == null) { + throw new IOException("File signature not present"); + } + final V4Signature signature = + V4Signature.readFrom(baseFileSignature); + if (signature.hashingInfo == null) { + throw new IOException("Hashing info not present"); + } + final HashingInfo hashInfo = + HashingInfo.fromByteArray(signature.hashingInfo); + if (ArrayUtils.isEmpty(hashInfo.rawRootHash)) { + throw new IOException("Root has not present"); + } + return hashInfo.rawRootHash; + } catch (IOException ignore) { + Slog.e(TAG, "ERROR: could not load root hash from incremental install"); + } + return null; + } } diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java index b4eacf6226ce..88f442c7b6a0 100644 --- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java +++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java @@ -297,6 +297,8 @@ class PackageManagerShellCommand extends ShellCommand { return runGetModuleInfo(); case "log-visibility": return runLogVisibility(); + case "bypass-staged-installer-check": + return runBypassStagedInstallerCheck(); default: { String nextArg = getNextArg(); if (nextArg == null) { @@ -392,6 +394,20 @@ class PackageManagerShellCommand extends ShellCommand { return 1; } + private int runBypassStagedInstallerCheck() { + final PrintWriter pw = getOutPrintWriter(); + try { + mInterface.getPackageInstaller() + .bypassNextStagedInstallerCheck(Boolean.parseBoolean(getNextArg())); + return 0; + } catch (RemoteException e) { + pw.println("Failure [" + + e.getClass().getName() + " - " + + e.getMessage() + "]"); + return -1; + } + } + private int uninstallSystemUpdates() { final PrintWriter pw = getOutPrintWriter(); List<String> failedUninstalls = new LinkedList<>(); diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java index 323ffcfc2a1c..fc70af4e7bd4 100644 --- a/services/core/java/com/android/server/pm/UserManagerService.java +++ b/services/core/java/com/android/server/pm/UserManagerService.java @@ -103,6 +103,7 @@ import com.android.internal.logging.MetricsLogger; import com.android.internal.os.BackgroundThread; import com.android.internal.util.DumpUtils; import com.android.internal.util.FastXmlSerializer; +import com.android.internal.util.FrameworkStatsLog; import com.android.internal.util.Preconditions; import com.android.internal.util.XmlUtils; import com.android.internal.widget.LockPatternUtils; @@ -137,6 +138,7 @@ import java.util.LinkedList; import java.util.List; import java.util.Objects; import java.util.Set; +import java.util.concurrent.ThreadLocalRandom; /** * Service for {@link UserManager}. @@ -3244,16 +3246,39 @@ public class UserManagerService extends IUserManager.Stub { @NonNull String userType, @UserInfoFlag int flags, @UserIdInt int parentId, boolean preCreate, @Nullable String[] disallowedPackages) throws UserManager.CheckedUserOperationException { + final int nextProbableUserId = getNextAvailableId(); final TimingsTraceAndSlog t = new TimingsTraceAndSlog(); t.traceBegin("createUser-" + flags); + final long sessionId = logUserCreateJourneyBegin(nextProbableUserId, userType, flags); try { return createUserInternalUncheckedNoTracing(name, userType, flags, parentId, preCreate, disallowedPackages, t); } finally { + logUserCreateJourneyFinish(sessionId, nextProbableUserId); t.traceEnd(); } } + private long logUserCreateJourneyBegin(@UserIdInt int userId, String userType, + @UserInfoFlag int flags) { + final long sessionId = ThreadLocalRandom.current().nextLong(1, Long.MAX_VALUE); + // log the journey atom with the user metadata + FrameworkStatsLog.write(FrameworkStatsLog.USER_LIFECYCLE_JOURNEY_REPORTED, sessionId, + FrameworkStatsLog.USER_LIFECYCLE_JOURNEY_REPORTED__JOURNEY__USER_CREATE, + /* origin_user= */ -1, userId, UserManager.getUserTypeForStatsd(userType), flags); + // log the event atom to indicate the event start + FrameworkStatsLog.write(FrameworkStatsLog.USER_LIFECYCLE_EVENT_OCCURRED, sessionId, userId, + FrameworkStatsLog.USER_LIFECYCLE_EVENT_OCCURRED__EVENT__CREATE_USER, + FrameworkStatsLog.USER_LIFECYCLE_EVENT_OCCURRED__STATE__BEGIN); + return sessionId; + } + + private void logUserCreateJourneyFinish(long sessionId, @UserIdInt int userId) { + FrameworkStatsLog.write(FrameworkStatsLog.USER_LIFECYCLE_EVENT_OCCURRED, sessionId, userId, + FrameworkStatsLog.USER_LIFECYCLE_EVENT_OCCURRED__EVENT__CREATE_USER, + FrameworkStatsLog.USER_LIFECYCLE_EVENT_OCCURRED__STATE__FINISH); + } + private UserInfo createUserInternalUncheckedNoTracing(@Nullable String name, @NonNull String userType, @UserInfoFlag int flags, @UserIdInt int parentId, boolean preCreate, @Nullable String[] disallowedPackages, diff --git a/services/core/java/com/android/server/pm/dex/DexManager.java b/services/core/java/com/android/server/pm/dex/DexManager.java index 6dcf71e9fbf0..f7bf1d985786 100644 --- a/services/core/java/com/android/server/pm/dex/DexManager.java +++ b/services/core/java/com/android/server/pm/dex/DexManager.java @@ -79,6 +79,10 @@ public class DexManager { private static final String PROPERTY_NAME_PM_DEXOPT_PRIV_APPS_OOB_LIST = "pm.dexopt.priv-apps-oob-list"; + // System server cannot load executable code outside system partitions. + // However it can load verification data - thus we pick the "verify" compiler filter. + private static final String SYSTEM_SERVER_COMPILER_FILTER = "verify"; + private final Context mContext; // Maps package name to code locations. @@ -443,6 +447,14 @@ public class DexManager { * because they don't need to be compiled).. */ public boolean dexoptSecondaryDex(DexoptOptions options) { + if (PLATFORM_PACKAGE_NAME.equals(options.getPackageName())) { + // We could easily redirect to #dexoptSystemServer in this case. But there should be + // no-one calling this method directly for system server. + // As such we prefer to abort in this case. + Slog.wtf(TAG, "System server jars should be optimized with dexoptSystemServer"); + return false; + } + PackageDexOptimizer pdo = getPackageDexOptimizer(options); String packageName = options.getPackageName(); PackageUseInfo useInfo = getPackageUseInfoOrDefault(packageName); @@ -501,8 +513,17 @@ public class DexManager { return PackageDexOptimizer.DEX_OPT_FAILED; } - PackageDexOptimizer pdo = getPackageDexOptimizer(options); - String packageName = options.getPackageName(); + // Override compiler filter for system server to the expected one. + // + // We could let the caller do this every time the invoke PackageManagerServer#dexopt. + // However, there are a few places were this will need to be done which creates + // redundancy and the danger of overlooking the config (and thus generating code that will + // waste storage and time). + DexoptOptions overriddenOptions = options.overrideCompilerFilter( + SYSTEM_SERVER_COMPILER_FILTER); + + PackageDexOptimizer pdo = getPackageDexOptimizer(overriddenOptions); + String packageName = overriddenOptions.getPackageName(); PackageUseInfo useInfo = getPackageUseInfoOrDefault(packageName); if (useInfo.getDexUseInfoMap().isEmpty()) { if (DEBUG) { @@ -527,7 +548,7 @@ public class DexManager { continue; } - int newResult = pdo.dexoptSystemServerPath(dexPath, dexUseInfo, options); + int newResult = pdo.dexoptSystemServerPath(dexPath, dexUseInfo, overriddenOptions); // The end result is: // - FAILED if any path failed, @@ -600,6 +621,23 @@ public class DexManager { packageName, dexUseInfo.getOwnerUserId()) || updated; continue; } + + // Special handle system server files. + // We don't need an installd call because we have permissions to check if the file + // exists. + if (PLATFORM_PACKAGE_NAME.equals(packageName)) { + if (!Files.exists(Paths.get(dexPath))) { + if (DEBUG) { + Slog.w(TAG, "A dex file previously loaded by System Server does not exist " + + " anymore: " + dexPath); + } + updated = mPackageDexUsage.removeUserPackage( + packageName, dexUseInfo.getOwnerUserId()) || updated; + } + continue; + } + + // This is a regular application. ApplicationInfo info = pkg.applicationInfo; int flags = 0; if (info.deviceProtectedDataDir != null && diff --git a/services/core/java/com/android/server/pm/dex/DexoptOptions.java b/services/core/java/com/android/server/pm/dex/DexoptOptions.java index de3c9f28218d..b453c898ded8 100644 --- a/services/core/java/com/android/server/pm/dex/DexoptOptions.java +++ b/services/core/java/com/android/server/pm/dex/DexoptOptions.java @@ -166,4 +166,17 @@ public final class DexoptOptions { public int getCompilationReason() { return mCompilationReason; } + + /** + * Creates a new set of DexoptOptions which are the same with the exception of the compiler + * filter (set to the given value). + */ + public DexoptOptions overrideCompilerFilter(String newCompilerFilter) { + return new DexoptOptions( + mPackageName, + mCompilationReason, + newCompilerFilter, + mSplitName, + mFlags); + } } diff --git a/services/core/java/com/android/server/pm/permission/OneTimePermissionUserManager.java b/services/core/java/com/android/server/pm/permission/OneTimePermissionUserManager.java index 1c4568095ce3..4bbe3733719e 100644 --- a/services/core/java/com/android/server/pm/permission/OneTimePermissionUserManager.java +++ b/services/core/java/com/android/server/pm/permission/OneTimePermissionUserManager.java @@ -81,9 +81,6 @@ public class OneTimePermissionUserManager { mAlarmManager = context.getSystemService(AlarmManager.class); mPermissionControllerManager = context.getSystemService(PermissionControllerManager.class); mHandler = context.getMainThreadHandler(); - - // Listen for tracked uid being uninstalled - context.registerReceiver(mUninstallListener, new IntentFilter(Intent.ACTION_UID_REMOVED)); } /** @@ -171,6 +168,14 @@ public class OneTimePermissionUserManager { } /** + * Register to listen for Uids being uninstalled. This must be done outside of the + * PermissionManagerService lock. + */ + void registerUninstallListener() { + mContext.registerReceiver(mUninstallListener, new IntentFilter(Intent.ACTION_UID_REMOVED)); + } + + /** * A class which watches a package for inactivity and notifies the permission controller when * the package becomes inactive */ 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 ccc749232dc3..244364ebbf0a 100644 --- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java +++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java @@ -3210,16 +3210,19 @@ public class PermissionManagerService extends IPermissionManager.Stub { } private OneTimePermissionUserManager getOneTimePermissionUserManager(@UserIdInt int userId) { + OneTimePermissionUserManager oneTimePermissionUserManager; synchronized (mLock) { - OneTimePermissionUserManager oneTimePermissionUserManager = + oneTimePermissionUserManager = mOneTimePermissionUserManagers.get(userId); - if (oneTimePermissionUserManager == null) { - oneTimePermissionUserManager = new OneTimePermissionUserManager( - mContext.createContextAsUser(UserHandle.of(userId), /*flags*/ 0)); - mOneTimePermissionUserManagers.put(userId, oneTimePermissionUserManager); + if (oneTimePermissionUserManager != null) { + return oneTimePermissionUserManager; } - return oneTimePermissionUserManager; + oneTimePermissionUserManager = new OneTimePermissionUserManager( + mContext.createContextAsUser(UserHandle.of(userId), /*flags*/ 0)); + mOneTimePermissionUserManagers.put(userId, oneTimePermissionUserManager); } + oneTimePermissionUserManager.registerUninstallListener(); + return oneTimePermissionUserManager; } @Override diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index c9736401f680..4624e9ea0209 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -4468,12 +4468,6 @@ public class PhoneWindowManager implements WindowManagerPolicy { private void wakeUpFromPowerKey(long eventTime) { wakeUp(eventTime, mAllowTheaterModeWakeFromPowerKey, PowerManager.WAKE_REASON_POWER_BUTTON, "android.policy:POWER"); - - // Turn on the connected TV and switch HDMI input if we're a HDMI playback device. - final HdmiControl hdmiControl = getHdmiControl(); - if (hdmiControl != null) { - hdmiControl.turnOnTv(); - } } private boolean wakeUp(long wakeTime, boolean wakeInTheaterMode, @WakeReason int reason, @@ -4489,6 +4483,12 @@ public class PhoneWindowManager implements WindowManagerPolicy { } mPowerManager.wakeUp(wakeTime, reason, details); + + // Turn on the connected TV and switch HDMI input if we're a HDMI playback device. + final HdmiControl hdmiControl = getHdmiControl(); + if (hdmiControl != null) { + hdmiControl.turnOnTv(); + } return true; } diff --git a/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerHw2Enforcer.java b/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerHw2Enforcer.java index 870d909fbbcc..a18b690f08cd 100644 --- a/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerHw2Enforcer.java +++ b/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerHw2Enforcer.java @@ -33,7 +33,7 @@ import java.util.Map; * This is not necessarily a strict enforcement for the HAL contract, but a place to add checks for * common HAL malfunctions, to help track them and assist in debugging. * - * The class is not thread-safe. + * The class is thread-safe. */ public class SoundTriggerHw2Enforcer implements ISoundTriggerHw2 { static final String TAG = "SoundTriggerHw2Enforcer"; @@ -55,7 +55,9 @@ public class SoundTriggerHw2Enforcer implements ISoundTriggerHw2 { public int loadSoundModel(ISoundTriggerHw.SoundModel soundModel, Callback callback, int cookie) { int handle = mUnderlying.loadSoundModel(soundModel, new CallbackEnforcer(callback), cookie); - mModelStates.put(handle, false); + synchronized (mModelStates) { + mModelStates.put(handle, false); + } return handle; } @@ -64,27 +66,35 @@ public class SoundTriggerHw2Enforcer implements ISoundTriggerHw2 { int cookie) { int handle = mUnderlying.loadPhraseSoundModel(soundModel, new CallbackEnforcer(callback), cookie); - mModelStates.put(handle, false); + synchronized (mModelStates) { + mModelStates.put(handle, false); + } return handle; } @Override public void unloadSoundModel(int modelHandle) { mUnderlying.unloadSoundModel(modelHandle); - mModelStates.remove(modelHandle); + synchronized (mModelStates) { + mModelStates.remove(modelHandle); + } } @Override public void stopRecognition(int modelHandle) { mUnderlying.stopRecognition(modelHandle); - mModelStates.replace(modelHandle, false); + synchronized (mModelStates) { + mModelStates.replace(modelHandle, false); + } } @Override public void stopAllRecognitions() { mUnderlying.stopAllRecognitions(); - for (Map.Entry<Integer, Boolean> entry : mModelStates.entrySet()) { - entry.setValue(false); + synchronized (mModelStates) { + for (Map.Entry<Integer, Boolean> entry : mModelStates.entrySet()) { + entry.setValue(false); + } } } @@ -92,7 +102,9 @@ public class SoundTriggerHw2Enforcer implements ISoundTriggerHw2 { public void startRecognition(int modelHandle, RecognitionConfig config, Callback callback, int cookie) { mUnderlying.startRecognition(modelHandle, config, new CallbackEnforcer(callback), cookie); - mModelStates.replace(modelHandle, true); + synchronized (mModelStates) { + mModelStates.replace(modelHandle, true); + } } @Override @@ -142,12 +154,14 @@ public class SoundTriggerHw2Enforcer implements ISoundTriggerHw2 { public void recognitionCallback(ISoundTriggerHwCallback.RecognitionEvent event, int cookie) { int model = event.header.model; - if (!mModelStates.getOrDefault(model, false)) { - Log.wtfStack(TAG, "Unexpected recognition event for model: " + model); - } - if (event.header.status - != android.media.soundtrigger_middleware.RecognitionStatus.FORCED) { - mModelStates.replace(model, false); + synchronized (mModelStates) { + if (!mModelStates.getOrDefault(model, false)) { + Log.wtfStack(TAG, "Unexpected recognition event for model: " + model); + } + if (event.header.status + != android.media.soundtrigger_middleware.RecognitionStatus.FORCED) { + mModelStates.replace(model, false); + } } mUnderlying.recognitionCallback(event, cookie); } @@ -156,12 +170,14 @@ public class SoundTriggerHw2Enforcer implements ISoundTriggerHw2 { public void phraseRecognitionCallback(ISoundTriggerHwCallback.PhraseRecognitionEvent event, int cookie) { int model = event.common.header.model; - if (!mModelStates.getOrDefault(model, false)) { - Log.wtfStack(TAG, "Unexpected recognition event for model: " + model); - } - if (event.common.header.status - != android.media.soundtrigger_middleware.RecognitionStatus.FORCED) { - mModelStates.replace(model, false); + synchronized (mModelStates) { + if (!mModelStates.getOrDefault(model, false)) { + Log.wtfStack(TAG, "Unexpected recognition event for model: " + model); + } + if (event.common.header.status + != android.media.soundtrigger_middleware.RecognitionStatus.FORCED) { + mModelStates.replace(model, false); + } } mUnderlying.phraseRecognitionCallback(event, cookie); } diff --git a/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareLogging.java b/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareLogging.java index 04ba6bfeb4ee..8b6ed1ff5081 100644 --- a/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareLogging.java +++ b/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareLogging.java @@ -377,11 +377,7 @@ public class SoundTriggerMiddlewareLogging implements ISoundTriggerMiddlewareInt } private static void printObject(@NonNull StringBuilder builder, @Nullable Object obj) { - if (obj instanceof Parcelable) { - ObjectPrinter.print(builder, obj, true, 16); - } else { - builder.append(obj.toString()); - } + ObjectPrinter.print(builder, obj, true, 16); } private static String printObject(@Nullable Object obj) { diff --git a/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareValidation.java b/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareValidation.java index 23259558eeb7..bae244179346 100644 --- a/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareValidation.java +++ b/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareValidation.java @@ -32,9 +32,9 @@ import android.media.soundtrigger_middleware.RecognitionEvent; import android.media.soundtrigger_middleware.RecognitionStatus; import android.media.soundtrigger_middleware.SoundModel; import android.media.soundtrigger_middleware.SoundTriggerModuleDescriptor; +import android.media.soundtrigger_middleware.SoundTriggerModuleProperties; import android.media.soundtrigger_middleware.Status; import android.os.IBinder; -import android.os.Process; import android.os.RemoteException; import android.os.ServiceSpecificException; import android.util.Log; @@ -108,17 +108,26 @@ import java.util.Set; public class SoundTriggerMiddlewareValidation implements ISoundTriggerMiddlewareInternal, Dumpable { private static final String TAG = "SoundTriggerMiddlewareValidation"; - private enum ModuleState { + private enum ModuleStatus { ALIVE, DETACHED, DEAD }; + private class ModuleState { + final @NonNull SoundTriggerModuleProperties properties; + Set<ModuleService> sessions = new HashSet<>(); + + private ModuleState(@NonNull SoundTriggerModuleProperties properties) { + this.properties = properties; + } + } + private Boolean mCaptureState; private final @NonNull ISoundTriggerMiddlewareInternal mDelegate; private final @NonNull Context mContext; - private Map<Integer, Set<ModuleService>> mModules; + private Map<Integer, ModuleState> mModules; public SoundTriggerMiddlewareValidation( @NonNull ISoundTriggerMiddlewareInternal delegate, @NonNull Context context) { @@ -168,7 +177,7 @@ public class SoundTriggerMiddlewareValidation implements ISoundTriggerMiddleware SoundTriggerModuleDescriptor[] result = mDelegate.listModules(); mModules = new HashMap<>(result.length); for (SoundTriggerModuleDescriptor desc : result) { - mModules.put(desc.handle, new HashSet<>()); + mModules.put(desc.handle, new ModuleState(desc.properties)); } return result; } catch (Exception e) { @@ -278,18 +287,21 @@ public class SoundTriggerMiddlewareValidation implements ISoundTriggerMiddleware @Override public void dump(PrintWriter pw) { synchronized (this) { - pw.printf("Capture state is %s\n", mCaptureState == null ? "uninitialized" + pw.printf("Capture state is %s\n\n", mCaptureState == null ? "uninitialized" : (mCaptureState ? "active" : "inactive")); if (mModules != null) { for (int handle : mModules.keySet()) { + final ModuleState module = mModules.get(handle); pw.println("========================================="); - pw.printf("Active sessions for module %d", handle); - pw.println(); + pw.printf("Module %d\n%s\n", handle, + ObjectPrinter.print(module.properties, true, 16)); pw.println("========================================="); - for (ModuleService session : mModules.get(handle)) { + for (ModuleService session : module.sessions) { session.dump(pw); } } + } else { + pw.println("Modules have not yet been enumerated."); } } pw.println(); @@ -297,11 +309,18 @@ public class SoundTriggerMiddlewareValidation implements ISoundTriggerMiddleware if (mDelegate instanceof Dumpable) { ((Dumpable) mDelegate).dump(pw); } - } /** State of a sound model. */ static class ModelState { + ModelState(SoundModel model) { + this.description = ObjectPrinter.print(model, true, 16); + } + + ModelState(PhraseSoundModel model) { + this.description = ObjectPrinter.print(model, true, 16); + } + /** Activity state of a sound model. */ enum Activity { /** Model is loaded, recognition is inactive. */ @@ -313,6 +332,9 @@ public class SoundTriggerMiddlewareValidation implements ISoundTriggerMiddleware /** Activity state. */ Activity activityState = Activity.LOADED; + /** Human-readable description of the model. */ + final String description; + /** * A map of known parameter support. A missing key means we don't know yet whether the * parameter is supported. A null value means it is known to not be supported. A non-null @@ -375,7 +397,7 @@ public class SoundTriggerMiddlewareValidation implements ISoundTriggerMiddleware private ISoundTriggerModule mDelegate; private @NonNull Map<Integer, ModelState> mLoadedModels = new HashMap<>(); private final int mHandle; - private ModuleState mState = ModuleState.ALIVE; + private ModuleStatus mState = ModuleStatus.ALIVE; ModuleService(int handle, @NonNull ISoundTriggerCallback callback) { mCallback = callback; @@ -389,7 +411,7 @@ public class SoundTriggerMiddlewareValidation implements ISoundTriggerMiddleware void attach(@NonNull ISoundTriggerModule delegate) { mDelegate = delegate; - mModules.get(mHandle).add(this); + mModules.get(mHandle).sessions.add(this); } @Override @@ -401,14 +423,14 @@ public class SoundTriggerMiddlewareValidation implements ISoundTriggerMiddleware synchronized (SoundTriggerMiddlewareValidation.this) { // State validation. - if (mState == ModuleState.DETACHED) { + if (mState == ModuleStatus.DETACHED) { throw new IllegalStateException("Module has been detached."); } // From here on, every exception isn't client's fault. try { int handle = mDelegate.loadModel(model); - mLoadedModels.put(handle, new ModelState()); + mLoadedModels.put(handle, new ModelState(model)); return handle; } catch (Exception e) { throw handleException(e); @@ -425,14 +447,14 @@ public class SoundTriggerMiddlewareValidation implements ISoundTriggerMiddleware synchronized (SoundTriggerMiddlewareValidation.this) { // State validation. - if (mState == ModuleState.DETACHED) { + if (mState == ModuleStatus.DETACHED) { throw new IllegalStateException("Module has been detached."); } // From here on, every exception isn't client's fault. try { int handle = mDelegate.loadPhraseModel(model); - mLoadedModels.put(handle, new ModelState()); + mLoadedModels.put(handle, new ModelState(model)); return handle; } catch (Exception e) { throw handleException(e); @@ -448,7 +470,7 @@ public class SoundTriggerMiddlewareValidation implements ISoundTriggerMiddleware synchronized (SoundTriggerMiddlewareValidation.this) { // State validation. - if (mState == ModuleState.DETACHED) { + if (mState == ModuleStatus.DETACHED) { throw new IllegalStateException("Module has been detached."); } ModelState modelState = mLoadedModels.get( @@ -481,7 +503,7 @@ public class SoundTriggerMiddlewareValidation implements ISoundTriggerMiddleware synchronized (SoundTriggerMiddlewareValidation.this) { // State validation. - if (mState == ModuleState.DETACHED) { + if (mState == ModuleStatus.DETACHED) { throw new IllegalStateException("Module has been detached."); } ModelState modelState = mLoadedModels.get( @@ -515,7 +537,7 @@ public class SoundTriggerMiddlewareValidation implements ISoundTriggerMiddleware synchronized (SoundTriggerMiddlewareValidation.this) { // State validation. - if (mState == ModuleState.DETACHED) { + if (mState == ModuleStatus.DETACHED) { throw new IllegalStateException("Module has been detached."); } ModelState modelState = mLoadedModels.get( @@ -544,7 +566,7 @@ public class SoundTriggerMiddlewareValidation implements ISoundTriggerMiddleware synchronized (SoundTriggerMiddlewareValidation.this) { // State validation. - if (mState == ModuleState.DETACHED) { + if (mState == ModuleStatus.DETACHED) { throw new IllegalStateException("Module has been detached."); } ModelState modelState = mLoadedModels.get( @@ -572,7 +594,7 @@ public class SoundTriggerMiddlewareValidation implements ISoundTriggerMiddleware synchronized (SoundTriggerMiddlewareValidation.this) { // State validation. - if (mState == ModuleState.DETACHED) { + if (mState == ModuleStatus.DETACHED) { throw new IllegalStateException("Module has been detached."); } ModelState modelState = mLoadedModels.get( @@ -600,7 +622,7 @@ public class SoundTriggerMiddlewareValidation implements ISoundTriggerMiddleware synchronized (SoundTriggerMiddlewareValidation.this) { // State validation. - if (mState == ModuleState.DETACHED) { + if (mState == ModuleStatus.DETACHED) { throw new IllegalStateException("Module has been detached."); } ModelState modelState = mLoadedModels.get( @@ -629,7 +651,7 @@ public class SoundTriggerMiddlewareValidation implements ISoundTriggerMiddleware synchronized (SoundTriggerMiddlewareValidation.this) { // State validation. - if (mState == ModuleState.DETACHED) { + if (mState == ModuleStatus.DETACHED) { throw new IllegalStateException("Module has been detached."); } ModelState modelState = mLoadedModels.get( @@ -658,10 +680,10 @@ public class SoundTriggerMiddlewareValidation implements ISoundTriggerMiddleware synchronized (SoundTriggerMiddlewareValidation.this) { // State validation. - if (mState == ModuleState.DETACHED) { + if (mState == ModuleStatus.DETACHED) { throw new IllegalStateException("Module has already been detached."); } - if (mState == ModuleState.ALIVE && !mLoadedModels.isEmpty()) { + if (mState == ModuleStatus.ALIVE && !mLoadedModels.isEmpty()) { throw new IllegalStateException("Cannot detach while models are loaded."); } @@ -683,16 +705,16 @@ public class SoundTriggerMiddlewareValidation implements ISoundTriggerMiddleware private void detachInternal() { try { mDelegate.detach(); - mState = ModuleState.DETACHED; + mState = ModuleStatus.DETACHED; mCallback.asBinder().unlinkToDeath(this, 0); - mModules.get(mHandle).remove(this); + mModules.get(mHandle).sessions.remove(this); } catch (RemoteException e) { throw e.rethrowAsRuntimeException(); } } void dump(PrintWriter pw) { - if (mState == ModuleState.ALIVE) { + if (mState == ModuleStatus.ALIVE) { pw.printf("Loaded models for session %s (handle, active)", toString()); pw.println(); pw.println("-------------------------------"); @@ -700,6 +722,8 @@ public class SoundTriggerMiddlewareValidation implements ISoundTriggerMiddleware pw.print(entry.getKey()); pw.print('\t'); pw.print(entry.getValue().activityState.name()); + pw.print('\t'); + pw.print(entry.getValue().description); pw.println(); } } else { @@ -762,7 +786,7 @@ public class SoundTriggerMiddlewareValidation implements ISoundTriggerMiddleware public void onModuleDied() { synchronized (SoundTriggerMiddlewareValidation.this) { try { - mState = ModuleState.DEAD; + mState = ModuleStatus.DEAD; mCallback.onModuleDied(); } catch (RemoteException e) { // Dead client will be handled by binderDied() - no need to handle here. diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java index d7a0c9871b48..289bf66e1add 100644 --- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java +++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java @@ -1380,11 +1380,11 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D } @Override - public void onNotificationBubbleChanged(String key, boolean isBubble) { + public void onNotificationBubbleChanged(String key, boolean isBubble, int flags) { enforceStatusBarService(); long identity = Binder.clearCallingIdentity(); try { - mNotificationDelegate.onNotificationBubbleChanged(key, isBubble); + mNotificationDelegate.onNotificationBubbleChanged(key, isBubble, flags); } finally { Binder.restoreCallingIdentity(identity); } diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java index 68224b59a287..4fe58433ddb6 100644 --- a/services/core/java/com/android/server/wm/AccessibilityController.java +++ b/services/core/java/com/android/server/wm/AccessibilityController.java @@ -16,6 +16,7 @@ package com.android.server.wm; +import static android.view.InsetsState.ITYPE_NAVIGATION_BAR; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY; import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER; import static android.view.WindowManager.LayoutParams.TYPE_MAGNIFICATION_OVERLAY; @@ -48,6 +49,7 @@ import android.util.Slog; import android.util.SparseArray; import android.util.TypedValue; import android.view.Display; +import android.view.InsetsState; import android.view.MagnificationSpec; import android.view.Surface; import android.view.Surface.OutOfResourcesException; @@ -672,6 +674,15 @@ final class AccessibilityController { availableBounds.op(windowBounds, Region.Op.DIFFERENCE); } + // If the navigation bar window doesn't have touchable region, count + // navigation bar insets into nonMagnifiedBounds. It happens when + // navigation mode is gestural. + if (isUntouchableNavigationBar(windowState, mTempRegion3)) { + final Rect navBarInsets = getNavBarInsets(mDisplayContent); + nonMagnifiedBounds.op(navBarInsets, Region.Op.UNION); + availableBounds.op(navBarInsets, Region.Op.DIFFERENCE); + } + // Count letterbox into nonMagnifiedBounds if (windowState.isLetterboxedForDisplayCutoutLw()) { Region letterboxBounds = getLetterboxBounds(windowState); @@ -1089,6 +1100,24 @@ final class AccessibilityController { } } + static boolean isUntouchableNavigationBar(WindowState windowState, + Region touchableRegion) { + if (windowState.mAttrs.type != WindowManager.LayoutParams.TYPE_NAVIGATION_BAR) { + return false; + } + + // Gets the touchable region. + windowState.getTouchableRegion(touchableRegion); + + return touchableRegion.isEmpty(); + } + + static Rect getNavBarInsets(DisplayContent displayContent) { + final InsetsState insetsState = + displayContent.getInsetsStateController().getRawInsetsState(); + return insetsState.getSource(ITYPE_NAVIGATION_BAR).getFrame(); + } + /** * This class encapsulates the functionality related to computing the windows * reported for accessibility purposes. These windows are all windows a sighted @@ -1203,6 +1232,13 @@ final class AccessibilityController { updateUnaccountedSpace(windowState, regionInScreen, unaccountedSpace, skipRemainingWindowsForTasks); focusedWindowAdded |= windowState.isFocused(); + } else if (isUntouchableNavigationBar(windowState, mTempRegion1)) { + // If this widow is navigation bar without touchable region, accounting the + // region of navigation bar inset because all touch events from this region + // would be received by launcher, i.e. this region is a un-touchable one + // for the application. + unaccountedSpace.op(getNavBarInsets(dc), unaccountedSpace, + Region.Op.REVERSE_DIFFERENCE); } if (unaccountedSpace.isEmpty() && focusedWindowAdded) { diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index aabac77ebe33..e79b804f76f9 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -1298,6 +1298,19 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A if (newTask != null && isState(RESUMED)) { newTask.setResumedActivity(this, "onParentChanged"); } + + if (stack != null && stack.topRunningActivity() == this) { + // carry over the PictureInPictureParams to the parent stack without calling + // TaskOrganizerController#dispatchTaskInfoChanged. + // this is to ensure the stack holding up-to-dated pinned stack information + // when activity is re-parented to enter pip mode, see also + // RootWindowContainer#moveActivityToPinnedStack + stack.mPictureInPictureParams.copyOnlySet(pictureInPictureArgs); + // make ensure the TaskOrganizer still works after re-parenting + if (firstWindowDrawn) { + stack.setHasBeenVisible(true); + } + } } private void updateColorTransform() { @@ -2656,6 +2669,17 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A return this; } + // Ensure activity visibilities and update lockscreen occluded/dismiss state when + // finishing the top activity that occluded keyguard. So that, the + // ActivityStack#mTopActivityOccludesKeyguard can be updated and the activity below won't + // be resumed. + if (isState(PAUSED) + && mStackSupervisor.getKeyguardController().isKeyguardLocked() + && getStack().topActivityOccludesKeyguard()) { + getStack().ensureActivitiesVisible(null /* starting */, 0 /* configChanges */, + false /* preserveWindows */, false /* notifyClients */); + } + boolean activityRemoved = false; // If this activity is currently visible, and the resumed activity is not yet visible, then @@ -5112,26 +5136,48 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } void startFreezingScreen() { + startFreezingScreen(ROTATION_UNDEFINED /* overrideOriginalDisplayRotation */); + } + + void startFreezingScreen(int overrideOriginalDisplayRotation) { ProtoLog.i(WM_DEBUG_ORIENTATION, "Set freezing of %s: visible=%b freezing=%b visibleRequested=%b. %s", appToken, isVisible(), mFreezingScreen, mVisibleRequested, new RuntimeException().fillInStackTrace()); - if (mVisibleRequested) { - if (!mFreezingScreen) { - mFreezingScreen = true; - mWmService.registerAppFreezeListener(this); - mWmService.mAppsFreezingScreen++; - if (mWmService.mAppsFreezingScreen == 1) { - mWmService.startFreezingDisplayLocked(0, 0, getDisplayContent()); - mWmService.mH.removeMessages(H.APP_FREEZE_TIMEOUT); - mWmService.mH.sendEmptyMessageDelayed(H.APP_FREEZE_TIMEOUT, 2000); + if (!mVisibleRequested) { + return; + } + + // If the override is given, the rotation of display doesn't change but we still want to + // cover the activity whose configuration is changing by freezing the display and running + // the rotation animation. + final boolean forceRotation = overrideOriginalDisplayRotation != ROTATION_UNDEFINED; + if (!mFreezingScreen) { + mFreezingScreen = true; + mWmService.registerAppFreezeListener(this); + mWmService.mAppsFreezingScreen++; + if (mWmService.mAppsFreezingScreen == 1) { + if (forceRotation) { + // Make sure normal rotation animation will be applied. + mDisplayContent.getDisplayRotation().cancelSeamlessRotation(); } + mWmService.startFreezingDisplay(0 /* exitAnim */, 0 /* enterAnim */, + mDisplayContent, overrideOriginalDisplayRotation); + mWmService.mH.removeMessages(H.APP_FREEZE_TIMEOUT); + mWmService.mH.sendEmptyMessageDelayed(H.APP_FREEZE_TIMEOUT, 2000); } - final int count = mChildren.size(); - for (int i = 0; i < count; i++) { - final WindowState w = mChildren.get(i); - w.onStartFreezingScreen(); - } + } + if (forceRotation) { + // The rotation of the real display won't change, so in order to unfreeze the screen + // via {@link #checkAppWindowsReadyToShow}, the windows have to be able to call + // {@link WindowState#reportResized} (it is skipped if the window is freezing) to update + // the drawn state. + return; + } + final int count = mChildren.size(); + for (int i = 0; i < count; i++) { + final WindowState w = mChildren.get(i); + w.onStartFreezingScreen(); } } @@ -6146,6 +6192,21 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A ensureActivityConfiguration(0 /* globalChanges */, false /* preserveWindow */); } + @Override + void onCancelFixedRotationTransform(int originalDisplayRotation) { + if (this != mDisplayContent.getLastOrientationSource() + || getRequestedConfigurationOrientation() != ORIENTATION_UNDEFINED) { + // Only need to handle the activity that should be rotated with display. + return; + } + + // Perform rotation animation according to the rotation of this activity. + startFreezingScreen(originalDisplayRotation); + // This activity may relaunch or perform configuration change so once it has reported drawn, + // the screen can be unfrozen. + ensureActivityConfiguration(0 /* globalChanges */, !PRESERVE_WINDOWS); + } + void setRequestedOrientation(int requestedOrientation) { setOrientation(requestedOrientation, mayFreezeScreenLocked()); mAtmService.getTaskChangeNotificationController().notifyActivityRequestedOrientationChanged( diff --git a/services/core/java/com/android/server/wm/ActivityStack.java b/services/core/java/com/android/server/wm/ActivityStack.java index bcad7586b918..8bf46bc7c2e8 100644 --- a/services/core/java/com/android/server/wm/ActivityStack.java +++ b/services/core/java/com/android/server/wm/ActivityStack.java @@ -783,6 +783,11 @@ class ActivityStack extends Task { if (currentMode == WINDOWING_MODE_PINNED) { mAtmService.getTaskChangeNotificationController().notifyActivityUnpinned(); } + if (likelyResolvedMode == WINDOWING_MODE_PINNED + && taskDisplayArea.getRootPinnedTask() != null) { + // Can only have 1 pip at a time, so replace an existing pip + taskDisplayArea.getRootPinnedTask().dismissPip(); + } if (likelyResolvedMode != WINDOWING_MODE_FULLSCREEN && topActivity != null && !topActivity.noDisplay && topActivity.isNonResizableOrForcedResizable(likelyResolvedMode)) { @@ -1049,6 +1054,9 @@ class ActivityStack extends Task { } /** + * This moves 'task' to the back of this task and also recursively moves this task to the back + * of its parents (if applicable). + * * @param reason The reason for moving the stack to the back. * @param task If non-null, the task will be moved to the bottom of the stack. **/ @@ -1056,18 +1064,41 @@ class ActivityStack extends Task { if (!isAttached()) { return; } - - getDisplayArea().positionStackAtBottom(this, reason); - if (task != null && task != this) { - positionChildAtBottom(task); + final TaskDisplayArea displayArea = getDisplayArea(); + if (!mCreatedByOrganizer) { + // If this is just a normal task, so move to back of parent and then move 'task' to + // back of this. + final WindowContainer parent = getParent(); + final Task parentTask = parent != null ? parent.asTask() : null; + if (parentTask != null) { + ((ActivityStack) parentTask).moveToBack(reason, this); + } else { + displayArea.positionStackAtBottom(this, reason); + } + if (task != null && task != this) { + positionChildAtBottom(task); + } + return; } - - /** - * The intent behind moving a primary split screen stack to the back is usually to hide - * behind the home stack. Exit split screen in this case. - */ - if (getWindowingMode() == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) { - setWindowingMode(WINDOWING_MODE_UNDEFINED); + if (task == null || task == this) { + return; + } + // This is a created-by-organizer task. In this case, let the organizer deal with this + // task's ordering. However, we still need to move 'task' to back. The intention is that + // this ends up behind the home-task so that it is made invisible; so, if the home task + // is not a child of this, reparent 'task' to the back of the home task's actual parent. + final ActivityStack home = displayArea.getOrCreateRootHomeTask(); + final WindowContainer homeParent = home.getParent(); + final Task homeParentTask = homeParent != null ? homeParent.asTask() : null; + if (homeParentTask == null) { + ((ActivityStack) task).reparent(displayArea, false /* onTop */); + } else if (homeParentTask == this) { + // Apparently reparent early-outs if same stack, so we have to explicitly reorder. + positionChildAtBottom(task); + } else { + task.reparent((ActivityStack) homeParentTask, false /* toTop */, + REPARENT_LEAVE_STACK_IN_PLACE, false /* animate */, false /* deferResume */, + "moveToBack"); } } diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java index f4eb0d2c8e89..7a04894523f5 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java @@ -4093,11 +4093,8 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { r.setPictureInPictureParams(params); final float aspectRatio = r.pictureInPictureArgs.getAspectRatio(); final List<RemoteAction> actions = r.pictureInPictureArgs.getActions(); - // Adjust the source bounds by the insets for the transition down - final Rect sourceBounds = new Rect( - r.pictureInPictureArgs.getSourceRectHint()); mRootWindowContainer.moveActivityToPinnedStack( - r, sourceBounds, aspectRatio, "enterPictureInPictureMode"); + r, "enterPictureInPictureMode"); final ActivityStack stack = r.getRootTask(); stack.setPictureInPictureAspectRatio(aspectRatio); stack.setPictureInPictureActions(actions); diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 80a1a4592ff3..2a676e1de5af 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -25,6 +25,7 @@ import static android.app.WindowConfiguration.ROTATION_UNDEFINED; import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; 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.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET; @@ -72,7 +73,6 @@ import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER; import static android.view.WindowManager.TRANSIT_ACTIVITY_OPEN; import static android.view.WindowManager.TRANSIT_TASK_OPEN; import static android.view.WindowManager.TRANSIT_TASK_TO_FRONT; -import static android.window.DisplayAreaOrganizer.FEATURE_DEFAULT_TASK_CONTAINER; import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM; import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG; @@ -198,7 +198,6 @@ import android.view.ViewRootImpl; import android.view.WindowInsets; import android.view.WindowManager; import android.view.WindowManagerPolicyConstants.PointerEventListener; -import android.window.ITaskOrganizer; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.logging.MetricsLogger; @@ -494,6 +493,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo * The launching activity which is using fixed rotation transformation. * * @see #handleTopActivityLaunchingInDifferentOrientation + * @see DisplayRotation#shouldRotateSeamlessly */ ActivityRecord mFixedRotationLaunchingApp; @@ -538,6 +538,15 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo */ WindowState mInputMethodTarget; + /** + * The window which receives input from the input method. This is also a candidate of the + * input method control target. + */ + WindowState mInputMethodInputTarget; + + /** + * This controls the visibility and animation of the input method window. + */ InsetsControlTarget mInputMethodControlTarget; /** If true hold off on modifying the animation layer of mInputMethodTarget */ @@ -1237,7 +1246,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo if (configChanged) { mWaitingForConfig = true; - mWmService.startFreezingDisplayLocked(0 /* exitAnim */, 0 /* enterAnim */, this); + mWmService.startFreezingDisplay(0 /* exitAnim */, 0 /* enterAnim */, this); sendNewConfiguration(); } @@ -1475,6 +1484,9 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo sendNewConfiguration(); return true; } + // The display won't rotate (e.g. the orientation from sensor has updated again before + // applying rotation to display), so clear it to stop using seamless rotation. + mFixedRotationLaunchingApp = null; return false; } @@ -3242,6 +3254,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo mInsetsStateController.getSourceProvider(ITYPE_IME).setWindow(win, null /* frameProvider */, null /* imeFrameProvider */); computeImeTarget(true /* updateImeTarget */); + updateImeControlTarget(); } /** @@ -3421,8 +3434,6 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo } private void setInputMethodTarget(WindowState target, boolean targetWaitingAnim) { - // Always update control target. This is needed to handle rotation. - updateImeControlTarget(target); if (target == mInputMethodTarget && mInputMethodTargetWaitingAnim == targetWaitingAnim) { return; } @@ -3431,32 +3442,34 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo mInputMethodTargetWaitingAnim = targetWaitingAnim; assignWindowLayers(false /* setLayoutNeeded */); updateImeParent(); + updateImeControlTarget(); } /** - * IME control target is the window that controls the IME visibility and animation. - * This window is same as the window on which startInput is called. - * @param target the window that receives IME control. This is ignored if we aren't attaching - * the IME to an app (eg. when in multi-window mode). + * The IME input target is the window which receives input from IME. It is also a candidate + * which controls the visibility and animation of the input method window. * - * @see #getImeControlTarget() + * @param target the window that receives input from IME. */ - void updateImeControlTarget(InsetsControlTarget target) { + void setInputMethodInputTarget(WindowState target) { + if (mInputMethodInputTarget != target) { + mInputMethodInputTarget = target; + updateImeControlTarget(); + } + } + + private void updateImeControlTarget() { if (!isImeAttachedToApp() && mRemoteInsetsControlTarget != null) { mInputMethodControlTarget = mRemoteInsetsControlTarget; } else { - // Otherwise, we just use the ime target - mInputMethodControlTarget = target; + // Otherwise, we just use the ime input target + mInputMethodControlTarget = mInputMethodInputTarget; } mInsetsStateController.onImeControlTargetChanged(mInputMethodControlTarget); } private void updateImeParent() { - // Force attaching IME to the display when magnifying, or it would be magnified with - // target app together. - final boolean shouldAttachToDisplay = (mMagnificationSpec != null); - final SurfaceControl newParent = - shouldAttachToDisplay ? mWindowContainers.getSurfaceControl() : computeImeParent(); + final SurfaceControl newParent = computeImeParent(); if (newParent != null) { getPendingTransaction().reparent(mImeWindowsContainers.mSurfaceControl, newParent); scheduleAnimation(); @@ -3468,16 +3481,19 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo */ @VisibleForTesting SurfaceControl computeImeParent() { + // Force attaching IME to the display when magnifying, or it would be magnified with + // target app together. + final boolean allowAttachToApp = (mMagnificationSpec == null); // Attach it to app if the target is part of an app and such app is covering the entire // screen. If it's not covering the entire screen the IME might extend beyond the apps // bounds. - if (isImeAttachedToApp()) { + if (allowAttachToApp && isImeAttachedToApp()) { return mInputMethodTarget.mActivityRecord.getSurfaceControl(); } - // Otherwise, we just attach it to the display. - return mWindowContainers.getSurfaceControl(); + // Otherwise, we just attach it to where the display area policy put it. + return mImeWindowsContainers.getParent().getSurfaceControl(); } void setLayoutNeeded() { @@ -4722,6 +4738,11 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo return mWindowContainers.getSurfaceControl(); } + @VisibleForTesting + WindowContainer<?> getImeContainer() { + return mImeWindowsContainers; + } + SurfaceControl getOverlayLayer() { return mOverlayContainers.getSurfaceControl(); } @@ -5028,6 +5049,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo return activityType == ACTIVITY_TYPE_STANDARD && (windowingMode == WINDOWING_MODE_FULLSCREEN || windowingMode == WINDOWING_MODE_FREEFORM + || windowingMode == WINDOWING_MODE_PINNED || windowingMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY || windowingMode == WINDOWING_MODE_MULTI_WINDOW); } diff --git a/services/core/java/com/android/server/wm/DisplayRotation.java b/services/core/java/com/android/server/wm/DisplayRotation.java index bef80f0a230a..ebfe70c0c371 100644 --- a/services/core/java/com/android/server/wm/DisplayRotation.java +++ b/services/core/java/com/android/server/wm/DisplayRotation.java @@ -537,8 +537,29 @@ public class DisplayRotation { } void prepareNormalRotationAnimation() { + cancelSeamlessRotation(); final RotationAnimationPair anim = selectRotationAnimation(); - mService.startFreezingDisplayLocked(anim.mExit, anim.mEnter, mDisplayContent); + mService.startFreezingDisplay(anim.mExit, anim.mEnter, mDisplayContent); + } + + /** + * This ensures that normal rotation animation is used. E.g. {@link #mRotatingSeamlessly} was + * set by previous {@link #updateRotationUnchecked}, but another orientation change happens + * before calling {@link DisplayContent#sendNewConfiguration} (remote rotation hasn't finished) + * and it doesn't choose seamless rotation. + */ + void cancelSeamlessRotation() { + if (!mRotatingSeamlessly) { + return; + } + mDisplayContent.forAllWindows(w -> { + if (w.mSeamlesslyRotated) { + w.finishSeamlessRotation(false /* timeout */); + w.mSeamlesslyRotated = false; + } + }, true /* traverseTopToBottom */); + mSeamlessRotationCount = 0; + mRotatingSeamlessly = false; } private void prepareSeamlessRotation() { diff --git a/services/core/java/com/android/server/wm/InsetsSourceProvider.java b/services/core/java/com/android/server/wm/InsetsSourceProvider.java index cb0d8536fe72..1ca82ceeb570 100644 --- a/services/core/java/com/android/server/wm/InsetsSourceProvider.java +++ b/services/core/java/com/android/server/wm/InsetsSourceProvider.java @@ -266,7 +266,7 @@ class InsetsSourceProvider { if (getSource().getType() == ITYPE_IME) { setClientVisible(InsetsState.getDefaultVisibility(mSource.getType())); } - final Transaction t = mDisplayContent.getPendingTransaction(); + final Transaction t = mDisplayContent.mWmService.mTransactionFactory.get(); mWin.startAnimation(t, mAdapter, !mClientVisible /* hidden */, ANIMATION_TYPE_INSETS_CONTROL, null /* animationFinishedCallback */); final SurfaceControl leash = mAdapter.mCapturedLeash; @@ -281,6 +281,9 @@ class InsetsSourceProvider { t.deferTransactionUntil(mWin.getSurfaceControl(), barrier, frameNumber); t.deferTransactionUntil(leash, barrier, frameNumber); } + // Applying the transaction here can prevent the client from applying its transaction sooner + // than us which makes us overwrite the client's operation to the leash. + t.apply(); mControlTarget = target; mControl = new InsetsSourceControl(mSource.getType(), leash, new Point(mWin.getWindowFrames().mFrame.left, mWin.getWindowFrames().mFrame.top)); diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java index 1a70de71df4f..e8f7ba550bd8 100644 --- a/services/core/java/com/android/server/wm/RootWindowContainer.java +++ b/services/core/java/com/android/server/wm/RootWindowContainer.java @@ -2147,13 +2147,11 @@ class RootWindowContainer extends WindowContainer<DisplayContent> return false; } - moveActivityToPinnedStack(r, null /* sourceBounds */, 0f /* aspectRatio */, - "moveTopActivityToPinnedStack"); + moveActivityToPinnedStack(r, "moveTopActivityToPinnedStack"); return true; } - void moveActivityToPinnedStack(ActivityRecord r, Rect sourceHintBounds, float aspectRatio, - String reason) { + void moveActivityToPinnedStack(ActivityRecord r, String reason) { mService.deferWindowLayout(); final TaskDisplayArea taskDisplayArea = r.getDisplayArea(); @@ -2176,17 +2174,19 @@ class RootWindowContainer extends WindowContainer<DisplayContent> final ActivityStack stack; if (singleActivity) { stack = r.getRootTask(); - stack.setWindowingMode(WINDOWING_MODE_PINNED); } else { // In the case of multiple activities, we will create a new task for it and then // move the PIP activity into the task. - stack = taskDisplayArea.createStack(WINDOWING_MODE_PINNED, r.getActivityType(), + stack = taskDisplayArea.createStack(WINDOWING_MODE_UNDEFINED, r.getActivityType(), ON_TOP, r.info, r.intent, false /* createdByOrganizer */); // There are multiple activities in the task and moving the top activity should // reveal/leave the other activities in their original task. - r.reparent(stack, MAX_VALUE, "moveActivityToStack"); + // On the other hand, ActivityRecord#onParentChanged takes care of setting the + // up-to-dated pinned stack information on this newly created stack. + r.reparent(stack, MAX_VALUE, reason); } + stack.setWindowingMode(WINDOWING_MODE_PINNED); // Reset the state that indicates it can enter PiP while pausing after we've moved it // to the pinned stack diff --git a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java index b92ead1a0531..5f33ea170923 100644 --- a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java +++ b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java @@ -41,7 +41,6 @@ import android.graphics.Rect; import android.os.Trace; import android.util.Slog; import android.util.proto.ProtoOutputStream; -import android.view.Display; import android.view.DisplayInfo; import android.view.Surface; import android.view.Surface.OutOfResourcesException; @@ -117,8 +116,9 @@ class ScreenRotationAnimation { private BlackFrame mEnteringBlackFrame; private int mWidth, mHeight; - private int mOriginalRotation; - private int mOriginalWidth, mOriginalHeight; + private final int mOriginalRotation; + private final int mOriginalWidth; + private final int mOriginalHeight; private int mCurRotation; private Rect mOriginalDisplayRect = new Rect(); @@ -140,20 +140,18 @@ class ScreenRotationAnimation { /** Intensity of light/whiteness of the layout after rotation occurs. */ private float mEndLuma; - public ScreenRotationAnimation(Context context, DisplayContent displayContent, - boolean fixedToUserRotation, boolean isSecure, WindowManagerService service) { - mService = service; - mContext = context; + ScreenRotationAnimation(DisplayContent displayContent, @Surface.Rotation int originalRotation) { + mService = displayContent.mWmService; + mContext = mService.mContext; mDisplayContent = displayContent; displayContent.getBounds(mOriginalDisplayRect); // Screenshot does NOT include rotation! - final Display display = displayContent.getDisplay(); - int originalRotation = display.getRotation(); + final DisplayInfo displayInfo = displayContent.getDisplayInfo(); + final int realOriginalRotation = displayInfo.rotation; final int originalWidth; final int originalHeight; - DisplayInfo displayInfo = displayContent.getDisplayInfo(); - if (fixedToUserRotation) { + if (displayContent.getDisplayRotation().isFixedToUserRotation()) { // Emulated orientation. mForceDefaultOrientation = true; originalWidth = displayContent.mBaseDisplayWidth; @@ -163,8 +161,8 @@ class ScreenRotationAnimation { originalWidth = displayInfo.logicalWidth; originalHeight = displayInfo.logicalHeight; } - if (originalRotation == Surface.ROTATION_90 - || originalRotation == Surface.ROTATION_270) { + if (realOriginalRotation == Surface.ROTATION_90 + || realOriginalRotation == Surface.ROTATION_270) { mWidth = originalHeight; mHeight = originalWidth; } else { @@ -173,10 +171,18 @@ class ScreenRotationAnimation { } mOriginalRotation = originalRotation; - mOriginalWidth = originalWidth; - mOriginalHeight = originalHeight; + // If the delta is not zero, the rotation of display may not change, but we still want to + // apply rotation animation because there should be a top app shown as rotated. So the + // specified original rotation customizes the direction of animation to have better look + // when restoring the rotated app to the same rotation as current display. + final int delta = DisplayContent.deltaRotation(originalRotation, realOriginalRotation); + final boolean flipped = delta == Surface.ROTATION_90 || delta == Surface.ROTATION_270; + mOriginalWidth = flipped ? originalHeight : originalWidth; + mOriginalHeight = flipped ? originalWidth : originalHeight; mSurfaceRotationAnimationController = new SurfaceRotationAnimationController(); + // Check whether the current screen contains any secure content. + final boolean isSecure = displayContent.hasSecureWindowOnScreen(); final SurfaceControl.Transaction t = mService.mTransactionFactory.get(); try { mBackColorSurface = displayContent.makeChildSurface(null) @@ -202,7 +208,7 @@ class ScreenRotationAnimation { t2.apply(true /* sync */); // Capture a screenshot into the surface we just created. - final int displayId = display.getDisplayId(); + final int displayId = displayContent.getDisplayId(); final Surface surface = mService.mSurfaceFactory.get(); surface.copyFrom(mScreenshotLayer); SurfaceControl.ScreenshotGraphicBuffer gb = @@ -242,7 +248,7 @@ class ScreenRotationAnimation { ProtoLog.i(WM_SHOW_SURFACE_ALLOC, " FREEZE %s: CREATE", mScreenshotLayer); - setRotation(t, originalRotation); + setRotation(t, realOriginalRotation); t.apply(); } diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java index f8ee09b7a142..ad1a205a4910 100644 --- a/services/core/java/com/android/server/wm/Task.java +++ b/services/core/java/com/android/server/wm/Task.java @@ -212,7 +212,6 @@ class Task extends WindowContainer<WindowContainer> { static final int INVALID_MIN_SIZE = -1; private float mShadowRadius = 0; private final Rect mLastSurfaceCrop = new Rect(); - private static final boolean ENABLE_FREEFORM_COMPOSITOR_SHADOWS = false; /** * The modes to control how the stack is moved to the front when calling {@link Task#reparent}. @@ -2729,10 +2728,8 @@ class Task extends WindowContainer<WindowContainer> { } private void updateSurfaceCrop() { - // TODO(b/149585281) remove when root task has the correct bounds for freeform // Only update the crop if we are drawing shadows on the task. - if (mSurfaceControl == null || !mWmService.mRenderShadowsInCompositor - || !isRootTask() || !ENABLE_FREEFORM_COMPOSITOR_SHADOWS) { + if (mSurfaceControl == null || !mWmService.mRenderShadowsInCompositor || !isRootTask()) { return; } @@ -3072,6 +3069,7 @@ class Task extends WindowContainer<WindowContainer> { mForceShowForAllUsers = forceShowForAllUsers; } + @Override public boolean isAttached() { final TaskDisplayArea taskDisplayArea = getDisplayArea(); return taskDisplayArea != null && !taskDisplayArea.isRemoved(); @@ -4272,8 +4270,7 @@ class Task extends WindowContainer<WindowContainer> { // Get elevation for a specific windowing mode. if (inPinnedWindowingMode()) { elevation = PINNED_WINDOWING_MODE_ELEVATION_IN_DIP; - } else if (ENABLE_FREEFORM_COMPOSITOR_SHADOWS && inFreeformWindowingMode()) { - // TODO(b/149585281) remove when root task has the correct bounds for freeform + } else if (inFreeformWindowingMode()) { elevation = taskIsFocused ? DECOR_SHADOW_FOCUSED_HEIGHT_IN_DIP : DECOR_SHADOW_UNFOCUSED_HEIGHT_IN_DIP; } else { diff --git a/services/core/java/com/android/server/wm/TaskDisplayArea.java b/services/core/java/com/android/server/wm/TaskDisplayArea.java index ea9a3629a40f..d71e56106e18 100644 --- a/services/core/java/com/android/server/wm/TaskDisplayArea.java +++ b/services/core/java/com/android/server/wm/TaskDisplayArea.java @@ -879,6 +879,11 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> { + windowingMode); } + if (windowingMode == WINDOWING_MODE_PINNED && getRootPinnedTask() != null) { + // Only 1 stack can be PINNED at a time, so dismiss the existing one + getRootPinnedTask().dismissPip(); + } + final int stackId = getNextStackId(); return createStackUnchecked(windowingMode, activityType, stackId, onTop, info, intent, createdByOrganizer); diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java index fba22dd4e9df..77530fb629bc 100644 --- a/services/core/java/com/android/server/wm/WindowContainer.java +++ b/services/core/java/com/android/server/wm/WindowContainer.java @@ -737,6 +737,10 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< return parent != null ? parent.getDisplayArea() : null; } + boolean isAttached() { + return getDisplayArea() != null; + } + void setWaitingForDrawnIfResizingChanged() { for (int i = mChildren.size() - 1; i >= 0; --i) { final WindowContainer wc = mChildren.get(i); @@ -2300,14 +2304,18 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< } } + void resetSurfacePositionForAnimationLeash(Transaction t) { + t.setPosition(mSurfaceControl, 0, 0); + mLastSurfacePosition.set(0, 0); + } + @Override public void onAnimationLeashCreated(Transaction t, SurfaceControl leash) { mLastLayer = -1; reassignLayer(t); // Leash is now responsible for position, so set our position to 0. - t.setPosition(mSurfaceControl, 0, 0); - mLastSurfacePosition.set(0, 0); + resetSurfacePositionForAnimationLeash(t); } @Override diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 9d879765f8df..84cc19d68a24 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -29,6 +29,7 @@ import static android.app.ActivityManagerInternal.ALLOW_NON_FULL; import static android.app.ActivityTaskManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT; import static android.app.AppOpsManager.OP_SYSTEM_ALERT_WINDOW; import static android.app.StatusBarManager.DISABLE_MASK; +import static android.app.WindowConfiguration.ROTATION_UNDEFINED; import static android.app.admin.DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED; import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT; import static android.content.pm.PackageManager.FEATURE_PC; @@ -1696,15 +1697,14 @@ public class WindowManagerService extends IWindowManager.Stub } displayContent.getInputMonitor().updateInputWindowsLw(false /*force*/); - getInsetsSourceControls(win, outActiveControls); - ProtoLog.v(WM_DEBUG_ADD_REMOVE, "addWindow: New client %s" + ": window=%s Callers=%s", client.asBinder(), win, Debug.getCallers(5)); - if (win.isVisibleOrAdding() && displayContent.updateOrientation()) { displayContent.sendNewConfiguration(); } + + getInsetsSourceControls(win, outActiveControls); } Binder.restoreCallingIdentity(origId); @@ -2400,7 +2400,6 @@ public class WindowManagerService extends IWindowManager.Stub outCutout.set(win.getWmDisplayCutout().getDisplayCutout()); outBackdropFrame.set(win.getBackdropFrame(win.getFrameLw())); outInsetsState.set(win.getInsetsState(), win.isClientLocal()); - getInsetsSourceControls(win, outActiveControls); if (DEBUG) { Slog.v(TAG_WM, "Relayout given client " + client.asBinder() + ", requestedWidth=" + requestedWidth @@ -2431,6 +2430,7 @@ public class WindowManagerService extends IWindowManager.Stub outSurfaceSize.set(winAnimator.mSurfaceController.getWidth(), winAnimator.mSurfaceController.getHeight()); } + getInsetsSourceControls(win, outActiveControls); } Binder.restoreCallingIdentity(origId); @@ -2445,8 +2445,17 @@ public class WindowManagerService extends IWindowManager.Stub if (controls != null) { final int length = Math.min(controls.length, outControls.length); for (int i = 0; i < length; i++) { - outControls[i] = win.isClientLocal() - ? new InsetsSourceControl(controls[i]) : controls[i]; + final InsetsSourceControl control = controls[i]; + + // Check if we are sending invalid leashes. + final SurfaceControl leash = control != null ? control.getLeash() : null; + if (leash != null && !leash.isValid()) { + Slog.wtf(TAG, leash + " is not valid before sending to " + win, + leash.getReleaseStack()); + } + + outControls[i] = win.isClientLocal() && control != null + ? new InsetsSourceControl(control) : control; } } } @@ -2941,7 +2950,7 @@ public class WindowManagerService extends IWindowManager.Stub mClientFreezingScreen = true; final long origId = Binder.clearCallingIdentity(); try { - startFreezingDisplayLocked(exitAnim, enterAnim); + startFreezingDisplay(exitAnim, enterAnim); mH.removeMessages(H.CLIENT_FREEZE_TIMEOUT); mH.sendEmptyMessageDelayed(H.CLIENT_FREEZE_TIMEOUT, 5000); } finally { @@ -5479,13 +5488,17 @@ public class WindowManagerService extends IWindowManager.Stub return changed; } - void startFreezingDisplayLocked(int exitAnim, int enterAnim) { - startFreezingDisplayLocked(exitAnim, enterAnim, - getDefaultDisplayContentLocked()); + void startFreezingDisplay(int exitAnim, int enterAnim) { + startFreezingDisplay(exitAnim, enterAnim, getDefaultDisplayContentLocked()); } - void startFreezingDisplayLocked(int exitAnim, int enterAnim, - DisplayContent displayContent) { + void startFreezingDisplay(int exitAnim, int enterAnim, DisplayContent displayContent) { + startFreezingDisplay(exitAnim, enterAnim, displayContent, + ROTATION_UNDEFINED /* overrideOriginalRotation */); + } + + void startFreezingDisplay(int exitAnim, int enterAnim, DisplayContent displayContent, + int overrideOriginalRotation) { if (mDisplayFrozen || displayContent.getDisplayRotation().isRotatingSeamlessly()) { return; } @@ -5529,14 +5542,12 @@ public class WindowManagerService extends IWindowManager.Stub screenRotationAnimation.kill(); } - // Check whether the current screen contains any secure content. - boolean isSecure = displayContent.hasSecureWindowOnScreen(); - displayContent.updateDisplayInfo(); - screenRotationAnimation = new ScreenRotationAnimation(mContext, displayContent, - displayContent.getDisplayRotation().isFixedToUserRotation(), isSecure, - this); - displayContent.setRotationAnimation(screenRotationAnimation); + final int originalRotation = overrideOriginalRotation != ROTATION_UNDEFINED + ? overrideOriginalRotation + : displayContent.getDisplayInfo().rotation; + displayContent.setRotationAnimation(new ScreenRotationAnimation(displayContent, + originalRotation)); } void stopFreezingDisplayLocked() { @@ -6104,10 +6115,15 @@ public class WindowManagerService extends IWindowManager.Stub mRoot.forAllDisplays(dc -> { final int displayId = dc.getDisplayId(); final WindowState inputMethodTarget = dc.mInputMethodTarget; + final WindowState inputMethodInputTarget = dc.mInputMethodInputTarget; if (inputMethodTarget != null) { pw.print(" mInputMethodTarget in display# "); pw.print(displayId); pw.print(' '); pw.println(inputMethodTarget); } + if (inputMethodInputTarget != null) { + pw.print(" mInputMethodInputTarget in display# "); pw.print(displayId); + pw.print(' '); pw.println(inputMethodInputTarget); + } if (mAccessibilityController != null) { final Region magnificationRegion = new Region(); mAccessibilityController.getMagnificationRegionLocked(displayId, @@ -7359,7 +7375,7 @@ public class WindowManagerService extends IWindowManager.Stub synchronized (mGlobalLock) { final WindowState imeTarget = mWindowMap.get(imeTargetWindowToken); if (imeTarget != null) { - imeTarget.getDisplayContent().updateImeControlTarget(imeTarget); + imeTarget.getDisplayContent().setInputMethodInputTarget(imeTarget); } } } diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java index 86bc013e3638..d9c0219c4779 100644 --- a/services/core/java/com/android/server/wm/WindowOrganizerController.java +++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java @@ -129,6 +129,10 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub final Map.Entry<IBinder, WindowContainerTransaction.Change> entry = entries.next(); final WindowContainer wc = WindowContainer.fromBinder(entry.getKey()); + if (!wc.isAttached()) { + Slog.e(TAG, "Attempt to operate on detached container: " + wc); + continue; + } int containerEffect = applyWindowContainerChange(wc, entry.getValue()); effects |= containerEffect; @@ -146,6 +150,10 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub for (int i = 0, n = hops.size(); i < n; ++i) { final WindowContainerTransaction.HierarchyOp hop = hops.get(i); final WindowContainer wc = WindowContainer.fromBinder(hop.getContainer()); + if (!wc.isAttached()) { + Slog.e(TAG, "Attempt to operate on detached container: " + wc); + continue; + } effects |= sanitizeAndApplyHierarchyOp(wc, hop); } if ((effects & TRANSACT_EFFECTS_LIFECYCLE) != 0) { diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index c11c29b5deb6..5f2e14f86c94 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -1469,6 +1469,11 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP @Override void onDisplayChanged(DisplayContent dc) { + if (dc != null && mDisplayContent != null + && mDisplayContent.mInputMethodInputTarget == this) { + dc.setInputMethodInputTarget(mDisplayContent.mInputMethodInputTarget); + mDisplayContent.mInputMethodInputTarget = null; + } super.onDisplayChanged(dc); // Window was not laid out for this display yet, so make sure mLayoutSeq does not match. if (dc != null && mInputWindowHandle.displayId != dc.getDisplayId()) { @@ -5245,16 +5250,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP } @Override - public void onAnimationLeashCreated(Transaction t, SurfaceControl leash) { - super.onAnimationLeashCreated(t, leash); - } - - @Override - public void onAnimationLeashLost(Transaction t) { - super.onAnimationLeashLost(t); - } - - @Override @VisibleForTesting void updateSurfacePosition(Transaction t) { if (mSurfaceControl == null) { diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java index e34b81654c72..21c76874f5c0 100644 --- a/services/core/java/com/android/server/wm/WindowToken.java +++ b/services/core/java/com/android/server/wm/WindowToken.java @@ -422,14 +422,17 @@ class WindowToken extends WindowContainer<WindowState> { if (!shouldReportToClient()) { return; } + if (mLastReportedConfig == null) { + mLastReportedConfig = new Configuration(); + } final Configuration config = getConfiguration(); final int displayId = getDisplayContent().getDisplayId(); - if (config.equals(mLastReportedConfig) && displayId == mLastReportedDisplay) { + if (config.diff(mLastReportedConfig) == 0 && displayId == mLastReportedDisplay) { // No changes since last reported time. return; } - mLastReportedConfig = config; + mLastReportedConfig.setTo(config); mLastReportedDisplay = displayId; IWindowToken windowTokenClient = IWindowToken.Stub.asInterface(token); @@ -595,7 +598,17 @@ class WindowToken extends WindowContainer<WindowState> { // The window may be detached or detaching. return; } + final int originalRotation = getWindowConfiguration().getRotation(); onConfigurationChanged(parent.getConfiguration()); + onCancelFixedRotationTransform(originalRotation); + } + + /** + * It is called when the window is using fixed rotation transform, and before display applies + * the same rotation, the rotation change for display is canceled, e.g. the orientation from + * sensor is updated to previous direction. + */ + void onCancelFixedRotationTransform(int originalDisplayRotation) { } @Override @@ -619,6 +632,15 @@ class WindowToken extends WindowContainer<WindowState> { } } + @Override + void resetSurfacePositionForAnimationLeash(SurfaceControl.Transaction t) { + // Keep the transformed position to animate because the surface will show in different + // rotation than the animator of leash. + if (!isFixedRotationTransforming()) { + super.resetSurfacePositionForAnimationLeash(t); + } + } + /** * Gives a chance to this {@link WindowToken} to adjust the {@link * android.view.WindowManager.LayoutParams} of its windows. diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 1da074002456..2c0d4c0c9208 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -4733,33 +4733,13 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { if (!parent && isSeparateProfileChallengeEnabled(userHandle)) { // If this user has a separate challenge, only return its restrictions. return getUserDataUnchecked(userHandle).mAdminList; - } else { - // Return all admins for this user and the profiles that are visible from this - // user that do not use a separate work challenge. - ArrayList<ActiveAdmin> admins = new ArrayList<ActiveAdmin>(); - for (UserInfo userInfo : mUserManager.getProfiles(userHandle)) { - DevicePolicyData policy = getUserData(userInfo.id); - if (!userInfo.isManagedProfile()) { - admins.addAll(policy.mAdminList); - } else { - // For managed profiles, we always include the policies set on the parent - // profile. Additionally, we include the ones set on the managed profile - // if no separate challenge is in place. - boolean hasSeparateChallenge = isSeparateProfileChallengeEnabled(userInfo.id); - final int N = policy.mAdminList.size(); - for (int i = 0; i < N; i++) { - ActiveAdmin admin = policy.mAdminList.get(i); - if (admin.hasParentActiveAdmin()) { - admins.add(admin.getParentActiveAdmin()); - } - if (!hasSeparateChallenge) { - admins.add(admin); - } - } - } - } - return admins; } + // Either parent == true, or isSeparateProfileChallengeEnabled == false + // If parent is true, query the parent user of userHandle by definition, + // If isSeparateProfileChallengeEnabled is false, userHandle points to a managed profile + // with unified challenge so also need to query the parent user who owns the credential. + return getActiveAdminsForUserAndItsManagedProfilesLocked(getProfileParentId(userHandle), + (user) -> !mLockPatternUtils.isSeparateProfileChallengeEnabled(user.id)); } /** @@ -4777,6 +4757,19 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { if (isManagedProfile(userHandle)) { return getUserDataUnchecked(userHandle).mAdminList; } + return getActiveAdminsForUserAndItsManagedProfilesLocked(userHandle, + /* shouldIncludeProfileAdmins */ (user) -> false); + } + + /** + * Returns the list of admins on the given user, as well as parent admins for each managed + * profile associated with the given user. Optionally also include the admin of each managed + * profile. + * <p> Should not be called on a profile user. + */ + @GuardedBy("getLockObject()") + private List<ActiveAdmin> getActiveAdminsForUserAndItsManagedProfilesLocked(int userHandle, + Predicate<UserInfo> shouldIncludeProfileAdmins) { ArrayList<ActiveAdmin> admins = new ArrayList<>(); mInjector.binderWithCleanCallingIdentity(() -> { for (UserInfo userInfo : mUserManager.getProfiles(userHandle)) { @@ -4784,12 +4777,14 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { if (userInfo.id == userHandle) { admins.addAll(policy.mAdminList); } else if (userInfo.isManagedProfile()) { - // For managed profiles, policies set on the parent profile will be included for (int i = 0; i < policy.mAdminList.size(); i++) { ActiveAdmin admin = policy.mAdminList.get(i); if (admin.hasParentActiveAdmin()) { admins.add(admin.getParentActiveAdmin()); } + if (shouldIncludeProfileAdmins.test(userInfo)) { + admins.add(admin); + } } } else { Slog.w(LOG_TAG, "Unknown user type: " + userInfo); @@ -5366,6 +5361,32 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } } + @Override + public boolean isPasswordSufficientAfterProfileUnification(int userHandle, int profileUser) { + if (!mHasFeature) { + return true; + } + enforceFullCrossUsersPermission(userHandle); + enforceNotManagedProfile(userHandle, "check password sufficiency"); + enforceUserUnlocked(userHandle); + + synchronized (getLockObject()) { + PasswordMetrics metrics = mLockSettingsInternal.getUserPasswordMetrics(userHandle); + + // Combine password policies across the user and its profiles. Profile admins are + // included if the profile is to be unified or currently has unified challenge + List<ActiveAdmin> admins = getActiveAdminsForUserAndItsManagedProfilesLocked(userHandle, + /* shouldIncludeProfileAdmins */ (user) -> user.id == profileUser + || !mLockPatternUtils.isSeparateProfileChallengeEnabled(user.id)); + ArrayList<PasswordMetrics> adminMetrics = new ArrayList<>(admins.size()); + for (ActiveAdmin admin : admins) { + adminMetrics.add(admin.mPasswordPolicy.getMinMetrics()); + } + return PasswordMetrics.validatePasswordMetrics(PasswordMetrics.merge(adminMetrics), + PASSWORD_COMPLEXITY_NONE, false, metrics).isEmpty(); + } + } + private boolean isActivePasswordSufficientForUserLocked( boolean passwordValidAtLastCheckpoint, @Nullable PasswordMetrics metrics, int userHandle, boolean parent) { diff --git a/services/incremental/IncrementalService.cpp b/services/incremental/IncrementalService.cpp index 149dfa6be6c4..c1f237f91b44 100644 --- a/services/incremental/IncrementalService.cpp +++ b/services/incremental/IncrementalService.cpp @@ -258,10 +258,6 @@ IncrementalService::IncrementalService(ServiceManagerWrapper&& sm, std::string_v mountExistingImages(); } -FileId IncrementalService::idFromMetadata(std::span<const uint8_t> metadata) { - return IncFs_FileIdFromMetadata({(const char*)metadata.data(), metadata.size()}); -} - IncrementalService::~IncrementalService() { { std::lock_guard lock(mJobMutex); @@ -1016,7 +1012,7 @@ bool IncrementalService::startLoading(StorageId storage) const { return false; } } - return dataLoaderStub->start(); + return dataLoaderStub->requestStart(); } void IncrementalService::mountExistingImages() { @@ -1337,13 +1333,13 @@ void IncrementalService::extractZipFile(const IfsMountPtr& ifs, ZipArchiveHandle std::vector<IncFsDataBlock> instructions(numBlocks); auto remainingData = std::span(libData.get(), entry.uncompressed_length); for (int i = 0; i < numBlocks; i++) { - const auto blockSize = std::min<uint16_t>(constants().blockSize, remainingData.size()); + const auto blockSize = std::min<long>(constants().blockSize, remainingData.size()); instructions[i] = IncFsDataBlock{ .fileFd = writeFd.get(), .pageIndex = static_cast<IncFsBlockIndex>(i), .compression = INCFS_COMPRESSION_KIND_NONE, .kind = INCFS_BLOCK_KIND_DATA, - .dataSize = blockSize, + .dataSize = static_cast<uint32_t>(blockSize), .data = reinterpret_cast<const char*>(remainingData.data()), }; remainingData = remainingData.subspan(blockSize); @@ -1475,12 +1471,15 @@ void IncrementalService::onAppOpChanged(const std::string& packageName) { } IncrementalService::DataLoaderStub::~DataLoaderStub() { - CHECK(mStatus == -1 || mStatus == IDataLoaderStatusListener::DATA_LOADER_DESTROYED) - << "Dataloader has to be destroyed prior to destructor: " << mId - << ", status: " << mStatus; + waitForDestroy(); } bool IncrementalService::DataLoaderStub::create() { + { + std::unique_lock lock(mStatusMutex); + mStartRequested = false; + mDestroyRequested = false; + } bool created = false; auto status = mService.mDataLoaderManager->initializeDataLoader(mId, mParams, mControl, this, &created); @@ -1491,12 +1490,18 @@ bool IncrementalService::DataLoaderStub::create() { return true; } -bool IncrementalService::DataLoaderStub::start() { - if (mStatus != IDataLoaderStatusListener::DATA_LOADER_CREATED) { +bool IncrementalService::DataLoaderStub::requestStart() { + { + std::unique_lock lock(mStatusMutex); mStartRequested = true; - return true; + if (mStatus != IDataLoaderStatusListener::DATA_LOADER_CREATED) { + return true; + } } + return start(); +} +bool IncrementalService::DataLoaderStub::start() { sp<IDataLoader> dataloader; auto status = mService.mDataLoaderManager->getDataLoader(mId, &dataloader); if (!status.isOk()) { @@ -1513,8 +1518,21 @@ bool IncrementalService::DataLoaderStub::start() { } void IncrementalService::DataLoaderStub::destroy() { - mDestroyRequested = true; + { + std::unique_lock lock(mStatusMutex); + mDestroyRequested = true; + } mService.mDataLoaderManager->destroyDataLoader(mId); + + waitForDestroy(); +} + +bool IncrementalService::DataLoaderStub::waitForDestroy() { + auto now = std::chrono::steady_clock::now(); + std::unique_lock lock(mStatusMutex); + return mStatusCondition.wait_until(lock, now + 60s, [this] { + return mStatus == IDataLoaderStatusListener::DATA_LOADER_DESTROYED; + }); } binder::Status IncrementalService::DataLoaderStub::onStatusChanged(MountId mountId, int newStatus) { @@ -1523,34 +1541,36 @@ binder::Status IncrementalService::DataLoaderStub::onStatusChanged(MountId mount } if (mListener) { - // Give an external listener a chance to act before we destroy something. mListener->onStatusChanged(mountId, newStatus); } + bool startRequested; + bool destroyRequested; { - std::unique_lock l(mService.mLock); - const auto& ifs = mService.getIfsLocked(mountId); - if (!ifs) { - LOG(WARNING) << "Received data loader status " << int(newStatus) - << " for unknown mount " << mountId; + std::unique_lock lock(mStatusMutex); + if (mStatus == newStatus) { return binder::Status::ok(); } - mStatus = newStatus; - if (!mDestroyRequested && newStatus == IDataLoaderStatusListener::DATA_LOADER_DESTROYED) { - mService.deleteStorageLocked(*ifs, std::move(l)); - return binder::Status::ok(); - } + startRequested = mStartRequested; + destroyRequested = mDestroyRequested; + + mStatus = newStatus; } switch (newStatus) { case IDataLoaderStatusListener::DATA_LOADER_CREATED: { - if (mStartRequested) { + if (startRequested) { + LOG(WARNING) << "Start was requested, triggering, for mount: " << mountId; start(); } break; } case IDataLoaderStatusListener::DATA_LOADER_DESTROYED: { + if (!destroyRequested) { + LOG(WARNING) << "DataLoader destroyed, reconnecting, for mount: " << mountId; + create(); + } break; } case IDataLoaderStatusListener::DATA_LOADER_STARTED: { @@ -1589,4 +1609,8 @@ binder::Status IncrementalService::IncrementalServiceConnector::setStorageParams return binder::Status::ok(); } +FileId IncrementalService::idFromMetadata(std::span<const uint8_t> metadata) { + return IncFs_FileIdFromMetadata({(const char*)metadata.data(), metadata.size()}); +} + } // namespace android::incremental diff --git a/services/incremental/IncrementalService.h b/services/incremental/IncrementalService.h index c016bab067be..8c79d7725dcf 100644 --- a/services/incremental/IncrementalService.h +++ b/services/incremental/IncrementalService.h @@ -180,27 +180,32 @@ private: ~DataLoaderStub(); bool create(); - bool start(); + bool requestStart(); void destroy(); // accessors MountId id() const { return mId; } const DataLoaderParamsParcel& params() const { return mParams; } - int status() const { return mStatus.load(); } + int status() const { return mStatus; } bool startRequested() const { return mStartRequested; } private: binder::Status onStatusChanged(MountId mount, int newStatus) final; + bool start(); + bool waitForDestroy(); + IncrementalService& mService; MountId const mId; DataLoaderParamsParcel const mParams; FileSystemControlParcel const mControl; DataLoaderStatusListener const mListener; - std::atomic<int> mStatus = -1; + std::mutex mStatusMutex; + std::condition_variable mStatusCondition; + int mStatus = IDataLoaderStatusListener::DATA_LOADER_DESTROYED; bool mStartRequested = false; - bool mDestroyRequested = false; + bool mDestroyRequested = true; }; using DataLoaderStubPtr = sp<DataLoaderStub>; diff --git a/services/incremental/test/IncrementalServiceTest.cpp b/services/incremental/test/IncrementalServiceTest.cpp index 117dca8c37b3..f9737fee450d 100644 --- a/services/incremental/test/IncrementalServiceTest.cpp +++ b/services/incremental/test/IncrementalServiceTest.cpp @@ -103,25 +103,34 @@ private: TemporaryFile logFile; }; -class FakeDataLoader : public IDataLoader { +class MockDataLoader : public IDataLoader { public: - IBinder* onAsBinder() override { return nullptr; } - binder::Status create(int32_t, const DataLoaderParamsParcel&, const FileSystemControlParcel&, - const sp<IDataLoaderStatusListener>&) override { - return binder::Status::ok(); - } - binder::Status start(int32_t) override { return binder::Status::ok(); } - binder::Status stop(int32_t) override { return binder::Status::ok(); } - binder::Status destroy(int32_t) override { return binder::Status::ok(); } - binder::Status prepareImage(int32_t, - const std::vector<InstallationFileParcel>&, - const std::vector<std::string>&) override { - return binder::Status::ok(); + MockDataLoader() { + ON_CALL(*this, create(_, _, _, _)).WillByDefault(Return((binder::Status::ok()))); + ON_CALL(*this, start(_)).WillByDefault(Return((binder::Status::ok()))); + ON_CALL(*this, stop(_)).WillByDefault(Return((binder::Status::ok()))); + ON_CALL(*this, destroy(_)).WillByDefault(Return((binder::Status::ok()))); + ON_CALL(*this, prepareImage(_, _, _)).WillByDefault(Return((binder::Status::ok()))); } + IBinder* onAsBinder() override { return nullptr; } + MOCK_METHOD4(create, + binder::Status(int32_t id, const DataLoaderParamsParcel& params, + const FileSystemControlParcel& control, + const sp<IDataLoaderStatusListener>& listener)); + MOCK_METHOD1(start, binder::Status(int32_t id)); + MOCK_METHOD1(stop, binder::Status(int32_t id)); + MOCK_METHOD1(destroy, binder::Status(int32_t id)); + MOCK_METHOD3(prepareImage, + binder::Status(int32_t id, const std::vector<InstallationFileParcel>& addedFiles, + const std::vector<std::string>& removedFiles)); }; class MockDataLoaderManager : public DataLoaderManagerWrapper { public: + MockDataLoaderManager(sp<IDataLoader> dataLoader) : mDataLoaderHolder(std::move(dataLoader)) { + EXPECT_TRUE(mDataLoaderHolder != nullptr); + } + MOCK_CONST_METHOD5(initializeDataLoader, binder::Status(int32_t mountId, const DataLoaderParamsParcel& params, const FileSystemControlParcel& control, @@ -144,9 +153,9 @@ public: ON_CALL(*this, getDataLoader(_, _)) .WillByDefault(Invoke(this, &MockDataLoaderManager::getDataLoaderOk)); } - void destroyDataLoaderOk() { + void destroyDataLoaderSuccess() { ON_CALL(*this, destroyDataLoader(_)) - .WillByDefault(Invoke(this, &MockDataLoaderManager::setDataLoaderStatusDestroyed)); + .WillByDefault(Invoke(this, &MockDataLoaderManager::destroyDataLoaderOk)); } binder::Status initializeDataLoaderOk(int32_t mountId, const DataLoaderParamsParcel& params, const FileSystemControlParcel& control, @@ -155,20 +164,30 @@ public: mId = mountId; mListener = listener; mServiceConnector = control.service; + mDataLoader = mDataLoaderHolder; *_aidl_return = true; - return binder::Status::ok(); + return mDataLoader->create(mountId, params, control, listener); } binder::Status getDataLoaderOk(int32_t mountId, sp<IDataLoader>* _aidl_return) { *_aidl_return = mDataLoader; return binder::Status::ok(); } - void setDataLoaderStatusNotReady() { - mListener->onStatusChanged(mId, IDataLoaderStatusListener::DATA_LOADER_DESTROYED); - } - void setDataLoaderStatusReady() { + void setDataLoaderStatusCreated() { mListener->onStatusChanged(mId, IDataLoaderStatusListener::DATA_LOADER_CREATED); } - binder::Status setDataLoaderStatusDestroyed(int32_t id) { + void setDataLoaderStatusStarted() { + mListener->onStatusChanged(mId, IDataLoaderStatusListener::DATA_LOADER_STARTED); + } + void setDataLoaderStatusDestroyed() { + mListener->onStatusChanged(mId, IDataLoaderStatusListener::DATA_LOADER_DESTROYED); + } + binder::Status destroyDataLoaderOk(int32_t id) { + if (mDataLoader) { + if (auto status = mDataLoader->destroy(id); !status.isOk()) { + return status; + } + mDataLoader = nullptr; + } if (mListener) { mListener->onStatusChanged(id, IDataLoaderStatusListener::DATA_LOADER_DESTROYED); } @@ -185,7 +204,8 @@ private: int mId; sp<IDataLoaderStatusListener> mListener; sp<IIncrementalServiceConnector> mServiceConnector; - sp<IDataLoader> mDataLoader = sp<IDataLoader>(new FakeDataLoader()); + sp<IDataLoader> mDataLoader; + sp<IDataLoader> mDataLoaderHolder; }; class MockIncFs : public IncFsWrapper { @@ -303,7 +323,9 @@ public: void SetUp() override { auto vold = std::make_unique<NiceMock<MockVoldService>>(); mVold = vold.get(); - auto dataloaderManager = std::make_unique<NiceMock<MockDataLoaderManager>>(); + sp<NiceMock<MockDataLoader>> dataLoader{new NiceMock<MockDataLoader>}; + mDataLoader = dataLoader.get(); + auto dataloaderManager = std::make_unique<NiceMock<MockDataLoaderManager>>(dataLoader); mDataLoaderManager = dataloaderManager.get(); auto incFs = std::make_unique<NiceMock<MockIncFs>>(); mIncFs = incFs.get(); @@ -321,7 +343,7 @@ public: mRootDir.path); mDataLoaderParcel.packageName = "com.test"; mDataLoaderParcel.arguments = "uri"; - mDataLoaderManager->destroyDataLoaderOk(); + mDataLoaderManager->destroyDataLoaderSuccess(); mIncrementalService->onSystemReady(); } @@ -352,6 +374,7 @@ protected: NiceMock<MockDataLoaderManager>* mDataLoaderManager; NiceMock<MockAppOpsManager>* mAppOpsManager; NiceMock<MockJniWrapper>* mJni; + NiceMock<MockDataLoader>* mDataLoader; std::unique_ptr<IncrementalService> mIncrementalService; TemporaryDir mRootDir; DataLoaderParamsParcel mDataLoaderParcel; @@ -410,7 +433,11 @@ TEST_F(IncrementalServiceTest, testCreateStoragePrepareDataLoaderFails) { mIncFs->makeFileSuccess(); mVold->bindMountSuccess(); mDataLoaderManager->initializeDataLoaderFails(); + EXPECT_CALL(*mDataLoaderManager, initializeDataLoader(_, _, _, _, _)).Times(1); EXPECT_CALL(*mDataLoaderManager, destroyDataLoader(_)).Times(1); + EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(0); + EXPECT_CALL(*mDataLoader, start(_)).Times(0); + EXPECT_CALL(*mDataLoader, destroy(_)).Times(0); EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2); TemporaryDir tempDir; int storageId = @@ -424,46 +451,84 @@ TEST_F(IncrementalServiceTest, testDeleteStorageSuccess) { mIncFs->makeFileSuccess(); mVold->bindMountSuccess(); mDataLoaderManager->initializeDataLoaderSuccess(); + EXPECT_CALL(*mDataLoaderManager, initializeDataLoader(_, _, _, _, _)).Times(1); EXPECT_CALL(*mDataLoaderManager, destroyDataLoader(_)).Times(1); + EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1); + EXPECT_CALL(*mDataLoader, start(_)).Times(0); + EXPECT_CALL(*mDataLoader, destroy(_)).Times(1); EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2); TemporaryDir tempDir; int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), {}, IncrementalService::CreateOptions::CreateNew); ASSERT_GE(storageId, 0); + mDataLoaderManager->setDataLoaderStatusCreated(); mIncrementalService->deleteStorage(storageId); } -TEST_F(IncrementalServiceTest, testOnStatusNotReady) { +TEST_F(IncrementalServiceTest, testDataLoaderDestroyed) { mVold->mountIncFsSuccess(); mIncFs->makeFileSuccess(); mVold->bindMountSuccess(); mDataLoaderManager->initializeDataLoaderSuccess(); - EXPECT_CALL(*mDataLoaderManager, destroyDataLoader(_)); + mDataLoaderManager->getDataLoaderSuccess(); + EXPECT_CALL(*mDataLoaderManager, initializeDataLoader(_, _, _, _, _)).Times(2); + EXPECT_CALL(*mDataLoaderManager, destroyDataLoader(_)).Times(1); + EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(2); + EXPECT_CALL(*mDataLoader, start(_)).Times(0); + EXPECT_CALL(*mDataLoader, destroy(_)).Times(1); EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2); TemporaryDir tempDir; int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), {}, IncrementalService::CreateOptions::CreateNew); ASSERT_GE(storageId, 0); - mDataLoaderManager->setDataLoaderStatusNotReady(); + mDataLoaderManager->setDataLoaderStatusCreated(); + // Simulated crash/other connection breakage. + mDataLoaderManager->setDataLoaderStatusDestroyed(); } -TEST_F(IncrementalServiceTest, testStartDataLoaderSuccess) { +TEST_F(IncrementalServiceTest, testStartDataLoaderCreate) { mVold->mountIncFsSuccess(); mIncFs->makeFileSuccess(); mVold->bindMountSuccess(); mDataLoaderManager->initializeDataLoaderSuccess(); mDataLoaderManager->getDataLoaderSuccess(); - EXPECT_CALL(*mDataLoaderManager, destroyDataLoader(_)); + EXPECT_CALL(*mDataLoaderManager, initializeDataLoader(_, _, _, _, _)).Times(1); + EXPECT_CALL(*mDataLoaderManager, destroyDataLoader(_)).Times(1); + EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1); + EXPECT_CALL(*mDataLoader, start(_)).Times(1); + EXPECT_CALL(*mDataLoader, destroy(_)).Times(1); + EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2); + TemporaryDir tempDir; + int storageId = + mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), {}, + IncrementalService::CreateOptions::CreateNew); + ASSERT_GE(storageId, 0); + mDataLoaderManager->setDataLoaderStatusCreated(); + ASSERT_TRUE(mIncrementalService->startLoading(storageId)); + mDataLoaderManager->setDataLoaderStatusStarted(); +} + +TEST_F(IncrementalServiceTest, testStartDataLoaderPendingStart) { + mVold->mountIncFsSuccess(); + mIncFs->makeFileSuccess(); + mVold->bindMountSuccess(); + mDataLoaderManager->initializeDataLoaderSuccess(); + mDataLoaderManager->getDataLoaderSuccess(); + EXPECT_CALL(*mDataLoaderManager, initializeDataLoader(_, _, _, _, _)).Times(1); + EXPECT_CALL(*mDataLoaderManager, destroyDataLoader(_)).Times(1); + EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1); + EXPECT_CALL(*mDataLoader, start(_)).Times(1); + EXPECT_CALL(*mDataLoader, destroy(_)).Times(1); EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2); TemporaryDir tempDir; int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), {}, IncrementalService::CreateOptions::CreateNew); ASSERT_GE(storageId, 0); - mDataLoaderManager->setDataLoaderStatusReady(); ASSERT_TRUE(mIncrementalService->startLoading(storageId)); + mDataLoaderManager->setDataLoaderStatusCreated(); } TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccess) { diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index e2a247394a81..2c3e3df46e7c 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -112,6 +112,7 @@ import com.android.server.inputmethod.InputMethodSystemProperty; import com.android.server.inputmethod.MultiClientInputMethodManagerService; import com.android.server.integrity.AppIntegrityManagerService; import com.android.server.lights.LightsService; +import com.android.server.location.LocationManagerService; import com.android.server.media.MediaResourceMonitorService; import com.android.server.media.MediaRouterService; import com.android.server.media.MediaSessionService; diff --git a/services/tests/servicestests/AndroidManifest.xml b/services/tests/servicestests/AndroidManifest.xml index 109c1191523b..270a3b50b934 100644 --- a/services/tests/servicestests/AndroidManifest.xml +++ b/services/tests/servicestests/AndroidManifest.xml @@ -78,6 +78,7 @@ <uses-permission android:name="android.permission.DUMP"/> <uses-permission android:name="android.permission.READ_DREAM_STATE"/> <uses-permission android:name="android.permission.WRITE_DREAM_STATE"/> + <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/> <!-- Uses API introduced in O (26) --> <uses-sdk android:minSdkVersion="1" diff --git a/services/tests/servicestests/src/com/android/server/audio/AudioDeviceBrokerTest.java b/services/tests/servicestests/src/com/android/server/audio/AudioDeviceBrokerTest.java index 73a191dc78cc..22f8b9c8ae92 100644 --- a/services/tests/servicestests/src/com/android/server/audio/AudioDeviceBrokerTest.java +++ b/services/tests/servicestests/src/com/android/server/audio/AudioDeviceBrokerTest.java @@ -66,7 +66,7 @@ public class AudioDeviceBrokerTest { mContext = InstrumentationRegistry.getTargetContext(); mMockAudioService = mock(AudioService.class); - mSpyAudioSystem = spy(AudioSystemAdapter.getAlwaysOkAdapter()); + mSpyAudioSystem = spy(AudioSystemAdapter.getConfigurableAdapter()); mSpyDevInventory = spy(new AudioDeviceInventory(mSpyAudioSystem)); mAudioDeviceBroker = new AudioDeviceBroker(mContext, mMockAudioService, mSpyDevInventory); mSpyDevInventory.setDeviceBroker(mAudioDeviceBroker); diff --git a/services/tests/servicestests/src/com/android/server/audio/AudioServiceTest.java b/services/tests/servicestests/src/com/android/server/audio/AudioServiceTest.java new file mode 100644 index 000000000000..6185ae6d93f9 --- /dev/null +++ b/services/tests/servicestests/src/com/android/server/audio/AudioServiceTest.java @@ -0,0 +1,115 @@ +/* + * Copyright 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.server.audio; + +import static org.mockito.Mockito.reset; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +import android.content.Context; +import android.os.Looper; +import android.os.UserHandle; +import android.util.Log; + +import androidx.test.InstrumentationRegistry; +import androidx.test.filters.MediumTest; +import androidx.test.runner.AndroidJUnit4; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Spy; + +@MediumTest +@RunWith(AndroidJUnit4.class) +public class AudioServiceTest { + private static final String TAG = "AudioServiceTest"; + + private static final int MAX_MESSAGE_HANDLING_DELAY_MS = 100; + + private Context mContext; + private AudioSystemAdapter mAudioSystem; + @Spy private SystemServerAdapter mSpySystemServer; + // the class being unit-tested here + private AudioService mAudioService; + + private static boolean sLooperPrepared = false; + + @Before + public void setUp() throws Exception { + if (!sLooperPrepared) { + Looper.prepare(); + sLooperPrepared = true; + } + mContext = InstrumentationRegistry.getTargetContext(); + mAudioSystem = AudioSystemAdapter.getConfigurableAdapter(); + mSpySystemServer = spy(SystemServerAdapter.getNoOpAdapter()); + mAudioService = new AudioService(mContext, mAudioSystem, mSpySystemServer); + } + + /** + * Test muting the mic reports the expected value, and the corresponding intent was fired + * @throws Exception + */ + @Test + public void testMuteMicrophone() throws Exception { + Log.i(TAG, "running testMuteMicrophone"); + Assert.assertNotNull(mAudioService); + final AudioSystemAdapter.AudioSystemConfigurableAdapter testAudioSystem = + (AudioSystemAdapter.AudioSystemConfigurableAdapter) mAudioSystem; + testAudioSystem.configureMuteMicrophoneToFail(false); + for (boolean muted : new boolean[] { true, false}) { + testAudioSystem.configureIsMicrophoneMuted(!muted); + mAudioService.setMicrophoneMute(muted, mContext.getOpPackageName(), + UserHandle.getCallingUserId()); + Assert.assertEquals("mic mute reporting wrong value", + muted, mAudioService.isMicrophoneMuted()); + // verify the intent for mic mute changed is supposed to be fired + Thread.sleep(MAX_MESSAGE_HANDLING_DELAY_MS); + verify(mSpySystemServer, times(1)) + .sendMicrophoneMuteChangedIntent(); + reset(mSpySystemServer); + } + } + + /** + * Test muting the mic with simulated failure reports the expected value, and the corresponding + * intent was fired + * @throws Exception + */ + @Test + public void testMuteMicrophoneWhenFail() throws Exception { + Log.i(TAG, "running testMuteMicrophoneWhenFail"); + Assert.assertNotNull(mAudioService); + final AudioSystemAdapter.AudioSystemConfigurableAdapter testAudioSystem = + (AudioSystemAdapter.AudioSystemConfigurableAdapter) mAudioSystem; + testAudioSystem.configureMuteMicrophoneToFail(true); + for (boolean muted : new boolean[] { true, false}) { + testAudioSystem.configureIsMicrophoneMuted(!muted); + mAudioService.setMicrophoneMute(muted, mContext.getOpPackageName(), + UserHandle.getCallingUserId()); + Assert.assertEquals("mic mute reporting wrong value", + !muted, mAudioService.isMicrophoneMuted()); + // verify the intent for mic mute changed is supposed to be fired + Thread.sleep(MAX_MESSAGE_HANDLING_DELAY_MS); + verify(mSpySystemServer, times(1)) + .sendMicrophoneMuteChangedIntent(); + reset(mSpySystemServer); + } + } +} diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java index fe224ce058f4..4faed659f5df 100644 --- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java @@ -4841,6 +4841,33 @@ public class DevicePolicyManagerTest extends DpmTestBase { assertFalse(dpm.isActivePasswordSufficient()); } + public void testIsPasswordSufficientAfterProfileUnification() throws Exception { + final int managedProfileUserId = DpmMockContext.CALLER_USER_HANDLE; + final int managedProfileAdminUid = + UserHandle.getUid(managedProfileUserId, DpmMockContext.SYSTEM_UID); + mContext.binder.callingUid = managedProfileAdminUid; + + addManagedProfile(admin1, managedProfileAdminUid, admin1); + doReturn(true).when(getServices().lockPatternUtils) + .isSeparateProfileChallengeEnabled(managedProfileUserId); + + dpm.setPasswordQuality(admin1, DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC); + parentDpm.setPasswordQuality(admin1, DevicePolicyManager.PASSWORD_QUALITY_NUMERIC); + + when(getServices().lockSettingsInternal.getUserPasswordMetrics(UserHandle.USER_SYSTEM)) + .thenReturn(computeForPassword("1234".getBytes())); + + // Numeric password is compliant with current requirement (QUALITY_NUMERIC set explicitly + // on the parent admin) + assertTrue(dpm.isPasswordSufficientAfterProfileUnification(UserHandle.USER_SYSTEM, + UserHandle.USER_NULL)); + // Numeric password is not compliant if profile is to be unified: the profile has a + // QUALITY_ALPHABETIC policy on itself which will be enforced on the password after + // unification. + assertFalse(dpm.isPasswordSufficientAfterProfileUnification(UserHandle.USER_SYSTEM, + managedProfileUserId)); + } + private void setActivePasswordState(PasswordMetrics passwordMetrics) throws Exception { final int userHandle = UserHandle.getUserId(mContext.binder.callingUid); diff --git a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java index 07d7830c9b0f..12b144f2b778 100644 --- a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java +++ b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java @@ -209,6 +209,26 @@ public class LockSettingsServiceTests extends BaseLockSettingsServiceTests { } @Test + public void testManagedProfileChallengeUnification_parentUserNoPassword() throws Exception { + // Start with a profile with unified challenge, parent user has not password + mService.setSeparateProfileChallengeEnabled(MANAGED_PROFILE_USER_ID, false, null); + assertEquals(0, mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID)); + assertEquals(CREDENTIAL_TYPE_NONE, mService.getCredentialType(MANAGED_PROFILE_USER_ID)); + + // Set a separate challenge on the profile + assertTrue(mService.setLockCredential( + newPassword("12345678"), nonePassword(), MANAGED_PROFILE_USER_ID)); + assertNotEquals(0, mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID)); + assertEquals(CREDENTIAL_TYPE_PASSWORD, mService.getCredentialType(MANAGED_PROFILE_USER_ID)); + + // Now unify again, profile should become passwordless again + mService.setSeparateProfileChallengeEnabled(MANAGED_PROFILE_USER_ID, false, + newPassword("12345678")); + assertEquals(0, mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID)); + assertEquals(CREDENTIAL_TYPE_NONE, mService.getCredentialType(MANAGED_PROFILE_USER_ID)); + } + + @Test public void testSetLockCredential_forPrimaryUser_sendsCredentials() throws Exception { assertTrue(mService.setLockCredential( newPassword("password"), diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ArchiveTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ArchiveTest.java new file mode 100644 index 000000000000..c69ef8d93282 --- /dev/null +++ b/services/tests/uiservicestests/src/com/android/server/notification/ArchiveTest.java @@ -0,0 +1,143 @@ +/* + * 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.server.notification; + +import static android.os.UserHandle.USER_CURRENT; +import static android.os.UserHandle.USER_SYSTEM; +import static android.service.notification.NotificationListenerService.REASON_CANCEL; + +import static com.google.common.truth.Truth.assertThat; + +import android.app.Notification; +import android.os.UserHandle; +import android.service.notification.StatusBarNotification; +import android.test.suitebuilder.annotation.SmallTest; + +import androidx.test.runner.AndroidJUnit4; + +import com.android.server.UiServiceTestCase; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.MockitoAnnotations; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +@SmallTest +@RunWith(AndroidJUnit4.class) +public class ArchiveTest extends UiServiceTestCase { + private static final int SIZE = 5; + + private NotificationManagerService.Archive mArchive; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + + mArchive = new NotificationManagerService.Archive(SIZE); + mArchive.updateHistoryEnabled(USER_SYSTEM, true); + mArchive.updateHistoryEnabled(USER_CURRENT, true); + } + + private StatusBarNotification getNotification(String pkg, int id, UserHandle user) { + Notification n = new Notification.Builder(getContext(), "test") + .setContentTitle("A") + .setWhen(1205) + .build(); + return new StatusBarNotification( + pkg, pkg, id, null, 0, 0, n, user, null, System.currentTimeMillis()); + } + + + @Test + public void testRecordAndRead() { + List<String> expected = new ArrayList<>(); + for (int i = 0; i < SIZE; i++) { + StatusBarNotification sbn = getNotification("pkg" + i, i, + UserHandle.of(i % 2 ==0 ? USER_SYSTEM : USER_CURRENT)); + expected.add(sbn.getKey()); + mArchive.record(sbn, REASON_CANCEL); + } + + List<StatusBarNotification> actual = Arrays.asList(mArchive.getArray(SIZE, true)); + assertThat(actual).hasSize(expected.size()); + for (StatusBarNotification sbn : actual) { + assertThat(expected).contains(sbn.getKey()); + } + } + + @Test + public void testRecordAndRead_overLimit() { + List<String> expected = new ArrayList<>(); + for (int i = 0; i < (SIZE * 2); i++) { + StatusBarNotification sbn = getNotification("pkg" + i, i, UserHandle.of(USER_SYSTEM)); + mArchive.record(sbn, REASON_CANCEL); + if (i >= SIZE) { + expected.add(sbn.getKey()); + } + } + + List<StatusBarNotification> actual = Arrays.asList(mArchive.getArray((SIZE * 2), true)); + assertThat(actual).hasSize(expected.size()); + for (StatusBarNotification sbn : actual) { + assertThat(expected).contains(sbn.getKey()); + } + } + + @Test + public void testDoesNotRecordIfHistoryDisabled() { + mArchive.updateHistoryEnabled(USER_CURRENT, false); + List<String> expected = new ArrayList<>(); + for (int i = 0; i < SIZE; i++) { + StatusBarNotification sbn = getNotification("pkg" + i, i, + UserHandle.of(i % 2 ==0 ? USER_SYSTEM : USER_CURRENT)); + mArchive.record(sbn, REASON_CANCEL); + if (i % 2 ==0) { + expected.add(sbn.getKey()); + } + } + + List<StatusBarNotification> actual = Arrays.asList(mArchive.getArray(SIZE, true)); + assertThat(actual).hasSize(expected.size()); + for (StatusBarNotification sbn : actual) { + assertThat(expected).contains(sbn.getKey()); + } + } + + @Test + public void testRemovesEntriesWhenHistoryDisabled() { + mArchive.updateHistoryEnabled(USER_CURRENT, true); + List<String> expected = new ArrayList<>(); + for (int i = 0; i < SIZE; i++) { + StatusBarNotification sbn = getNotification("pkg" + i, i, + UserHandle.of(i % 2 ==0 ? USER_SYSTEM : USER_CURRENT)); + mArchive.record(sbn, REASON_CANCEL); + if (i % 2 ==0) { + expected.add(sbn.getKey()); + } + } + mArchive.updateHistoryEnabled(USER_CURRENT, false); + + List<StatusBarNotification> actual = Arrays.asList(mArchive.getArray(SIZE, true)); + assertThat(actual).hasSize(expected.size()); + for (StatusBarNotification sbn : actual) { + assertThat(expected).contains(sbn.getKey()); + } + } +} diff --git a/services/tests/uiservicestests/src/com/android/server/notification/BubbleCheckerTest.java b/services/tests/uiservicestests/src/com/android/server/notification/BubbleCheckerTest.java deleted file mode 100644 index 2578ca892520..000000000000 --- a/services/tests/uiservicestests/src/com/android/server/notification/BubbleCheckerTest.java +++ /dev/null @@ -1,261 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.notification; - -import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE; -import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE; - -import static junit.framework.Assert.assertTrue; - -import static org.junit.Assert.assertFalse; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import android.app.ActivityManager; -import android.app.Notification; -import android.app.NotificationChannel; -import android.app.PendingIntent; -import android.content.Intent; -import android.content.pm.ActivityInfo; -import android.content.pm.ShortcutInfo; -import android.os.UserHandle; -import android.service.notification.StatusBarNotification; -import android.test.suitebuilder.annotation.SmallTest; - -import androidx.test.runner.AndroidJUnit4; - -import com.android.server.UiServiceTestCase; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -@SmallTest -@RunWith(AndroidJUnit4.class) -public class BubbleCheckerTest extends UiServiceTestCase { - - private static final String SHORTCUT_ID = "shortcut"; - private static final String PKG = "pkg"; - private static final String KEY = "key"; - private static final int USER_ID = 1; - - @Mock - ActivityManager mActivityManager; - @Mock - RankingConfig mRankingConfig; - @Mock - ShortcutHelper mShortcutHelper; - - @Mock - NotificationRecord mNr; - @Mock - UserHandle mUserHandle; - @Mock - Notification mNotif; - @Mock - StatusBarNotification mSbn; - @Mock - NotificationChannel mChannel; - @Mock - Notification.BubbleMetadata mBubbleMetadata; - @Mock - PendingIntent mPendingIntent; - @Mock - Intent mIntent; - - BubbleExtractor.BubbleChecker mBubbleChecker; - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - - when(mNr.getKey()).thenReturn(KEY); - when(mNr.getSbn()).thenReturn(mSbn); - when(mNr.getUser()).thenReturn(mUserHandle); - when(mUserHandle.getIdentifier()).thenReturn(USER_ID); - when(mNr.getChannel()).thenReturn(mChannel); - when(mSbn.getPackageName()).thenReturn(PKG); - when(mSbn.getUser()).thenReturn(mUserHandle); - when(mNr.getNotification()).thenReturn(mNotif); - when(mNotif.getBubbleMetadata()).thenReturn(mBubbleMetadata); - - mBubbleChecker = new BubbleExtractor.BubbleChecker(mContext, - mShortcutHelper, - mRankingConfig, - mActivityManager); - } - - void setUpIntentBubble() { - when(mPendingIntent.getIntent()).thenReturn(mIntent); - when(mBubbleMetadata.getIntent()).thenReturn(mPendingIntent); - when(mBubbleMetadata.getShortcutId()).thenReturn(null); - } - - void setUpShortcutBubble(boolean isValid) { - when(mBubbleMetadata.getShortcutId()).thenReturn(SHORTCUT_ID); - ShortcutInfo info = mock(ShortcutInfo.class); - when(info.getId()).thenReturn(SHORTCUT_ID); - when(mShortcutHelper.getValidShortcutInfo(SHORTCUT_ID, PKG, mUserHandle)) - .thenReturn(isValid ? info : null); - when(mBubbleMetadata.getIntent()).thenReturn(null); - } - - void setUpBubblesEnabled(boolean feature, boolean app, boolean channel) { - when(mRankingConfig.bubblesEnabled()).thenReturn(feature); - when(mRankingConfig.areBubblesAllowed(PKG, USER_ID)).thenReturn(app); - when(mChannel.canBubble()).thenReturn(channel); - } - - void setUpActivityIntent(boolean isResizable) { - when(mPendingIntent.getIntent()).thenReturn(mIntent); - ActivityInfo info = new ActivityInfo(); - info.resizeMode = isResizable - ? RESIZE_MODE_RESIZEABLE - : RESIZE_MODE_UNRESIZEABLE; - when(mIntent.resolveActivityInfo(any(), anyInt())).thenReturn(info); - } - - // - // canBubble - // - - @Test - public void testCanBubble_true_intentBubble() { - setUpBubblesEnabled(true /* feature */, true /* app */, true /* channel */); - setUpIntentBubble(); - setUpActivityIntent(true /* isResizable */); - when(mActivityManager.isLowRamDevice()).thenReturn(false); - assertTrue(mBubbleChecker.canBubble(mNr, PKG, USER_ID)); - } - - @Test - public void testCanBubble_true_shortcutBubble() { - setUpBubblesEnabled(true /* feature */, true /* app */, true /* channel */); - setUpShortcutBubble(true /* isValid */); - assertTrue(mBubbleChecker.canBubble(mNr, PKG, USER_ID)); - } - - @Test - public void testCanBubble_false_noIntentInvalidShortcut() { - setUpBubblesEnabled(true /* feature */, true /* app */, true /* channel */); - setUpShortcutBubble(false /* isValid */); - assertFalse(mBubbleChecker.canBubble(mNr, PKG, USER_ID)); - } - - @Test - public void testCanBubble_false_noIntentNoShortcut() { - setUpBubblesEnabled(true /* feature */, true /* app */, true /* channel */); - when(mBubbleMetadata.getIntent()).thenReturn(null); - when(mBubbleMetadata.getShortcutId()).thenReturn(null); - assertFalse(mBubbleChecker.canBubble(mNr, PKG, USER_ID)); - } - - @Test - public void testCanBubbble_false_noMetadata() { - setUpBubblesEnabled(true/* feature */, true /* app */, true /* channel */); - when(mNotif.getBubbleMetadata()).thenReturn(null); - assertFalse(mBubbleChecker.canBubble(mNr, PKG, USER_ID)); - } - - @Test - public void testCanBubble_false_bubblesNotEnabled() { - setUpBubblesEnabled(false /* feature */, true /* app */, true /* channel */); - assertFalse(mBubbleChecker.canBubble(mNr, PKG, USER_ID)); - } - - @Test - public void testCanBubble_false_packageNotAllowed() { - setUpBubblesEnabled(true /* feature */, false /* app */, true /* channel */); - assertFalse(mBubbleChecker.canBubble(mNr, PKG, USER_ID)); - } - - @Test - public void testCanBubble_false_channelNotAllowed() { - setUpBubblesEnabled(true /* feature */, true /* app */, false /* channel */); - assertFalse(mBubbleChecker.canBubble(mNr, PKG, USER_ID)); - } - - // - // canLaunchInActivityView - // - - @Test - public void testCanLaunchInActivityView_true() { - setUpActivityIntent(true /* resizable */); - assertTrue(mBubbleChecker.canLaunchInActivityView(mContext, mPendingIntent, PKG)); - } - - @Test - public void testCanLaunchInActivityView_false_noIntent() { - when(mPendingIntent.getIntent()).thenReturn(null); - assertFalse(mBubbleChecker.canLaunchInActivityView(mContext, mPendingIntent, PKG)); - } - - @Test - public void testCanLaunchInActivityView_false_noInfo() { - when(mPendingIntent.getIntent()).thenReturn(mIntent); - when(mIntent.resolveActivityInfo(any(), anyInt())).thenReturn(null); - assertFalse(mBubbleChecker.canLaunchInActivityView(mContext, mPendingIntent, PKG)); - } - - @Test - public void testCanLaunchInActivityView_false_notResizable() { - setUpActivityIntent(false /* resizable */); - assertFalse(mBubbleChecker.canLaunchInActivityView(mContext, mPendingIntent, PKG)); - } - - // - // isNotificationAppropriateToBubble - // - - @Test - public void testIsNotifAppropriateToBubble_true() { - setUpBubblesEnabled(true /* feature */, true /* app */, true /* channel */); - setUpIntentBubble(); - when(mActivityManager.isLowRamDevice()).thenReturn(false); - setUpActivityIntent(true /* resizable */); - doReturn(Notification.MessagingStyle.class).when(mNotif).getNotificationStyle(); - - assertTrue(mBubbleChecker.isNotificationAppropriateToBubble(mNr)); - } - - @Test - public void testIsNotifAppropriateToBubble_false_lowRam() { - setUpBubblesEnabled(true /* feature */, true /* app */, true /* channel */); - when(mActivityManager.isLowRamDevice()).thenReturn(true); - setUpActivityIntent(true /* resizable */); - doReturn(Notification.MessagingStyle.class).when(mNotif).getNotificationStyle(); - - assertFalse(mBubbleChecker.isNotificationAppropriateToBubble(mNr)); - } - - @Test - public void testIsNotifAppropriateToBubble_false_notMessageStyle() { - setUpBubblesEnabled(true /* feature */, true /* app */, true /* channel */); - when(mActivityManager.isLowRamDevice()).thenReturn(false); - setUpActivityIntent(true /* resizable */); - doReturn(Notification.BigPictureStyle.class).when(mNotif).getNotificationStyle(); - - assertFalse(mBubbleChecker.isNotificationAppropriateToBubble(mNr)); - } - -} diff --git a/services/tests/uiservicestests/src/com/android/server/notification/BubbleExtractorTest.java b/services/tests/uiservicestests/src/com/android/server/notification/BubbleExtractorTest.java index 0dbbbaa9cdd6..3c376c9972ac 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/BubbleExtractorTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/BubbleExtractorTest.java @@ -15,12 +15,19 @@ */ package com.android.server.notification; -import static android.app.NotificationManager.IMPORTANCE_HIGH; -import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED; +import static android.app.NotificationChannel.USER_LOCKED_ALLOW_BUBBLE; +import static android.app.NotificationManager.BUBBLE_PREFERENCE_ALL; +import static android.app.NotificationManager.BUBBLE_PREFERENCE_NONE; +import static android.app.NotificationManager.BUBBLE_PREFERENCE_SELECTED; +import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE; +import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE; import static junit.framework.Assert.assertFalse; import static junit.framework.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -28,6 +35,12 @@ import android.app.ActivityManager; import android.app.Notification; import android.app.Notification.Builder; import android.app.NotificationChannel; +import android.app.PendingIntent; +import android.app.Person; +import android.content.Intent; +import android.content.pm.ActivityInfo; +import android.content.pm.ShortcutInfo; +import android.os.SystemClock; import android.os.UserHandle; import android.service.notification.StatusBarNotification; import android.test.suitebuilder.annotation.SmallTest; @@ -46,16 +59,32 @@ import org.mockito.MockitoAnnotations; @RunWith(AndroidJUnit4.class) public class BubbleExtractorTest extends UiServiceTestCase { - @Mock RankingConfig mConfig; - @Mock BubbleExtractor.BubbleChecker mBubbleChecker; + private static final String SHORTCUT_ID = "shortcut"; + private static final String PKG = "com.android.server.notification"; + private static final String TAG = null; + private static final int ID = 1001; + private static final int UID = 1000; + private static final int PID = 2000; + UserHandle mUser = UserHandle.of(ActivityManager.getCurrentUser()); + BubbleExtractor mBubbleExtractor; - private String mPkg = "com.android.server.notification"; - private int mId = 1001; - private String mTag = null; - private int mUid = 1000; - private int mPid = 2000; - private UserHandle mUser = UserHandle.of(ActivityManager.getCurrentUser()); + @Mock + RankingConfig mConfig; + @Mock + NotificationChannel mChannel; + @Mock + Notification.BubbleMetadata mBubbleMetadata; + @Mock + PendingIntent mPendingIntent; + @Mock + Intent mIntent; + @Mock + ShortcutInfo mShortcutInfo; + @Mock + ShortcutHelper mShortcutHelper; + @Mock + ActivityManager mActivityManager; @Before public void setUp() { @@ -63,58 +92,103 @@ public class BubbleExtractorTest extends UiServiceTestCase { mBubbleExtractor = new BubbleExtractor(); mBubbleExtractor.initialize(mContext, mock(NotificationUsageStats.class)); mBubbleExtractor.setConfig(mConfig); - mBubbleExtractor.setShortcutHelper(mock(ShortcutHelper.class)); - } + mBubbleExtractor.setShortcutHelper(mShortcutHelper); + mBubbleExtractor.setActivityManager(mActivityManager); - private NotificationRecord getNotificationRecord(boolean allow, int importanceHigh) { - NotificationChannel channel = new NotificationChannel("a", "a", importanceHigh); - channel.setAllowBubbles(allow); - when(mConfig.getNotificationChannel(mPkg, mUid, "a", false)).thenReturn(channel); + when(mConfig.getNotificationChannel(PKG, UID, "a", false)).thenReturn(mChannel); + when(mShortcutInfo.getId()).thenReturn(SHORTCUT_ID); + } + /* NotificationRecord that fulfills conversation requirements (message style + shortcut) */ + private NotificationRecord getNotificationRecord(boolean addBubble) { final Builder builder = new Builder(getContext()) .setContentTitle("foo") .setSmallIcon(android.R.drawable.sym_def_app_icon) .setPriority(Notification.PRIORITY_HIGH) .setDefaults(Notification.DEFAULT_SOUND); - + Person person = new Person.Builder() + .setName("bubblebot") + .build(); + builder.setShortcutId(SHORTCUT_ID); + builder.setStyle(new Notification.MessagingStyle(person) + .setConversationTitle("Bubble Chat") + .addMessage("Hello?", + SystemClock.currentThreadTimeMillis() - 300000, person) + .addMessage("Is it me you're looking for?", + SystemClock.currentThreadTimeMillis(), person)); Notification n = builder.build(); - StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, mId, mTag, mUid, - mPid, n, mUser, null, System.currentTimeMillis()); - NotificationRecord r = new NotificationRecord(getContext(), sbn, channel); + if (addBubble) { + n.setBubbleMetadata(mBubbleMetadata); + } + StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, ID, TAG, UID, + PID, n, mUser, null, System.currentTimeMillis()); + NotificationRecord r = new NotificationRecord(getContext(), sbn, mChannel); + r.setShortcutInfo(mShortcutInfo); return r; } + void setUpIntentBubble(boolean isValid) { + when(mPendingIntent.getIntent()).thenReturn(mIntent); + when(mBubbleMetadata.getIntent()).thenReturn(mPendingIntent); + when(mBubbleMetadata.getShortcutId()).thenReturn(null); + + when(mPendingIntent.getIntent()).thenReturn(mIntent); + ActivityInfo info = new ActivityInfo(); + info.resizeMode = isValid + ? RESIZE_MODE_RESIZEABLE + : RESIZE_MODE_UNRESIZEABLE; + when(mIntent.resolveActivityInfo(any(), anyInt())).thenReturn(info); + } + + void setUpShortcutBubble(boolean isValid) { + when(mBubbleMetadata.getShortcutId()).thenReturn(SHORTCUT_ID); + when(mBubbleMetadata.getIntent()).thenReturn(null); + ShortcutInfo answer = isValid ? mShortcutInfo : null; + when(mShortcutHelper.getValidShortcutInfo(SHORTCUT_ID, PKG, mUser)).thenReturn(answer); + } + + void setUpBubblesEnabled(boolean feature, int app, boolean channel) { + when(mConfig.bubblesEnabled()).thenReturn(feature); + when(mConfig.getBubblePreference(anyString(), anyInt())).thenReturn(app); + when(mChannel.canBubble()).thenReturn(channel); + } + // - // Tests + // Tests for the record being allowed to bubble. // @Test public void testAppYesChannelNo() { - when(mConfig.bubblesEnabled()).thenReturn(true); - when(mConfig.areBubblesAllowed(mPkg, mUid)).thenReturn(true); - NotificationRecord r = getNotificationRecord(false, IMPORTANCE_UNSPECIFIED); - + setUpBubblesEnabled(true /* feature */, + BUBBLE_PREFERENCE_ALL /* app */, + false /* channel */); + NotificationRecord r = getNotificationRecord(true /* bubble */); + when(mChannel.getUserLockedFields()).thenReturn(USER_LOCKED_ALLOW_BUBBLE); mBubbleExtractor.process(r); assertFalse(r.canBubble()); + assertFalse(r.getNotification().isBubbleNotification()); } @Test public void testAppNoChannelYes() throws Exception { - when(mConfig.bubblesEnabled()).thenReturn(true); - when(mConfig.areBubblesAllowed(mPkg, mUid)).thenReturn(false); - NotificationRecord r = getNotificationRecord(true, IMPORTANCE_HIGH); + setUpBubblesEnabled(true /* feature */, + BUBBLE_PREFERENCE_NONE /* app */, + true /* channel */); + NotificationRecord r = getNotificationRecord(true /* bubble */); mBubbleExtractor.process(r); assertFalse(r.canBubble()); + assertFalse(r.getNotification().isBubbleNotification()); } @Test public void testAppYesChannelYes() { - when(mConfig.bubblesEnabled()).thenReturn(true); - when(mConfig.areBubblesAllowed(mPkg, mUid)).thenReturn(true); - NotificationRecord r = getNotificationRecord(true, IMPORTANCE_UNSPECIFIED); + setUpBubblesEnabled(true /* feature */, + BUBBLE_PREFERENCE_ALL /* app */, + true /* channel */); + NotificationRecord r = getNotificationRecord(true /* bubble */); mBubbleExtractor.process(r); @@ -123,49 +197,228 @@ public class BubbleExtractorTest extends UiServiceTestCase { @Test public void testAppNoChannelNo() { - when(mConfig.bubblesEnabled()).thenReturn(true); - when(mConfig.areBubblesAllowed(mPkg, mUid)).thenReturn(false); - NotificationRecord r = getNotificationRecord(false, IMPORTANCE_UNSPECIFIED); + setUpBubblesEnabled(true /* feature */, + BUBBLE_PREFERENCE_NONE /* app */, + false /* channel */); + NotificationRecord r = getNotificationRecord(true /* bubble */); mBubbleExtractor.process(r); assertFalse(r.canBubble()); + assertFalse(r.getNotification().isBubbleNotification()); } @Test public void testAppYesChannelYesUserNo() { - when(mConfig.bubblesEnabled()).thenReturn(false); - when(mConfig.areBubblesAllowed(mPkg, mUid)).thenReturn(true); - NotificationRecord r = getNotificationRecord(true, IMPORTANCE_HIGH); + setUpBubblesEnabled(false /* feature */, + BUBBLE_PREFERENCE_ALL /* app */, + true /* channel */); + NotificationRecord r = getNotificationRecord(true /* bubble */); + + mBubbleExtractor.process(r); + + assertFalse(r.canBubble()); + assertFalse(r.getNotification().isBubbleNotification()); + } + + @Test + public void testAppSelectedChannelNo() { + setUpBubblesEnabled(true /* feature */, + BUBBLE_PREFERENCE_SELECTED /* app */, + false /* channel */); + NotificationRecord r = getNotificationRecord(true /* bubble */); mBubbleExtractor.process(r); assertFalse(r.canBubble()); + assertFalse(r.getNotification().isBubbleNotification()); } @Test - public void testFlagBubble_true() { - when(mConfig.bubblesEnabled()).thenReturn(true); - when(mConfig.areBubblesAllowed(mPkg, mUid)).thenReturn(true); - NotificationRecord r = getNotificationRecord(true, IMPORTANCE_UNSPECIFIED); + public void testAppSeletedChannelYes() { + setUpBubblesEnabled(true /* feature */, + BUBBLE_PREFERENCE_SELECTED /* app */, + true /* channel */); + NotificationRecord r = getNotificationRecord(true /* bubble */); + when(mChannel.getUserLockedFields()).thenReturn(USER_LOCKED_ALLOW_BUBBLE); - mBubbleExtractor.setBubbleChecker(mBubbleChecker); - when(mBubbleChecker.isNotificationAppropriateToBubble(r)).thenReturn(true); mBubbleExtractor.process(r); assertTrue(r.canBubble()); - assertTrue(r.getNotification().isBubbleNotification()); } + // + // Tests for flagging it as a bubble. + // + @Test - public void testFlagBubble_noFlag_previouslyRemoved() { - when(mConfig.bubblesEnabled()).thenReturn(true); - when(mConfig.areBubblesAllowed(mPkg, mUid)).thenReturn(true); - NotificationRecord r = getNotificationRecord(true, IMPORTANCE_UNSPECIFIED); + public void testFlagBubble_false_previouslyRemoved() { + setUpBubblesEnabled(true /* feature */, + BUBBLE_PREFERENCE_ALL /* app */, + true /* channel */); + when(mActivityManager.isLowRamDevice()).thenReturn(false); + + NotificationRecord r = getNotificationRecord(true /* bubble */); r.setFlagBubbleRemoved(true); - mBubbleExtractor.setBubbleChecker(mBubbleChecker); - when(mBubbleChecker.isNotificationAppropriateToBubble(r)).thenReturn(true); + mBubbleExtractor.process(r); + + assertTrue(r.canBubble()); + assertFalse(r.getNotification().isBubbleNotification()); + } + + @Test + public void testFlagBubble_true_shortcutBubble() { + setUpBubblesEnabled(true /* feature */, + BUBBLE_PREFERENCE_ALL /* app */, + true /* channel */); + when(mActivityManager.isLowRamDevice()).thenReturn(false); + setUpShortcutBubble(true /* isValid */); + + NotificationRecord r = getNotificationRecord(true /* bubble */); + mBubbleExtractor.process(r); + + assertTrue(r.canBubble()); + assertTrue(r.getNotification().isBubbleNotification()); + } + + @Test + public void testFlagBubble_true_intentBubble() { + setUpBubblesEnabled(true /* feature */, + BUBBLE_PREFERENCE_ALL /* app */, + true /* channel */); + when(mActivityManager.isLowRamDevice()).thenReturn(false); + setUpIntentBubble(true /* isValid */); + + NotificationRecord r = getNotificationRecord(true /* bubble */); + mBubbleExtractor.process(r); + + assertTrue(r.canBubble()); + assertTrue(r.getNotification().isBubbleNotification()); + } + + @Test + public void testFlagBubble_false_noIntentInvalidShortcut() { + setUpBubblesEnabled(true /* feature */, + BUBBLE_PREFERENCE_ALL /* app */, + true /* channel */); + when(mActivityManager.isLowRamDevice()).thenReturn(false); + setUpShortcutBubble(false /* isValid */); + + NotificationRecord r = getNotificationRecord(true /* bubble */); + r.setShortcutInfo(null); + mBubbleExtractor.process(r); + + assertTrue(r.canBubble()); + assertFalse(r.getNotification().isBubbleNotification()); + } + + @Test + public void testFlagBubble_false_invalidIntentNoShortcut() { + setUpBubblesEnabled(true /* feature */, + BUBBLE_PREFERENCE_ALL /* app */, + true /* channel */); + when(mActivityManager.isLowRamDevice()).thenReturn(false); + setUpIntentBubble(false /* isValid */); + + NotificationRecord r = getNotificationRecord(true /* bubble */); + r.setShortcutInfo(null); + mBubbleExtractor.process(r); + + assertTrue(r.canBubble()); + assertFalse(r.getNotification().isBubbleNotification()); + } + + @Test + public void testFlagBubble_false_noIntentNoShortcut() { + setUpBubblesEnabled(true /* feature */, + BUBBLE_PREFERENCE_ALL /* app */, + true /* channel */); + when(mActivityManager.isLowRamDevice()).thenReturn(false); + + // Shortcut here is for the notification not the bubble + NotificationRecord r = getNotificationRecord(true /* bubble */); + mBubbleExtractor.process(r); + + assertTrue(r.canBubble()); + assertFalse(r.getNotification().isBubbleNotification()); + } + + @Test + public void testFlagBubble_false_noMetadata() { + setUpBubblesEnabled(true /* feature */, + BUBBLE_PREFERENCE_ALL /* app */, + true /* channel */); + when(mActivityManager.isLowRamDevice()).thenReturn(false); + + NotificationRecord r = getNotificationRecord(false /* bubble */); + mBubbleExtractor.process(r); + + assertTrue(r.canBubble()); + assertFalse(r.getNotification().isBubbleNotification()); + } + + @Test + public void testFlagBubble_false_notConversation() { + setUpBubblesEnabled(true /* feature */, + BUBBLE_PREFERENCE_ALL /* app */, + true /* channel */); + when(mActivityManager.isLowRamDevice()).thenReturn(false); + setUpIntentBubble(true /* isValid */); + + NotificationRecord r = getNotificationRecord(true /* bubble */); + // No longer a conversation: + r.setShortcutInfo(null); + r.getNotification().extras.putString(Notification.EXTRA_TEMPLATE, null); + + mBubbleExtractor.process(r); + + assertTrue(r.canBubble()); + assertFalse(r.getNotification().isBubbleNotification()); + } + + @Test + public void testFlagBubble_false_lowRamDevice() { + setUpBubblesEnabled(true /* feature */, + BUBBLE_PREFERENCE_ALL /* app */, + true /* channel */); + when(mActivityManager.isLowRamDevice()).thenReturn(true); + setUpIntentBubble(true /* isValid */); + + NotificationRecord r = getNotificationRecord(true /* bubble */); + mBubbleExtractor.process(r); + + assertTrue(r.canBubble()); + assertFalse(r.getNotification().isBubbleNotification()); + } + + @Test + public void testFlagBubble_false_noIntent() { + setUpBubblesEnabled(true /* feature */, + BUBBLE_PREFERENCE_ALL /* app */, + true /* channel */); + when(mActivityManager.isLowRamDevice()).thenReturn(true); + setUpIntentBubble(true /* isValid */); + when(mPendingIntent.getIntent()).thenReturn(null); + + NotificationRecord r = getNotificationRecord(true /* bubble */); + mBubbleExtractor.process(r); + + assertTrue(r.canBubble()); + assertFalse(r.getNotification().isBubbleNotification()); + } + + @Test + public void testFlagBubble_false_noActivityInfo() { + setUpBubblesEnabled(true /* feature */, + BUBBLE_PREFERENCE_ALL /* app */, + true /* channel */); + when(mActivityManager.isLowRamDevice()).thenReturn(true); + setUpIntentBubble(true /* isValid */); + when(mPendingIntent.getIntent()).thenReturn(mIntent); + when(mIntent.resolveActivityInfo(any(), anyInt())).thenReturn(null); + + NotificationRecord r = getNotificationRecord(true /* bubble */); mBubbleExtractor.process(r); assertTrue(r.canBubble()); diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java index 15220e1ff54a..2d66aa51ee0f 100755 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java @@ -21,6 +21,10 @@ import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIB import static android.app.Notification.FLAG_AUTO_CANCEL; import static android.app.Notification.FLAG_BUBBLE; import static android.app.Notification.FLAG_FOREGROUND_SERVICE; +import static android.app.NotificationChannel.USER_LOCKED_ALLOW_BUBBLE; +import static android.app.NotificationManager.BUBBLE_PREFERENCE_ALL; +import static android.app.NotificationManager.BUBBLE_PREFERENCE_NONE; +import static android.app.NotificationManager.BUBBLE_PREFERENCE_SELECTED; import static android.app.NotificationManager.EXTRA_BLOCKED_STATE; import static android.app.NotificationManager.IMPORTANCE_DEFAULT; import static android.app.NotificationManager.IMPORTANCE_HIGH; @@ -39,6 +43,7 @@ import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_PEEK; import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_SCREEN_OFF; import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_SCREEN_ON; import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_STATUS_BAR; +import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE; import static android.content.pm.PackageManager.FEATURE_WATCH; import static android.content.pm.PackageManager.PERMISSION_DENIED; import static android.content.pm.PackageManager.PERMISSION_GRANTED; @@ -101,12 +106,14 @@ import android.content.ComponentName; import android.content.ContentUris; import android.content.Context; import android.content.Intent; +import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; import android.content.pm.IPackageManager; import android.content.pm.LauncherApps; import android.content.pm.PackageManager; import android.content.pm.ParceledListSlice; import android.content.pm.ShortcutInfo; +import android.content.pm.ShortcutServiceInternal; import android.content.pm.UserInfo; import android.content.res.Resources; import android.graphics.Color; @@ -204,7 +211,6 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { private TestableNotificationManagerService mService; private INotificationManager mBinderService; private NotificationManagerInternal mInternalService; - private TestableBubbleChecker mTestableBubbleChecker; private ShortcutHelper mShortcutHelper; @Mock private IPackageManager mPackageManager; @@ -229,6 +235,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Mock private LauncherApps mLauncherApps; @Mock + private ShortcutServiceInternal mShortcutServiceInternal; + @Mock ActivityManager mActivityManager; @Mock Resources mResources; @@ -347,21 +355,6 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { } } - private class TestableBubbleChecker extends BubbleExtractor.BubbleChecker { - - TestableBubbleChecker(Context context, ShortcutHelper helper, RankingConfig config, - ActivityManager manager) { - super(context, helper, config, manager); - } - - @Override - protected boolean canLaunchInActivityView(Context context, PendingIntent pendingIntent, - String packageName) { - // Tests for this not being true are in CTS NotificationManagerTest - return true; - } - } - private class TestableToastCallback extends ITransientNotification.Stub { @Override public void show(IBinder windowToken) { @@ -476,13 +469,12 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { mShortcutHelper = mService.getShortcutHelper(); mShortcutHelper.setLauncherApps(mLauncherApps); + mShortcutHelper.setShortcutServiceInternal(mShortcutServiceInternal); // Set the testable bubble extractor RankingHelper rankingHelper = mService.getRankingHelper(); BubbleExtractor extractor = rankingHelper.findExtractor(BubbleExtractor.class); - mTestableBubbleChecker = new TestableBubbleChecker(mContext, mShortcutHelper, - mService.mPreferencesHelper, mActivityManager); - extractor.setBubbleChecker(mTestableBubbleChecker); + extractor.setActivityManager(mActivityManager); // Tests call directly into the Binder. mBinderService = mService.getBinderService(); @@ -544,13 +536,13 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { } private void setUpPrefsForBubbles(String pkg, int uid, boolean globalEnabled, - boolean pkgEnabled, boolean channelEnabled) { + int pkgPref, boolean channelEnabled) { Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.NOTIFICATION_BUBBLES, globalEnabled ? 1 : 0); mService.mPreferencesHelper.updateBubblesEnabled(); assertEquals(globalEnabled, mService.mPreferencesHelper.bubblesEnabled()); try { - mBinderService.setBubblesAllowed(pkg, uid, pkgEnabled); + mBinderService.setBubblesAllowed(pkg, uid, pkgPref); } catch (RemoteException e) { e.printStackTrace(); } @@ -687,19 +679,12 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { false); } - private Notification.BubbleMetadata.Builder getBubbleMetadataBuilder() { - PendingIntent pi = PendingIntent.getActivity(mContext, 0, new Intent(), 0); - return new Notification.BubbleMetadata.Builder(pi, - Icon.createWithResource(mContext, android.R.drawable.sym_def_app_icon)); - } - private Notification.Builder getMessageStyleNotifBuilder(boolean addBubbleMetadata, String groupKey, boolean isSummary) { // Give it a person Person person = new Person.Builder() .setName("bubblebot") .build(); - // It needs remote input to be bubble-able RemoteInput remoteInput = new RemoteInput.Builder("reply_key").setLabel("reply").build(); PendingIntent inputIntent = PendingIntent.getActivity(mContext, 0, new Intent(), 0); Icon icon = Icon.createWithResource(mContext, android.R.drawable.sym_def_app_icon); @@ -724,11 +709,26 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { nb.setGroup(groupKey); } if (addBubbleMetadata) { - nb.setBubbleMetadata(getBubbleMetadataBuilder().build()); + nb.setBubbleMetadata(getBubbleMetadata()); } return nb; } + private Notification.BubbleMetadata getBubbleMetadata() { + PendingIntent pendingIntent = mock(PendingIntent.class); + Intent intent = mock(Intent.class); + when(pendingIntent.getIntent()).thenReturn(intent); + + ActivityInfo info = new ActivityInfo(); + info.resizeMode = RESIZE_MODE_RESIZEABLE; + when(intent.resolveActivityInfo(any(), anyInt())).thenReturn(info); + + return new Notification.BubbleMetadata.Builder( + pendingIntent, + Icon.createWithResource(mContext, android.R.drawable.sym_def_app_icon)) + .build(); + } + private NotificationRecord addGroupWithBubblesAndValidateAdded(boolean summaryAutoCancel) throws RemoteException { @@ -4483,24 +4483,31 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test public void testBubble() throws Exception { - mBinderService.setBubblesAllowed(PKG, mUid, false); - assertFalse(mBinderService.areBubblesAllowedForPackage(PKG, mUid)); + mBinderService.setBubblesAllowed(PKG, mUid, BUBBLE_PREFERENCE_NONE); + assertFalse(mBinderService.areBubblesAllowed(PKG)); + assertEquals(mBinderService.getBubblePreferenceForPackage(PKG, mUid), + BUBBLE_PREFERENCE_NONE); } @Test - public void testUserApprovedBubblesForPackage() throws Exception { - assertFalse(mBinderService.hasUserApprovedBubblesForPackage(PKG, mUid)); - mBinderService.setBubblesAllowed(PKG, mUid, true); - assertTrue(mBinderService.hasUserApprovedBubblesForPackage(PKG, mUid)); - assertTrue(mBinderService.areBubblesAllowedForPackage(PKG, mUid)); + public void testUserApprovedBubblesForPackageSelected() throws Exception { + mBinderService.setBubblesAllowed(PKG, mUid, BUBBLE_PREFERENCE_SELECTED); + assertEquals(mBinderService.getBubblePreferenceForPackage(PKG, mUid), + BUBBLE_PREFERENCE_SELECTED); + } + + @Test + public void testUserApprovedBubblesForPackageAll() throws Exception { + mBinderService.setBubblesAllowed(PKG, mUid, BUBBLE_PREFERENCE_ALL); + assertTrue(mBinderService.areBubblesAllowed(PKG)); + assertEquals(mBinderService.getBubblePreferenceForPackage(PKG, mUid), + BUBBLE_PREFERENCE_ALL); } @Test public void testUserRejectsBubblesForPackage() throws Exception { - assertFalse(mBinderService.hasUserApprovedBubblesForPackage(PKG, mUid)); - mBinderService.setBubblesAllowed(PKG, mUid, false); - assertTrue(mBinderService.hasUserApprovedBubblesForPackage(PKG, mUid)); - assertFalse(mBinderService.areBubblesAllowedForPackage(PKG, mUid)); + mBinderService.setBubblesAllowed(PKG, mUid, BUBBLE_PREFERENCE_NONE); + assertFalse(mBinderService.areBubblesAllowed(PKG)); } @Test @@ -5166,8 +5173,10 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test public void testFlagBubble() throws RemoteException { - // Bubbles are allowed! - setUpPrefsForBubbles(PKG, mUid, true /* global */, true /* app */, true /* channel */); + setUpPrefsForBubbles(PKG, mUid, + true /* global */, + BUBBLE_PREFERENCE_ALL /* app */, + true /* channel */); NotificationRecord nr = generateMessageBubbleNotifRecord(mTestNotificationChannel, "testFlagBubble"); @@ -5185,8 +5194,10 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test public void testFlagBubble_noFlag_appNotAllowed() throws RemoteException { - // Bubbles are allowed! - setUpPrefsForBubbles(PKG, mUid, true /* global */, false /* app */, true /* channel */); + setUpPrefsForBubbles(PKG, mUid, + true /* global */, + BUBBLE_PREFERENCE_NONE /* app */, + true /* channel */); NotificationRecord nr = generateMessageBubbleNotifRecord(mTestNotificationChannel, "testFlagBubble_noFlag_appNotAllowed"); @@ -5204,15 +5215,17 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test public void testFlagBubbleNotifs_noFlag_whenAppForeground() throws RemoteException { - // Bubbles are allowed! - setUpPrefsForBubbles(PKG, mUid, true /* global */, true /* app */, true /* channel */); + setUpPrefsForBubbles(PKG, mUid, + true /* global */, + BUBBLE_PREFERENCE_ALL /* app */, + true /* channel */); // Notif with bubble metadata but not our other misc requirements Notification.Builder nb = new Notification.Builder(mContext, mTestNotificationChannel.getId()) .setContentTitle("foo") .setSmallIcon(android.R.drawable.sym_def_app_icon) - .setBubbleMetadata(getBubbleMetadataBuilder().build()); + .setBubbleMetadata(getBubbleMetadata()); StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1, "tag", mUid, 0, nb.build(), new UserHandle(mUid), null, 0); NotificationRecord nr = new NotificationRecord(mContext, sbn, mTestNotificationChannel); @@ -5232,8 +5245,10 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test public void testFlagBubbleNotifs_flag_messaging() throws RemoteException { - // Bubbles are allowed! - setUpPrefsForBubbles(PKG, mUid, true /* global */, true /* app */, true /* channel */); + setUpPrefsForBubbles(PKG, mUid, + true /* global */, + BUBBLE_PREFERENCE_ALL /* app */, + true /* channel */); NotificationRecord nr = generateMessageBubbleNotifRecord(mTestNotificationChannel, "testFlagBubbleNotifs_flag_messaging"); @@ -5249,8 +5264,10 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test public void testFlagBubbleNotifs_noFlag_messaging_appNotAllowed() throws RemoteException { - // Bubbles are NOT allowed! - setUpPrefsForBubbles(PKG, mUid, true /* global */, false /* app */, true /* channel */); + setUpPrefsForBubbles(PKG, mUid, + true /* global */, + BUBBLE_PREFERENCE_NONE /* app */, + true /* channel */); NotificationRecord nr = generateMessageBubbleNotifRecord(mTestNotificationChannel, "testFlagBubbleNotifs_noFlag_messaging_appNotAllowed"); @@ -5267,8 +5284,10 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test public void testFlagBubbleNotifs_noFlag_notBubble() throws RemoteException { - // Bubbles are allowed! - setUpPrefsForBubbles(PKG, mUid, true /* global */, true /* app */, true /* channel */); + setUpPrefsForBubbles(PKG, mUid, + true /* global */, + BUBBLE_PREFERENCE_ALL /* app */, + true /* channel */); // Messaging notif WITHOUT bubble metadata Notification.Builder nb = getMessageStyleNotifBuilder(false /* addBubbleMetadata */, @@ -5291,11 +5310,14 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test public void testFlagBubbleNotifs_noFlag_messaging_channelNotAllowed() throws RemoteException { - // Bubbles are allowed except on this channel - setUpPrefsForBubbles(PKG, mUid, true /* global */, true /* app */, false /* channel */); + setUpPrefsForBubbles(PKG, mUid, + true /* global */, + BUBBLE_PREFERENCE_ALL /* app */, + false /* channel */); NotificationRecord nr = generateMessageBubbleNotifRecord(mTestNotificationChannel, "testFlagBubbleNotifs_noFlag_messaging_channelNotAllowed"); + nr.getChannel().lockFields(USER_LOCKED_ALLOW_BUBBLE); // Post the notification mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(), @@ -5488,7 +5510,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test public void testAreBubblesAllowedForPackage_crossUser() throws Exception { try { - mBinderService.areBubblesAllowedForPackage(mContext.getPackageName(), + mBinderService.getBubblePreferenceForPackage(mContext.getPackageName(), mUid + UserHandle.PER_USER_RANGE); fail("Cannot call cross user without permission"); } catch (SecurityException e) { @@ -5497,7 +5519,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { // cross user, with permission, no problem enableInteractAcrossUsers(); - mBinderService.areBubblesAllowedForPackage(mContext.getPackageName(), + mBinderService.getBubblePreferenceForPackage(mContext.getPackageName(), mUid + UserHandle.PER_USER_RANGE); } @@ -5508,8 +5530,10 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test public void testNotificationBubbleChanged_false() throws Exception { - // Bubbles are allowed! - setUpPrefsForBubbles(PKG, mUid, true /* global */, true /* app */, true /* channel */); + setUpPrefsForBubbles(PKG, mUid, + true /* global */, + BUBBLE_PREFERENCE_ALL /* app */, + true /* channel */); // Notif with bubble metadata NotificationRecord nr = generateMessageBubbleNotifRecord(mTestNotificationChannel, @@ -5528,7 +5552,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { assertTrue((notifsBefore[0].getNotification().flags & FLAG_BUBBLE) != 0); // Notify we're not a bubble - mService.mNotificationDelegate.onNotificationBubbleChanged(nr.getKey(), false); + mService.mNotificationDelegate.onNotificationBubbleChanged(nr.getKey(), false, 0); waitForIdle(); // Make sure we are not a bubble @@ -5539,8 +5563,10 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test public void testNotificationBubbleChanged_true() throws Exception { - // Bubbles are allowed! - setUpPrefsForBubbles(PKG, mUid, true /* global */, true /* app */, true /* channel */); + setUpPrefsForBubbles(PKG, mUid, + true /* global */, + BUBBLE_PREFERENCE_ALL /* app */, + true /* channel */); // Notif that is not a bubble NotificationRecord nr = generateNotificationRecord(mTestNotificationChannel, @@ -5565,7 +5591,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { reset(mListeners); // Notify we are now a bubble - mService.mNotificationDelegate.onNotificationBubbleChanged(nr.getKey(), true); + mService.mNotificationDelegate.onNotificationBubbleChanged(nr.getKey(), true, 0); waitForIdle(); // Make sure we are a bubble @@ -5576,8 +5602,10 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test public void testNotificationBubbleChanged_true_notAllowed() throws Exception { - // Bubbles are allowed! - setUpPrefsForBubbles(PKG, mUid, true /* global */, true /* app */, true /* channel */); + setUpPrefsForBubbles(PKG, mUid, + true /* global */, + BUBBLE_PREFERENCE_ALL /* app */, + true /* channel */); // Notif that is not a bubble NotificationRecord nr = generateNotificationRecord(mTestNotificationChannel); @@ -5594,7 +5622,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { assertEquals((notifsBefore[0].getNotification().flags & FLAG_BUBBLE), 0); // Notify we are now a bubble - mService.mNotificationDelegate.onNotificationBubbleChanged(nr.getKey(), true); + mService.mNotificationDelegate.onNotificationBubbleChanged(nr.getKey(), true, 0); waitForIdle(); // We still wouldn't be a bubble because the notification didn't meet requirements @@ -5605,8 +5633,11 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test public void testNotificationBubbleIsFlagRemoved_resetOnUpdate() throws Exception { - // Bubbles are allowed! - setUpPrefsForBubbles(PKG, mUid, true /* global */, true /* app */, true /* channel */); + setUpPrefsForBubbles(PKG, mUid, + true /* global */, + BUBBLE_PREFERENCE_ALL /* app */, + true /* channel */); + // Notif with bubble metadata NotificationRecord nr = generateMessageBubbleNotifRecord(mTestNotificationChannel, "testNotificationBubbleIsFlagRemoved_resetOnUpdate"); @@ -5619,7 +5650,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { assertFalse(recordToCheck.isFlagBubbleRemoved()); // Notify we're not a bubble - mService.mNotificationDelegate.onNotificationBubbleChanged(nr.getKey(), false); + mService.mNotificationDelegate.onNotificationBubbleChanged(nr.getKey(), false, 0); waitForIdle(); // Flag should be modified recordToCheck = mService.getNotificationRecord(nr.getSbn().getKey()); @@ -5637,8 +5668,11 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test public void testNotificationBubbleIsFlagRemoved_resetOnBubbleChangedTrue() throws Exception { - // Bubbles are allowed! - setUpPrefsForBubbles(PKG, mUid, true /* global */, true /* app */, true /* channel */); + setUpPrefsForBubbles(PKG, mUid, + true /* global */, + BUBBLE_PREFERENCE_ALL /* app */, + true /* channel */); + // Notif with bubble metadata NotificationRecord nr = generateMessageBubbleNotifRecord(mTestNotificationChannel, "testNotificationBubbleIsFlagRemoved_trueOnBubbleChangedTrue"); @@ -5651,14 +5685,14 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { assertFalse(recordToCheck.isFlagBubbleRemoved()); // Notify we're not a bubble - mService.mNotificationDelegate.onNotificationBubbleChanged(nr.getKey(), false); + mService.mNotificationDelegate.onNotificationBubbleChanged(nr.getKey(), false, 0); waitForIdle(); // Flag should be modified recordToCheck = mService.getNotificationRecord(nr.getSbn().getKey()); assertTrue(recordToCheck.isFlagBubbleRemoved()); // Notify we are a bubble - mService.mNotificationDelegate.onNotificationBubbleChanged(nr.getKey(), true); + mService.mNotificationDelegate.onNotificationBubbleChanged(nr.getKey(), true, 0); waitForIdle(); // And the flag is reset assertFalse(recordToCheck.isFlagBubbleRemoved()); @@ -5666,16 +5700,14 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test public void testOnBubbleNotificationSuppressionChanged() throws Exception { - // Bubbles are allowed! - setUpPrefsForBubbles(PKG, mUid, true /* global */, true /* app */, true /* channel */); + setUpPrefsForBubbles(PKG, mUid, + true /* global */, + BUBBLE_PREFERENCE_ALL /* app */, + true /* channel */); // Bubble notification NotificationRecord nr = generateMessageBubbleNotifRecord(mTestNotificationChannel, "tag"); - // Bubbles are allowed! - setUpPrefsForBubbles(PKG, nr.getSbn().getUserId(), true /* global */, - true /* app */, true /* channel */); - mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(), nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId()); waitForIdle(); @@ -5888,8 +5920,10 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test public void testNotificationBubbles_disabled_lowRamDevice() throws Exception { - // Bubbles are allowed! - setUpPrefsForBubbles(PKG, mUid, true /* global */, true /* app */, true /* channel */); + setUpPrefsForBubbles(PKG, mUid, + true /* global */, + BUBBLE_PREFERENCE_ALL /* app */, + true /* channel */); // And we are low ram when(mActivityManager.isLowRamDevice()).thenReturn(true); @@ -5972,8 +6006,10 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test public void testNotificationBubbles_flagAutoExpandForeground_fails_notForeground() throws Exception { - // Bubbles are allowed! - setUpPrefsForBubbles(PKG, mUid, true /* global */, true /* app */, true /* channel */); + setUpPrefsForBubbles(PKG, mUid, + true /* global */, + BUBBLE_PREFERENCE_ALL /* app */, + true /* channel */); NotificationRecord nr = generateMessageBubbleNotifRecord(mTestNotificationChannel, "testNotificationBubbles_flagAutoExpandForeground_fails_notForeground"); @@ -6002,8 +6038,10 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test public void testNotificationBubbles_flagAutoExpandForeground_succeeds_foreground() throws RemoteException { - // Bubbles are allowed! - setUpPrefsForBubbles(PKG, mUid, true /* global */, true /* app */, true /* channel */); + setUpPrefsForBubbles(PKG, mUid, + true /* global */, + BUBBLE_PREFERENCE_ALL /* app */, + true /* channel */); NotificationRecord nr = generateMessageBubbleNotifRecord(mTestNotificationChannel, "testNotificationBubbles_flagAutoExpandForeground_succeeds_foreground"); @@ -6032,8 +6070,10 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test public void testNotificationBubbles_flagRemoved_whenShortcutRemoved() throws RemoteException { - // Bubbles are allowed! - setUpPrefsForBubbles(PKG, mUid, true /* global */, true /* app */, true /* channel */); + setUpPrefsForBubbles(PKG, mUid, + true /* global */, + BUBBLE_PREFERENCE_ALL /* app */, + true /* channel */); ArgumentCaptor<LauncherApps.Callback> launcherAppsCallback = ArgumentCaptor.forClass(LauncherApps.Callback.class); @@ -6052,8 +6092,11 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { List<ShortcutInfo> shortcutInfos = new ArrayList<>(); ShortcutInfo info = mock(ShortcutInfo.class); when(info.isLongLived()).thenReturn(true); + when(info.isEnabled()).thenReturn(true); shortcutInfos.add(info); when(mLauncherApps.getShortcuts(any(), any())).thenReturn(shortcutInfos); + when(mShortcutServiceInternal.isSharingShortcut(anyInt(), anyString(), anyString(), + anyString(), anyInt(), any())).thenReturn(true); // Test: Send the bubble notification mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(), @@ -6090,8 +6133,10 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test public void testNotificationBubbles_shortcut_stopListeningWhenNotifRemoved() throws RemoteException { - // Bubbles are allowed! - setUpPrefsForBubbles(PKG, mUid, true /* global */, true /* app */, true /* channel */); + setUpPrefsForBubbles(PKG, mUid, + true /* global */, + BUBBLE_PREFERENCE_ALL /* app */, + true /* channel */); ArgumentCaptor<LauncherApps.Callback> launcherAppsCallback = ArgumentCaptor.forClass(LauncherApps.Callback.class); @@ -6110,8 +6155,11 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { List<ShortcutInfo> shortcutInfos = new ArrayList<>(); ShortcutInfo info = mock(ShortcutInfo.class); when(info.isLongLived()).thenReturn(true); + when(info.isEnabled()).thenReturn(true); shortcutInfos.add(info); when(mLauncherApps.getShortcuts(any(), any())).thenReturn(shortcutInfos); + when(mShortcutServiceInternal.isSharingShortcut(anyInt(), anyString(), anyString(), + anyString(), anyInt(), any())).thenReturn(true); // Test: Send the bubble notification mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(), @@ -6141,8 +6189,10 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test public void testNotificationBubbles_bubbleChildrenStay_whenGroupSummaryDismissed() throws Exception { - // Bubbles are allowed! - setUpPrefsForBubbles(PKG, mUid, true /* global */, true /* app */, true /* channel */); + setUpPrefsForBubbles(PKG, mUid, + true /* global */, + BUBBLE_PREFERENCE_ALL /* app */, + true /* channel */); NotificationRecord nrSummary = addGroupWithBubblesAndValidateAdded( true /* summaryAutoCancel */); @@ -6165,8 +6215,10 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test public void testNotificationBubbles_bubbleChildrenStay_whenGroupSummaryClicked() throws Exception { - // Bubbles are allowed! - setUpPrefsForBubbles(PKG, mUid, true /* global */, true /* app */, true /* channel */); + setUpPrefsForBubbles(PKG, mUid, + true /* global */, + BUBBLE_PREFERENCE_ALL /* app */, + true /* channel */); NotificationRecord nrSummary = addGroupWithBubblesAndValidateAdded( true /* summaryAutoCancel */); @@ -6197,8 +6249,12 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test public void testNotificationBubbles_bubbleStays_whenClicked() throws Exception { + setUpPrefsForBubbles(PKG, mUid, + true /* global */, + BUBBLE_PREFERENCE_ALL /* app */, + true /* channel */); + // GIVEN a notification that has the auto cancels flag (cancel on click) and is a bubble - setUpPrefsForBubbles(PKG, mUid, true /* global */, true /* app */, true /* channel */); final NotificationRecord nr = generateNotificationRecord(mTestNotificationChannel); nr.getSbn().getNotification().flags |= FLAG_BUBBLE | FLAG_AUTO_CANCEL; mService.addNotification(nr); @@ -6332,7 +6388,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { assertEquals("friend", friendChannel.getConversationId()); assertEquals(null, original.getConversationId()); assertEquals(original.canShowBadge(), friendChannel.canShowBadge()); - assertEquals(original.canBubble(), friendChannel.canBubble()); + assertFalse(friendChannel.canBubble()); // can't be modified by app assertFalse(original.getId().equals(friendChannel.getId())); assertNotNull(friendChannel.getId()); } @@ -6446,7 +6502,10 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { ShortcutInfo si = mock(ShortcutInfo.class); when(si.getShortLabel()).thenReturn("Hello"); when(si.isLongLived()).thenReturn(true); + when(si.isEnabled()).thenReturn(true); when(mLauncherApps.getShortcuts(any(), any())).thenReturn(Arrays.asList(si)); + when(mShortcutServiceInternal.isSharingShortcut(anyInt(), anyString(), anyString(), + anyString(), anyInt(), any())).thenReturn(true); List<ConversationChannelWrapper> conversations = mBinderService.getConversationsForPackage(PKG_P, mUid).getList(); diff --git a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java index ed5ec6ac785b..ac51750f23f8 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java @@ -15,7 +15,13 @@ */ package com.android.server.notification; +import static android.app.AppOpsManager.MODE_ALLOWED; +import static android.app.AppOpsManager.MODE_DEFAULT; +import static android.app.AppOpsManager.OP_SYSTEM_ALERT_WINDOW; import static android.app.NotificationChannel.CONVERSATION_CHANNEL_ID_FORMAT; +import static android.app.NotificationManager.BUBBLE_PREFERENCE_ALL; +import static android.app.NotificationManager.BUBBLE_PREFERENCE_NONE; +import static android.app.NotificationManager.BUBBLE_PREFERENCE_SELECTED; import static android.app.NotificationManager.IMPORTANCE_DEFAULT; import static android.app.NotificationManager.IMPORTANCE_HIGH; import static android.app.NotificationManager.IMPORTANCE_LOW; @@ -23,6 +29,7 @@ import static android.app.NotificationManager.IMPORTANCE_MAX; import static android.app.NotificationManager.IMPORTANCE_NONE; import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED; +import static com.android.server.notification.PreferencesHelper.DEFAULT_BUBBLE_PREFERENCE; import static com.android.server.notification.PreferencesHelper.NOTIFICATION_CHANNEL_COUNT_LIMIT; import static com.google.common.truth.Truth.assertThat; @@ -46,6 +53,7 @@ import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import android.app.AppOpsManager; import android.app.Notification; import android.app.NotificationChannel; import android.app.NotificationChannelGroup; @@ -128,6 +136,7 @@ public class PreferencesHelperTest extends UiServiceTestCase { @Spy IContentProvider mTestIContentProvider = new MockIContentProvider(); @Mock Context mContext; @Mock ZenModeHelper mMockZenModeHelper; + @Mock AppOpsManager mAppOpsManager; private NotificationManager.Policy mTestNotificationPolicy; @@ -183,7 +192,10 @@ public class PreferencesHelperTest extends UiServiceTestCase { mTestNotificationPolicy = new NotificationManager.Policy(0, 0, 0, 0, NotificationManager.Policy.STATE_CHANNELS_BYPASSING_DND, 0); when(mMockZenModeHelper.getNotificationPolicy()).thenReturn(mTestNotificationPolicy); - mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger); + when(mAppOpsManager.noteOpNoThrow(anyInt(), anyInt(), + anyString(), eq(null), anyString())).thenReturn(MODE_DEFAULT); + mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger, + mAppOpsManager); resetZenModeHelper(); mAudioAttributes = new AudioAttributes.Builder() @@ -1094,7 +1106,7 @@ public class PreferencesHelperTest extends UiServiceTestCase { .getUserLockedFields()); final NotificationChannel update = getChannel(); - update.setAllowBubbles(false); + update.setAllowBubbles(true); mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, update, true); assertEquals(NotificationChannel.USER_LOCKED_ALLOW_BUBBLE, mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, update.getId(), false) @@ -1460,7 +1472,8 @@ public class PreferencesHelperTest extends UiServiceTestCase { mTestNotificationPolicy = new NotificationManager.Policy(0, 0, 0, 0, NotificationManager.Policy.STATE_CHANNELS_BYPASSING_DND, 0); when(mMockZenModeHelper.getNotificationPolicy()).thenReturn(mTestNotificationPolicy); - mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger); + mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger, + mAppOpsManager); assertFalse(mHelper.areChannelsBypassingDnd()); verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any()); resetZenModeHelper(); @@ -1471,7 +1484,8 @@ public class PreferencesHelperTest extends UiServiceTestCase { // start notification policy off with mAreChannelsBypassingDnd = false mTestNotificationPolicy = new NotificationManager.Policy(0, 0, 0, 0, 0, 0); when(mMockZenModeHelper.getNotificationPolicy()).thenReturn(mTestNotificationPolicy); - mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger); + mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger, + mAppOpsManager); assertFalse(mHelper.areChannelsBypassingDnd()); verify(mMockZenModeHelper, never()).setNotificationPolicy(any()); resetZenModeHelper(); @@ -1734,14 +1748,14 @@ public class PreferencesHelperTest extends UiServiceTestCase { mHelper.updateDefaultApps(UserHandle.getUserId(UID_O), null, pkgPair); mHelper.setNotificationDelegate(PKG_O, UID_O, "", 1); mHelper.setImportance(PKG_O, UID_O, IMPORTANCE_NONE); - mHelper.setBubblesAllowed(PKG_O, UID_O, false); + mHelper.setBubblesAllowed(PKG_O, UID_O, DEFAULT_BUBBLE_PREFERENCE); mHelper.setShowBadge(PKG_O, UID_O, false); mHelper.setAppImportanceLocked(PKG_O, UID_O); mHelper.clearData(PKG_O, UID_O); assertEquals(IMPORTANCE_UNSPECIFIED, mHelper.getImportance(PKG_O, UID_O)); - assertTrue(mHelper.areBubblesAllowed(PKG_O, UID_O)); + assertEquals(mHelper.getBubblePreference(PKG_O, UID_O), DEFAULT_BUBBLE_PREFERENCE); assertTrue(mHelper.canShowBadge(PKG_O, UID_O)); assertNull(mHelper.getNotificationDelegate(PKG_O, UID_O)); assertEquals(0, mHelper.getAppLockedFields(PKG_O, UID_O)); @@ -2237,7 +2251,8 @@ public class PreferencesHelperTest extends UiServiceTestCase { + "content_type=\"4\" flags=\"0\" show_badge=\"true\" />\n" + "</package>\n" + "</ranking>\n"; - mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger); + mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger, + mAppOpsManager); loadByteArrayXml(preQXml.getBytes(), true, UserHandle.USER_SYSTEM); assertEquals(PreferencesHelper.DEFAULT_HIDE_SILENT_STATUS_BAR_ICONS, @@ -2249,7 +2264,8 @@ public class PreferencesHelperTest extends UiServiceTestCase { mHelper.setHideSilentStatusIcons(!PreferencesHelper.DEFAULT_HIDE_SILENT_STATUS_BAR_ICONS); ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL); - mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger); + mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger, + mAppOpsManager); loadStreamXml(baos, false, UserHandle.USER_ALL); assertEquals(!PreferencesHelper.DEFAULT_HIDE_SILENT_STATUS_BAR_ICONS, @@ -2345,7 +2361,8 @@ public class PreferencesHelperTest extends UiServiceTestCase { mHelper.setImportance(PKG_O, UID_O, IMPORTANCE_UNSPECIFIED); ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL); - mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger); + mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger, + mAppOpsManager); loadStreamXml(baos, false, UserHandle.USER_ALL); assertNull(mHelper.getNotificationDelegate(PKG_O, UID_O)); @@ -2356,7 +2373,8 @@ public class PreferencesHelperTest extends UiServiceTestCase { mHelper.setNotificationDelegate(PKG_O, UID_O, "other", 53); ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL); - mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger); + mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger, + mAppOpsManager); loadStreamXml(baos, false, UserHandle.USER_ALL); assertEquals("other", mHelper.getNotificationDelegate(PKG_O, UID_O)); @@ -2368,7 +2386,8 @@ public class PreferencesHelperTest extends UiServiceTestCase { mHelper.revokeNotificationDelegate(PKG_O, UID_O); ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL); - mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger); + mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger, + mAppOpsManager); loadStreamXml(baos, false, UserHandle.USER_ALL); assertNull(mHelper.getNotificationDelegate(PKG_O, UID_O)); @@ -2380,7 +2399,8 @@ public class PreferencesHelperTest extends UiServiceTestCase { mHelper.toggleNotificationDelegate(PKG_O, UID_O, false); ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL); - mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger); + mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger, + mAppOpsManager); loadStreamXml(baos, false, UserHandle.USER_ALL); // appears disabled @@ -2398,7 +2418,8 @@ public class PreferencesHelperTest extends UiServiceTestCase { mHelper.revokeNotificationDelegate(PKG_O, UID_O); ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL); - mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger); + mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger, + mAppOpsManager); loadStreamXml(baos, false, UserHandle.USER_ALL); // appears disabled @@ -2412,29 +2433,87 @@ public class PreferencesHelperTest extends UiServiceTestCase { } @Test - public void testAllowBubbles_defaults() throws Exception { - assertTrue(mHelper.areBubblesAllowed(PKG_O, UID_O)); + public void testBubblePreference_defaults() throws Exception { + assertEquals(BUBBLE_PREFERENCE_NONE, mHelper.getBubblePreference(PKG_O, UID_O)); ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL); - mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger); + mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger, + mAppOpsManager); loadStreamXml(baos, false, UserHandle.USER_ALL); - assertTrue(mHelper.areBubblesAllowed(PKG_O, UID_O)); + assertEquals(BUBBLE_PREFERENCE_NONE, mHelper.getBubblePreference(PKG_O, UID_O)); + assertEquals(0, mHelper.getAppLockedFields(PKG_O, UID_O)); + } + + @Test + public void testBubblePreference_upgradeWithSAWPermission() throws Exception { + when(mAppOpsManager.noteOpNoThrow(eq(OP_SYSTEM_ALERT_WINDOW), anyInt(), + anyString(), eq(null), anyString())).thenReturn(MODE_ALLOWED); + + final String xml = "<ranking version=\"1\">\n" + + "<package name=\"" + PKG_O + "\" uid=\"" + UID_O + "\">\n" + + "<channel id=\"someId\" name=\"hi\"" + + " importance=\"3\"/>" + + "</package>" + + "</ranking>"; + XmlPullParser parser = Xml.newPullParser(); + parser.setInput(new BufferedInputStream(new ByteArrayInputStream(xml.getBytes())), + null); + parser.nextTag(); + mHelper.readXml(parser, false, UserHandle.USER_ALL); + + assertEquals(BUBBLE_PREFERENCE_ALL, mHelper.getBubblePreference(PKG_O, UID_O)); assertEquals(0, mHelper.getAppLockedFields(PKG_O, UID_O)); } @Test - public void testAllowBubbles_xml() throws Exception { - mHelper.setBubblesAllowed(PKG_O, UID_O, false); - assertFalse(mHelper.areBubblesAllowed(PKG_O, UID_O)); + public void testBubblePreference_upgradeWithSAWThenUserOverride() throws Exception { + when(mAppOpsManager.noteOpNoThrow(eq(OP_SYSTEM_ALERT_WINDOW), anyInt(), + anyString(), eq(null), anyString())).thenReturn(MODE_ALLOWED); + + final String xml = "<ranking version=\"1\">\n" + + "<package name=\"" + PKG_O + "\" uid=\"" + UID_O + "\">\n" + + "<channel id=\"someId\" name=\"hi\"" + + " importance=\"3\"/>" + + "</package>" + + "</ranking>"; + XmlPullParser parser = Xml.newPullParser(); + parser.setInput(new BufferedInputStream(new ByteArrayInputStream(xml.getBytes())), + null); + parser.nextTag(); + mHelper.readXml(parser, false, UserHandle.USER_ALL); + + assertEquals(BUBBLE_PREFERENCE_ALL, mHelper.getBubblePreference(PKG_O, UID_O)); + assertEquals(0, mHelper.getAppLockedFields(PKG_O, UID_O)); + + mHelper.setBubblesAllowed(PKG_O, UID_O, BUBBLE_PREFERENCE_SELECTED); + assertEquals(BUBBLE_PREFERENCE_SELECTED, mHelper.getBubblePreference(PKG_O, UID_O)); assertEquals(PreferencesHelper.LockableAppFields.USER_LOCKED_BUBBLE, mHelper.getAppLockedFields(PKG_O, UID_O)); ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL); - mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger); + mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger, + mAppOpsManager); loadStreamXml(baos, false, UserHandle.USER_ALL); - assertFalse(mHelper.areBubblesAllowed(PKG_O, UID_O)); + assertEquals(BUBBLE_PREFERENCE_SELECTED, mHelper.getBubblePreference(PKG_O, UID_O)); + assertEquals(PreferencesHelper.LockableAppFields.USER_LOCKED_BUBBLE, + mHelper.getAppLockedFields(PKG_O, UID_O)); + } + + @Test + public void testBubblePreference_xml() throws Exception { + mHelper.setBubblesAllowed(PKG_O, UID_O, BUBBLE_PREFERENCE_NONE); + assertEquals(mHelper.getBubblePreference(PKG_O, UID_O), BUBBLE_PREFERENCE_NONE); + assertEquals(PreferencesHelper.LockableAppFields.USER_LOCKED_BUBBLE, + mHelper.getAppLockedFields(PKG_O, UID_O)); + + ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL); + mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger, + mAppOpsManager); + loadStreamXml(baos, false, UserHandle.USER_ALL); + + assertEquals(mHelper.getBubblePreference(PKG_O, UID_O), BUBBLE_PREFERENCE_NONE); assertEquals(PreferencesHelper.LockableAppFields.USER_LOCKED_BUBBLE, mHelper.getAppLockedFields(PKG_O, UID_O)); } @@ -2766,9 +2845,29 @@ public class PreferencesHelperTest extends UiServiceTestCase { } @Test - public void testSetBubblesAllowed_false() { - mHelper.setBubblesAllowed(PKG_O, UID_O, false); - assertFalse(mHelper.areBubblesAllowed(PKG_O, UID_O)); + public void testSetBubblesAllowed_none() { + // Change it to non-default first + mHelper.setBubblesAllowed(PKG_O, UID_O, BUBBLE_PREFERENCE_ALL); + assertEquals(mHelper.getBubblePreference(PKG_O, UID_O), BUBBLE_PREFERENCE_ALL); + verify(mHandler, times(1)).requestSort(); + reset(mHandler); + // Now test + mHelper.setBubblesAllowed(PKG_O, UID_O, BUBBLE_PREFERENCE_NONE); + assertEquals(mHelper.getBubblePreference(PKG_O, UID_O), BUBBLE_PREFERENCE_NONE); + verify(mHandler, times(1)).requestSort(); + } + + @Test + public void testSetBubblesAllowed_all() { + mHelper.setBubblesAllowed(PKG_O, UID_O, BUBBLE_PREFERENCE_ALL); + assertEquals(mHelper.getBubblePreference(PKG_O, UID_O), BUBBLE_PREFERENCE_ALL); + verify(mHandler, times(1)).requestSort(); + } + + @Test + public void testSetBubblesAllowed_selected() { + mHelper.setBubblesAllowed(PKG_O, UID_O, BUBBLE_PREFERENCE_SELECTED); + assertEquals(mHelper.getBubblePreference(PKG_O, UID_O), BUBBLE_PREFERENCE_SELECTED); verify(mHandler, times(1)).requestSort(); } @@ -2925,7 +3024,8 @@ public class PreferencesHelperTest extends UiServiceTestCase { Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.REQUIRE_SHORTCUTS_FOR_CONVERSATIONS, 0); - mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger); + mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger, + mAppOpsManager); final String xml = "<ranking version=\"1\">\n" + "<package name=\"" + PKG_O + "\" uid=\"" + UID_O + "\" >\n" @@ -2945,7 +3045,8 @@ public class PreferencesHelperTest extends UiServiceTestCase { public void testPlaceholderConversationId_shortcutRequired() throws Exception { Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.REQUIRE_SHORTCUTS_FOR_CONVERSATIONS, 1); - mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger); + mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger, + mAppOpsManager); final String xml = "<ranking version=\"1\">\n" + "<package name=\"" + PKG_O + "\" uid=\"" + UID_O + "\" >\n" @@ -2965,7 +3066,8 @@ public class PreferencesHelperTest extends UiServiceTestCase { public void testNormalConversationId_shortcutRequired() throws Exception { Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.REQUIRE_SHORTCUTS_FOR_CONVERSATIONS, 1); - mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger); + mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger, + mAppOpsManager); final String xml = "<ranking version=\"1\">\n" + "<package name=\"" + PKG_O + "\" uid=\"" + UID_O + "\" >\n" @@ -2985,7 +3087,8 @@ public class PreferencesHelperTest extends UiServiceTestCase { public void testNoConversationId_shortcutRequired() throws Exception { Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.REQUIRE_SHORTCUTS_FOR_CONVERSATIONS, 1); - mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger); + mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger, + mAppOpsManager); final String xml = "<ranking version=\"1\">\n" + "<package name=\"" + PKG_O + "\" uid=\"" + UID_O + "\" >\n" diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ShortcutHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ShortcutHelperTest.java index 50fb9b425652..f7304bd0075b 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/ShortcutHelperTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/ShortcutHelperTest.java @@ -16,7 +16,11 @@ package com.android.server.notification; +import static com.google.common.truth.Truth.assertThat; + import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -25,6 +29,7 @@ import static org.mockito.Mockito.when; import android.app.Notification; import android.content.pm.LauncherApps; import android.content.pm.ShortcutInfo; +import android.content.pm.ShortcutServiceInternal; import android.os.UserHandle; import android.service.notification.StatusBarNotification; import android.test.suitebuilder.annotation.SmallTest; @@ -58,6 +63,8 @@ public class ShortcutHelperTest extends UiServiceTestCase { @Mock ShortcutHelper.ShortcutListener mShortcutListener; @Mock + ShortcutServiceInternal mShortcutServiceInternal; + @Mock NotificationRecord mNr; @Mock Notification mNotif; @@ -72,7 +79,8 @@ public class ShortcutHelperTest extends UiServiceTestCase { public void setUp() { MockitoAnnotations.initMocks(this); - mShortcutHelper = new ShortcutHelper(mLauncherApps, mShortcutListener); + mShortcutHelper = new ShortcutHelper( + mLauncherApps, mShortcutListener, mShortcutServiceInternal); when(mNr.getKey()).thenReturn(KEY); when(mNr.getSbn()).thenReturn(mSbn); when(mSbn.getPackageName()).thenReturn(PKG); @@ -138,4 +146,80 @@ public class ShortcutHelperTest extends UiServiceTestCase { callback.onShortcutsChanged(PKG, shortcutInfos, mock(UserHandle.class)); verify(mShortcutListener).onShortcutRemoved(mNr.getKey()); } + + @Test + public void testGetValidShortcutInfo_noMatchingShortcut() { + when(mLauncherApps.getShortcuts(any(), any())).thenReturn(null); + when(mShortcutServiceInternal.isSharingShortcut(anyInt(), anyString(), anyString(), + anyString(), anyInt(), any())).thenReturn(true); + + assertThat(mShortcutHelper.getValidShortcutInfo("a", "p", UserHandle.SYSTEM)).isNull(); + } + + @Test + public void testGetValidShortcutInfo_nullShortcut() { + ArrayList<ShortcutInfo> shortcuts = new ArrayList<>(); + shortcuts.add(null); + when(mLauncherApps.getShortcuts(any(), any())).thenReturn(shortcuts); + when(mShortcutServiceInternal.isSharingShortcut(anyInt(), anyString(), anyString(), + anyString(), anyInt(), any())).thenReturn(true); + + assertThat(mShortcutHelper.getValidShortcutInfo("a", "p", UserHandle.SYSTEM)).isNull(); + } + + @Test + public void testGetValidShortcutInfo_notLongLived() { + ShortcutInfo si = mock(ShortcutInfo.class); + when(si.isLongLived()).thenReturn(false); + when(si.isEnabled()).thenReturn(true); + ArrayList<ShortcutInfo> shortcuts = new ArrayList<>(); + shortcuts.add(si); + when(mLauncherApps.getShortcuts(any(), any())).thenReturn(shortcuts); + when(mShortcutServiceInternal.isSharingShortcut(anyInt(), anyString(), anyString(), + anyString(), anyInt(), any())).thenReturn(true); + + assertThat(mShortcutHelper.getValidShortcutInfo("a", "p", UserHandle.SYSTEM)).isNull(); + } + + @Test + public void testGetValidShortcutInfo_notSharingShortcut() { + ShortcutInfo si = mock(ShortcutInfo.class); + when(si.isLongLived()).thenReturn(true); + when(si.isEnabled()).thenReturn(true); + ArrayList<ShortcutInfo> shortcuts = new ArrayList<>(); + shortcuts.add(si); + when(mLauncherApps.getShortcuts(any(), any())).thenReturn(shortcuts); + when(mShortcutServiceInternal.isSharingShortcut(anyInt(), anyString(), anyString(), + anyString(), anyInt(), any())).thenReturn(false); + + assertThat(mShortcutHelper.getValidShortcutInfo("a", "p", UserHandle.SYSTEM)).isNull(); + } + + @Test + public void testGetValidShortcutInfo_notEnabled() { + ShortcutInfo si = mock(ShortcutInfo.class); + when(si.isLongLived()).thenReturn(true); + when(si.isEnabled()).thenReturn(false); + ArrayList<ShortcutInfo> shortcuts = new ArrayList<>(); + shortcuts.add(si); + when(mLauncherApps.getShortcuts(any(), any())).thenReturn(shortcuts); + when(mShortcutServiceInternal.isSharingShortcut(anyInt(), anyString(), anyString(), + anyString(), anyInt(), any())).thenReturn(true); + + assertThat(mShortcutHelper.getValidShortcutInfo("a", "p", UserHandle.SYSTEM)).isNull(); + } + + @Test + public void testGetValidShortcutInfo_isValid() { + ShortcutInfo si = mock(ShortcutInfo.class); + when(si.isLongLived()).thenReturn(true); + when(si.isEnabled()).thenReturn(true); + ArrayList<ShortcutInfo> shortcuts = new ArrayList<>(); + shortcuts.add(si); + when(mLauncherApps.getShortcuts(any(), any())).thenReturn(shortcuts); + when(mShortcutServiceInternal.isSharingShortcut(anyInt(), anyString(), anyString(), + anyString(), anyInt(), any())).thenReturn(true); + + assertThat(mShortcutHelper.getValidShortcutInfo("a", "p", UserHandle.SYSTEM)).isSameAs(si); + } } 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 08f6409cb902..5bbb4d9e712c 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java @@ -32,6 +32,7 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.any; import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyBoolean; import static com.android.dx.mockito.inline.extended.ExtendedMockito.atLeast; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.doCallRealMethod; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.eq; import static com.android.dx.mockito.inline.extended.ExtendedMockito.reset; @@ -63,6 +64,7 @@ import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.never; @@ -1024,6 +1026,38 @@ public class ActivityRecordTests extends ActivityTestsBase { } /** + * Verify that complete finish request for a show-when-locked activity must ensure the + * keyguard occluded state being updated. + */ + @Test + public void testCompleteFinishing_showWhenLocked() { + // Make keyguard locked and set the top activity show-when-locked. + KeyguardController keyguardController = mActivity.mStackSupervisor.getKeyguardController(); + doReturn(true).when(keyguardController).isKeyguardLocked(); + final ActivityRecord topActivity = new ActivityBuilder(mService).setTask(mTask).build(); + topActivity.mVisibleRequested = true; + topActivity.nowVisible = true; + topActivity.setState(RESUMED, "true"); + doCallRealMethod().when(mRootWindowContainer).ensureActivitiesVisible( + any() /* starting */, anyInt() /* configChanges */, + anyBoolean() /* preserveWindows */, anyBoolean() /* notifyClients */); + topActivity.setShowWhenLocked(true); + + // Verify the stack-top activity is occluded keyguard. + assertEquals(topActivity, mStack.topRunningActivity()); + assertTrue(mStack.topActivityOccludesKeyguard()); + + // Finish the top activity + topActivity.setState(PAUSED, "true"); + topActivity.finishing = true; + topActivity.completeFinishing("test"); + + // Verify new top activity does not occlude keyguard. + assertEquals(mActivity, mStack.topRunningActivity()); + assertFalse(mStack.topActivityOccludesKeyguard()); + } + + /** * Verify destroy activity request completes successfully. */ @Test @@ -1273,6 +1307,48 @@ public class ActivityRecordTests extends ActivityTestsBase { } @Test + public void testActivityOnCancelFixedRotationTransform() { + mService.mWindowManager.mIsFixedRotationTransformEnabled = true; + final DisplayRotation displayRotation = mActivity.mDisplayContent.getDisplayRotation(); + spyOn(displayRotation); + + final DisplayContent display = mActivity.mDisplayContent; + final int originalRotation = display.getRotation(); + + // Make {@link DisplayContent#sendNewConfiguration} not apply rotation immediately. + doReturn(true).when(displayRotation).isWaitingForRemoteRotation(); + doReturn((originalRotation + 1) % 4).when(displayRotation).rotationForOrientation( + anyInt() /* orientation */, anyInt() /* lastRotation */); + // Set to visible so the activity can freeze the screen. + mActivity.setVisibility(true); + + display.rotateInDifferentOrientationIfNeeded(mActivity); + display.mFixedRotationLaunchingApp = mActivity; + displayRotation.updateRotationUnchecked(true /* forceUpdate */); + + assertTrue(displayRotation.isRotatingSeamlessly()); + + // Simulate the rotation has been updated to previous one, e.g. sensor updates before the + // remote rotation is completed. + doReturn(originalRotation).when(displayRotation).rotationForOrientation( + anyInt() /* orientation */, anyInt() /* lastRotation */); + display.updateOrientation(); + + final DisplayInfo rotatedInfo = mActivity.getFixedRotationTransformDisplayInfo(); + mActivity.finishFixedRotationTransform(); + final ScreenRotationAnimation rotationAnim = display.getRotationAnimation(); + rotationAnim.setRotation(display.getPendingTransaction(), originalRotation); + + // Because the display doesn't rotate, the rotated activity needs to cancel the fixed + // rotation. There should be a rotation animation to cover the change of activity. + verify(mActivity).onCancelFixedRotationTransform(rotatedInfo.rotation); + assertTrue(mActivity.isFreezingScreen()); + assertFalse(displayRotation.isRotatingSeamlessly()); + assertNotNull(rotationAnim); + assertTrue(rotationAnim.isRotating()); + } + + @Test public void testActivityOnDifferentDisplayUpdatesProcessOverride() { final ActivityRecord secondaryDisplayActivity = createActivityOnDisplay(false /* defaultDisplay */, null /* process */); diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java index 3d15401cdfb9..3bed05f383a8 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java @@ -46,6 +46,7 @@ import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_F import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_WINDOWING_MODE_RESIZE; import static com.android.server.wm.Task.REPARENT_MOVE_STACK_TO_FRONT; import static com.android.server.wm.TaskDisplayArea.getStackAbove; +import static com.android.server.wm.WindowContainer.POSITION_TOP; import static com.google.common.truth.Truth.assertThat; @@ -140,9 +141,12 @@ public class ActivityStackTests extends ActivityTestsBase { } @Test - public void testPrimarySplitScreenRestoresWhenMovedToBack() { - // Create primary splitscreen stack. This will create secondary stacks and places the - // existing fullscreen stack on the bottom. + public void testPrimarySplitScreenMoveToBack() { + TestSplitOrganizer organizer = new TestSplitOrganizer(mService); + // We're testing an edge case here where we have primary + fullscreen rather than secondary. + organizer.setMoveToSecondaryOnEnter(false); + + // Create primary splitscreen stack. final ActivityStack primarySplitScreen = mDefaultTaskDisplayArea.createStack( WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD, true /* onTop */); @@ -165,12 +169,14 @@ public class ActivityStackTests extends ActivityTestsBase { } @Test - public void testPrimarySplitScreenRestoresPreviousWhenMovedToBack() { + public void testMoveToPrimarySplitScreenThenMoveToBack() { + TestSplitOrganizer organizer = new TestSplitOrganizer(mService); // This time, start with a fullscreen activitystack final ActivityStack primarySplitScreen = mDefaultTaskDisplayArea.createStack( - WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); + WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD, true /* onTop */); - primarySplitScreen.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY); + primarySplitScreen.reparent((ActivityStack) organizer.mPrimary, POSITION_TOP, + false /*moveParents*/, "test"); // Assert windowing mode. assertEquals(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, primarySplitScreen.getWindowingMode()); @@ -180,14 +186,52 @@ public class ActivityStackTests extends ActivityTestsBase { null /* task */); // Assert that stack is at the bottom. - assertEquals(0, mDefaultTaskDisplayArea.getIndexOf(primarySplitScreen)); + assertEquals(primarySplitScreen, organizer.mSecondary.getChildAt(0)); // Ensure that the override mode is restored to what it was (fullscreen) - assertEquals(WINDOWING_MODE_FULLSCREEN, + assertEquals(WINDOWING_MODE_UNDEFINED, primarySplitScreen.getRequestedOverrideWindowingMode()); } @Test + public void testSplitScreenMoveToBack() { + TestSplitOrganizer organizer = new TestSplitOrganizer(mService); + // Set up split-screen with primary on top and secondary containing the home task below + // another stack. + final ActivityStack primaryTask = mDefaultTaskDisplayArea.createStack( + WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD, true /* onTop */); + final ActivityStack homeRoot = mDefaultTaskDisplayArea.getStack( + WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME); + final ActivityStack secondaryTask = mDefaultTaskDisplayArea.createStack( + WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD, true /* onTop */); + mDefaultTaskDisplayArea.positionStackAtTop((ActivityStack) organizer.mPrimary, + false /* includingParents */); + + // Move primary to back. + primaryTask.moveToBack("test", null /* task */); + + // Assert that the primaryTask is now below home in its parent but primary is left alone. + assertEquals(0, organizer.mPrimary.getChildCount()); + assertEquals(primaryTask, organizer.mSecondary.getChildAt(0)); + assertEquals(1, organizer.mPrimary.compareTo(organizer.mSecondary)); + assertEquals(1, homeRoot.compareTo(primaryTask)); + assertEquals(homeRoot.getParent(), primaryTask.getParent()); + + // Make sure windowing modes are correct + assertEquals(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, organizer.mPrimary.getWindowingMode()); + assertEquals(WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, primaryTask.getWindowingMode()); + + // Move secondary to back via parent (should be equivalent) + ((ActivityStack) organizer.mSecondary).moveToBack("test", secondaryTask); + + // Assert that it is now in back but still in secondary split + assertEquals(1, homeRoot.compareTo(primaryTask)); + assertEquals(secondaryTask, organizer.mSecondary.getChildAt(0)); + assertEquals(1, primaryTask.compareTo(secondaryTask)); + assertEquals(homeRoot.getParent(), secondaryTask.getParent()); + } + + @Test public void testStackInheritsDisplayWindowingMode() { final ActivityStack primarySplitScreen = mDefaultTaskDisplayArea.createStack( WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD, true /* onTop */); diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java index bdba4b6c8ac8..97734ff32de2 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java @@ -30,7 +30,6 @@ import static android.app.ActivityManager.START_SUCCESS; import static android.app.ActivityManager.START_SWITCHES_CANCELED; import static android.app.ActivityManager.START_TASK_TO_FRONT; import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; -import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY; import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY; @@ -64,10 +63,8 @@ import static org.mockito.ArgumentMatchers.anyObject; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; -import android.app.ActivityManager; import android.app.ActivityOptions; import android.app.IApplicationThread; -import android.app.WindowConfiguration; import android.content.ComponentName; import android.content.Intent; import android.content.pm.ActivityInfo; @@ -82,8 +79,6 @@ import android.os.RemoteException; import android.platform.test.annotations.Presubmit; import android.service.voice.IVoiceInteractionSession; import android.view.Gravity; -import android.window.ITaskOrganizer; -import android.window.WindowContainerToken; import androidx.test.filters.SmallTest; @@ -1004,62 +999,4 @@ public class ActivityStarterTests extends ActivityTestsBase { verify(recentTasks, times(1)).add(any()); } - - static class TestSplitOrganizer extends ITaskOrganizer.Stub { - final ActivityTaskManagerService mService; - Task mPrimary; - Task mSecondary; - boolean mInSplit = false; - int mDisplayId; - TestSplitOrganizer(ActivityTaskManagerService service, int displayId) { - mService = service; - mDisplayId = displayId; - mService.mTaskOrganizerController.registerTaskOrganizer(this, - WINDOWING_MODE_SPLIT_SCREEN_PRIMARY); - mService.mTaskOrganizerController.registerTaskOrganizer(this, - WINDOWING_MODE_SPLIT_SCREEN_SECONDARY); - WindowContainerToken primary = mService.mTaskOrganizerController.createRootTask( - displayId, WINDOWING_MODE_SPLIT_SCREEN_PRIMARY).token; - mPrimary = WindowContainer.fromBinder(primary.asBinder()).asTask(); - WindowContainerToken secondary = mService.mTaskOrganizerController.createRootTask( - displayId, WINDOWING_MODE_SPLIT_SCREEN_SECONDARY).token; - mSecondary = WindowContainer.fromBinder(secondary.asBinder()).asTask(); - } - @Override - public void onTaskAppeared(ActivityManager.RunningTaskInfo info) { - } - @Override - public void onTaskVanished(ActivityManager.RunningTaskInfo info) { - } - @Override - public void onTaskInfoChanged(ActivityManager.RunningTaskInfo info) { - if (mInSplit) { - return; - } - if (info.topActivityType != ACTIVITY_TYPE_UNDEFINED) { - if (info.configuration.windowConfiguration.getWindowingMode() - == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) { - mInSplit = true; - mService.mTaskOrganizerController.setLaunchRoot(mDisplayId, - mSecondary.mRemoteToken.toWindowContainerToken()); - // move everything to secondary because test expects this but usually sysui - // does it. - DisplayContent dc = mService.mRootWindowContainer.getDisplayContent(mDisplayId); - for (int tdaNdx = dc.getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) { - final TaskDisplayArea taskDisplayArea = dc.getTaskDisplayAreaAt(tdaNdx); - for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) { - final ActivityStack stack = taskDisplayArea.getStackAt(sNdx); - if (!WindowConfiguration.isSplitScreenWindowingMode( - stack.getWindowingMode())) { - stack.reparent(mSecondary, POSITION_BOTTOM); - } - } - } - } - } - } - @Override - public void onBackPressedOnTaskRoot(ActivityManager.RunningTaskInfo taskInfo) { - } - }; } diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java index 67d4769522b0..6ae8313e39dd 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java @@ -17,7 +17,10 @@ package com.android.server.wm; import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; +import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; +import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY; +import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; @@ -30,9 +33,12 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; +import static com.android.server.wm.WindowContainer.POSITION_BOTTOM; +import android.app.ActivityManager; import android.app.ActivityOptions; import android.app.IApplicationThread; +import android.app.WindowConfiguration; import android.content.ComponentName; import android.content.Context; import android.content.Intent; @@ -43,6 +49,8 @@ import android.os.Build; import android.os.Bundle; import android.os.UserHandle; import android.service.voice.IVoiceInteractionSession; +import android.window.ITaskOrganizer; +import android.window.WindowContainerToken; import com.android.server.AttributeCache; @@ -505,4 +513,74 @@ class ActivityTestsBase extends SystemServiceTestsBase { } } + + static class TestSplitOrganizer extends ITaskOrganizer.Stub { + final ActivityTaskManagerService mService; + Task mPrimary; + Task mSecondary; + boolean mInSplit = false; + // moves everything to secondary. Most tests expect this since sysui usually does it. + boolean mMoveToSecondaryOnEnter = true; + int mDisplayId; + TestSplitOrganizer(ActivityTaskManagerService service, int displayId) { + mService = service; + mDisplayId = displayId; + mService.mTaskOrganizerController.registerTaskOrganizer(this, + WINDOWING_MODE_SPLIT_SCREEN_PRIMARY); + mService.mTaskOrganizerController.registerTaskOrganizer(this, + WINDOWING_MODE_SPLIT_SCREEN_SECONDARY); + WindowContainerToken primary = mService.mTaskOrganizerController.createRootTask( + displayId, WINDOWING_MODE_SPLIT_SCREEN_PRIMARY).token; + mPrimary = WindowContainer.fromBinder(primary.asBinder()).asTask(); + WindowContainerToken secondary = mService.mTaskOrganizerController.createRootTask( + displayId, WINDOWING_MODE_SPLIT_SCREEN_SECONDARY).token; + mSecondary = WindowContainer.fromBinder(secondary.asBinder()).asTask(); + } + TestSplitOrganizer(ActivityTaskManagerService service) { + this(service, + service.mStackSupervisor.mRootWindowContainer.getDefaultDisplay().mDisplayId); + } + public void setMoveToSecondaryOnEnter(boolean move) { + mMoveToSecondaryOnEnter = move; + } + @Override + public void onTaskAppeared(ActivityManager.RunningTaskInfo info) { + } + @Override + public void onTaskVanished(ActivityManager.RunningTaskInfo info) { + } + @Override + public void onTaskInfoChanged(ActivityManager.RunningTaskInfo info) { + if (mInSplit) { + return; + } + if (info.topActivityType == ACTIVITY_TYPE_UNDEFINED) { + // Not populated + return; + } + if (info.configuration.windowConfiguration.getWindowingMode() + != WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) { + return; + } + mInSplit = true; + if (!mMoveToSecondaryOnEnter) { + return; + } + mService.mTaskOrganizerController.setLaunchRoot(mDisplayId, + mSecondary.mRemoteToken.toWindowContainerToken()); + DisplayContent dc = mService.mRootWindowContainer.getDisplayContent(mDisplayId); + for (int tdaNdx = dc.getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) { + final TaskDisplayArea taskDisplayArea = dc.getTaskDisplayAreaAt(tdaNdx); + for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) { + final ActivityStack stack = taskDisplayArea.getStackAt(sNdx); + if (!WindowConfiguration.isSplitScreenWindowingMode(stack.getWindowingMode())) { + stack.reparent(mSecondary, POSITION_BOTTOM); + } + } + } + } + @Override + public void onBackPressedOnTaskRoot(ActivityManager.RunningTaskInfo taskInfo) { + } + }; } diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java index a901d1ebd890..3fd81b47c546 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java @@ -90,6 +90,7 @@ import android.view.ISystemGestureExclusionListener; import android.view.IWindowManager; import android.view.MotionEvent; import android.view.Surface; +import android.view.SurfaceControl.Transaction; import android.view.ViewRootImpl; import android.view.WindowManager; import android.view.test.InsetsModeSession; @@ -826,7 +827,7 @@ public class DisplayContentTests extends WindowTestsBase { dc.mInputMethodTarget = createWindow(null, TYPE_STATUS_BAR, "app"); dc.mInputMethodTarget.setWindowingMode( WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY); - assertEquals(dc.getWindowingLayer(), dc.computeImeParent()); + assertEquals(dc.getImeContainer().getParentSurfaceControl(), dc.computeImeParent()); } } @@ -836,7 +837,8 @@ public class DisplayContentTests extends WindowTestsBase { doReturn(false).when(mAppWindow.mActivityRecord).matchParentBounds(); mDisplayContent.mInputMethodTarget = mAppWindow; // The surface parent of IME should be the display instead of app window. - assertEquals(mDisplayContent.getWindowingLayer(), mDisplayContent.computeImeParent()); + assertEquals(mDisplayContent.getImeContainer().getParentSurfaceControl(), + mDisplayContent.computeImeParent()); } @Test @@ -845,7 +847,7 @@ public class DisplayContentTests extends WindowTestsBase { new InsetsModeSession(ViewRootImpl.NEW_INSETS_MODE_IME)) { final DisplayContent dc = createNewDisplay(); dc.mInputMethodTarget = createWindow(null, TYPE_STATUS_BAR, "statusBar"); - assertEquals(dc.getWindowingLayer(), dc.computeImeParent()); + assertEquals(dc.getImeContainer().getParentSurfaceControl(), dc.computeImeParent()); } } @@ -1039,6 +1041,12 @@ public class DisplayContentTests extends WindowTestsBase { assertEquals(config90.orientation, app.getConfiguration().orientation); assertEquals(config90.windowConfiguration.getBounds(), app.getBounds()); + // Make wallaper laid out with the fixed rotation transform. + final WindowToken wallpaperToken = mWallpaperWindow.mToken; + wallpaperToken.linkFixedRotationTransform(app); + mWallpaperWindow.mLayoutNeeded = true; + performLayout(mDisplayContent); + // Force the negative offset to verify it can be updated. mWallpaperWindow.mWinAnimator.mXOffset = mWallpaperWindow.mWinAnimator.mYOffset = -1; assertTrue(mDisplayContent.mWallpaperController.updateWallpaperOffset(mWallpaperWindow, @@ -1046,6 +1054,13 @@ public class DisplayContentTests extends WindowTestsBase { assertThat(mWallpaperWindow.mWinAnimator.mXOffset).isGreaterThan(-1); assertThat(mWallpaperWindow.mWinAnimator.mYOffset).isGreaterThan(-1); + // The wallpaper need to animate with transformed position, so its surface position should + // not be reset. + final Transaction t = wallpaperToken.getPendingTransaction(); + spyOn(t); + mWallpaperWindow.mToken.onAnimationLeashCreated(t, null /* leash */); + verify(t, never()).setPosition(any(), eq(0), eq(0)); + mDisplayContent.mAppTransition.notifyAppTransitionFinishedLocked(app.token); // The animation in old rotation should be cancelled. diff --git a/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java index 7613655e9f35..3c9051547eed 100644 --- a/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java @@ -58,7 +58,6 @@ import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; import android.content.pm.ResolveInfo; import android.content.res.Resources; -import android.graphics.Rect; import android.platform.test.annotations.Presubmit; import android.util.Pair; @@ -126,9 +125,7 @@ public class RootActivityContainerTests extends ActivityTestsBase { ensureStackPlacement(mFullscreenStack, firstActivity, secondActivity); // Move first activity to pinned stack. - final Rect sourceBounds = new Rect(); - mRootWindowContainer.moveActivityToPinnedStack(firstActivity, sourceBounds, - 0f /*aspectRatio*/, "initialMove"); + mRootWindowContainer.moveActivityToPinnedStack(firstActivity, "initialMove"); final TaskDisplayArea taskDisplayArea = mFullscreenStack.getDisplayArea(); ActivityStack pinnedStack = taskDisplayArea.getRootPinnedTask(); @@ -137,8 +134,7 @@ public class RootActivityContainerTests extends ActivityTestsBase { ensureStackPlacement(mFullscreenStack, secondActivity); // Move second activity to pinned stack. - mRootWindowContainer.moveActivityToPinnedStack(secondActivity, sourceBounds, - 0f /*aspectRatio*/, "secondMove"); + mRootWindowContainer.moveActivityToPinnedStack(secondActivity, "secondMove"); // Need to get stacks again as a new instance might have been created. pinnedStack = taskDisplayArea.getRootPinnedTask(); diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java index a7085334bece..52a51875427f 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java @@ -172,7 +172,7 @@ public class TaskDisplayAreaTests extends WindowTestsBase { assertGetOrCreateStack(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, type, candidateTask, false /* reuseCandidate */); assertGetOrCreateStack(WINDOWING_MODE_PINNED, type, candidateTask, - false /* reuseCandidate */); + true /* reuseCandidate */); final int windowingMode = WINDOWING_MODE_FULLSCREEN; assertGetOrCreateStack(windowingMode, ACTIVITY_TYPE_HOME, candidateTask, diff --git a/startop/iorap/functional_tests/Android.bp b/startop/iorap/functional_tests/Android.bp index ad85f1430bdf..8a5bd34af653 100644 --- a/startop/iorap/functional_tests/Android.bp +++ b/startop/iorap/functional_tests/Android.bp @@ -15,7 +15,7 @@ android_test { name: "iorap-functional-tests", srcs: ["src/**/*.java"], - data: ["test_data/*"], + data: [":iorap-functional-test-apps"], static_libs: [ // Non-test dependencies // library under test diff --git a/startop/iorap/functional_tests/test_data/iorap_test_app_v1.apk b/startop/iorap/functional_tests/test_data/iorap_test_app_v1.apk deleted file mode 120000 index 1c1a437f6a55..000000000000 --- a/startop/iorap/functional_tests/test_data/iorap_test_app_v1.apk +++ /dev/null @@ -1 +0,0 @@ -../../../../../../packages/modules/ArtPrebuilt/iorap/test/iorap_test_app_v1.apk
\ No newline at end of file diff --git a/startop/iorap/functional_tests/test_data/iorap_test_app_v2.apk b/startop/iorap/functional_tests/test_data/iorap_test_app_v2.apk deleted file mode 120000 index 7cd41c48ba3a..000000000000 --- a/startop/iorap/functional_tests/test_data/iorap_test_app_v2.apk +++ /dev/null @@ -1 +0,0 @@ -../../../../../../packages/modules/ArtPrebuilt/iorap/test/iorap_test_app_v2.apk
\ No newline at end of file diff --git a/startop/iorap/functional_tests/test_data/iorap_test_app_v3.apk b/startop/iorap/functional_tests/test_data/iorap_test_app_v3.apk deleted file mode 120000 index 7f4e996e57d0..000000000000 --- a/startop/iorap/functional_tests/test_data/iorap_test_app_v3.apk +++ /dev/null @@ -1 +0,0 @@ -../../../../../../packages/modules/ArtPrebuilt/iorap/test/iorap_test_app_v3.apk
\ No newline at end of file diff --git a/startop/iorap/src/com/google/android/startop/iorap/DexOptEvent.java b/startop/iorap/src/com/google/android/startop/iorap/DexOptEvent.java new file mode 100644 index 000000000000..72c5eaa84c96 --- /dev/null +++ b/startop/iorap/src/com/google/android/startop/iorap/DexOptEvent.java @@ -0,0 +1,114 @@ +/* + * 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.google.android.startop.iorap; + +import android.annotation.NonNull; +import android.os.Parcelable; +import android.os.Parcel; + +import android.annotation.IntDef; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.util.Objects; + +/** + * Notifications for iorapd specifying when a package is updated by dexopt service.<br /><br /> + * + * @hide + */ +public class DexOptEvent implements Parcelable { + public static final int TYPE_PACKAGE_UPDATE = 0; + private static final int TYPE_MAX = 0; + + /** @hide */ + @IntDef(flag = true, prefix = { "TYPE_" }, value = { + TYPE_PACKAGE_UPDATE, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface Type {} + + @Type public final int type; + public final String packageName; + + @NonNull + public static DexOptEvent createPackageUpdate(String packageName) { + return new DexOptEvent(TYPE_PACKAGE_UPDATE, packageName); + } + + private DexOptEvent(@Type int type, String packageName) { + this.type = type; + this.packageName = packageName; + + checkConstructorArguments(); + } + + private void checkConstructorArguments() { + CheckHelpers.checkTypeInRange(type, TYPE_MAX); + Objects.requireNonNull(packageName, "packageName"); + } + + @Override + public String toString() { + return String.format("{DexOptEvent: packageName: %s}", packageName); + } + + @Override + public boolean equals(Object other) { + if (this == other) { + return true; + } else if (other instanceof DexOptEvent) { + return equals((DexOptEvent) other); + } + return false; + } + + private boolean equals(DexOptEvent other) { + return packageName.equals(other.packageName); + } + + //<editor-fold desc="Binder boilerplate"> + @Override + public void writeToParcel(Parcel out, int flags) { + out.writeInt(type); + out.writeString(packageName); + } + + private DexOptEvent(Parcel in) { + this.type = in.readInt(); + this.packageName = in.readString(); + + checkConstructorArguments(); + } + + @Override + public int describeContents() { + return 0; + } + + public static final Parcelable.Creator<DexOptEvent> CREATOR + = new Parcelable.Creator<DexOptEvent>() { + public DexOptEvent createFromParcel(Parcel in) { + return new DexOptEvent(in); + } + + public DexOptEvent[] newArray(int size) { + return new DexOptEvent[size]; + } + }; + //</editor-fold> +} diff --git a/startop/iorap/src/com/google/android/startop/iorap/IorapForwardingService.java b/startop/iorap/src/com/google/android/startop/iorap/IorapForwardingService.java index 0c25cfb968fd..8f1d0addbcd8 100644 --- a/startop/iorap/src/com/google/android/startop/iorap/IorapForwardingService.java +++ b/startop/iorap/src/com/google/android/startop/iorap/IorapForwardingService.java @@ -324,6 +324,11 @@ public class IorapForwardingService extends SystemService { String[] updated = updatedPackages.toArray(new String[0]); for (String packageName : updated) { Log.d(TAG, "onPackagesUpdated: " + packageName); + invokeRemote(mIorapRemote, + (IIorap remote) -> + remote.onDexOptEvent(RequestId.nextValueForSequence(), + DexOptEvent.createPackageUpdate(packageName)) + ); } } } diff --git a/telecomm/java/android/telecom/Conference.java b/telecomm/java/android/telecom/Conference.java index 4e14fd3d59a1..d9605522b3b0 100644 --- a/telecomm/java/android/telecom/Conference.java +++ b/telecomm/java/android/telecom/Conference.java @@ -106,6 +106,7 @@ public abstract class Conference extends Conferenceable { private int mCallerDisplayNamePresentation; private int mCallDirection; private boolean mRingbackRequested = false; + private boolean mIsMultiparty = true; private final Connection.Listener mConnectionDeathListener = new Connection.Listener() { @Override @@ -998,8 +999,8 @@ public abstract class Conference extends Conferenceable { public void onExtrasChanged(Bundle extras) {} /** - * Set whether Telecom should treat this {@link Conference} as a conference call or if it - * should treat it as a single-party call. + * Set whether Telecom should treat this {@link Conference} as a multiparty conference call or + * if it should treat it as a single-party call. * This method is used as part of a workaround regarding IMS conference calls and user * expectation. In IMS, once a conference is formed, the UE is connected to an IMS conference * server. If all participants of the conference drop out of the conference except for one, the @@ -1020,6 +1021,7 @@ public abstract class Conference extends Conferenceable { @TestApi @RequiresPermission(MODIFY_PHONE_STATE) public void setConferenceState(boolean isConference) { + mIsMultiparty = isConference; for (Listener l : mListeners) { l.onConferenceStateChanged(this, isConference); } @@ -1043,6 +1045,20 @@ public abstract class Conference extends Conferenceable { } } + /** + * Determines if the {@link Conference} is considered "multiparty" or not. By default all + * conferences are considered multiparty. A multiparty conference is one where there are + * multiple conference participants (other than the host) in the conference. + * This is tied to {@link #setConferenceState(boolean)}, which is used for some use cases to + * have a conference appear as if it is a standalone call, in which case the conference will + * no longer be multiparty. + * @return {@code true} if conference is treated as a conference (i.e. it is multiparty), + * {@code false} if it should emulate a standalone call (i.e. not multiparty). + * @hide + */ + public boolean isMultiparty() { + return mIsMultiparty; + } /** * Sets the address of this {@link Conference}. Used when {@link #setConferenceState(boolean)} diff --git a/telecomm/java/android/telecom/ConnectionService.java b/telecomm/java/android/telecom/ConnectionService.java index 73296986d82e..1b60e4820ad0 100755 --- a/telecomm/java/android/telecom/ConnectionService.java +++ b/telecomm/java/android/telecom/ConnectionService.java @@ -2505,6 +2505,11 @@ public abstract class ConnectionService extends Service { mAdapter.addConferenceCall(id, parcelableConference); mAdapter.setVideoProvider(id, conference.getVideoProvider()); mAdapter.setVideoState(id, conference.getVideoState()); + // In some instances a conference can start its life as a standalone call with just a + // single participant; ensure we signal to Telecom in this case. + if (!conference.isMultiparty()) { + mAdapter.setConferenceState(id, conference.isMultiparty()); + } // Go through any child calls and set the parent. for (Connection connection : conference.getConnections()) { diff --git a/telecomm/java/android/telecom/GatewayInfo.java b/telecomm/java/android/telecom/GatewayInfo.java index 0faa4fd2027a..31c24d54918a 100644 --- a/telecomm/java/android/telecom/GatewayInfo.java +++ b/telecomm/java/android/telecom/GatewayInfo.java @@ -111,7 +111,7 @@ public class GatewayInfo implements Parcelable { @Override public void writeToParcel(Parcel destination, int flags) { destination.writeString(mGatewayProviderPackageName); - mGatewayAddress.writeToParcel(destination, 0); - mOriginalAddress.writeToParcel(destination, 0); + Uri.writeToParcel(destination, mGatewayAddress); + Uri.writeToParcel(destination, mOriginalAddress); } } diff --git a/telecomm/java/android/telecom/ParcelableCall.java b/telecomm/java/android/telecom/ParcelableCall.java index 415a817b58d5..182dc8bb8325 100644 --- a/telecomm/java/android/telecom/ParcelableCall.java +++ b/telecomm/java/android/telecom/ParcelableCall.java @@ -629,7 +629,7 @@ public final class ParcelableCall implements Parcelable { int capabilities = source.readInt(); int properties = source.readInt(); long connectTimeMillis = source.readLong(); - Uri handle = source.readParcelable(classLoader); + Uri handle = Uri.CREATOR.createFromParcel(source); int handlePresentation = source.readInt(); String callerDisplayName = source.readString(); int callerDisplayNamePresentation = source.readInt(); @@ -711,7 +711,7 @@ public final class ParcelableCall implements Parcelable { destination.writeInt(mCapabilities); destination.writeInt(mProperties); destination.writeLong(mConnectTimeMillis); - destination.writeParcelable(mHandle, 0); + Uri.writeToParcel(destination, mHandle); destination.writeInt(mHandlePresentation); destination.writeString(mCallerDisplayName); destination.writeInt(mCallerDisplayNamePresentation); diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java index 7f6e123ce69e..d2de19aaf89a 100755 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -505,6 +505,15 @@ public class CarrierConfigManager { public static final String KEY_CARRIER_VT_AVAILABLE_BOOL = "carrier_vt_available_bool"; /** + * Flag specifying whether to show an alert dialog for 5G disable when the user disables VoLTE. + * By default this value is {@code false}. + * + * @hide + */ + public static final String KEY_VOLTE_5G_LIMITED_ALERT_DIALOG_BOOL = + "volte_5g_limited_alert_dialog_bool"; + + /** * Flag specifying whether the carrier wants to notify the user when a VT call has been handed * over from WIFI to LTE. * <p> @@ -2529,6 +2538,16 @@ public class CarrierConfigManager { "parameters_use_for_5g_nr_signal_bar_int"; /** + * There are two signal strengths, NR and LTE signal strength, during NR (non-standalone). + * Boolean indicating whether to use LTE signal strength as primary during NR (non-standalone). + * By default this value is true. + * + * @hide + */ + public static final String KEY_SIGNAL_STRENGTH_NR_NSA_USE_LTE_AS_PRIMARY_BOOL = + "signal_strength_nr_nsa_use_lte_as_primary_bool"; + + /** * String array of default bandwidth values per network type. * The entries should be of form "network_name:downstream,upstream", with values in Kbps. * @hide @@ -3074,6 +3093,16 @@ public class CarrierConfigManager { public static final String KEY_UNMETERED_NR_NSA_SUB6_BOOL = "unmetered_nr_nsa_sub6_bool"; /** + * Whether NR (non-standalone) should be unmetered when the device is roaming. + * If false, then the values for {@link #KEY_UNMETERED_NR_NSA_BOOL}, + * {@link #KEY_UNMETERED_NR_NSA_MMWAVE_BOOL}, {@link #KEY_UNMETERED_NR_NSA_SUB6_BOOL}, + * and unmetered {@link SubscriptionPlan} will be ignored. + * @hide + */ + public static final String KEY_UNMETERED_NR_NSA_WHEN_ROAMING_BOOL = + "unmetered_nr_nsa_when_roaming_bool"; + + /** * Whether NR (standalone) should be unmetered for all frequencies. * If either {@link #KEY_UNMETERED_NR_SA_MMWAVE_BOOL} or * {@link #KEY_UNMETERED_NR_SA_SUB6_BOOL} are true, then this value will be ignored. @@ -3693,6 +3722,7 @@ public class CarrierConfigManager { sDefaults.putBoolean(KEY_CARRIER_SETTINGS_ENABLE_BOOL, false); sDefaults.putBoolean(KEY_CARRIER_VOLTE_AVAILABLE_BOOL, false); sDefaults.putBoolean(KEY_CARRIER_VT_AVAILABLE_BOOL, false); + sDefaults.putBoolean(KEY_VOLTE_5G_LIMITED_ALERT_DIALOG_BOOL, false); sDefaults.putBoolean(KEY_NOTIFY_HANDOVER_VIDEO_FROM_WIFI_TO_LTE_BOOL, false); sDefaults.putBoolean(KEY_ALLOW_MERGING_RTT_CALLS_BOOL, false); sDefaults.putBoolean(KEY_NOTIFY_HANDOVER_VIDEO_FROM_LTE_TO_WIFI_BOOL, false); @@ -4095,6 +4125,7 @@ public class CarrierConfigManager { }); sDefaults.putInt(KEY_PARAMETERS_USE_FOR_5G_NR_SIGNAL_BAR_INT, CellSignalStrengthNr.USE_SSRSRP); + sDefaults.putBoolean(KEY_SIGNAL_STRENGTH_NR_NSA_USE_LTE_AS_PRIMARY_BOOL, true); sDefaults.putStringArray(KEY_BANDWIDTH_STRING_ARRAY, new String[]{ "GPRS:24,24", "EDGE:70,18", "UMTS:115,115", "CDMA-IS95A:14,14", "CDMA-IS95B:14,14", "1xRTT:30,30", "EvDo-rev.0:750,48", "EvDo-rev.A:950,550", "HSDPA:4300,620", @@ -4123,6 +4154,7 @@ public class CarrierConfigManager { sDefaults.putBoolean(KEY_UNMETERED_NR_NSA_BOOL, false); sDefaults.putBoolean(KEY_UNMETERED_NR_NSA_MMWAVE_BOOL, false); sDefaults.putBoolean(KEY_UNMETERED_NR_NSA_SUB6_BOOL, false); + sDefaults.putBoolean(KEY_UNMETERED_NR_NSA_WHEN_ROAMING_BOOL, false); sDefaults.putBoolean(KEY_UNMETERED_NR_SA_BOOL, false); sDefaults.putBoolean(KEY_UNMETERED_NR_SA_MMWAVE_BOOL, false); sDefaults.putBoolean(KEY_UNMETERED_NR_SA_SUB6_BOOL, false); diff --git a/telephony/java/android/telephony/SignalStrength.java b/telephony/java/android/telephony/SignalStrength.java index 2bb4eb1538bd..1376cddbc41f 100644 --- a/telephony/java/android/telephony/SignalStrength.java +++ b/telephony/java/android/telephony/SignalStrength.java @@ -82,6 +82,8 @@ public class SignalStrength implements Parcelable { // Effectively final. Timestamp is set during construction of SignalStrength private long mTimestampMillis; + private boolean mLteAsPrimaryInNrNsa = true; + CellSignalStrengthCdma mCdma; CellSignalStrengthGsm mGsm; CellSignalStrengthWcdma mWcdma; @@ -188,6 +190,10 @@ public class SignalStrength implements Parcelable { private CellSignalStrength getPrimary() { // This behavior is intended to replicate the legacy behavior of getLevel() by prioritizing // newer faster RATs for default/for display purposes. + + if (mLteAsPrimaryInNrNsa) { + if (mLte.isValid()) return mLte; + } if (mNr.isValid()) return mNr; if (mLte.isValid()) return mLte; if (mCdma.isValid()) return mCdma; @@ -268,6 +274,10 @@ public class SignalStrength implements Parcelable { /** @hide */ public void updateLevel(PersistableBundle cc, ServiceState ss) { + if (cc != null) { + mLteAsPrimaryInNrNsa = cc.getBoolean( + CarrierConfigManager.KEY_SIGNAL_STRENGTH_NR_NSA_USE_LTE_AS_PRIMARY_BOOL, true); + } mCdma.updateLevel(cc, ss); mGsm.updateLevel(cc, ss); mWcdma.updateLevel(cc, ss); diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index f623649fb25e..835ef59f9ef3 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -13250,4 +13250,21 @@ public class TelephonyManager { public static void enableServiceHandleCaching() { sServiceHandleCacheEnabled = true; } + + /** + * Whether device can connect to 5G network when two SIMs are active. + * @hide + * TODO b/153669716: remove or make system API. + */ + public boolean canConnectTo5GInDsdsMode() { + ITelephony telephony = getITelephony(); + if (telephony == null) return true; + try { + return telephony.canConnectTo5GInDsdsMode(); + } catch (RemoteException ex) { + return true; + } catch (NullPointerException ex) { + return true; + } + } } diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl index 43aeb19fe1bd..f5cd68f050a4 100644 --- a/telephony/java/com/android/internal/telephony/ITelephony.aidl +++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl @@ -2268,4 +2268,9 @@ interface ITelephony { * @return operatorinfo on success */ String getManualNetworkSelectionPlmn(int subId); + + /** + * Whether device can connect to 5G network when two SIMs are active. + */ + boolean canConnectTo5GInDsdsMode(); } diff --git a/tests/AppLaunch/Android.bp b/tests/AppLaunch/Android.bp index f90f26f00e6d..75db55122553 100644 --- a/tests/AppLaunch/Android.bp +++ b/tests/AppLaunch/Android.bp @@ -8,6 +8,8 @@ android_test { "android.test.base", "android.test.runner", ], - static_libs: ["androidx.test.rules"], + static_libs: [ + "androidx.test.rules", + "ub-uiautomator"], test_suites: ["device-tests"], } diff --git a/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java b/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java index 2d2f4dbdf907..7d750b7bf690 100644 --- a/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java +++ b/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java @@ -15,6 +15,8 @@ */ package com.android.tests.applaunch; +import static org.junit.Assert.assertNotNull; + import android.accounts.Account; import android.accounts.AccountManager; import android.app.ActivityManager; @@ -29,7 +31,9 @@ import android.content.pm.ResolveInfo; import android.os.Bundle; import android.os.ParcelFileDescriptor; import android.os.RemoteException; +import android.os.SystemClock; import android.os.UserHandle; +import android.support.test.uiautomator.UiDevice; import android.test.InstrumentationTestCase; import android.test.InstrumentationTestRunner; import android.util.Log; @@ -46,6 +50,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStreamWriter; +import java.nio.file.Paths; import java.time.format.DateTimeFormatter; import java.time.ZonedDateTime; import java.time.ZoneOffset; @@ -67,6 +72,7 @@ import java.util.Set; * in the following format: * -e apps <app name>^<result key>|<app name>^<result key> */ +@Deprecated public class AppLaunch extends InstrumentationTestCase { private static final int JOIN_TIMEOUT = 10000; @@ -94,6 +100,9 @@ public class AppLaunch extends InstrumentationTestCase { private static final String KEY_TRACE_DUMPINTERVAL = "tracedump_interval"; private static final String KEY_COMPILER_FILTERS = "compiler_filters"; private static final String KEY_FORCE_STOP_APP = "force_stop_app"; + private static final String ENABLE_SCREEN_RECORDING = "enable_screen_recording"; + private static final int MAX_RECORDING_PARTS = 5; + private static final long VIDEO_TAIL_BUFFER = 500; private static final String SIMPLEPERF_APP_CMD = "simpleperf --log fatal stat --csv -e cpu-cycles,major-faults --app %s & %s"; @@ -144,14 +153,17 @@ public class AppLaunch extends InstrumentationTestCase { private Map<String, Intent> mNameToIntent; private List<LaunchOrder> mLaunchOrderList = new ArrayList<LaunchOrder>(); + private RecordingThread mCurrentThread; private Map<String, String> mNameToResultKey; private Map<String, Map<String, List<AppLaunchResult>>> mNameToLaunchTime; private IActivityManager mAm; + private File launchSubDir = null; private String mSimplePerfCmd = null; private String mLaunchOrder = null; private boolean mDropCache = false; private int mLaunchIterations = 10; private boolean mForceStopApp = true; + private boolean mEnableRecording = false; private int mTraceLaunchCount = 0; private String mTraceDirectoryStr = null; private Bundle mResult = new Bundle(); @@ -166,6 +178,7 @@ public class AppLaunch extends InstrumentationTestCase { private boolean mCycleCleanUp = false; private boolean mTraceAll = false; private boolean mIterationCycle = false; + private UiDevice mDevice; enum IorapStatus { UNDEFINED, @@ -222,7 +235,7 @@ public class AppLaunch extends InstrumentationTestCase { } try { - File launchSubDir = new File(launchRootDir, LAUNCH_SUB_DIRECTORY); + launchSubDir = new File(launchRootDir, LAUNCH_SUB_DIRECTORY); if (!launchSubDir.exists() && !launchSubDir.mkdirs()) { throw new IOException("Unable to create the lauch file sub directory " @@ -923,9 +936,16 @@ public class AppLaunch extends InstrumentationTestCase { mLaunchIterations = Integer.parseInt(launchIterations); } String forceStopApp = args.getString(KEY_FORCE_STOP_APP); + if (forceStopApp != null) { mForceStopApp = Boolean.parseBoolean(forceStopApp); } + + String enableRecording = args.getString(ENABLE_SCREEN_RECORDING); + + if (enableRecording != null) { + mEnableRecording = Boolean.parseBoolean(enableRecording); + } String appList = args.getString(KEY_APPS); if (appList == null) return; @@ -1038,6 +1058,9 @@ public class AppLaunch extends InstrumentationTestCase { private AppLaunchResult startApp(String appName, String launchReason) throws NameNotFoundException, RemoteException { Log.i(TAG, "Starting " + appName); + if(mEnableRecording) { + startRecording(appName, launchReason); + } Intent startIntent = mNameToIntent.get(appName); if (startIntent == null) { @@ -1053,6 +1076,10 @@ public class AppLaunch extends InstrumentationTestCase { } catch (InterruptedException e) { // ignore } + + if(mEnableRecording) { + stopRecording(); + } return runnable.getResult(); } @@ -1360,4 +1387,126 @@ public class AppLaunch extends InstrumentationTestCase { } } + + /** + * Start the screen recording while launching the app. + * + * @param appName + * @param launchReason + */ + private void startRecording(String appName, String launchReason) { + Log.v(TAG, "Started Recording"); + mCurrentThread = new RecordingThread("test-screen-record", + String.format("%s_%s", appName, launchReason)); + mCurrentThread.start(); + } + + /** + * Stop already started screen recording. + */ + private void stopRecording() { + // Skip if not directory. + if (launchSubDir == null) { + return; + } + + // Add some extra time to the video end. + SystemClock.sleep(VIDEO_TAIL_BUFFER); + // Ctrl + C all screen record processes. + mCurrentThread.cancel(); + // Wait for the thread to completely die. + try { + mCurrentThread.join(); + } catch (InterruptedException ex) { + Log.e(TAG, "Interrupted when joining the recording thread.", ex); + } + Log.v(TAG, "Stopped Recording"); + } + + /** Returns the recording's name for part {@code part} of launch description. */ + private File getOutputFile(String description, int part) { + // Omit the iteration number for the first iteration. + final String fileName = + String.format( + "%s-video%s.mp4", description, part == 1 ? "" : part); + return Paths.get(launchSubDir.getAbsolutePath(), description).toFile(); + } + + + /** + * Encapsulates the start and stop screen recording logic. + * Copied from ScreenRecordCollector. + */ + private class RecordingThread extends Thread { + private final String mDescription; + private final List<File> mRecordings; + + private boolean mContinue; + + public RecordingThread(String name, String description) { + super(name); + + mContinue = true; + mRecordings = new ArrayList<>(); + + assertNotNull("No test description provided for recording.", description); + mDescription = description; + } + + @Override + public void run() { + try { + // Start at i = 1 to encode parts as X.mp4, X2.mp4, X3.mp4, etc. + for (int i = 1; i <= MAX_RECORDING_PARTS && mContinue; i++) { + File output = getOutputFile(mDescription, i); + Log.d( + TAG, + String.format("Recording screen to %s", output.getAbsolutePath())); + mRecordings.add(output); + // Make sure not to block on this background command in the main thread so + // that the test continues to run, but block in this thread so it does not + // trigger a new screen recording session before the prior one completes. + getDevice().executeShellCommand( + String.format("screenrecord %s", output.getAbsolutePath())); + } + } catch (IOException e) { + throw new RuntimeException("Caught exception while screen recording."); + } + } + + public void cancel() { + mContinue = false; + + // Identify the screenrecord PIDs and send SIGINT 2 (Ctrl + C) to each. + try { + String[] pids = getDevice().executeShellCommand( + "pidof screenrecord").split(" "); + for (String pid : pids) { + // Avoid empty process ids, because of weird splitting behavior. + if (pid.isEmpty()) { + continue; + } + + getDevice().executeShellCommand( + String.format("kill -2 %s", pid)); + Log.d( + TAG, + String.format("Sent SIGINT 2 to screenrecord process (%s)", pid)); + } + } catch (IOException e) { + throw new RuntimeException("Failed to kill screen recording process."); + } + } + + public List<File> getRecordings() { + return mRecordings; + } + } + + public UiDevice getDevice() { + if (mDevice == null) { + mDevice = UiDevice.getInstance(getInstrumentation()); + } + return mDevice; + } } diff --git a/tests/DozeTest/src/com/android/dreams/dozetest/DozeTestDream.java b/tests/DozeTest/src/com/android/dreams/dozetest/DozeTestDream.java index f4f610b1b280..fa292bd0d57a 100644 --- a/tests/DozeTest/src/com/android/dreams/dozetest/DozeTestDream.java +++ b/tests/DozeTest/src/com/android/dreams/dozetest/DozeTestDream.java @@ -100,7 +100,6 @@ public class DozeTestDream extends DreamService { public void onAttachedToWindow() { super.onAttachedToWindow(); setInteractive(false); - setLowProfile(true); setFullscreen(true); setContentView(R.layout.dream); setScreenBright(false); diff --git a/tests/RollbackTest/MultiUserRollbackTest/src/com/android/tests/rollback/host/MultiUserRollbackTest.java b/tests/RollbackTest/MultiUserRollbackTest/src/com/android/tests/rollback/host/MultiUserRollbackTest.java index 4c29e72ec713..a4c81d577522 100644 --- a/tests/RollbackTest/MultiUserRollbackTest/src/com/android/tests/rollback/host/MultiUserRollbackTest.java +++ b/tests/RollbackTest/MultiUserRollbackTest/src/com/android/tests/rollback/host/MultiUserRollbackTest.java @@ -56,8 +56,7 @@ public class MultiUserRollbackTest extends BaseHostJUnit4Test { cleanUp(); mOriginalUserId = getDevice().getCurrentUser(); createAndStartSecondaryUser(); - // TODO(b/149733368): Remove the '-g' workaround when the bug is fixed. - installPackage("RollbackTest.apk", "-g --user all"); + installPackage("RollbackTest.apk", "--user all"); } @Test diff --git a/tests/net/java/android/net/CaptivePortalDataTest.kt b/tests/net/common/java/android/net/CaptivePortalDataTest.kt index 00714382684f..bd1847b7c440 100644 --- a/tests/net/java/android/net/CaptivePortalDataTest.kt +++ b/tests/net/common/java/android/net/CaptivePortalDataTest.kt @@ -16,17 +16,22 @@ package android.net +import android.os.Build import androidx.test.filters.SmallTest -import androidx.test.runner.AndroidJUnit4 import com.android.testutils.assertParcelSane import com.android.testutils.assertParcelingIsLossless +import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo +import com.android.testutils.DevSdkIgnoreRunner +import org.junit.Assert.assertFalse +import org.junit.Assert.assertTrue import org.junit.Test import org.junit.runner.RunWith import kotlin.test.assertEquals import kotlin.test.assertNotEquals @SmallTest -@RunWith(AndroidJUnit4::class) +@RunWith(DevSdkIgnoreRunner::class) +@IgnoreUpTo(Build.VERSION_CODES.Q) class CaptivePortalDataTest { private val data = CaptivePortalData.Builder() .setRefreshTime(123L) @@ -63,6 +68,46 @@ class CaptivePortalDataTest { assertNotEqualsAfterChange { it.setCaptive(false) } } + @Test + fun testUserPortalUrl() { + assertEquals(Uri.parse("https://portal.example.com/test"), data.userPortalUrl) + } + + @Test + fun testVenueInfoUrl() { + assertEquals(Uri.parse("https://venue.example.com/test"), data.venueInfoUrl) + } + + @Test + fun testIsSessionExtendable() { + assertTrue(data.isSessionExtendable) + } + + @Test + fun testByteLimit() { + assertEquals(456L, data.byteLimit) + // Test byteLimit unset. + assertEquals(-1L, CaptivePortalData.Builder(null).build().byteLimit) + } + + @Test + fun testRefreshTimeMillis() { + assertEquals(123L, data.refreshTimeMillis) + } + + @Test + fun testExpiryTimeMillis() { + assertEquals(789L, data.expiryTimeMillis) + // Test expiryTimeMillis unset. + assertEquals(-1L, CaptivePortalData.Builder(null).build().expiryTimeMillis) + } + + @Test + fun testIsCaptive() { + assertTrue(data.isCaptive) + assertFalse(makeBuilder().setCaptive(false).build().isCaptive) + } + private fun CaptivePortalData.mutate(mutator: (CaptivePortalData.Builder) -> Unit) = CaptivePortalData.Builder(this).apply { mutator(this) }.build() diff --git a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java index 6e6331312eac..a1bb0d586916 100644 --- a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java +++ b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java @@ -60,14 +60,13 @@ import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.annotation.NonNull; -import android.annotation.Nullable; import android.app.AlarmManager; import android.app.usage.NetworkStatsManager; import android.content.Context; @@ -95,8 +94,6 @@ import android.os.Message; import android.os.Messenger; import android.os.PowerManager; import android.os.SimpleClock; -import android.telephony.PhoneStateListener; -import android.telephony.ServiceState; import android.telephony.TelephonyManager; import androidx.test.InstrumentationRegistry; @@ -109,7 +106,7 @@ import com.android.internal.util.test.BroadcastInterceptingContext; import com.android.server.net.NetworkStatsService.NetworkStatsSettings; import com.android.server.net.NetworkStatsService.NetworkStatsSettings.Config; import com.android.testutils.HandlerUtilsKt; -import com.android.testutils.TestableNetworkStatsProvider; +import com.android.testutils.TestableNetworkStatsProviderBinder; import libcore.io.IoUtils; @@ -126,6 +123,7 @@ import java.io.File; import java.time.Clock; import java.time.ZoneOffset; import java.util.Objects; +import java.util.concurrent.Executor; /** * Tests for {@link NetworkStatsService}. @@ -168,14 +166,13 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { private @Mock NetworkStatsSettings mSettings; private @Mock IBinder mBinder; private @Mock AlarmManager mAlarmManager; - private @Mock TelephonyManager mTelephonyManager; + @Mock + private NetworkStatsSubscriptionsMonitor mNetworkStatsSubscriptionsMonitor; private HandlerThread mHandlerThread; private NetworkStatsService mService; private INetworkStatsSession mSession; private INetworkManagementEventObserver mNetworkObserver; - @Nullable - private PhoneStateListener mPhoneStateListener; private final Clock mClock = new SimpleClock(ZoneOffset.UTC) { @Override @@ -203,8 +200,8 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { mHandlerThread = new HandlerThread("HandlerThread"); final NetworkStatsService.Dependencies deps = makeDependencies(); mService = new NetworkStatsService(mServiceContext, mNetManager, mAlarmManager, wakeLock, - mClock, mTelephonyManager, mSettings, - mStatsFactory, new NetworkStatsObservers(), mStatsDir, getBaseDir(mStatsDir), deps); + mClock, mSettings, mStatsFactory, new NetworkStatsObservers(), mStatsDir, + getBaseDir(mStatsDir), deps); mElapsedRealtime = 0L; @@ -224,12 +221,6 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { ArgumentCaptor.forClass(INetworkManagementEventObserver.class); verify(mNetManager).registerObserver(networkObserver.capture()); mNetworkObserver = networkObserver.getValue(); - - // Capture the phone state listener that created by service. - final ArgumentCaptor<PhoneStateListener> phoneStateListenerCaptor = - ArgumentCaptor.forClass(PhoneStateListener.class); - verify(mTelephonyManager).listen(phoneStateListenerCaptor.capture(), anyInt()); - mPhoneStateListener = phoneStateListenerCaptor.getValue(); } @NonNull @@ -239,6 +230,14 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { public HandlerThread makeHandlerThread() { return mHandlerThread; } + + @Override + public NetworkStatsSubscriptionsMonitor makeSubscriptionsMonitor( + @NonNull Context context, @NonNull Executor executor, + @NonNull NetworkStatsService service) { + + return mNetworkStatsSubscriptionsMonitor; + } }; } @@ -678,10 +677,9 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { // TODO: support per IMSI state private void setMobileRatTypeAndWaitForIdle(int ratType) { - final ServiceState mockSs = mock(ServiceState.class); - when(mockSs.getDataNetworkType()).thenReturn(ratType); - mPhoneStateListener.onServiceStateChanged(mockSs); - + when(mNetworkStatsSubscriptionsMonitor.getRatTypeForSubscriberId(anyString())) + .thenReturn(ratType); + mService.handleOnCollapsedRatTypeChanged(); HandlerUtilsKt.waitForIdle(mHandlerThread, WAIT_TIMEOUT); } @@ -1118,7 +1116,8 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { expectNetworkStatsUidDetail(buildEmptyStats()); // Register custom provider and retrieve callback. - final TestableNetworkStatsProvider provider = new TestableNetworkStatsProvider(); + final TestableNetworkStatsProviderBinder provider = + new TestableNetworkStatsProviderBinder(); final INetworkStatsProviderCallback cb = mService.registerNetworkStatsProvider("TEST", provider); assertNotNull(cb); @@ -1176,7 +1175,8 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states), new VpnInfo[0]); // Register custom provider and retrieve callback. - final TestableNetworkStatsProvider provider = new TestableNetworkStatsProvider(); + final TestableNetworkStatsProviderBinder provider = + new TestableNetworkStatsProviderBinder(); final INetworkStatsProviderCallback cb = mService.registerNetworkStatsProvider("TEST", provider); assertNotNull(cb); |