diff options
382 files changed, 7957 insertions, 3118 deletions
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/FieldValue.h b/cmds/statsd/src/FieldValue.h index 92e09ea0f8f9..e251399776fb 100644 --- a/cmds/statsd/src/FieldValue.h +++ b/cmds/statsd/src/FieldValue.h @@ -181,6 +181,7 @@ public: return false; } + bool matches(const Matcher& that) const; }; @@ -360,7 +361,9 @@ struct Value { class Annotations { public: - Annotations() {} + Annotations() { + setNested(true); // Nested = true by default + } // This enum stores where particular annotations can be found in the // bitmask. Note that these pos do not correspond to annotation ids. @@ -379,7 +382,9 @@ public: inline void setUidField(bool isUid) { setBitmaskAtPos(UID_POS, isUid); } - inline void setResetState(int resetState) { mResetState = resetState; } + inline void setResetState(int32_t resetState) { + mResetState = resetState; + } // Default value = false inline bool isNested() const { return getValueFromBitmask(NESTED_POS); } @@ -395,7 +400,9 @@ public: // If a reset state is not sent in the StatsEvent, returns -1. Note that a // reset satate is only sent if and only if a reset should be triggered. - inline int getResetState() const { return mResetState; } + inline int32_t getResetState() const { + return mResetState; + } private: inline void setBitmaskAtPos(int pos, bool value) { @@ -411,7 +418,7 @@ private: // there are only 4 booleans, just one byte is required. uint8_t mBooleanBitmask = 0; - int mResetState = -1; + int32_t mResetState = -1; }; /** diff --git a/cmds/statsd/src/HashableDimensionKey.cpp b/cmds/statsd/src/HashableDimensionKey.cpp index 29249f4a6c55..eba66e0cb7b0 100644 --- a/cmds/statsd/src/HashableDimensionKey.cpp +++ b/cmds/statsd/src/HashableDimensionKey.cpp @@ -180,6 +180,23 @@ bool filterValues(const vector<Matcher>& matcherFields, const vector<FieldValue> return num_matches > 0; } +bool filterPrimaryKey(const std::vector<FieldValue>& values, HashableDimensionKey* output) { + size_t num_matches = 0; + const int32_t simpleFieldMask = 0xff7f0000; + const int32_t attributionUidFieldMask = 0xff7f7f7f; + for (const auto& value : values) { + if (value.mAnnotations.isPrimaryField()) { + output->addValue(value); + output->mutableValue(num_matches)->mField.setTag(value.mField.getTag()); + const int32_t mask = + isAttributionUidField(value) ? attributionUidFieldMask : simpleFieldMask; + output->mutableValue(num_matches)->mField.setField(value.mField.getField() & mask); + num_matches++; + } + } + return num_matches > 0; +} + void filterGaugeValues(const std::vector<Matcher>& matcherFields, const std::vector<FieldValue>& values, std::vector<FieldValue>* output) { for (const auto& field : matcherFields) { diff --git a/cmds/statsd/src/HashableDimensionKey.h b/cmds/statsd/src/HashableDimensionKey.h index 33a502497746..bd011005a301 100644 --- a/cmds/statsd/src/HashableDimensionKey.h +++ b/cmds/statsd/src/HashableDimensionKey.h @@ -154,6 +154,18 @@ bool filterValues(const std::vector<Matcher>& matcherFields, const std::vector<F HashableDimensionKey* output); /** + * Creating HashableDimensionKeys from State Primary Keys in FieldValues. + * + * This function may make modifications to the Field if the matcher has Position=FIRST,LAST or ALL + * in it. This is because: for example, when we create dimension from last uid in attribution chain, + * In one event, uid 1000 is at position 5 and it's the last + * In another event, uid 1000 is at position 6, and it's the last + * these 2 events should be mapped to the same dimension. So we will remove the original position + * from the dimension key for the uid field (by applying 0x80 bit mask). + */ +bool filterPrimaryKey(const std::vector<FieldValue>& values, HashableDimensionKey* output); + +/** * Filter the values from FieldValues using the matchers. * * In contrast to the above function, this function will not do any modification to the original 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 1f090fda2ce7..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; } @@ -9357,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/logd/LogEvent.cpp b/cmds/statsd/src/logd/LogEvent.cpp index 8b6a86464155..61cd01728ab1 100644 --- a/cmds/statsd/src/logd/LogEvent.cpp +++ b/cmds/statsd/src/logd/LogEvent.cpp @@ -293,7 +293,8 @@ void LogEvent::parseExclusiveStateAnnotation(uint8_t annotationType) { } const bool exclusiveState = readNextValue<uint8_t>(); - mValues[mValues.size() - 1].mAnnotations.setExclusiveState(exclusiveState); + mExclusiveStateFieldIndex = mValues.size() - 1; + mValues[getExclusiveStateFieldIndex()].mAnnotations.setExclusiveState(exclusiveState); } void LogEvent::parseTriggerStateResetAnnotation(uint8_t annotationType) { diff --git a/cmds/statsd/src/logd/LogEvent.h b/cmds/statsd/src/logd/LogEvent.h index 4eeb7d64a463..41fdcc2cbe7a 100644 --- a/cmds/statsd/src/logd/LogEvent.h +++ b/cmds/statsd/src/logd/LogEvent.h @@ -145,7 +145,7 @@ public: } // Default value = false - inline bool shouldTruncateTimestamp() { + inline bool shouldTruncateTimestamp() const { return mTruncateTimestamp; } @@ -170,6 +170,20 @@ public: return mAttributionChainIndex; } + // Returns the index of the exclusive state field within the FieldValues vector if + // an exclusive state exists. If there is no exclusive state field, returns -1. + // + // If the index within the atom definition is desired, do the following: + // int vectorIndex = LogEvent.getExclusiveStateFieldIndex(); + // if (vectorIndex != -1) { + // FieldValue& v = LogEvent.getValues()[vectorIndex]; + // int atomIndex = v.mField.getPosAtDepth(0); + // } + // Note that atomIndex is 1-indexed. + inline int getExclusiveStateFieldIndex() const { + return mExclusiveStateFieldIndex; + } + inline LogEvent makeCopy() { return LogEvent(*this); } @@ -297,6 +311,7 @@ private: bool mTruncateTimestamp = false; int mUidFieldIndex = -1; int mAttributionChainIndex = -1; + int mExclusiveStateFieldIndex = -1; }; void writeExperimentIdsToProto(const std::vector<int64_t>& experimentIds, std::vector<uint8_t>* protoOut); diff --git a/cmds/statsd/src/metrics/EventMetricProducer.cpp b/cmds/statsd/src/metrics/EventMetricProducer.cpp index 6833f8dd0114..d68f64ae40b0 100644 --- a/cmds/statsd/src/metrics/EventMetricProducer.cpp +++ b/cmds/statsd/src/metrics/EventMetricProducer.cpp @@ -151,8 +151,7 @@ void EventMetricProducer::onMatchedLogEventInternalLocked( uint64_t wrapperToken = mProto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_DATA); - const int64_t elapsedTimeNs = truncateTimestampIfNecessary( - event.GetTagId(), event.GetElapsedTimestampNs()); + const int64_t elapsedTimeNs = truncateTimestampIfNecessary(event); mProto->write(FIELD_TYPE_INT64 | FIELD_ID_ELAPSED_TIMESTAMP_NANOS, (long long) elapsedTimeNs); uint64_t eventToken = mProto->start(FIELD_TYPE_MESSAGE | FIELD_ID_ATOMS); diff --git a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp index 42bbd8eb4d35..c4bd0549465a 100644 --- a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp +++ b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp @@ -270,11 +270,9 @@ void GaugeMetricProducer::onDumpReportLocked(const int64_t dumpTimeNs, protoOutput->end(atomsToken); } for (const auto& atom : bucket.mGaugeAtoms) { - const int64_t elapsedTimestampNs = - truncateTimestampIfNecessary(mAtomId, atom.mElapsedTimestamps); - protoOutput->write( - FIELD_TYPE_INT64 | FIELD_COUNT_REPEATED | FIELD_ID_ELAPSED_ATOM_TIMESTAMP, - (long long)elapsedTimestampNs); + protoOutput->write(FIELD_TYPE_INT64 | FIELD_COUNT_REPEATED | + FIELD_ID_ELAPSED_ATOM_TIMESTAMP, + (long long)atom.mElapsedTimestampNs); } } protoOutput->end(bucketInfoToken); @@ -477,7 +475,9 @@ void GaugeMetricProducer::onMatchedLogEventInternalLocked( if ((*mCurrentSlicedBucket)[eventKey].size() >= mGaugeAtomsPerDimensionLimit) { return; } - GaugeAtom gaugeAtom(getGaugeFields(event), eventTimeNs); + + const int64_t truncatedElapsedTimestampNs = truncateTimestampIfNecessary(event); + GaugeAtom gaugeAtom(getGaugeFields(event), truncatedElapsedTimestampNs); (*mCurrentSlicedBucket)[eventKey].push_back(gaugeAtom); // Anomaly detection on gauge metric only works when there is one numeric // field specified. diff --git a/cmds/statsd/src/metrics/GaugeMetricProducer.h b/cmds/statsd/src/metrics/GaugeMetricProducer.h index 79ec71120f18..aa0cae26080d 100644 --- a/cmds/statsd/src/metrics/GaugeMetricProducer.h +++ b/cmds/statsd/src/metrics/GaugeMetricProducer.h @@ -35,10 +35,10 @@ namespace statsd { struct GaugeAtom { GaugeAtom(std::shared_ptr<vector<FieldValue>> fields, int64_t elapsedTimeNs) - : mFields(fields), mElapsedTimestamps(elapsedTimeNs) { + : mFields(fields), mElapsedTimestampNs(elapsedTimeNs) { } std::shared_ptr<vector<FieldValue>> mFields; - int64_t mElapsedTimestamps; + int64_t mElapsedTimestampNs; }; struct GaugeBucket { diff --git a/cmds/statsd/src/metrics/MetricProducer.h b/cmds/statsd/src/metrics/MetricProducer.h index 4550e65b6438..6aba13ca7859 100644 --- a/cmds/statsd/src/metrics/MetricProducer.h +++ b/cmds/statsd/src/metrics/MetricProducer.h @@ -451,7 +451,7 @@ protected: std::vector<int32_t> mSlicedStateAtoms; // Maps atom ids and state values to group_ids (<atom_id, <value, group_id>>). - std::unordered_map<int32_t, std::unordered_map<int, int64_t>> mStateGroupMap; + const std::unordered_map<int32_t, std::unordered_map<int, int64_t>> mStateGroupMap; // MetricStateLinks defined in statsd_config that link fields in the state // atom to fields in the "what" atom. diff --git a/cmds/statsd/src/metrics/metrics_manager_util.cpp b/cmds/statsd/src/metrics/metrics_manager_util.cpp index 2fcb13b709f9..88616dde61b7 100644 --- a/cmds/statsd/src/metrics/metrics_manager_util.cpp +++ b/cmds/statsd/src/metrics/metrics_manager_util.cpp @@ -795,9 +795,7 @@ bool initMetrics(const ConfigKey& key, const StatsdConfig& config, const int64_t for (const auto& it : allMetricProducers) { // Register metrics to StateTrackers for (int atomId : it->getSlicedStateAtoms()) { - if (!StateManager::getInstance().registerListener(atomId, it)) { - return false; - } + StateManager::getInstance().registerListener(atomId, it); } } return true; diff --git a/cmds/statsd/src/state/StateManager.cpp b/cmds/statsd/src/state/StateManager.cpp index ea776fae0583..5514b446b306 100644 --- a/cmds/statsd/src/state/StateManager.cpp +++ b/cmds/statsd/src/state/StateManager.cpp @@ -38,20 +38,12 @@ void StateManager::onLogEvent(const LogEvent& event) { } } -bool StateManager::registerListener(const int32_t atomId, wp<StateListener> listener) { +void StateManager::registerListener(const int32_t atomId, wp<StateListener> listener) { // Check if state tracker already exists. if (mStateTrackers.find(atomId) == mStateTrackers.end()) { - // Create a new state tracker iff atom is a state atom. - auto it = android::util::AtomsInfo::kStateAtomsFieldOptions.find(atomId); - if (it != android::util::AtomsInfo::kStateAtomsFieldOptions.end()) { - mStateTrackers[atomId] = new StateTracker(atomId, it->second); - } else { - ALOGE("StateManager cannot register listener, Atom %d is not a state atom", atomId); - return false; - } + mStateTrackers[atomId] = new StateTracker(atomId); } mStateTrackers[atomId]->registerListener(listener); - return true; } void StateManager::unregisterListener(const int32_t atomId, wp<StateListener> listener) { diff --git a/cmds/statsd/src/state/StateManager.h b/cmds/statsd/src/state/StateManager.h index 8b3a4218238c..577a0f51e38b 100644 --- a/cmds/statsd/src/state/StateManager.h +++ b/cmds/statsd/src/state/StateManager.h @@ -45,10 +45,11 @@ public: // Notifies the correct StateTracker of an event. void onLogEvent(const LogEvent& event); - // Returns true if atomId is being tracked and is associated with a state - // atom. StateManager notifies the correct StateTracker to register listener. + // Notifies the StateTracker for the given atomId to register listener. // If the correct StateTracker does not exist, a new StateTracker is created. - bool registerListener(const int32_t atomId, wp<StateListener> listener); + // Note: StateTrackers can be created for non-state atoms. They are essentially empty and + // do not perform any actions. + void registerListener(const int32_t atomId, wp<StateListener> listener); // Notifies the correct StateTracker to unregister a listener // and removes the tracker if it no longer has any listeners. diff --git a/cmds/statsd/src/state/StateTracker.cpp b/cmds/statsd/src/state/StateTracker.cpp index ab861275073c..b7f314a819df 100644 --- a/cmds/statsd/src/state/StateTracker.cpp +++ b/cmds/statsd/src/state/StateTracker.cpp @@ -25,81 +25,43 @@ namespace android { namespace os { namespace statsd { -StateTracker::StateTracker(const int32_t atomId, const util::StateAtomFieldOptions& stateAtomInfo) - : mAtomId(atomId), - mStateField(getSimpleMatcher(atomId, stateAtomInfo.exclusiveField)), - mNested(stateAtomInfo.nested) { - // create matcher for each primary field - for (const auto& primaryField : stateAtomInfo.primaryFields) { - if (primaryField == util::FIRST_UID_IN_CHAIN) { - Matcher matcher = getFirstUidMatcher(atomId); - mPrimaryFields.push_back(matcher); - } else { - Matcher matcher = getSimpleMatcher(atomId, primaryField); - mPrimaryFields.push_back(matcher); - } - } - - if (stateAtomInfo.defaultState != util::UNSET_VALUE) { - mDefaultState = stateAtomInfo.defaultState; - } - - if (stateAtomInfo.resetState != util::UNSET_VALUE) { - mResetState = stateAtomInfo.resetState; - } +StateTracker::StateTracker(const int32_t atomId) : mField(atomId, 0) { } void StateTracker::onLogEvent(const LogEvent& event) { - int64_t eventTimeNs = event.GetElapsedTimestampNs(); + const int64_t eventTimeNs = event.GetElapsedTimestampNs(); // Parse event for primary field values i.e. primary key. HashableDimensionKey primaryKey; - if (mPrimaryFields.size() > 0) { - if (!filterValues(mPrimaryFields, event.getValues(), &primaryKey) || - primaryKey.getValues().size() != mPrimaryFields.size()) { - ALOGE("StateTracker error extracting primary key from log event."); - handleReset(eventTimeNs); - return; - } - } else { - // Use an empty HashableDimensionKey if atom has no primary fields. - primaryKey = DEFAULT_DIMENSION_KEY; - } + filterPrimaryKey(event.getValues(), &primaryKey); - // Parse event for state value. FieldValue stateValue; - if (!filterValues(mStateField, event.getValues(), &stateValue) || - stateValue.mValue.getType() != INT) { + if (!getStateFieldValueFromLogEvent(event, &stateValue)) { + ALOGE("StateTracker error extracting state from log event. Missing exclusive state field."); + clearStateForPrimaryKey(eventTimeNs, primaryKey); + return; + } + + mField.setField(stateValue.mField.getField()); + + if (stateValue.mValue.getType() != INT) { ALOGE("StateTracker error extracting state from log event. Type: %d", stateValue.mValue.getType()); - handlePartialReset(eventTimeNs, primaryKey); + clearStateForPrimaryKey(eventTimeNs, primaryKey); return; } - int32_t state = stateValue.mValue.int_value; - if (state == mResetState) { - VLOG("StateTracker Reset state: %s", stateValue.mValue.toString().c_str()); - handleReset(eventTimeNs); + const int32_t resetState = stateValue.mAnnotations.getResetState(); + if (resetState != -1) { + VLOG("StateTracker new reset state: %d", resetState); + handleReset(eventTimeNs, resetState); return; } - // Track and update state. - int32_t oldState = 0; - int32_t newState = 0; - updateState(primaryKey, state, &oldState, &newState); - - // Notify all listeners if state has changed. - if (oldState != newState) { - VLOG("StateTracker updated state"); - for (auto listener : mListeners) { - auto sListener = listener.promote(); // safe access to wp<> - if (sListener != nullptr) { - sListener->onStateChanged(eventTimeNs, mAtomId, primaryKey, oldState, newState); - } - } - } else { - VLOG("StateTracker NO updated state"); - } + const int32_t newState = stateValue.mValue.int_value; + const bool nested = stateValue.mAnnotations.isNested(); + StateValueInfo* stateValueInfo = &mStateMap[primaryKey]; + updateStateForPrimaryKey(eventTimeNs, primaryKey, newState, nested, stateValueInfo); } void StateTracker::registerListener(wp<StateListener> listener) { @@ -111,81 +73,62 @@ void StateTracker::unregisterListener(wp<StateListener> listener) { } bool StateTracker::getStateValue(const HashableDimensionKey& queryKey, FieldValue* output) const { - output->mField = mStateField.mMatcher; - - // Check that the query key has the correct number of primary fields. - if (queryKey.getValues().size() == mPrimaryFields.size()) { - auto it = mStateMap.find(queryKey); - if (it != mStateMap.end()) { - output->mValue = it->second.state; - return true; - } - } else if (queryKey.getValues().size() > mPrimaryFields.size()) { - ALOGE("StateTracker query key size %zu > primary key size %zu is illegal", - queryKey.getValues().size(), mPrimaryFields.size()); - } else { - ALOGE("StateTracker query key size %zu < primary key size %zu is not supported", - queryKey.getValues().size(), mPrimaryFields.size()); + output->mField = mField; + + if (const auto it = mStateMap.find(queryKey); it != mStateMap.end()) { + output->mValue = it->second.state; + return true; } - // Set the state value to default state if: - // - query key size is incorrect - // - query key is not found in state map - output->mValue = mDefaultState; + // Set the state value to kStateUnknown if query key is not found in state map. + output->mValue = kStateUnknown; return false; } -void StateTracker::handleReset(const int64_t eventTimeNs) { +void StateTracker::handleReset(const int64_t eventTimeNs, const int32_t newState) { VLOG("StateTracker handle reset"); - for (const auto pair : mStateMap) { - for (auto l : mListeners) { - auto sl = l.promote(); - if (sl != nullptr) { - sl->onStateChanged(eventTimeNs, mAtomId, pair.first, pair.second.state, - mDefaultState); - } - } + for (auto& [primaryKey, stateValueInfo] : mStateMap) { + updateStateForPrimaryKey(eventTimeNs, primaryKey, newState, + false /* nested; treat this state change as not nested */, + &stateValueInfo); } - mStateMap.clear(); } -void StateTracker::handlePartialReset(const int64_t eventTimeNs, - const HashableDimensionKey& primaryKey) { - VLOG("StateTracker handle partial reset"); - if (mStateMap.find(primaryKey) != mStateMap.end()) { - for (auto l : mListeners) { - auto sl = l.promote(); - if (sl != nullptr) { - sl->onStateChanged(eventTimeNs, mAtomId, primaryKey, - mStateMap.find(primaryKey)->second.state, mDefaultState); - } - } - mStateMap.erase(primaryKey); +void StateTracker::clearStateForPrimaryKey(const int64_t eventTimeNs, + const HashableDimensionKey& primaryKey) { + VLOG("StateTracker clear state for primary key"); + const std::unordered_map<HashableDimensionKey, StateValueInfo>::iterator it = + mStateMap.find(primaryKey); + + // If there is no entry for the primaryKey in mStateMap, then the state is already + // kStateUnknown. + if (it != mStateMap.end()) { + updateStateForPrimaryKey(eventTimeNs, primaryKey, kStateUnknown, + false /* nested; treat this state change as not nested */, + &it->second); } } -void StateTracker::updateState(const HashableDimensionKey& primaryKey, const int32_t eventState, - int32_t* oldState, int32_t* newState) { - // get old state (either current state in map or default state) - auto it = mStateMap.find(primaryKey); - if (it != mStateMap.end()) { - *oldState = it->second.state; - } else { - *oldState = mDefaultState; +void StateTracker::updateStateForPrimaryKey(const int64_t eventTimeNs, + const HashableDimensionKey& primaryKey, + const int32_t newState, const bool nested, + StateValueInfo* stateValueInfo) { + const int32_t oldState = stateValueInfo->state; + + if (kStateUnknown == newState) { + mStateMap.erase(primaryKey); } // Update state map for non-nested counting case. // Every state event triggers a state overwrite. - if (!mNested) { - if (eventState == mDefaultState) { - // remove (key, state) pair if state returns to default state - VLOG("\t StateTracker changed to default state") - mStateMap.erase(primaryKey); - } else { - mStateMap[primaryKey].state = eventState; - mStateMap[primaryKey].count = 1; + if (!nested) { + stateValueInfo->state = newState; + stateValueInfo->count = 1; + + // Notify listeners if state has changed. + if (oldState != newState) { + notifyListeners(eventTimeNs, primaryKey, oldState, newState); } - *newState = eventState; return; } @@ -197,31 +140,47 @@ void StateTracker::updateState(const HashableDimensionKey& primaryKey, const int // number of OFF events as ON events. // // In atoms.proto, a state atom with nested counting enabled - // must only have 2 states and one of the states must be the default state. - it = mStateMap.find(primaryKey); - if (it != mStateMap.end()) { - *newState = it->second.state; - if (eventState == it->second.state) { - it->second.count++; - } else if (eventState == mDefaultState) { - if ((--it->second.count) == 0) { - mStateMap.erase(primaryKey); - *newState = mDefaultState; - } - } else { - ALOGE("StateTracker Nest counting state has a third state instead of the binary state " - "limit."); - return; + // must only have 2 states. There is no enforcemnt here of this requirement. + // The atom must be logged correctly. + if (kStateUnknown == newState) { + if (kStateUnknown != oldState) { + notifyListeners(eventTimeNs, primaryKey, oldState, newState); } - } else { - if (eventState != mDefaultState) { - mStateMap[primaryKey].state = eventState; - mStateMap[primaryKey].count = 1; + } else if (oldState == kStateUnknown) { + stateValueInfo->state = newState; + stateValueInfo->count = 1; + notifyListeners(eventTimeNs, primaryKey, oldState, newState); + } else if (oldState == newState) { + stateValueInfo->count++; + } else if (--stateValueInfo->count == 0) { + stateValueInfo->state = newState; + stateValueInfo->count = 1; + notifyListeners(eventTimeNs, primaryKey, oldState, newState); + } +} + +void StateTracker::notifyListeners(const int64_t eventTimeNs, + const HashableDimensionKey& primaryKey, const int32_t oldState, + const int32_t newState) { + for (auto l : mListeners) { + auto sl = l.promote(); + if (sl != nullptr) { + sl->onStateChanged(eventTimeNs, mField.getTag(), primaryKey, oldState, newState); } - *newState = eventState; } } +bool getStateFieldValueFromLogEvent(const LogEvent& event, FieldValue* output) { + const int exclusiveStateFieldIndex = event.getExclusiveStateFieldIndex(); + if (-1 == exclusiveStateFieldIndex) { + ALOGE("error extracting state from log event. Missing exclusive state field."); + return false; + } + + *output = event.getValues()[exclusiveStateFieldIndex]; + return true; +} + } // namespace statsd } // namespace os } // namespace android diff --git a/cmds/statsd/src/state/StateTracker.h b/cmds/statsd/src/state/StateTracker.h index 154750e6da3d..c5f6315fc992 100644 --- a/cmds/statsd/src/state/StateTracker.h +++ b/cmds/statsd/src/state/StateTracker.h @@ -15,7 +15,6 @@ */ #pragma once -#include <atoms_info.h> #include <utils/RefBase.h> #include "HashableDimensionKey.h" #include "logd/LogEvent.h" @@ -30,7 +29,7 @@ namespace statsd { class StateTracker : public virtual RefBase { public: - StateTracker(const int32_t atomId, const android::util::StateAtomFieldOptions& stateAtomInfo); + StateTracker(const int32_t atomId); virtual ~StateTracker(){}; @@ -60,21 +59,11 @@ public: private: struct StateValueInfo { - int32_t state; // state value - int count; // nested count (only used for binary states) + int32_t state = kStateUnknown; // state value + int count = 0; // nested count (only used for binary states) }; - const int32_t mAtomId; // id of the state atom being tracked - - Matcher mStateField; // matches the atom's exclusive state field - - std::vector<Matcher> mPrimaryFields; // matches the atom's primary fields - - int32_t mDefaultState = kStateUnknown; - - int32_t mResetState = kStateUnknown; - - const bool mNested; + Field mField; // Maps primary key to state value info std::unordered_map<HashableDimensionKey, StateValueInfo> mStateMap; @@ -82,20 +71,24 @@ private: // Set of all StateListeners (objects listening for state changes) std::set<wp<StateListener>> mListeners; - // Reset all state values in map to default state. - void handleReset(const int64_t eventTimeNs); + // Reset all state values in map to the given state. + void handleReset(const int64_t eventTimeNs, const int32_t newState); - // Reset only the state value mapped to the given primary key to default state. - // Partial resets are used when we only need to update the state of one primary - // key instead of clearing/reseting every key in the map. - void handlePartialReset(const int64_t eventTimeNs, const HashableDimensionKey& primaryKey); + // Clears the state value mapped to the given primary key by setting it to kStateUnknown. + void clearStateForPrimaryKey(const int64_t eventTimeNs, const HashableDimensionKey& primaryKey); // Update the StateMap based on the received state value. - // Store the old and new states. - void updateState(const HashableDimensionKey& primaryKey, const int32_t eventState, - int32_t* oldState, int32_t* newState); + void updateStateForPrimaryKey(const int64_t eventTimeNs, const HashableDimensionKey& primaryKey, + const int32_t newState, const bool nested, + StateValueInfo* stateValueInfo); + + // Notify registered state listeners of state change. + void notifyListeners(const int64_t eventTimeNs, const HashableDimensionKey& primaryKey, + const int32_t oldState, const int32_t newState); }; +bool getStateFieldValueFromLogEvent(const LogEvent& event, FieldValue* output); + } // namespace statsd } // namespace os } // namespace android diff --git a/cmds/statsd/src/stats_log_util.cpp b/cmds/statsd/src/stats_log_util.cpp index 77a3eb31fdd4..563531351fe0 100644 --- a/cmds/statsd/src/stats_log_util.cpp +++ b/cmds/statsd/src/stats_log_util.cpp @@ -549,14 +549,13 @@ int64_t getWallClockMillis() { return time(nullptr) * MS_PER_SEC; } -int64_t truncateTimestampIfNecessary(int atomId, int64_t timestampNs) { - if (AtomsInfo::kTruncatingTimestampAtomBlackList.find(atomId) != - AtomsInfo::kTruncatingTimestampAtomBlackList.end() || - (atomId >= StatsdStats::kTimestampTruncationStartTag && - atomId <= StatsdStats::kTimestampTruncationEndTag)) { - return timestampNs / NS_PER_SEC / (5 * 60) * NS_PER_SEC * (5 * 60); +int64_t truncateTimestampIfNecessary(const LogEvent& event) { + if (event.shouldTruncateTimestamp() || + (event.GetTagId() >= StatsdStats::kTimestampTruncationStartTag && + event.GetTagId() <= StatsdStats::kTimestampTruncationEndTag)) { + return event.GetElapsedTimestampNs() / NS_PER_SEC / (5 * 60) * NS_PER_SEC * (5 * 60); } else { - return timestampNs; + return event.GetElapsedTimestampNs(); } } diff --git a/cmds/statsd/src/stats_log_util.h b/cmds/statsd/src/stats_log_util.h index ade25d69a3a4..20d93b5a5365 100644 --- a/cmds/statsd/src/stats_log_util.h +++ b/cmds/statsd/src/stats_log_util.h @@ -17,11 +17,12 @@ #pragma once #include <android/util/ProtoOutputStream.h> + #include "FieldValue.h" #include "HashableDimensionKey.h" -#include "atoms_info.h" #include "frameworks/base/cmds/statsd/src/statsd_config.pb.h" #include "guardrail/StatsdStats.h" +#include "logd/LogEvent.h" using android::util::ProtoOutputStream; @@ -93,9 +94,9 @@ bool parseProtoOutputStream(ProtoOutputStream& protoOutput, T* message) { return message->ParseFromArray(pbBytes.c_str(), pbBytes.size()); } -// Checks the blacklist of atoms as well as the blacklisted range of 300,000 - 304,999. +// Checks the truncate timestamp annotation as well as the blacklisted range of 300,000 - 304,999. // Returns the truncated timestamp to the nearest 5 minutes if needed. -int64_t truncateTimestampIfNecessary(int atomId, int64_t timestampNs); +int64_t truncateTimestampIfNecessary(const LogEvent& event); // Checks permission for given pid and uid. bool checkPermissionForIds(const char* permission, pid_t pid, uid_t uid); 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/e2e/CountMetric_e2e_test.cpp b/cmds/statsd/tests/e2e/CountMetric_e2e_test.cpp index a5da9c8a6f56..b1461a1535ba 100644 --- a/cmds/statsd/tests/e2e/CountMetric_e2e_test.cpp +++ b/cmds/statsd/tests/e2e/CountMetric_e2e_test.cpp @@ -232,7 +232,7 @@ TEST(CountMetricE2eTest, TestSlicedStateWithMap) { StateMap map = state.map(); for (auto group : map.group()) { for (auto value : group.value()) { - EXPECT_EQ(metricProducer->mStateGroupMap[SCREEN_STATE_ATOM_ID][value], + EXPECT_EQ(metricProducer->mStateGroupMap.at(SCREEN_STATE_ATOM_ID).at(value), group.group_id()); } } @@ -614,7 +614,7 @@ TEST(CountMetricE2eTest, TestMultipleSlicedStates) { StateMap map = state1.map(); for (auto group : map.group()) { for (auto value : group.value()) { - EXPECT_EQ(metricProducer->mStateGroupMap[SCREEN_STATE_ATOM_ID][value], + EXPECT_EQ(metricProducer->mStateGroupMap.at(SCREEN_STATE_ATOM_ID).at(value), group.group_id()); } } diff --git a/cmds/statsd/tests/e2e/DurationMetric_e2e_test.cpp b/cmds/statsd/tests/e2e/DurationMetric_e2e_test.cpp index ba09a353e8b6..d59ec3ef4a29 100644 --- a/cmds/statsd/tests/e2e/DurationMetric_e2e_test.cpp +++ b/cmds/statsd/tests/e2e/DurationMetric_e2e_test.cpp @@ -921,18 +921,18 @@ TEST(DurationMetricE2eTest, TestWithConditionAndSlicedState) { bucket #1 bucket #2 | 1 2 3 4 5 6 7 8 (minutes) |---------------------------------------|------------------ - ON OFF ON (BatterySaverMode) + ON OFF ON (BatterySaverMode) T F T (DeviceUnpluggedPredicate) - | | | (ScreenIsOnEvent) + | | | (ScreenIsOnEvent) | | | (ScreenIsOffEvent) | (ScreenDozeEvent) */ // Initialize log events. std::vector<std::unique_ptr<LogEvent>> events; - events.push_back(CreateBatterySaverOnEvent(bucketStartTimeNs + 20 * NS_PER_SEC)); // 0:30 events.push_back(CreateScreenStateChangedEvent( - bucketStartTimeNs + 60 * NS_PER_SEC, - android::view::DisplayStateEnum::DISPLAY_STATE_ON)); // 1:10 + bucketStartTimeNs + 20 * NS_PER_SEC, + android::view::DisplayStateEnum::DISPLAY_STATE_ON)); // 0:30 + events.push_back(CreateBatterySaverOnEvent(bucketStartTimeNs + 60 * NS_PER_SEC)); // 1:10 events.push_back(CreateScreenStateChangedEvent( bucketStartTimeNs + 80 * NS_PER_SEC, android::view::DisplayStateEnum::DISPLAY_STATE_OFF)); // 1:30 diff --git a/cmds/statsd/tests/state/StateTracker_test.cpp b/cmds/statsd/tests/state/StateTracker_test.cpp index 78c80bc8307c..ba2a4cfbe8fd 100644 --- a/cmds/statsd/tests/state/StateTracker_test.cpp +++ b/cmds/statsd/tests/state/StateTracker_test.cpp @@ -19,6 +19,7 @@ #include "state/StateListener.h" #include "state/StateManager.h" +#include "state/StateTracker.h" #include "stats_event.h" #include "tests/statsd_test_util.h" @@ -127,23 +128,23 @@ TEST(StateTrackerTest, TestRegisterListener) { // Register listener to non-existing StateTracker EXPECT_EQ(0, mgr.getStateTrackersCount()); - EXPECT_TRUE(mgr.registerListener(util::SCREEN_STATE_CHANGED, listener1)); + mgr.registerListener(util::SCREEN_STATE_CHANGED, listener1); EXPECT_EQ(1, mgr.getStateTrackersCount()); EXPECT_EQ(1, mgr.getListenersCount(util::SCREEN_STATE_CHANGED)); // Register listener to existing StateTracker - EXPECT_TRUE(mgr.registerListener(util::SCREEN_STATE_CHANGED, listener2)); + mgr.registerListener(util::SCREEN_STATE_CHANGED, listener2); EXPECT_EQ(1, mgr.getStateTrackersCount()); EXPECT_EQ(2, mgr.getListenersCount(util::SCREEN_STATE_CHANGED)); // Register already registered listener to existing StateTracker - EXPECT_TRUE(mgr.registerListener(util::SCREEN_STATE_CHANGED, listener2)); + mgr.registerListener(util::SCREEN_STATE_CHANGED, listener2); EXPECT_EQ(1, mgr.getStateTrackersCount()); EXPECT_EQ(2, mgr.getListenersCount(util::SCREEN_STATE_CHANGED)); // Register listener to non-state atom - EXPECT_FALSE(mgr.registerListener(util::BATTERY_LEVEL_CHANGED, listener2)); - EXPECT_EQ(1, mgr.getStateTrackersCount()); + mgr.registerListener(util::BATTERY_LEVEL_CHANGED, listener2); + EXPECT_EQ(2, mgr.getStateTrackersCount()); } /** @@ -249,6 +250,9 @@ TEST(StateTrackerTest, TestStateChangeReset) { EXPECT_EQ(1, listener->updates.size()); EXPECT_EQ(1000, listener->updates[0].mKey.getValues()[0].mValue.int_value); EXPECT_EQ(BleScanStateChanged::ON, listener->updates[0].mState); + FieldValue stateFieldValue; + mgr.getStateValue(util::BLE_SCAN_STATE_CHANGED, listener->updates[0].mKey, &stateFieldValue); + EXPECT_EQ(BleScanStateChanged::ON, stateFieldValue.mValue.int_value); listener->updates.clear(); std::unique_ptr<LogEvent> event2 = @@ -258,6 +262,8 @@ TEST(StateTrackerTest, TestStateChangeReset) { EXPECT_EQ(1, listener->updates.size()); EXPECT_EQ(2000, listener->updates[0].mKey.getValues()[0].mValue.int_value); EXPECT_EQ(BleScanStateChanged::ON, listener->updates[0].mState); + mgr.getStateValue(util::BLE_SCAN_STATE_CHANGED, listener->updates[0].mKey, &stateFieldValue); + EXPECT_EQ(BleScanStateChanged::ON, stateFieldValue.mValue.int_value); listener->updates.clear(); std::unique_ptr<LogEvent> event3 = @@ -265,8 +271,12 @@ TEST(StateTrackerTest, TestStateChangeReset) { BleScanStateChanged::RESET, false, false, false); mgr.onLogEvent(*event3); EXPECT_EQ(2, listener->updates.size()); - EXPECT_EQ(BleScanStateChanged::OFF, listener->updates[0].mState); - EXPECT_EQ(BleScanStateChanged::OFF, listener->updates[1].mState); + for (const TestStateListener::Update& update : listener->updates) { + EXPECT_EQ(BleScanStateChanged::OFF, update.mState); + + mgr.getStateValue(util::BLE_SCAN_STATE_CHANGED, update.mKey, &stateFieldValue); + EXPECT_EQ(BleScanStateChanged::OFF, stateFieldValue.mValue.int_value); + } } /** @@ -352,13 +362,13 @@ TEST(StateTrackerTest, TestStateChangePrimaryFieldAttrChain) { // No state stored for this query key. HashableDimensionKey queryKey2; getPartialWakelockKey(1002 /* uid */, "tag1", &queryKey2); - EXPECT_EQ(WakelockStateChanged::RELEASE, + EXPECT_EQ(-1 /*StateTracker::kStateUnknown*/, getStateInt(mgr, util::WAKELOCK_STATE_CHANGED, queryKey2)); // Partial query fails. HashableDimensionKey queryKey3; getPartialWakelockKey(1001 /* uid */, &queryKey3); - EXPECT_EQ(WakelockStateChanged::RELEASE, + EXPECT_EQ(-1 /*StateTracker::kStateUnknown*/, getStateInt(mgr, util::WAKELOCK_STATE_CHANGED, queryKey3)); } diff --git a/cmds/statsd/tests/statsd_test_util.cpp b/cmds/statsd/tests/statsd_test_util.cpp index 687014f6a298..7216e1d8cc8e 100644 --- a/cmds/statsd/tests/statsd_test_util.cpp +++ b/cmds/statsd/tests/statsd_test_util.cpp @@ -569,6 +569,8 @@ std::unique_ptr<LogEvent> CreateScreenStateChangedEvent( AStatsEvent_setAtomId(statsEvent, util::SCREEN_STATE_CHANGED); AStatsEvent_overwriteTimestamp(statsEvent, timestampNs); AStatsEvent_writeInt32(statsEvent, state); + AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_EXCLUSIVE_STATE, true); + AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_STATE_NESTED, false); std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0); parseStatsEventToLogEvent(statsEvent, logEvent.get()); @@ -662,9 +664,14 @@ std::unique_ptr<LogEvent> CreateWakelockStateChangedEvent(uint64_t timestampNs, AStatsEvent_overwriteTimestamp(statsEvent, timestampNs); writeAttribution(statsEvent, attributionUids, attributionTags); + AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_PRIMARY_FIELD_FIRST_UID, true); AStatsEvent_writeInt32(statsEvent, android::os::WakeLockLevelEnum::PARTIAL_WAKE_LOCK); + AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_PRIMARY_FIELD, true); AStatsEvent_writeString(statsEvent, wakelockName.c_str()); + AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_PRIMARY_FIELD, true); AStatsEvent_writeInt32(statsEvent, state); + AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_EXCLUSIVE_STATE, true); + AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_STATE_NESTED, true); std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0); parseStatsEventToLogEvent(statsEvent, logEvent.get()); @@ -803,7 +810,11 @@ std::unique_ptr<LogEvent> CreateUidProcessStateChangedEvent( AStatsEvent_overwriteTimestamp(statsEvent, timestampNs); AStatsEvent_writeInt32(statsEvent, uid); + AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_IS_UID, true); + AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_PRIMARY_FIELD, true); AStatsEvent_writeInt32(statsEvent, state); + AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_EXCLUSIVE_STATE, true); + AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_STATE_NESTED, false); std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0); parseStatsEventToLogEvent(statsEvent, logEvent.get()); @@ -821,10 +832,20 @@ std::unique_ptr<LogEvent> CreateBleScanStateChangedEvent(uint64_t timestampNs, AStatsEvent_overwriteTimestamp(statsEvent, timestampNs); writeAttribution(statsEvent, attributionUids, attributionTags); + AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_PRIMARY_FIELD_FIRST_UID, true); AStatsEvent_writeInt32(statsEvent, state); - AStatsEvent_writeInt32(statsEvent, filtered); // filtered - AStatsEvent_writeInt32(statsEvent, firstMatch); // first match - AStatsEvent_writeInt32(statsEvent, opportunistic); // opportunistic + AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_EXCLUSIVE_STATE, true); + AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_STATE_NESTED, true); + if (state == util::BLE_SCAN_STATE_CHANGED__STATE__RESET) { + AStatsEvent_addInt32Annotation(statsEvent, ANNOTATION_ID_TRIGGER_STATE_RESET, + util::BLE_SCAN_STATE_CHANGED__STATE__OFF); + } + AStatsEvent_writeBool(statsEvent, filtered); // filtered + AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_PRIMARY_FIELD, true); + AStatsEvent_writeBool(statsEvent, firstMatch); // first match + AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_PRIMARY_FIELD, true); + AStatsEvent_writeBool(statsEvent, opportunistic); // opportunistic + AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_PRIMARY_FIELD, true); std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0); parseStatsEventToLogEvent(statsEvent, logEvent.get()); @@ -840,9 +861,14 @@ std::unique_ptr<LogEvent> CreateOverlayStateChangedEvent(int64_t timestampNs, co AStatsEvent_overwriteTimestamp(statsEvent, timestampNs); AStatsEvent_writeInt32(statsEvent, uid); + AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_IS_UID, true); + AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_PRIMARY_FIELD, true); AStatsEvent_writeString(statsEvent, packageName.c_str()); - AStatsEvent_writeInt32(statsEvent, usingAlertWindow); + AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_PRIMARY_FIELD, true); + AStatsEvent_writeBool(statsEvent, usingAlertWindow); AStatsEvent_writeInt32(statsEvent, state); + AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_EXCLUSIVE_STATE, true); + AStatsEvent_addBoolAnnotation(statsEvent, util::ANNOTATION_ID_STATE_NESTED, false); std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0); parseStatsEventToLogEvent(statsEvent, logEvent.get()); 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/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/content/pm/parsing/ParsingPackage.java b/core/java/android/content/pm/parsing/ParsingPackage.java index 4c9553249a0c..2ee0ad67b108 100644 --- a/core/java/android/content/pm/parsing/ParsingPackage.java +++ b/core/java/android/content/pm/parsing/ParsingPackage.java @@ -34,6 +34,7 @@ import android.content.pm.parsing.component.ParsedProvider; import android.content.pm.parsing.component.ParsedService; import android.os.Bundle; import android.util.SparseArray; +import android.util.SparseIntArray; import java.security.PublicKey; import java.util.Map; @@ -258,6 +259,8 @@ public interface ParsingPackage extends ParsingPackageRead { ParsingPackage setManageSpaceActivityName(String manageSpaceActivityName); + ParsingPackage setMinExtensionVersions(@Nullable SparseIntArray minExtensionVersions); + ParsingPackage setMinSdkVersion(int minSdkVersion); ParsingPackage setNetworkSecurityConfigRes(int networkSecurityConfigRes); diff --git a/core/java/android/content/pm/parsing/ParsingPackageImpl.java b/core/java/android/content/pm/parsing/ParsingPackageImpl.java index be1817d09155..1a1395ca7e9e 100644 --- a/core/java/android/content/pm/parsing/ParsingPackageImpl.java +++ b/core/java/android/content/pm/parsing/ParsingPackageImpl.java @@ -51,6 +51,7 @@ import android.text.TextUtils; import android.util.ArraySet; import android.util.Pair; import android.util.SparseArray; +import android.util.SparseIntArray; import com.android.internal.R; import com.android.internal.annotations.VisibleForTesting; @@ -340,6 +341,8 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable { private String manageSpaceActivityName; private float maxAspectRatio; private float minAspectRatio; + @Nullable + private SparseIntArray minExtensionVersions; private int minSdkVersion; private int networkSecurityConfigRes; @Nullable @@ -1100,6 +1103,7 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable { dest.writeBoolean(this.preserveLegacyExternalStorage); dest.writeArraySet(this.mimeGroups); dest.writeInt(this.gwpAsanMode); + dest.writeSparseIntArray(this.minExtensionVersions); } public ParsingPackageImpl(Parcel in) { @@ -1259,6 +1263,7 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable { this.preserveLegacyExternalStorage = in.readBoolean(); this.mimeGroups = (ArraySet<String>) in.readArraySet(boot); this.gwpAsanMode = in.readInt(); + this.minExtensionVersions = in.readSparseIntArray(); } public static final Parcelable.Creator<ParsingPackageImpl> CREATOR = @@ -1767,6 +1772,12 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable { return minAspectRatio; } + @Nullable + @Override + public SparseIntArray getMinExtensionVersions() { + return minExtensionVersions; + } + @Override public int getMinSdkVersion() { return minSdkVersion; @@ -2215,6 +2226,12 @@ public class ParsingPackageImpl implements ParsingPackage, Parcelable { } @Override + public ParsingPackageImpl setMinExtensionVersions(@Nullable SparseIntArray value) { + minExtensionVersions = value; + return this; + } + + @Override public ParsingPackageImpl setMinSdkVersion(int value) { minSdkVersion = value; return this; diff --git a/core/java/android/content/pm/parsing/ParsingPackageRead.java b/core/java/android/content/pm/parsing/ParsingPackageRead.java index 687bc235cfa7..1ded8d40c727 100644 --- a/core/java/android/content/pm/parsing/ParsingPackageRead.java +++ b/core/java/android/content/pm/parsing/ParsingPackageRead.java @@ -41,6 +41,7 @@ import android.os.Parcelable; import android.util.ArraySet; import android.util.Pair; import android.util.SparseArray; +import android.util.SparseIntArray; import com.android.internal.R; @@ -609,6 +610,13 @@ public interface ParsingPackageRead extends Parcelable { String getManageSpaceActivityName(); /** + * @see ApplicationInfo#minExtensionVersions + * @see R.styleable#AndroidManifestExtensionSdk + */ + @Nullable + SparseIntArray getMinExtensionVersions(); + + /** * @see ApplicationInfo#minSdkVersion * @see R.styleable#AndroidManifestUsesSdk_minSdkVersion */ diff --git a/core/java/android/content/pm/parsing/ParsingPackageUtils.java b/core/java/android/content/pm/parsing/ParsingPackageUtils.java index c61362feaeae..29ece4924e5c 100644 --- a/core/java/android/content/pm/parsing/ParsingPackageUtils.java +++ b/core/java/android/content/pm/parsing/ParsingPackageUtils.java @@ -95,6 +95,7 @@ import android.util.DisplayMetrics; import android.util.Pair; import android.util.Slog; import android.util.SparseArray; +import android.util.SparseIntArray; import android.util.TypedValue; import android.util.apk.ApkSignatureVerifier; @@ -1255,6 +1256,7 @@ public class ParsingPackageUtils { int type; final int innerDepth = parser.getDepth(); + SparseIntArray minExtensionVersions = null; while ((type = parser.next()) != XmlPullParser.END_DOCUMENT && (type != XmlPullParser.END_TAG || parser.getDepth() > innerDepth)) { if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { @@ -1263,7 +1265,10 @@ public class ParsingPackageUtils { final ParseResult result; if (parser.getName().equals("extension-sdk")) { - result = parseExtensionSdk(input, pkg, res, parser); + if (minExtensionVersions == null) { + minExtensionVersions = new SparseIntArray(); + } + result = parseExtensionSdk(input, res, parser, minExtensionVersions); XmlUtils.skipCurrentTag(parser); } else { result = ParsingUtils.unknownTag("<uses-sdk>", pkg, parser, input); @@ -1273,6 +1278,7 @@ public class ParsingPackageUtils { return input.error(result); } } + pkg.setMinExtensionVersions(exactSizedCopyOfSparseArray(minExtensionVersions)); } finally { sa.recycle(); } @@ -1280,8 +1286,21 @@ public class ParsingPackageUtils { return input.success(pkg); } - private static ParseResult parseExtensionSdk(ParseInput input, ParsingPackage pkg, - Resources res, XmlResourceParser parser) { + @Nullable + private static SparseIntArray exactSizedCopyOfSparseArray(@Nullable SparseIntArray input) { + if (input == null) { + return null; + } + SparseIntArray output = new SparseIntArray(input.size()); + for (int i = 0; i < input.size(); i++) { + output.put(input.keyAt(i), input.valueAt(i)); + } + return output; + } + + private static ParseResult<SparseIntArray> parseExtensionSdk( + ParseInput input, Resources res, XmlResourceParser parser, + SparseIntArray minExtensionVersions) { int sdkVersion; int minVersion; TypedArray sa = res.obtainAttributes(parser, R.styleable.AndroidManifestExtensionSdk); @@ -1316,7 +1335,8 @@ public class ParsingPackageUtils { PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED, "Specified sdkVersion " + sdkVersion + " is not valid"); } - return input.success(pkg); + minExtensionVersions.put(sdkVersion, minVersion); + return input.success(minExtensionVersions); } /** diff --git a/core/java/android/hardware/camera2/legacy/LegacyFaceDetectMapper.java b/core/java/android/hardware/camera2/legacy/LegacyFaceDetectMapper.java index 882a7f4ab37d..b3b4549426f0 100644 --- a/core/java/android/hardware/camera2/legacy/LegacyFaceDetectMapper.java +++ b/core/java/android/hardware/camera2/legacy/LegacyFaceDetectMapper.java @@ -233,8 +233,10 @@ public class LegacyFaceDetectMapper { Camera.Parameters params = legacyRequest.parameters; Rect activeArray = characteristics.get(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE); - ZoomData zoomData = ParameterUtils.convertScalerCropRegion(activeArray, - request.get(CaptureRequest.SCALER_CROP_REGION), previewSize, params); + ZoomData zoomData = ParameterUtils.convertToLegacyZoom(activeArray, + request.get(CaptureRequest.SCALER_CROP_REGION), + request.get(CaptureRequest.CONTROL_ZOOM_RATIO), + previewSize, params); List<Face> convertedFaces = new ArrayList<>(); if (faces != null) { diff --git a/core/java/android/hardware/camera2/legacy/LegacyMetadataMapper.java b/core/java/android/hardware/camera2/legacy/LegacyMetadataMapper.java index 6953a5b793c3..362ddfae67bf 100644 --- a/core/java/android/hardware/camera2/legacy/LegacyMetadataMapper.java +++ b/core/java/android/hardware/camera2/legacy/LegacyMetadataMapper.java @@ -771,6 +771,7 @@ public class LegacyMetadataMapper { CameraCharacteristics.CONTROL_AWB_AVAILABLE_MODES , CameraCharacteristics.CONTROL_AWB_LOCK_AVAILABLE , CameraCharacteristics.CONTROL_MAX_REGIONS , + CameraCharacteristics.CONTROL_ZOOM_RATIO_RANGE , CameraCharacteristics.FLASH_INFO_AVAILABLE , CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL , CameraCharacteristics.JPEG_AVAILABLE_THUMBNAIL_SIZES , @@ -828,6 +829,7 @@ public class LegacyMetadataMapper { CaptureRequest.CONTROL_MODE, CaptureRequest.CONTROL_SCENE_MODE, CaptureRequest.CONTROL_VIDEO_STABILIZATION_MODE, + CaptureRequest.CONTROL_ZOOM_RATIO, CaptureRequest.FLASH_MODE, CaptureRequest.JPEG_GPS_COORDINATES, CaptureRequest.JPEG_GPS_PROCESSING_METHOD, @@ -872,6 +874,7 @@ public class LegacyMetadataMapper { CaptureResult.CONTROL_AWB_MODE , CaptureResult.CONTROL_AWB_LOCK , CaptureResult.CONTROL_MODE , + CaptureResult.CONTROL_ZOOM_RATIO , CaptureResult.FLASH_MODE , CaptureResult.JPEG_GPS_COORDINATES , CaptureResult.JPEG_GPS_PROCESSING_METHOD , @@ -935,6 +938,12 @@ public class LegacyMetadataMapper { private static void mapScaler(CameraMetadataNative m, Parameters p) { /* + * control.zoomRatioRange + */ + Range<Float> zoomRatioRange = new Range<Float>(1.0f, ParameterUtils.getMaxZoomRatio(p)); + m.set(CONTROL_ZOOM_RATIO_RANGE, zoomRatioRange); + + /* * scaler.availableMaxDigitalZoom */ m.set(SCALER_AVAILABLE_MAX_DIGITAL_ZOOM, ParameterUtils.getMaxZoomRatio(p)); @@ -1383,6 +1392,9 @@ public class LegacyMetadataMapper { // control.sceneMode -- DISABLED is always available m.set(CaptureRequest.CONTROL_SCENE_MODE, CONTROL_SCENE_MODE_DISABLED); + // control.zoomRatio -- 1.0 + m.set(CaptureRequest.CONTROL_ZOOM_RATIO, 1.0f); + /* * statistics.* */ diff --git a/core/java/android/hardware/camera2/legacy/LegacyRequestMapper.java b/core/java/android/hardware/camera2/legacy/LegacyRequestMapper.java index 2e06d5fb3b6f..3a46379477e9 100644 --- a/core/java/android/hardware/camera2/legacy/LegacyRequestMapper.java +++ b/core/java/android/hardware/camera2/legacy/LegacyRequestMapper.java @@ -68,8 +68,9 @@ public class LegacyRequestMapper { */ ParameterUtils.ZoomData zoomData; { - zoomData = ParameterUtils.convertScalerCropRegion(activeArray, + zoomData = ParameterUtils.convertToLegacyZoom(activeArray, request.get(SCALER_CROP_REGION), + request.get(CONTROL_ZOOM_RATIO), previewSize, params); diff --git a/core/java/android/hardware/camera2/legacy/LegacyResultMapper.java b/core/java/android/hardware/camera2/legacy/LegacyResultMapper.java index dc5823d80f21..09edf74f0d4c 100644 --- a/core/java/android/hardware/camera2/legacy/LegacyResultMapper.java +++ b/core/java/android/hardware/camera2/legacy/LegacyResultMapper.java @@ -118,8 +118,10 @@ public class LegacyResultMapper { Rect activeArraySize = characteristics.get( CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE); - ZoomData zoomData = ParameterUtils.convertScalerCropRegion(activeArraySize, - request.get(CaptureRequest.SCALER_CROP_REGION), previewSize, params); + ZoomData zoomData = ParameterUtils.convertToLegacyZoom(activeArraySize, + request.get(CaptureRequest.SCALER_CROP_REGION), + request.get(CaptureRequest.CONTROL_ZOOM_RATIO), + previewSize, params); /* * colorCorrection @@ -516,5 +518,12 @@ public class LegacyResultMapper { { m.set(SCALER_CROP_REGION, zoomData.reportedCrop); } + + /* + * control.zoomRatio + */ + { + m.set(CONTROL_ZOOM_RATIO, zoomData.reportedZoomRatio); + } } } diff --git a/core/java/android/hardware/camera2/legacy/ParameterUtils.java b/core/java/android/hardware/camera2/legacy/ParameterUtils.java index 3cfd020aeee3..eb435989e9a0 100644 --- a/core/java/android/hardware/camera2/legacy/ParameterUtils.java +++ b/core/java/android/hardware/camera2/legacy/ParameterUtils.java @@ -73,11 +73,15 @@ public class ParameterUtils { public final Rect previewCrop; /** Reported crop-region given the zoom index, coordinates relative to active-array */ public final Rect reportedCrop; + /** Reported zoom ratio given the zoom index */ + public final float reportedZoomRatio; - public ZoomData(int zoomIndex, Rect previewCrop, Rect reportedCrop) { + public ZoomData(int zoomIndex, Rect previewCrop, Rect reportedCrop, + float reportedZoomRatio) { this.zoomIndex = zoomIndex; this.previewCrop = previewCrop; this.reportedCrop = reportedCrop; + this.reportedZoomRatio = reportedZoomRatio; } } @@ -371,7 +375,8 @@ public class ParameterUtils { * @throws NullPointerException if any of the args were {@code null} */ public static int getClosestAvailableZoomCrop( - Camera.Parameters params, Rect activeArray, Size streamSize, Rect cropRegion, + Camera.Parameters params, Rect activeArray, + Size streamSize, Rect cropRegion, /*out*/ Rect reportedCropRegion, Rect previewCropRegion) { @@ -733,6 +738,92 @@ public class ParameterUtils { } /** + * Convert the user-specified crop region/zoom into zoom data; which can be used + * to set the parameters to a specific zoom index, or to report back to the user what + * the actual zoom was, or for other calculations requiring the current preview crop region. + * + * <p>None of the parameters are mutated.<p> + * + * @param activeArraySize active array size of the sensor (e.g. max jpeg size) + * @param cropRegion the user-specified crop region + * @param zoomRatio the user-specified zoom ratio + * @param previewSize the current preview size (in pixels) + * @param params the current camera parameters (not mutated) + * + * @return the zoom index, and the effective/reported crop regions (relative to active array) + */ + public static ZoomData convertToLegacyZoom(Rect activeArraySize, Rect + cropRegion, Float zoomRatio, Size previewSize, Camera.Parameters params) { + final float FLOAT_EQUAL_THRESHOLD = 0.0001f; + if (zoomRatio != null && + Math.abs(1.0f - zoomRatio) > FLOAT_EQUAL_THRESHOLD) { + // User uses CONTROL_ZOOM_RATIO to control zoom + return convertZoomRatio(activeArraySize, zoomRatio, previewSize, params); + } + + return convertScalerCropRegion(activeArraySize, cropRegion, previewSize, params); + } + + /** + * Convert the user-specified zoom ratio into zoom data; which can be used + * to set the parameters to a specific zoom index, or to report back to the user what the + * actual zoom was, or for other calculations requiring the current preview crop region. + * + * <p>None of the parameters are mutated.</p> + * + * @param activeArraySize active array size of the sensor (e.g. max jpeg size) + * @param zoomRatio the current zoom ratio + * @param previewSize the current preview size (in pixels) + * @param params the current camera parameters (not mutated) + * + * @return the zoom index, and the effective/reported crop regions (relative to active array) + */ + public static ZoomData convertZoomRatio(Rect activeArraySize, float zoomRatio, + Size previewSize, Camera.Parameters params) { + if (DEBUG) { + Log.v(TAG, "convertZoomRatio - user zoom ratio was " + zoomRatio); + } + + List<Rect> availableReportedCropRegions = + getAvailableZoomCropRectangles(params, activeArraySize); + List<Rect> availablePreviewCropRegions = + getAvailablePreviewZoomCropRectangles(params, activeArraySize, previewSize); + if (availableReportedCropRegions.size() != availablePreviewCropRegions.size()) { + throw new AssertionError("available reported/preview crop region size mismatch"); + } + + // Find the best matched legacy zoom ratio for the requested camera2 zoom ratio. + int bestZoomIndex = 0; + Rect reportedCropRegion = new Rect(availableReportedCropRegions.get(0)); + Rect previewCropRegion = new Rect(availablePreviewCropRegions.get(0)); + float reportedZoomRatio = 1.0f; + if (params.isZoomSupported()) { + List<Integer> zoomRatios = params.getZoomRatios(); + for (int i = 1; i < zoomRatios.size(); i++) { + if (zoomRatio * ZOOM_RATIO_MULTIPLIER >= zoomRatios.get(i)) { + bestZoomIndex = i; + reportedCropRegion = availableReportedCropRegions.get(i); + previewCropRegion = availablePreviewCropRegions.get(i); + reportedZoomRatio = zoomRatios.get(i); + } else { + break; + } + } + } + + if (DEBUG) { + Log.v(TAG, "convertZoomRatio - zoom calculated to: " + + "zoomIndex = " + bestZoomIndex + + ", reported crop region = " + reportedCropRegion + + ", preview crop region = " + previewCropRegion + + ", reported zoom ratio = " + reportedZoomRatio); + } + + return new ZoomData(bestZoomIndex, reportedCropRegion, + previewCropRegion, reportedZoomRatio); + } + + /** * Convert the user-specified crop region into zoom data; which can be used * to set the parameters to a specific zoom index, or to report back to the user what the * actual zoom was, or for other calculations requiring the current preview crop region. @@ -767,15 +858,17 @@ public class ParameterUtils { final int zoomIdx = ParameterUtils.getClosestAvailableZoomCrop(params, activeArraySizeOnly, previewSize, userCropRegion, /*out*/reportedCropRegion, /*out*/previewCropRegion); + final float reportedZoomRatio = 1.0f; if (DEBUG) { Log.v(TAG, "convertScalerCropRegion - zoom calculated to: " + "zoomIndex = " + zoomIdx + ", reported crop region = " + reportedCropRegion + - ", preview crop region = " + previewCropRegion); + ", preview crop region = " + previewCropRegion + + ", reported zoom ratio = " + reportedZoomRatio); } - return new ZoomData(zoomIdx, previewCropRegion, reportedCropRegion); + return new ZoomData(zoomIdx, previewCropRegion, reportedCropRegion, reportedZoomRatio); } /** 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/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/service/autofill/InlinePresentation.java b/core/java/android/service/autofill/InlinePresentation.java index 63b380404217..9cf1b87f7eab 100644 --- a/core/java/android/service/autofill/InlinePresentation.java +++ b/core/java/android/service/autofill/InlinePresentation.java @@ -19,7 +19,6 @@ package android.service.autofill; import android.annotation.NonNull; import android.annotation.Size; import android.app.slice.Slice; -import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; import android.widget.inline.InlinePresentationSpec; @@ -67,18 +66,6 @@ public final class InlinePresentation implements Parcelable { return hints.toArray(new String[hints.size()]); } - /** - * @hide - * @removed - */ - @UnsupportedAppUsage - public InlinePresentation( - @NonNull Slice slice, - @NonNull android.view.inline.InlinePresentationSpec inlinePresentationSpec, - boolean pinned) { - this(slice, inlinePresentationSpec.toWidget(), pinned); - } - // Code below generated by codegen v1.0.15. @@ -245,7 +232,7 @@ public final class InlinePresentation implements Parcelable { }; @DataClass.Generated( - time = 1585633564226L, + time = 1586992400667L, codegenVersion = "1.0.15", sourceFile = "frameworks/base/core/java/android/service/autofill/InlinePresentation.java", inputSignatures = "private final @android.annotation.NonNull android.app.slice.Slice mSlice\nprivate final @android.annotation.NonNull android.widget.inline.InlinePresentationSpec mInlinePresentationSpec\nprivate final boolean mPinned\npublic @android.annotation.NonNull @android.annotation.Size(min=0L) java.lang.String[] getAutofillHints()\nclass InlinePresentation extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genToString=true, genHiddenConstDefs=true, genEqualsHashCode=true)") 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/ImeFocusController.java b/core/java/android/view/ImeFocusController.java index dbbe4b61c81c..d6d9fc628ac9 100644 --- a/core/java/android/view/ImeFocusController.java +++ b/core/java/android/view/ImeFocusController.java @@ -123,7 +123,7 @@ public final class ImeFocusController { } // Update mNextServedView when focusedView changed. final View viewForWindowFocus = focusedView != null ? focusedView : mViewRootImpl.mView; - onViewFocusChanged(viewForWindowFocus, true); + onViewFocusChanged(viewForWindowFocus, viewForWindowFocus.hasFocus()); immDelegate.startInputAsyncOnWindowFocusGain(viewForWindowFocus, windowAttribute.softInputMode, windowAttribute.flags, forceFocus); 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/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java index 83a79344917c..6d3dbfe16b78 100644 --- a/core/java/android/view/autofill/AutofillManager.java +++ b/core/java/android/view/autofill/AutofillManager.java @@ -1258,13 +1258,6 @@ public final class AutofillManager { } } - if (mForAugmentedAutofillOnly) { - if (sVerbose) { - Log.v(TAG, "notifyValueChanged(): not notifying system server on " - + "augmented-only mode"); - } - return; - } if (!mEnabled || !isActiveLocked()) { if (!startAutofillIfNeededLocked(view)) { if (sVerbose) { @@ -1299,10 +1292,6 @@ public final class AutofillManager { return; } synchronized (mLock) { - if (mForAugmentedAutofillOnly) { - if (sVerbose) Log.v(TAG, "notifyValueChanged(): ignoring on augmented only mode"); - return; - } if (!mEnabled || !isActiveLocked()) { if (sVerbose) { Log.v(TAG, "notifyValueChanged(" + view.getAutofillId() + ":" + virtualId diff --git a/core/java/android/view/inline/InlineContentView.java b/core/java/android/view/inline/InlineContentView.java deleted file mode 100644 index 3df201c9145d..000000000000 --- a/core/java/android/view/inline/InlineContentView.java +++ /dev/null @@ -1,208 +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 android.view.inline; - -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.content.Context; -import android.graphics.PixelFormat; -import android.util.AttributeSet; -import android.view.SurfaceControl; -import android.view.SurfaceControlViewHost; -import android.view.SurfaceHolder; -import android.view.SurfaceView; -import android.view.ViewGroup; - -/** - * This class represents a view that holds opaque content from another app that - * you can inline in your UI. - * - * <p>Since the content presented by this view is from another security domain,it is - * shown on a remote surface preventing the host application from accessing that content. - * Also the host application cannot interact with the inlined content by injecting touch - * events or clicking programmatically. - * - * <p>This view can be overlaid by other windows, i.e. redressed, but if this is the case - * the inined UI would not be interactive. Sometimes this is desirable, e.g. animating - * transitions. - * - * <p>By default the surface backing this view is shown on top of the hosting window such - * that the inlined content is interactive. However, you can temporarily move the surface - * under the hosting window which could be useful in some cases, e.g. animating transitions. - * At this point the inlined content will not be interactive and the touch events would - * be delivered to your app. - * - * @hide - * @removed - */ -public class InlineContentView extends ViewGroup { - - /** - * Callback for observing the lifecycle of the surface control - * that manipulates the backing secure embedded UI surface. - */ - public interface SurfaceControlCallback { - /** - * Called when the backing surface is being created. - * - * @param surfaceControl The surface control to manipulate the surface. - */ - void onCreated(@NonNull SurfaceControl surfaceControl); - - /** - * Called when the backing surface is being destroyed. - * - * @param surfaceControl The surface control to manipulate the surface. - */ - void onDestroyed(@NonNull SurfaceControl surfaceControl); - } - - private final @NonNull SurfaceHolder.Callback mSurfaceCallback = new SurfaceHolder.Callback() { - @Override - public void surfaceCreated(@NonNull SurfaceHolder holder) { - mSurfaceControlCallback.onCreated(mSurfaceView.getSurfaceControl()); - } - - @Override - public void surfaceChanged(@NonNull SurfaceHolder holder, - int format, int width, int height) { - /* do nothing */ - } - - @Override - public void surfaceDestroyed(@NonNull SurfaceHolder holder) { - mSurfaceControlCallback.onDestroyed(mSurfaceView.getSurfaceControl()); - } - }; - - private final @NonNull SurfaceView mSurfaceView; - - private @Nullable SurfaceControlCallback mSurfaceControlCallback; - - /** - * @inheritDoc - * - * @hide - */ - public InlineContentView(@NonNull Context context) { - this(context, null); - } - - /** - * @inheritDoc - * - * @hide - */ - public InlineContentView(@NonNull Context context, @Nullable AttributeSet attrs) { - this(context, attrs, 0); - } - - /** - * @inheritDoc - * - * @hide - */ - public InlineContentView(@NonNull Context context, @Nullable AttributeSet attrs, - int defStyleAttr) { - this(context, attrs, defStyleAttr, 0); - } - - /** - * Gets the surface control. If the surface is not created this method - * returns {@code null}. - * - * @return The surface control. - * - * @see #setSurfaceControlCallback(SurfaceControlCallback) - */ - public @Nullable SurfaceControl getSurfaceControl() { - return mSurfaceView.getSurfaceControl(); - } - - /** - * @inheritDoc - * - * @hide - */ - public InlineContentView(@NonNull Context context, @Nullable AttributeSet attrs, - int defStyleAttr, int defStyleRes) { - super(context, attrs, defStyleAttr, defStyleRes); - mSurfaceView = new SurfaceView(context, attrs, defStyleAttr, defStyleRes); - mSurfaceView.setZOrderOnTop(true); - mSurfaceView.getHolder().setFormat(PixelFormat.TRANSPARENT); - addView(mSurfaceView); - } - - /** - * Sets the embedded UI. - * @param surfacePackage The embedded UI. - * - * @hide - */ - public void setChildSurfacePackage( - @Nullable SurfaceControlViewHost.SurfacePackage surfacePackage) { - mSurfaceView.setChildSurfacePackage(surfacePackage); - } - - @Override - public void onLayout(boolean changed, int l, int t, int r, int b) { - mSurfaceView.layout(0, 0, getMeasuredWidth(), getMeasuredHeight()); - } - - /** - * Sets a callback to observe the lifecycle of the surface control for - * managing the backing surface. - * - * @param callback The callback to set or {@code null} to clear. - */ - public void setSurfaceControlCallback(@Nullable SurfaceControlCallback callback) { - if (mSurfaceControlCallback != null) { - mSurfaceView.getHolder().removeCallback(mSurfaceCallback); - } - mSurfaceControlCallback = callback; - if (mSurfaceControlCallback != null) { - mSurfaceView.getHolder().addCallback(mSurfaceCallback); - } - } - - /** - * @return Whether the surface backing this view appears on top of its parent. - * - * @see #setZOrderedOnTop(boolean) - */ - public boolean isZOrderedOnTop() { - return mSurfaceView.isZOrderedOnTop(); - } - - /** - * Controls whether the backing surface is placed on top of this view's window. - * Normally, it is placed on top of the window, to allow interaction - * with the inlined UI. Via this method, you can place the surface below the - * window. This means that all of the contents of the window this view is in - * will be visible on top of its surface. - * - * <p> The Z ordering can be changed dynamically if the backing surface is - * created, otherwise the ordering would be applied at surface construction time. - * - * @param onTop Whether to show the surface on top of this view's window. - * - * @see #isZOrderedOnTop() - */ - public boolean setZOrderedOnTop(boolean onTop) { - return mSurfaceView.setZOrderedOnTop(onTop, /*allowDynamicChange*/ true); - } -} diff --git a/core/java/android/view/inline/InlinePresentationSpec.java b/core/java/android/view/inline/InlinePresentationSpec.java deleted file mode 100644 index d777cb8d8e0b..000000000000 --- a/core/java/android/view/inline/InlinePresentationSpec.java +++ /dev/null @@ -1,347 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.view.inline; - -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.compat.annotation.UnsupportedAppUsage; -import android.os.Bundle; -import android.os.Parcelable; -import android.util.Size; - -import com.android.internal.util.DataClass; - -import java.util.ArrayList; -import java.util.List; - -/** - * This class represents the presentation specification by which an inline suggestion - * should abide when constructing its UI. Since suggestions are inlined in a - * host application while provided by another source, they need to be consistent - * with the host's look at feel to allow building smooth and integrated UIs. - * - * @hide - * @removed - */ -@DataClass(genEqualsHashCode = true, genToString = true, genBuilder = true) -public final class InlinePresentationSpec implements Parcelable { - - /** The minimal size of the suggestion. */ - @NonNull - private final Size mMinSize; - /** The maximal size of the suggestion. */ - @NonNull - private final Size mMaxSize; - - /** - * The extras encoding the UI style information. Defaults to {@code Bundle.EMPTY} in which case - * the default system UI style will be used. - */ - @NonNull - private final Bundle mStyle; - - private static Bundle defaultStyle() { - return Bundle.EMPTY; - } - - /** @hide */ - @DataClass.Suppress({"setMaxSize", "setMinSize"}) - abstract static class BaseBuilder { - } - - /** - * @hide - */ - public android.widget.inline.InlinePresentationSpec toWidget() { - final android.widget.inline.InlinePresentationSpec.Builder builder = - new android.widget.inline.InlinePresentationSpec.Builder( - getMinSize(), getMaxSize()); - final Bundle style = getStyle(); - if (style != null) { - builder.setStyle(style); - } - return builder.build(); - } - - /** - * @hide - */ - public static android.view.inline.InlinePresentationSpec fromWidget( - android.widget.inline.InlinePresentationSpec widget) { - final android.view.inline.InlinePresentationSpec.Builder builder = - new android.view.inline.InlinePresentationSpec.Builder( - widget.getMinSize(), widget.getMaxSize()); - final Bundle style = widget.getStyle(); - if (style != null) { - builder.setStyle(style); - } - return builder.build(); - } - - /** - * @hide - */ - public static List<android.view.inline.InlinePresentationSpec> fromWidgets( - List<android.widget.inline.InlinePresentationSpec> widgets) { - final ArrayList<android.view.inline.InlinePresentationSpec> convertedSpecs = - new ArrayList<>(); - for (int i = 0; i < widgets.size(); i++) { - convertedSpecs.add(fromWidget(widgets.get(i))); - } - return convertedSpecs; - } - - - - // Code below generated by codegen v1.0.15. - // - // DO NOT MODIFY! - // CHECKSTYLE:OFF Generated code - // - // To regenerate run: - // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/view/inline/InlinePresentationSpec.java - // - // To exclude the generated code from IntelliJ auto-formatting enable (one-time): - // Settings > Editor > Code Style > Formatter Control - //@formatter:off - - - @DataClass.Generated.Member - /* package-private */ InlinePresentationSpec( - @NonNull Size minSize, - @NonNull Size maxSize, - @NonNull Bundle style) { - this.mMinSize = minSize; - com.android.internal.util.AnnotationValidations.validate( - NonNull.class, null, mMinSize); - this.mMaxSize = maxSize; - com.android.internal.util.AnnotationValidations.validate( - NonNull.class, null, mMaxSize); - this.mStyle = style; - com.android.internal.util.AnnotationValidations.validate( - NonNull.class, null, mStyle); - - // onConstructed(); // You can define this method to get a callback - } - - /** - * The minimal size of the suggestion. - */ - @UnsupportedAppUsage - @DataClass.Generated.Member - public @NonNull Size getMinSize() { - return mMinSize; - } - - /** - * The maximal size of the suggestion. - */ - @UnsupportedAppUsage - @DataClass.Generated.Member - public @NonNull Size getMaxSize() { - return mMaxSize; - } - - /** - * The extras encoding the UI style information. Defaults to {@code Bundle.EMPTY} in which case - * the default system UI style will be used. - */ - @DataClass.Generated.Member - public @NonNull Bundle getStyle() { - return mStyle; - } - - @Override - @DataClass.Generated.Member - public String toString() { - // You can override field toString logic by defining methods like: - // String fieldNameToString() { ... } - - return "InlinePresentationSpec { " + - "minSize = " + mMinSize + ", " + - "maxSize = " + mMaxSize + ", " + - "style = " + mStyle + - " }"; - } - - @Override - @DataClass.Generated.Member - public boolean equals(@Nullable Object o) { - // You can override field equality logic by defining either of the methods like: - // boolean fieldNameEquals(InlinePresentationSpec other) { ... } - // boolean fieldNameEquals(FieldType otherValue) { ... } - - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - @SuppressWarnings("unchecked") - InlinePresentationSpec that = (InlinePresentationSpec) o; - //noinspection PointlessBooleanExpression - return true - && java.util.Objects.equals(mMinSize, that.mMinSize) - && java.util.Objects.equals(mMaxSize, that.mMaxSize) - && java.util.Objects.equals(mStyle, that.mStyle); - } - - @Override - @DataClass.Generated.Member - public int hashCode() { - // You can override field hashCode logic by defining methods like: - // int fieldNameHashCode() { ... } - - int _hash = 1; - _hash = 31 * _hash + java.util.Objects.hashCode(mMinSize); - _hash = 31 * _hash + java.util.Objects.hashCode(mMaxSize); - _hash = 31 * _hash + java.util.Objects.hashCode(mStyle); - return _hash; - } - - @Override - @DataClass.Generated.Member - public void writeToParcel(@NonNull android.os.Parcel dest, int flags) { - // You can override field parcelling by defining methods like: - // void parcelFieldName(Parcel dest, int flags) { ... } - - dest.writeSize(mMinSize); - dest.writeSize(mMaxSize); - dest.writeBundle(mStyle); - } - - @Override - @DataClass.Generated.Member - public int describeContents() { return 0; } - - /** @hide */ - @SuppressWarnings({"unchecked", "RedundantCast"}) - @DataClass.Generated.Member - /* package-private */ InlinePresentationSpec(@NonNull android.os.Parcel in) { - // You can override field unparcelling by defining methods like: - // static FieldType unparcelFieldName(Parcel in) { ... } - - Size minSize = (Size) in.readSize(); - Size maxSize = (Size) in.readSize(); - Bundle style = in.readBundle(); - - this.mMinSize = minSize; - com.android.internal.util.AnnotationValidations.validate( - NonNull.class, null, mMinSize); - this.mMaxSize = maxSize; - com.android.internal.util.AnnotationValidations.validate( - NonNull.class, null, mMaxSize); - this.mStyle = style; - com.android.internal.util.AnnotationValidations.validate( - NonNull.class, null, mStyle); - - // onConstructed(); // You can define this method to get a callback - } - - @DataClass.Generated.Member - public static final @NonNull Parcelable.Creator<InlinePresentationSpec> CREATOR - = new Parcelable.Creator<InlinePresentationSpec>() { - @Override - public InlinePresentationSpec[] newArray(int size) { - return new InlinePresentationSpec[size]; - } - - @Override - public InlinePresentationSpec createFromParcel(@NonNull android.os.Parcel in) { - return new InlinePresentationSpec(in); - } - }; - - /** - * A builder for {@link InlinePresentationSpec} - */ - @SuppressWarnings("WeakerAccess") - @DataClass.Generated.Member - public static final class Builder extends BaseBuilder { - - private @NonNull Size mMinSize; - private @NonNull Size mMaxSize; - private @NonNull Bundle mStyle; - - private long mBuilderFieldsSet = 0L; - - /** - * Creates a new Builder. - * - * @param minSize - * The minimal size of the suggestion. - * @param maxSize - * The maximal size of the suggestion. - */ - @UnsupportedAppUsage - public Builder( - @NonNull Size minSize, - @NonNull Size maxSize) { - mMinSize = minSize; - com.android.internal.util.AnnotationValidations.validate( - NonNull.class, null, mMinSize); - mMaxSize = maxSize; - com.android.internal.util.AnnotationValidations.validate( - NonNull.class, null, mMaxSize); - } - - /** - * The extras encoding the UI style information. Defaults to {@code Bundle.EMPTY} in which case - * the default system UI style will be used. - */ - @DataClass.Generated.Member - public @NonNull Builder setStyle(@NonNull Bundle value) { - checkNotUsed(); - mBuilderFieldsSet |= 0x4; - mStyle = value; - return this; - } - - /** Builds the instance. This builder should not be touched after calling this! */ - @UnsupportedAppUsage - @NonNull - public InlinePresentationSpec build() { - checkNotUsed(); - mBuilderFieldsSet |= 0x8; // Mark builder used - - if ((mBuilderFieldsSet & 0x4) == 0) { - mStyle = defaultStyle(); - } - InlinePresentationSpec o = new InlinePresentationSpec( - mMinSize, - mMaxSize, - mStyle); - return o; - } - - private void checkNotUsed() { - if ((mBuilderFieldsSet & 0x8) != 0) { - throw new IllegalStateException( - "This Builder should not be reused. Use a new Builder instance instead"); - } - } - } - - @DataClass.Generated( - time = 1585691139012L, - codegenVersion = "1.0.15", - sourceFile = "frameworks/base/core/java/android/view/inline/InlinePresentationSpec.java", - inputSignatures = "private final @android.annotation.NonNull android.util.Size mMinSize\nprivate final @android.annotation.NonNull android.util.Size mMaxSize\nprivate final @android.annotation.NonNull android.os.Bundle mStyle\nprivate static android.os.Bundle defaultStyle()\npublic android.widget.inline.InlinePresentationSpec toWidget()\npublic static android.view.inline.InlinePresentationSpec fromWidget(android.widget.inline.InlinePresentationSpec)\npublic static java.util.List<android.view.inline.InlinePresentationSpec> fromWidgets(java.util.List<android.widget.inline.InlinePresentationSpec>)\nclass InlinePresentationSpec extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genEqualsHashCode=true, genToString=true, genBuilder=true)\nclass BaseBuilder extends java.lang.Object implements []") - @Deprecated - private void __metadata() {} - - - //@formatter:on - // End of generated code - -} diff --git a/core/java/android/view/inputmethod/InlineSuggestionInfo.java b/core/java/android/view/inputmethod/InlineSuggestionInfo.java index 3e9ffa7787f6..1c703ecf06ca 100644 --- a/core/java/android/view/inputmethod/InlineSuggestionInfo.java +++ b/core/java/android/view/inputmethod/InlineSuggestionInfo.java @@ -20,7 +20,6 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SuppressLint; import android.annotation.TestApi; -import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcelable; import android.widget.inline.InlinePresentationSpec; @@ -87,17 +86,6 @@ public final class InlineSuggestionInfo implements Parcelable { return new InlineSuggestionInfo(presentationSpec, source, autofillHints, type, isPinned); } - /** - * The presentation spec to which the inflated suggestion view abides. - * - * @hide - * @removed - */ - @UnsupportedAppUsage - public @NonNull android.view.inline.InlinePresentationSpec getPresentationSpec() { - return android.view.inline.InlinePresentationSpec.fromWidget(mInlinePresentationSpec); - } - // Code below generated by codegen v1.0.15. @@ -358,10 +346,10 @@ public final class InlineSuggestionInfo implements Parcelable { }; @DataClass.Generated( - time = 1585633580662L, + time = 1586992414034L, codegenVersion = "1.0.15", sourceFile = "frameworks/base/core/java/android/view/inputmethod/InlineSuggestionInfo.java", - inputSignatures = "public static final @android.view.inputmethod.InlineSuggestionInfo.Source java.lang.String SOURCE_AUTOFILL\npublic static final @android.view.inputmethod.InlineSuggestionInfo.Source java.lang.String SOURCE_PLATFORM\npublic static final @android.view.inputmethod.InlineSuggestionInfo.Type java.lang.String TYPE_SUGGESTION\npublic static final @android.annotation.SuppressLint({\"IntentName\"}) @android.view.inputmethod.InlineSuggestionInfo.Type java.lang.String TYPE_ACTION\nprivate final @android.annotation.NonNull android.widget.inline.InlinePresentationSpec mInlinePresentationSpec\nprivate final @android.annotation.NonNull @android.view.inputmethod.InlineSuggestionInfo.Source java.lang.String mSource\nprivate final @android.annotation.Nullable java.lang.String[] mAutofillHints\nprivate final @android.annotation.NonNull @android.view.inputmethod.InlineSuggestionInfo.Type java.lang.String mType\nprivate final boolean mPinned\npublic static @android.annotation.TestApi @android.annotation.NonNull android.view.inputmethod.InlineSuggestionInfo newInlineSuggestionInfo(android.widget.inline.InlinePresentationSpec,java.lang.String,java.lang.String[],java.lang.String,boolean)\npublic @android.compat.annotation.UnsupportedAppUsage @android.annotation.NonNull android.view.inline.InlinePresentationSpec getPresentationSpec()\nclass InlineSuggestionInfo extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genEqualsHashCode=true, genToString=true, genHiddenConstDefs=true, genHiddenConstructor=true)") + inputSignatures = "public static final @android.view.inputmethod.InlineSuggestionInfo.Source java.lang.String SOURCE_AUTOFILL\npublic static final @android.view.inputmethod.InlineSuggestionInfo.Source java.lang.String SOURCE_PLATFORM\npublic static final @android.view.inputmethod.InlineSuggestionInfo.Type java.lang.String TYPE_SUGGESTION\npublic static final @android.annotation.SuppressLint({\"IntentName\"}) @android.view.inputmethod.InlineSuggestionInfo.Type java.lang.String TYPE_ACTION\nprivate final @android.annotation.NonNull android.widget.inline.InlinePresentationSpec mInlinePresentationSpec\nprivate final @android.annotation.NonNull @android.view.inputmethod.InlineSuggestionInfo.Source java.lang.String mSource\nprivate final @android.annotation.Nullable java.lang.String[] mAutofillHints\nprivate final @android.annotation.NonNull @android.view.inputmethod.InlineSuggestionInfo.Type java.lang.String mType\nprivate final boolean mPinned\npublic static @android.annotation.TestApi @android.annotation.NonNull android.view.inputmethod.InlineSuggestionInfo newInlineSuggestionInfo(android.widget.inline.InlinePresentationSpec,java.lang.String,java.lang.String[],java.lang.String,boolean)\nclass InlineSuggestionInfo extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genEqualsHashCode=true, genToString=true, genHiddenConstDefs=true, genHiddenConstructor=true)") @Deprecated private void __metadata() {} diff --git a/core/java/android/view/inputmethod/InlineSuggestionsRequest.java b/core/java/android/view/inputmethod/InlineSuggestionsRequest.java index af896fca932a..d282b56aedb6 100644 --- a/core/java/android/view/inputmethod/InlineSuggestionsRequest.java +++ b/core/java/android/view/inputmethod/InlineSuggestionsRequest.java @@ -19,7 +19,6 @@ package android.view.inputmethod; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.ActivityThread; -import android.compat.annotation.UnsupportedAppUsage; import android.os.Bundle; import android.os.IBinder; import android.os.LocaleList; @@ -93,20 +92,6 @@ public final class InlineSuggestionsRequest implements Parcelable { private int mHostDisplayId; /** - * The {@link InlinePresentationSpec} for each suggestion in the response. If the max suggestion - * count is larger than the number of specs in the list, then the last spec is used for the - * remainder of the suggestions. The list should not be empty. - * - * @hide - * @removed - */ - @UnsupportedAppUsage - @NonNull - public List<android.view.inline.InlinePresentationSpec> getPresentationSpecs() { - return android.view.inline.InlinePresentationSpec.fromWidgets(mInlinePresentationSpecs); - } - - /** * @hide * @see {@link #mHostInputToken}. */ @@ -170,17 +155,6 @@ public final class InlineSuggestionsRequest implements Parcelable { /** @hide */ abstract static class BaseBuilder { - /** - * @hide - * @removed - */ - @UnsupportedAppUsage - @NonNull - public Builder addPresentationSpecs( - @NonNull android.view.inline.InlinePresentationSpec value) { - return ((Builder) this).addInlinePresentationSpecs(value.toWidget()); - } - abstract Builder setInlinePresentationSpecs( @NonNull List<android.widget.inline.InlinePresentationSpec> specs); @@ -608,10 +582,10 @@ public final class InlineSuggestionsRequest implements Parcelable { } @DataClass.Generated( - time = 1585768018462L, + time = 1586992395497L, codegenVersion = "1.0.15", sourceFile = "frameworks/base/core/java/android/view/inputmethod/InlineSuggestionsRequest.java", - inputSignatures = "public static final int SUGGESTION_COUNT_UNLIMITED\nprivate final int mMaxSuggestionCount\nprivate final @android.annotation.NonNull java.util.List<android.widget.inline.InlinePresentationSpec> mInlinePresentationSpecs\nprivate @android.annotation.NonNull java.lang.String mHostPackageName\nprivate @android.annotation.NonNull android.os.LocaleList mSupportedLocales\nprivate @android.annotation.NonNull android.os.Bundle mExtras\nprivate @android.annotation.Nullable android.os.IBinder mHostInputToken\nprivate int mHostDisplayId\npublic @android.compat.annotation.UnsupportedAppUsage @android.annotation.NonNull java.util.List<android.view.inline.InlinePresentationSpec> getPresentationSpecs()\npublic void setHostInputToken(android.os.IBinder)\nprivate boolean extrasEquals(android.os.Bundle)\nprivate void parcelHostInputToken(android.os.Parcel,int)\nprivate @android.annotation.Nullable android.os.IBinder unparcelHostInputToken(android.os.Parcel)\npublic void setHostDisplayId(int)\nprivate void onConstructed()\nprivate static int defaultMaxSuggestionCount()\nprivate static java.lang.String defaultHostPackageName()\nprivate static android.os.LocaleList defaultSupportedLocales()\nprivate static @android.annotation.Nullable android.os.IBinder defaultHostInputToken()\nprivate static @android.annotation.Nullable int defaultHostDisplayId()\nprivate static @android.annotation.NonNull android.os.Bundle defaultExtras()\nclass InlineSuggestionsRequest extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genEqualsHashCode=true, genToString=true, genBuilder=true)\npublic @android.compat.annotation.UnsupportedAppUsage @android.annotation.NonNull android.view.inputmethod.InlineSuggestionsRequest.Builder addPresentationSpecs(android.view.inline.InlinePresentationSpec)\nabstract android.view.inputmethod.InlineSuggestionsRequest.Builder setInlinePresentationSpecs(java.util.List<android.widget.inline.InlinePresentationSpec>)\nabstract android.view.inputmethod.InlineSuggestionsRequest.Builder setHostPackageName(java.lang.String)\nabstract android.view.inputmethod.InlineSuggestionsRequest.Builder setHostInputToken(android.os.IBinder)\nabstract android.view.inputmethod.InlineSuggestionsRequest.Builder setHostDisplayId(int)\nclass BaseBuilder extends java.lang.Object implements []") + inputSignatures = "public static final int SUGGESTION_COUNT_UNLIMITED\nprivate final int mMaxSuggestionCount\nprivate final @android.annotation.NonNull java.util.List<android.widget.inline.InlinePresentationSpec> mInlinePresentationSpecs\nprivate @android.annotation.NonNull java.lang.String mHostPackageName\nprivate @android.annotation.NonNull android.os.LocaleList mSupportedLocales\nprivate @android.annotation.NonNull android.os.Bundle mExtras\nprivate @android.annotation.Nullable android.os.IBinder mHostInputToken\nprivate int mHostDisplayId\npublic void setHostInputToken(android.os.IBinder)\nprivate boolean extrasEquals(android.os.Bundle)\nprivate void parcelHostInputToken(android.os.Parcel,int)\nprivate @android.annotation.Nullable android.os.IBinder unparcelHostInputToken(android.os.Parcel)\npublic void setHostDisplayId(int)\nprivate void onConstructed()\nprivate static int defaultMaxSuggestionCount()\nprivate static java.lang.String defaultHostPackageName()\nprivate static android.os.LocaleList defaultSupportedLocales()\nprivate static @android.annotation.Nullable android.os.IBinder defaultHostInputToken()\nprivate static @android.annotation.Nullable int defaultHostDisplayId()\nprivate static @android.annotation.NonNull android.os.Bundle defaultExtras()\nclass InlineSuggestionsRequest extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genEqualsHashCode=true, genToString=true, genBuilder=true)\nabstract android.view.inputmethod.InlineSuggestionsRequest.Builder setInlinePresentationSpecs(java.util.List<android.widget.inline.InlinePresentationSpec>)\nabstract android.view.inputmethod.InlineSuggestionsRequest.Builder setHostPackageName(java.lang.String)\nabstract android.view.inputmethod.InlineSuggestionsRequest.Builder setHostInputToken(android.os.IBinder)\nabstract android.view.inputmethod.InlineSuggestionsRequest.Builder setHostDisplayId(int)\nclass BaseBuilder extends java.lang.Object implements []") @Deprecated private void __metadata() {} diff --git a/core/java/com/android/internal/accessibility/AccessibilityShortcutController.java b/core/java/com/android/internal/accessibility/AccessibilityShortcutController.java index d64b5f1118dc..be66d0c238cc 100644 --- a/core/java/com/android/internal/accessibility/AccessibilityShortcutController.java +++ b/core/java/com/android/internal/accessibility/AccessibilityShortcutController.java @@ -232,9 +232,8 @@ public class AccessibilityShortcutController { } /** - * Show toast if current assigned shortcut target is an accessibility service and its target - * sdk version is less than or equal to Q, or greater than Q and does not request - * accessibility button. + * Show toast to alert the user that the accessibility shortcut turned on or off an + * accessibility service. */ private void showToast() { final AccessibilityServiceInfo serviceInfo = getInfoForTargetService(); @@ -247,12 +246,15 @@ public class AccessibilityShortcutController { } final boolean requestA11yButton = (serviceInfo.flags & AccessibilityServiceInfo.FLAG_REQUEST_ACCESSIBILITY_BUTTON) != 0; - if (serviceInfo.getResolveInfo().serviceInfo.applicationInfo - .targetSdkVersion > Build.VERSION_CODES.Q && requestA11yButton) { + final boolean isServiceEnabled = isServiceEnabled(serviceInfo); + if (serviceInfo.getResolveInfo().serviceInfo.applicationInfo.targetSdkVersion + > Build.VERSION_CODES.Q && requestA11yButton && isServiceEnabled) { + // An accessibility button callback is sent to the target accessibility service. + // No need to show up a toast in this case. return; } // For accessibility services, show a toast explaining what we're doing. - String toastMessageFormatString = mContext.getString(isServiceEnabled(serviceInfo) + String toastMessageFormatString = mContext.getString(isServiceEnabled ? R.string.accessibility_shortcut_disabling_service : R.string.accessibility_shortcut_enabling_service); String toastMessage = String.format(toastMessageFormatString, serviceName); diff --git a/core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java b/core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java index d43333e507a6..b81e47303a9d 100644 --- a/core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java +++ b/core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java @@ -429,16 +429,16 @@ public abstract class AbstractMultiProfilePagerAdapter extends PagerAdapter { subtitle.setVisibility(View.GONE); } - ImageView icon = emptyStateView.findViewById(R.id.resolver_empty_state_icon); Button button = emptyStateView.findViewById(R.id.resolver_empty_state_button); + button.setVisibility(buttonOnClick != null ? View.VISIBLE : View.GONE); + button.setOnClickListener(buttonOnClick); + + ImageView icon = emptyStateView.findViewById(R.id.resolver_empty_state_icon); if (!getContext().getResources().getBoolean(R.bool.resolver_landscape_phone)) { icon.setVisibility(View.VISIBLE); icon.setImageResource(iconRes); - button.setVisibility(buttonOnClick != null ? View.VISIBLE : View.GONE); - button.setOnClickListener(buttonOnClick); } else { icon.setVisibility(View.GONE); - button.setVisibility(View.GONE); } activeListAdapter.markTabLoaded(); 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/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/app/procstats/DumpUtils.java b/core/java/com/android/internal/app/procstats/DumpUtils.java index eda04a6a322a..ea41618a982f 100644 --- a/core/java/com/android/internal/app/procstats/DumpUtils.java +++ b/core/java/com/android/internal/app/procstats/DumpUtils.java @@ -16,14 +16,39 @@ package com.android.internal.app.procstats; +import static com.android.internal.app.procstats.ProcessStats.ADJ_COUNT; +import static com.android.internal.app.procstats.ProcessStats.ADJ_MEM_FACTOR_COUNT; +import static com.android.internal.app.procstats.ProcessStats.ADJ_MEM_FACTOR_CRITICAL; +import static com.android.internal.app.procstats.ProcessStats.ADJ_MEM_FACTOR_LOW; +import static com.android.internal.app.procstats.ProcessStats.ADJ_MEM_FACTOR_MODERATE; +import static com.android.internal.app.procstats.ProcessStats.ADJ_MEM_FACTOR_NORMAL; +import static com.android.internal.app.procstats.ProcessStats.ADJ_NOTHING; +import static com.android.internal.app.procstats.ProcessStats.ADJ_SCREEN_MOD; +import static com.android.internal.app.procstats.ProcessStats.ADJ_SCREEN_OFF; +import static com.android.internal.app.procstats.ProcessStats.ADJ_SCREEN_ON; +import static com.android.internal.app.procstats.ProcessStats.STATE_BACKUP; +import static com.android.internal.app.procstats.ProcessStats.STATE_CACHED_ACTIVITY; +import static com.android.internal.app.procstats.ProcessStats.STATE_CACHED_ACTIVITY_CLIENT; +import static com.android.internal.app.procstats.ProcessStats.STATE_CACHED_EMPTY; +import static com.android.internal.app.procstats.ProcessStats.STATE_COUNT; +import static com.android.internal.app.procstats.ProcessStats.STATE_HEAVY_WEIGHT; +import static com.android.internal.app.procstats.ProcessStats.STATE_HOME; +import static com.android.internal.app.procstats.ProcessStats.STATE_IMPORTANT_BACKGROUND; +import static com.android.internal.app.procstats.ProcessStats.STATE_IMPORTANT_FOREGROUND; +import static com.android.internal.app.procstats.ProcessStats.STATE_LAST_ACTIVITY; +import static com.android.internal.app.procstats.ProcessStats.STATE_NOTHING; +import static com.android.internal.app.procstats.ProcessStats.STATE_PERSISTENT; +import static com.android.internal.app.procstats.ProcessStats.STATE_RECEIVER; +import static com.android.internal.app.procstats.ProcessStats.STATE_SERVICE; +import static com.android.internal.app.procstats.ProcessStats.STATE_SERVICE_RESTARTING; +import static com.android.internal.app.procstats.ProcessStats.STATE_TOP; + import android.os.UserHandle; import android.service.procstats.ProcessStatsEnums; import android.service.procstats.ProcessStatsStateProto; import android.util.TimeUtils; import android.util.proto.ProtoOutputStream; -import static com.android.internal.app.procstats.ProcessStats.*; - import java.io.PrintWriter; import java.util.ArrayList; @@ -38,6 +63,7 @@ public final class DumpUtils { public static final String[] STATE_NAMES_CSV; static final String[] STATE_TAGS; static final int[] STATE_PROTO_ENUMS; + private static final int[] PROCESS_STATS_STATE_TO_AGGREGATED_STATE; // Make the mapping easy to update. static { @@ -126,6 +152,39 @@ public final class DumpUtils { STATE_PROTO_ENUMS[STATE_CACHED_ACTIVITY_CLIENT] = ProcessStatsEnums.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; STATE_PROTO_ENUMS[STATE_CACHED_EMPTY] = ProcessStatsEnums.PROCESS_STATE_CACHED_EMPTY; + + // Remap states, as defined by ProcessStats.java, to a reduced subset of states for data + // aggregation / size reduction purposes. + PROCESS_STATS_STATE_TO_AGGREGATED_STATE = new int[STATE_COUNT]; + PROCESS_STATS_STATE_TO_AGGREGATED_STATE[STATE_PERSISTENT] = + ProcessStatsEnums.AGGREGATED_PROCESS_STATE_PERSISTENT; + PROCESS_STATS_STATE_TO_AGGREGATED_STATE[STATE_TOP] = + ProcessStatsEnums.AGGREGATED_PROCESS_STATE_TOP; + PROCESS_STATS_STATE_TO_AGGREGATED_STATE[STATE_IMPORTANT_FOREGROUND] = + ProcessStatsEnums.AGGREGATED_PROCESS_STATE_IMPORTANT_FOREGROUND; + PROCESS_STATS_STATE_TO_AGGREGATED_STATE[STATE_IMPORTANT_BACKGROUND] = + ProcessStatsEnums.AGGREGATED_PROCESS_STATE_BACKGROUND; + PROCESS_STATS_STATE_TO_AGGREGATED_STATE[STATE_BACKUP] = + ProcessStatsEnums.AGGREGATED_PROCESS_STATE_BACKGROUND; + PROCESS_STATS_STATE_TO_AGGREGATED_STATE[STATE_SERVICE] = + ProcessStatsEnums.AGGREGATED_PROCESS_STATE_BACKGROUND; + // "Restarting" is not a real state, so this shouldn't exist. + PROCESS_STATS_STATE_TO_AGGREGATED_STATE[STATE_SERVICE_RESTARTING] = + ProcessStatsEnums.AGGREGATED_PROCESS_STATE_UNKNOWN; + PROCESS_STATS_STATE_TO_AGGREGATED_STATE[STATE_RECEIVER] = + ProcessStatsEnums.AGGREGATED_PROCESS_STATE_RECEIVER; + PROCESS_STATS_STATE_TO_AGGREGATED_STATE[STATE_HEAVY_WEIGHT] = + ProcessStatsEnums.AGGREGATED_PROCESS_STATE_BACKGROUND; + PROCESS_STATS_STATE_TO_AGGREGATED_STATE[STATE_HOME] = + ProcessStatsEnums.AGGREGATED_PROCESS_STATE_CACHED; + PROCESS_STATS_STATE_TO_AGGREGATED_STATE[STATE_LAST_ACTIVITY] = + ProcessStatsEnums.AGGREGATED_PROCESS_STATE_CACHED; + PROCESS_STATS_STATE_TO_AGGREGATED_STATE[STATE_CACHED_ACTIVITY] = + ProcessStatsEnums.AGGREGATED_PROCESS_STATE_CACHED; + PROCESS_STATS_STATE_TO_AGGREGATED_STATE[STATE_CACHED_ACTIVITY_CLIENT] = + ProcessStatsEnums.AGGREGATED_PROCESS_STATE_CACHED; + PROCESS_STATS_STATE_TO_AGGREGATED_STATE[STATE_CACHED_EMPTY] = + ProcessStatsEnums.AGGREGATED_PROCESS_STATE_CACHED; } public static final String[] ADJ_SCREEN_NAMES_CSV = new String[] { @@ -455,4 +514,29 @@ public final class DumpUtils { } return itemName; } + + /** + * Aggregate process states to reduce size of statistics logs. + * + * <p>Involves unpacking the three parts of state (process state / device memory state / + * screen state), manipulating the elements, then re-packing the new values into a single + * int. This integer is guaranteed to be unique for any given combination of state elements. + * + * @param curState current state as used in mCurState in {@class ProcessState} ie. a value + * combined from the process's state, the device's memory pressure state, and + * the device's screen on/off state. + * @return an integer representing the combination of screen state and process state, where + * process state has been aggregated. + */ + public static int aggregateCurrentProcessState(int curState) { + int screenStateIndex = curState / (ADJ_SCREEN_MOD * STATE_COUNT); + // extract process state from the compound state variable (discarding memory state) + int procStateIndex = curState % STATE_COUNT; + + // Remap process state per array above. + procStateIndex = PROCESS_STATS_STATE_TO_AGGREGATED_STATE[procStateIndex]; + + // Pack screen & process state using bit shifting + return (procStateIndex << 8) | screenStateIndex; + } } 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/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/proto/android/server/windowmanagerservice.proto b/core/proto/android/server/windowmanagerservice.proto index 60892557891b..55ea3159c44c 100644 --- a/core/proto/android/server/windowmanagerservice.proto +++ b/core/proto/android/server/windowmanagerservice.proto @@ -250,7 +250,7 @@ message TaskProto { reserved 3; // activity optional bool fills_parent = 4; optional .android.graphics.RectProto bounds = 5; - optional .android.graphics.RectProto displayed_bounds = 6; + optional .android.graphics.RectProto displayed_bounds = 6 [deprecated=true]; optional bool defer_removal = 7; optional int32 surface_width = 8; optional int32 surface_height = 9; diff --git a/core/proto/android/service/procstats_enum.proto b/core/proto/android/service/procstats_enum.proto index cc3fe5af775b..2abf3730aa9f 100644 --- a/core/proto/android/service/procstats_enum.proto +++ b/core/proto/android/service/procstats_enum.proto @@ -76,3 +76,27 @@ enum ServiceOperationState { SERVICE_OPERATION_STATE_BOUND = 4; SERVICE_OPERATION_STATE_EXECUTING = 5; } + +// this enum list is from frameworks/base/core/java/com/android/internal/app/procstats/ProcessStats.java +// and not frameworks/base/core/java/android/app/ActivityManager.java +enum AggregatedProcessState { + AGGREGATED_PROCESS_STATE_UNKNOWN = 0; + // Persistent system process; PERSISTENT or PERSISTENT_UI in ActivityManager + AGGREGATED_PROCESS_STATE_PERSISTENT = 1; + // Top activity; actually any visible activity; TOP or TOP_SLEEPING in ActivityManager + AGGREGATED_PROCESS_STATE_TOP = 2; + // Bound top foreground process; BOUND_TOP or BOUND_FOREGROUND_SERVICE in ActivityManager + AGGREGATED_PROCESS_STATE_BOUND_TOP_OR_FGS = 3; + // Important foreground process; FOREGROUND_SERVICE in ActivityManager + AGGREGATED_PROCESS_STATE_FGS = 4; + // Important foreground process ; IMPORTANT_FOREGROUND in ActivityManager + AGGREGATED_PROCESS_STATE_IMPORTANT_FOREGROUND = 5; + // Various background processes; IMPORTANT_BACKGROUND, TRANSIENT_BACKGROUND, BACKUP, SERVICE, + // HEAVY_WEIGHT in ActivityManager + AGGREGATED_PROCESS_STATE_BACKGROUND = 6; + // Process running a receiver; RECEIVER in ActivityManager + AGGREGATED_PROCESS_STATE_RECEIVER = 7; + // Various cached processes; HOME, LAST_ACTIVITY, CACHED_ACTIVITY, CACHED_RECENT, + // CACHED_ACTIVITY_CLIENT, CACHED_EMPTY in ActivityManager + AGGREGATED_PROCESS_STATE_CACHED = 8; +}
\ No newline at end of file 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/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 5317c8bd238e..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" /> @@ -3938,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/accessibility/AccessibilityShortcutControllerTest.java b/core/tests/coretests/src/com/android/internal/accessibility/AccessibilityShortcutControllerTest.java index 4a33da680585..b21504c73772 100644 --- a/core/tests/coretests/src/com/android/internal/accessibility/AccessibilityShortcutControllerTest.java +++ b/core/tests/coretests/src/com/android/internal/accessibility/AccessibilityShortcutControllerTest.java @@ -462,6 +462,7 @@ public class AccessibilityShortcutControllerTest { configureValidShortcutService(); configureApplicationTargetSdkVersion(Build.VERSION_CODES.R); configureRequestAccessibilityButton(); + configureEnabledService(); Settings.Secure.putInt(mContentResolver, ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN, 1); getController().performAccessibilityShortcut(); @@ -610,6 +611,11 @@ public class AccessibilityShortcutControllerTest { }).when(mHandler).sendMessageAtTime(any(), anyLong()); } + private void configureEnabledService() throws Exception { + when(mAccessibilityManagerService.getEnabledAccessibilityServiceList(anyInt(), anyInt())) + .thenReturn(Collections.singletonList(mServiceInfo)); + } + private AccessibilityShortcutController getController() { AccessibilityShortcutController accessibilityShortcutController = new AccessibilityShortcutController(mContext, mHandler, 0); 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/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/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/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/core/java/android/view/inline/InlinePresentationSpec.aidl b/media/tests/AudioPolicyTest/src/com/android/audiopolicytest/AudioPolicyTest.java index 680ee4e14b54..e0c7b223a2e4 100644 --- a/core/java/android/view/inline/InlinePresentationSpec.aidl +++ b/media/tests/AudioPolicyTest/src/com/android/audiopolicytest/AudioPolicyTest.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,10 +14,25 @@ * limitations under the License. */ -package android.view.inline; +package com.android.audiopolicytest; -/** - * @hide - * @removed - */ -parcelable InlinePresentationSpec; +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/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/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/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/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/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/notification_conversation_info.xml b/packages/SystemUI/res/layout/notification_conversation_info.xml index 9dc502efab43..f8a96e79d027 100644 --- a/packages/SystemUI/res/layout/notification_conversation_info.xml +++ b/packages/SystemUI/res/layout/notification_conversation_info.xml @@ -108,7 +108,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" - style="@style/TextAppearance.NotificationImportanceChannel"/> + style="@style/TextAppearance.NotificationImportanceChannelGroup"/> </LinearLayout> <TextView android:id="@+id/delegate_name" diff --git a/packages/SystemUI/res/layout/notification_info.xml b/packages/SystemUI/res/layout/notification_info.xml index 5b363820e4e2..e8e0133103eb 100644 --- a/packages/SystemUI/res/layout/notification_info.xml +++ b/packages/SystemUI/res/layout/notification_info.xml @@ -84,7 +84,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" - style="@style/TextAppearance.NotificationImportanceChannel"/> + style="@style/TextAppearance.NotificationImportanceChannelGroup"/> </LinearLayout> <TextView android:id="@+id/delegate_name" 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..7861211e802d 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()); } }; @@ -945,7 +948,12 @@ public class ScreenDecorations extends SystemUI implements Tunable { int dw = flipped ? lh : lw; int dh = flipped ? lw : lh; - mBoundingPath.set(DisplayCutout.pathFromResources(getResources(), dw, dh)); + Path path = DisplayCutout.pathFromResources(getResources(), dw, dh); + if (path != null) { + mBoundingPath.set(path); + } else { + mBoundingPath.reset(); + } Matrix m = new Matrix(); transformPhysicalToLogicalCoordinates(mInfo.rotation, dw, dh, m); mBoundingPath.transform(m); diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthCredentialPasswordView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthCredentialPasswordView.java index d8a11d36a335..e6a62c26712a 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthCredentialPasswordView.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthCredentialPasswordView.java @@ -17,6 +17,7 @@ package com.android.systemui.biometrics; import android.content.Context; +import android.os.UserHandle; import android.text.InputType; import android.util.AttributeSet; import android.view.KeyEvent; @@ -68,6 +69,7 @@ public class AuthCredentialPasswordView extends AuthCredentialView protected void onAttachedToWindow() { super.onAttachedToWindow(); + mPasswordField.setTextOperationUser(UserHandle.of(mUserId)); if (mCredentialType == Utils.CREDENTIAL_PIN) { mPasswordField.setInputType( InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_VARIATION_PASSWORD); diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthCredentialView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthCredentialView.java index 8bf259182544..496e60ddf99e 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthCredentialView.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthCredentialView.java @@ -286,6 +286,7 @@ public abstract class AuthCredentialView extends LinearLayout { if (matched) { mClearErrorRunnable.run(); + mLockPatternUtils.userPresent(mEffectiveUserId); mCallback.onCredentialMatched(attestation); } else { if (timeoutMs > 0) { diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java index da5c2968c6ac..c8e9a687ad23 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java @@ -108,7 +108,6 @@ import java.io.PrintWriter; import java.lang.annotation.Retention; import java.lang.annotation.Target; import java.util.ArrayList; -import java.util.HashSet; import java.util.List; /** @@ -162,14 +161,6 @@ public class BubbleController implements ConfigurationController.ConfigurationLi // Used when ranking updates occur and we check if things should bubble / unbubble private NotificationListenerService.Ranking mTmpRanking; - // Saves notification keys of user created "fake" bubbles so that we can allow notifications - // like these to bubble by default. Doesn't persist across reboots, not a long-term solution. - private final HashSet<String> mUserCreatedBubbles; - // If we're auto-bubbling bubbles via a whitelist, we need to track which notifs from that app - // have been "demoted" back to a notification so that we don't auto-bubbles those again. - // Doesn't persist across reboots, not a long-term solution. - private final HashSet<String> mUserBlockedBubbles; - // Bubbles get added to the status bar view private final NotificationShadeWindowController mNotificationShadeWindowController; private final ZenModeController mZenModeController; @@ -412,9 +403,6 @@ public class BubbleController implements ConfigurationController.ConfigurationLi } }); - mUserCreatedBubbles = new HashSet<>(); - mUserBlockedBubbles = new HashSet<>(); - mBubbleIconFactory = new BubbleIconFactory(context); } @@ -474,8 +462,7 @@ public class BubbleController implements ConfigurationController.ConfigurationLi (entry != null && entry.isRowDismissed() && !isAppCancel) || isClearAll || isUserDimiss || isSummaryCancel; - if (userRemovedNotif || isUserCreatedBubble(key) - || isSummaryOfUserCreatedBubble(entry)) { + if (userRemovedNotif) { return handleDismissalInterception(entry); } @@ -860,27 +847,6 @@ public class BubbleController implements ConfigurationController.ConfigurationLi } /** - * Whether this bubble was explicitly created by the user via a SysUI affordance. - */ - boolean isUserCreatedBubble(String key) { - return mUserCreatedBubbles.contains(key); - } - - boolean isSummaryOfUserCreatedBubble(NotificationEntry entry) { - if (isSummaryOfBubbles(entry)) { - List<Bubble> bubbleChildren = - mBubbleData.getBubblesInGroup(entry.getSbn().getGroupKey()); - for (int i = 0; i < bubbleChildren.size(); i++) { - // Check if any are user-created (i.e. experimental bubbles) - if (isUserCreatedBubble(bubbleChildren.get(i).getKey())) { - return true; - } - } - } - return false; - } - - /** * Removes the bubble with the given NotificationEntry. * <p> * Must be called from the main thread. @@ -893,37 +859,19 @@ public class BubbleController implements ConfigurationController.ConfigurationLi } private void onEntryAdded(NotificationEntry entry) { - boolean previouslyUserCreated = mUserCreatedBubbles.contains(entry.getKey()); - boolean userBlocked = mUserBlockedBubbles.contains(entry.getKey()); - boolean wasAdjusted = BubbleExperimentConfig.adjustForExperiments( - mContext, entry, previouslyUserCreated, userBlocked); - if (mNotificationInterruptStateProvider.shouldBubbleUp(entry) - && (canLaunchInActivityView(mContext, entry) || wasAdjusted)) { - if (wasAdjusted && !previouslyUserCreated) { - // Gotta treat the auto-bubbled / whitelisted packaged bubbles as usercreated - mUserCreatedBubbles.add(entry.getKey()); - } + && canLaunchInActivityView(mContext, entry)) { updateBubble(entry); } } private void onEntryUpdated(NotificationEntry entry) { - boolean previouslyUserCreated = mUserCreatedBubbles.contains(entry.getKey()); - boolean userBlocked = mUserBlockedBubbles.contains(entry.getKey()); - boolean wasAdjusted = BubbleExperimentConfig.adjustForExperiments( - mContext, entry, previouslyUserCreated, userBlocked); - boolean shouldBubble = mNotificationInterruptStateProvider.shouldBubbleUp(entry) - && (canLaunchInActivityView(mContext, entry) || wasAdjusted); + && canLaunchInActivityView(mContext, entry); if (!shouldBubble && mBubbleData.hasBubbleWithKey(entry.getKey())) { // It was previously a bubble but no longer a bubble -- lets remove it removeBubble(entry, DISMISS_NO_LONGER_BUBBLE); } else if (shouldBubble) { - if (wasAdjusted && !previouslyUserCreated) { - // Gotta treat the auto-bubbled / whitelisted packaged bubbles as usercreated - mUserCreatedBubbles.add(entry.getKey()); - } updateBubble(entry); } } diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java index 93fb6972fad5..3524696dbc79 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java @@ -193,7 +193,7 @@ public class BubbleExpandedView extends LinearLayout implements View.OnClickList + " mActivityViewStatus=" + mActivityViewStatus + " bubble=" + getBubbleKey()); } - if (mBubble != null && !mBubbleController.isUserCreatedBubble(mBubble.getKey())) { + if (mBubble != null) { // Must post because this is called from a binder thread. post(() -> mBubbleController.removeBubble(mBubble.getEntry(), BubbleController.DISMISS_TASK_FINISHED)); diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExperimentConfig.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExperimentConfig.java index 41dbb489c2f6..2060391d38a3 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExperimentConfig.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExperimentConfig.java @@ -57,16 +57,13 @@ import java.util.List; public class BubbleExperimentConfig { private static final String TAG = TAG_WITH_CLASS_NAME ? "BubbleController" : TAG_BUBBLES; - private static final String SHORTCUT_DUMMY_INTENT = "bubble_experiment_shortcut_intent"; - private static PendingIntent sDummyShortcutIntent; - private static final int BUBBLE_HEIGHT = 10000; private static final String ALLOW_ANY_NOTIF_TO_BUBBLE = "allow_any_notif_to_bubble"; private static final boolean ALLOW_ANY_NOTIF_TO_BUBBLE_DEFAULT = false; private static final String ALLOW_MESSAGE_NOTIFS_TO_BUBBLE = "allow_message_notifs_to_bubble"; - private static final boolean ALLOW_MESSAGE_NOTIFS_TO_BUBBLE_DEFAULT = true; + private static final boolean ALLOW_MESSAGE_NOTIFS_TO_BUBBLE_DEFAULT = false; private static final String ALLOW_SHORTCUTS_TO_BUBBLE = "allow_shortcuts_to_bubble"; private static final boolean ALLOW_SHORTCUT_TO_BUBBLE_DEFAULT = false; diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java index 1cabe221bef1..0534efc0949d 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java @@ -374,8 +374,9 @@ public class BubbleStackView extends FrameLayout { @Override public void onReleasedInTarget(@NonNull MagnetizedObject.MagneticTarget target) { mExpandedAnimationController.dismissDraggedOutBubble( - mExpandedAnimationController.getDraggedOutBubble(), - BubbleStackView.this::dismissMagnetizedObject); + mExpandedAnimationController.getDraggedOutBubble() /* bubble */, + mDismissTargetContainer.getHeight() /* translationYBy */, + BubbleStackView.this::dismissMagnetizedObject /* after */); hideDismissTarget(); } }; @@ -405,7 +406,8 @@ public class BubbleStackView extends FrameLayout { @Override public void onReleasedInTarget(@NonNull MagnetizedObject.MagneticTarget target) { - mStackAnimationController.implodeStack( + mStackAnimationController.animateStackDismissal( + mDismissTargetContainer.getHeight() /* translationYBy */, () -> { resetDesaturationAndDarken(); dismissMagnetizedObject(); diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleViewInfoTask.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleViewInfoTask.java index 501e5024d940..c96f9a470ca4 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleViewInfoTask.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleViewInfoTask.java @@ -139,22 +139,11 @@ public class BubbleViewInfoTask extends AsyncTask<Void, Void, BubbleViewInfoTask StatusBarNotification sbn = b.getEntry().getSbn(); String packageName = sbn.getPackageName(); - // Real shortcut info for this bubble String bubbleShortcutId = b.getEntry().getBubbleMetadata().getShortcutId(); if (bubbleShortcutId != null) { - info.shortcutInfo = BubbleExperimentConfig.getShortcutInfo(c, packageName, - sbn.getUser(), bubbleShortcutId); - } else { - // Check for experimental shortcut - String shortcutId = sbn.getNotification().getShortcutId(); - if (BubbleExperimentConfig.useShortcutInfoToBubble(c) && shortcutId != null) { - info.shortcutInfo = BubbleExperimentConfig.getShortcutInfo(c, - packageName, - sbn.getUser(), shortcutId); - } + info.shortcutInfo = b.getEntry().getRanking().getShortcutInfo(); } - // App name & app icon PackageManager pm = c.getPackageManager(); ApplicationInfo appInfo; diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java b/packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java index d974adc34ee0..0002e862bb41 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java @@ -329,7 +329,7 @@ public class ExpandedAnimationController } /** Plays a dismiss animation on the dragged out bubble. */ - public void dismissDraggedOutBubble(View bubble, Runnable after) { + public void dismissDraggedOutBubble(View bubble, float translationYBy, Runnable after) { if (bubble == null) { return; } @@ -337,6 +337,7 @@ public class ExpandedAnimationController .withStiffness(SpringForce.STIFFNESS_HIGH) .scaleX(1.1f) .scaleY(1.1f) + .translationY(bubble.getTranslationY() + translationYBy) .alpha(0f, after) .start(); diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/animation/StackAnimationController.java b/packages/SystemUI/src/com/android/systemui/bubbles/animation/StackAnimationController.java index 00de8b4a51b8..5f3a2bd9eb8b 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/animation/StackAnimationController.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/animation/StackAnimationController.java @@ -647,17 +647,18 @@ public class StackAnimationController extends } /** - * 'Implode' the stack by shrinking the bubbles via chained animations and fading them out. + * 'Implode' the stack by shrinking the bubbles, fading them out, and translating them down. */ - public void implodeStack(Runnable after) { - // Pop and fade the bubbles sequentially. - animationForChildAtIndex(0) - .scaleX(0.5f) - .scaleY(0.5f) - .alpha(0f) - .withDampingRatio(SpringForce.DAMPING_RATIO_NO_BOUNCY) - .withStiffness(SpringForce.STIFFNESS_HIGH) - .start(after); + public void animateStackDismissal(float translationYBy, Runnable after) { + animationsForChildrenFromIndex(0, (index, animation) -> + animation + .scaleX(0.5f) + .scaleY(0.5f) + .alpha(0f) + .translationY( + mLayout.getChildAt(index).getTranslationY() + translationYBy) + .withStiffness(SpringForce.STIFFNESS_HIGH)) + .startAll(after); } /** @@ -710,8 +711,6 @@ public class StackAnimationController extends if (property.equals(DynamicAnimation.TRANSLATION_X) || property.equals(DynamicAnimation.TRANSLATION_Y)) { return index + 1; - } else if (isStackStuckToTarget()) { - return index + 1; // Chain all animations in dismiss (scale, alpha, etc. are used). } else { return NONE; } 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/media/MediaControlPanel.java b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java index 62efd8ce4cee..8492fef97df5 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java +++ b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java @@ -82,6 +82,7 @@ public class MediaControlPanel { protected ComponentName mRecvComponent; private MediaDevice mDevice; private boolean mIsRegistered = false; + private String mKey; private final int[] mActionIds; @@ -203,14 +204,15 @@ public class MediaControlPanel { * @param bgColor * @param contentIntent * @param appNameString - * @param device + * @param key */ public void setMediaSession(MediaSession.Token token, Icon icon, int iconColor, - int bgColor, PendingIntent contentIntent, String appNameString) { + int bgColor, PendingIntent contentIntent, String appNameString, String key) { mToken = token; mForegroundColor = iconColor; mBackgroundColor = bgColor; mController = new MediaController(mContext, mToken); + mKey = key; MediaMetadata mediaMetadata = mController.getMetadata(); @@ -326,6 +328,14 @@ public class MediaControlPanel { } /** + * Return the original notification's key + * @return The notification key + */ + public String getKey() { + return mKey; + } + + /** * Check whether this player has an attached media session. * @return whether there is a controller with a current media session. */ diff --git a/packages/SystemUI/src/com/android/systemui/media/SeekBarObserver.kt b/packages/SystemUI/src/com/android/systemui/media/SeekBarObserver.kt index b7658a9f178d..51c157a56560 100644 --- a/packages/SystemUI/src/com/android/systemui/media/SeekBarObserver.kt +++ b/packages/SystemUI/src/com/android/systemui/media/SeekBarObserver.kt @@ -61,6 +61,7 @@ class SeekBarObserver(view: View) : Observer<SeekBarViewModel.Progress> { if (!data.enabled) { seekBarView.setEnabled(false) seekBarView.getThumb().setAlpha(0) + seekBarView.setProgress(0) elapsedTimeView.setText("") totalTimeView.setText("") return diff --git a/packages/SystemUI/src/com/android/systemui/media/SeekBarViewModel.kt b/packages/SystemUI/src/com/android/systemui/media/SeekBarViewModel.kt index dd83e42cde2d..142510030a5f 100644 --- a/packages/SystemUI/src/com/android/systemui/media/SeekBarViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/media/SeekBarViewModel.kt @@ -77,13 +77,25 @@ class SeekBarViewModel(val bgExecutor: DelayableExecutor) { val seekAvailable = ((playbackState?.actions ?: 0L) and PlaybackState.ACTION_SEEK_TO) != 0L val position = playbackState?.position?.toInt() val duration = mediaMetadata?.getLong(MediaMetadata.METADATA_KEY_DURATION)?.toInt() - val enabled = if (duration != null && duration <= 0) false else true + val enabled = if (playbackState == null || + playbackState?.getState() == PlaybackState.STATE_NONE || + (duration != null && duration <= 0)) false else true _data = Progress(enabled, seekAvailable, position, duration, color) if (shouldPollPlaybackPosition()) { checkPlaybackPosition() } } + /** + * Puts the seek bar into a resumption state. + * + * This should be called when the media session behind the controller has been destroyed. + */ + @AnyThread + fun clearController() = bgExecutor.execute { + _data = _data.copy(enabled = false) + } + @AnyThread private fun checkPlaybackPosition(): Runnable = bgExecutor.executeDelayed({ val currentPosition = controller?.playbackState?.position?.toInt() 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 c3779efcf4b2..ba9a30fb554f 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java +++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java @@ -339,18 +339,18 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio @Override public void onPipTransitionFinished(ComponentName activity, int direction) { - onPipTransitionFinishedOrCanceled(); + onPipTransitionFinishedOrCanceled(direction); } @Override public void onPipTransitionCanceled(ComponentName activity, int direction) { - onPipTransitionFinishedOrCanceled(); + onPipTransitionFinishedOrCanceled(direction); } - private void onPipTransitionFinishedOrCanceled() { + private void onPipTransitionFinishedOrCanceled(int direction) { // Re-enable touches after the animation completes mTouchHandler.setTouchEnabled(true); - mTouchHandler.onPinnedStackAnimationEnded(); + mTouchHandler.onPinnedStackAnimationEnded(direction); mMenuController.onPinnedStackAnimationEnded(); } diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java index 2b9b1716cb18..ec15dd16f46e 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java +++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java @@ -54,6 +54,7 @@ import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Bundle; import android.os.Handler; +import android.os.Looper; import android.os.Message; import android.os.Messenger; import android.os.RemoteException; @@ -129,9 +130,7 @@ public class PipMenuActivity extends Activity { } }; - private Handler mHandler = new Handler(); - private Messenger mToControllerMessenger; - private Messenger mMessenger = new Messenger(new Handler() { + private Handler mHandler = new Handler(Looper.getMainLooper()) { @Override public void handleMessage(Message msg) { switch (msg.what) { @@ -174,7 +173,9 @@ public class PipMenuActivity extends Activity { } } } - }); + }; + private Messenger mToControllerMessenger; + private Messenger mMessenger = new Messenger(mHandler); private final Runnable mFinishRunnable = new Runnable() { @Override diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java index d660b670446b..61ed40d5d782 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java +++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java @@ -30,6 +30,7 @@ import android.graphics.Rect; import android.os.Bundle; import android.os.Debug; import android.os.Handler; +import android.os.Looper; import android.os.Message; import android.os.Messenger; import android.os.RemoteException; @@ -122,7 +123,7 @@ public class PipMenuActivityController { private boolean mStartActivityRequested; private long mStartActivityRequestedTime; private Messenger mToActivityMessenger; - private Handler mHandler = new Handler() { + private Handler mHandler = new Handler(Looper.getMainLooper()) { @Override public void handleMessage(Message msg) { switch (msg.what) { @@ -133,15 +134,15 @@ public class PipMenuActivityController { break; } case MESSAGE_EXPAND_PIP: { - mListeners.forEach(l -> l.onPipExpand()); + mListeners.forEach(Listener::onPipExpand); break; } case MESSAGE_DISMISS_PIP: { - mListeners.forEach(l -> l.onPipDismiss()); + mListeners.forEach(Listener::onPipDismiss); break; } case MESSAGE_SHOW_MENU: { - mListeners.forEach(l -> l.onPipShowMenu()); + mListeners.forEach(Listener::onPipShowMenu); break; } case MESSAGE_UPDATE_ACTIVITY_CALLBACK: { @@ -259,6 +260,8 @@ public class PipMenuActivityController { if (DEBUG) { Log.d(TAG, "showMenu() state=" + menuState + " hasActivity=" + (mToActivityMessenger != null) + + " allowMenuTimeout=" + allowMenuTimeout + + " willResizeMenu=" + willResizeMenu + " callers=\n" + Debug.getCallers(5, " ")); } diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipResizeGestureHandler.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipResizeGestureHandler.java index 0b076559ae36..d80f18a983ee 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipResizeGestureHandler.java +++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipResizeGestureHandler.java @@ -56,7 +56,6 @@ public class PipResizeGestureHandler { private final DisplayMetrics mDisplayMetrics = new DisplayMetrics(); private final PipBoundsHandler mPipBoundsHandler; - private final PipTouchHandler mPipTouchHandler; private final PipMotionHelper mMotionHelper; private final int mDisplayId; private final Executor mMainExecutor; @@ -70,10 +69,10 @@ public class PipResizeGestureHandler { private final Rect mTmpBounds = new Rect(); private final int mDelta; - private boolean mAllowGesture = false; + private boolean mAllowGesture; private boolean mIsAttached; private boolean mIsEnabled; - private boolean mEnablePipResize; + private boolean mEnableUserResize; private InputMonitor mInputMonitor; private InputEventReceiver mInputEventReceiver; @@ -82,21 +81,20 @@ public class PipResizeGestureHandler { private int mCtrlType; public PipResizeGestureHandler(Context context, PipBoundsHandler pipBoundsHandler, - PipTouchHandler pipTouchHandler, PipMotionHelper motionHelper, - DeviceConfigProxy deviceConfig, PipTaskOrganizer pipTaskOrganizer) { + PipMotionHelper motionHelper, DeviceConfigProxy deviceConfig, + PipTaskOrganizer pipTaskOrganizer) { final Resources res = context.getResources(); context.getDisplay().getMetrics(mDisplayMetrics); mDisplayId = context.getDisplayId(); mMainExecutor = context.getMainExecutor(); mPipBoundsHandler = pipBoundsHandler; - mPipTouchHandler = pipTouchHandler; mMotionHelper = motionHelper; mPipTaskOrganizer = pipTaskOrganizer; context.getDisplay().getRealSize(mMaxSize); mDelta = res.getDimensionPixelSize(R.dimen.pip_resize_edge_size); - mEnablePipResize = DeviceConfig.getBoolean( + mEnableUserResize = DeviceConfig.getBoolean( DeviceConfig.NAMESPACE_SYSTEMUI, PIP_USER_RESIZE, /* defaultValue = */ true); @@ -105,7 +103,7 @@ public class PipResizeGestureHandler { @Override public void onPropertiesChanged(DeviceConfig.Properties properties) { if (properties.getKeyset().contains(PIP_USER_RESIZE)) { - mEnablePipResize = properties.getBoolean( + mEnableUserResize = properties.getBoolean( PIP_USER_RESIZE, /* defaultValue = */ true); } } @@ -134,7 +132,7 @@ public class PipResizeGestureHandler { } private void updateIsEnabled() { - boolean isEnabled = mIsAttached && mEnablePipResize; + boolean isEnabled = mIsAttached && mEnableUserResize; if (isEnabled == mIsEnabled) { return; } 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..f5c83c1fffd7 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java +++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java @@ -16,6 +16,7 @@ package com.android.systemui.pip.phone; +import static com.android.systemui.pip.PipAnimationController.TRANSITION_DIRECTION_TO_PIP; import static com.android.systemui.pip.phone.PipMenuActivityController.MENU_STATE_CLOSE; import static com.android.systemui.pip.phone.PipMenuActivityController.MENU_STATE_FULL; import static com.android.systemui.pip.phone.PipMenuActivityController.MENU_STATE_NONE; @@ -56,6 +57,7 @@ import androidx.dynamicanimation.animation.SpringForce; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.os.logging.MetricsLoggerWrapper; import com.android.systemui.R; +import com.android.systemui.pip.PipAnimationController; import com.android.systemui.pip.PipBoundsHandler; import com.android.systemui.pip.PipSnapAlgorithm; import com.android.systemui.pip.PipTaskOrganizer; @@ -229,7 +231,7 @@ public class PipTouchHandler { mMotionHelper = new PipMotionHelper(mContext, activityTaskManager, pipTaskOrganizer, mMenuController, mSnapAlgorithm, mFlingAnimationUtils, floatingContentCoordinator); mPipResizeGestureHandler = - new PipResizeGestureHandler(context, pipBoundsHandler, this, mMotionHelper, + new PipResizeGestureHandler(context, pipBoundsHandler, mMotionHelper, deviceConfig, pipTaskOrganizer); mTouchState = new PipTouchState(ViewConfiguration.get(context), mHandler, () -> mMenuController.showMenu(MENU_STATE_FULL, mMotionHelper.getBounds(), @@ -266,6 +268,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 +327,7 @@ public class PipTouchHandler { } public void onActivityPinned() { - createDismissTargetMaybe(); + createOrUpdateDismissTarget(); mShowPipMenuOnAnimationEnd = true; mPipResizeGestureHandler.onActivityPinned(); @@ -339,11 +345,16 @@ public class PipTouchHandler { mPipResizeGestureHandler.onActivityUnpinned(); } - public void onPinnedStackAnimationEnded() { + public void onPinnedStackAnimationEnded( + @PipAnimationController.TransitionDirection int direction) { // Always synchronize the motion helper bounds once PiP animations finish mMotionHelper.synchronizePinnedStackBounds(); updateMovementBounds(); - mResizedBounds.set(mMotionHelper.getBounds()); + if (direction == TRANSITION_DIRECTION_TO_PIP) { + // updates mResizedBounds only if it's an entering PiP animation + // mResized should be otherwise updated in setMenuState. + mResizedBounds.set(mMotionHelper.getBounds()); + } if (mShowPipMenuOnAnimationEnd) { mMenuController.showMenu(MENU_STATE_CLOSE, mMotionHelper.getBounds(), @@ -357,8 +368,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 +464,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/QSMediaPlayer.java b/packages/SystemUI/src/com/android/systemui/qs/QSMediaPlayer.java index e636707a9722..e4bcb0921284 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSMediaPlayer.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSMediaPlayer.java @@ -99,15 +99,14 @@ public class QSMediaPlayer extends MediaControlPanel { * @param bgColor background color * @param actionsContainer a LinearLayout containing the media action buttons * @param notif reference to original notification - * @param device current playback device + * @param key original notification's key */ public void setMediaSession(MediaSession.Token token, Icon icon, int iconColor, - int bgColor, View actionsContainer, Notification notif) { + int bgColor, View actionsContainer, Notification notif, String key) { String appName = Notification.Builder.recoverBuilder(getContext(), notif) .loadHeaderAppName(); - super.setMediaSession(token, icon, iconColor, bgColor, notif.contentIntent, - appName); + super.setMediaSession(token, icon, iconColor, bgColor, notif.contentIntent, appName, key); // Media controls LinearLayout parentActionsLayout = (LinearLayout) actionsContainer; @@ -171,6 +170,8 @@ public class QSMediaPlayer extends MediaControlPanel { public void clearControls() { super.clearControls(); + mSeekBarViewModel.clearController(); + View guts = mMediaNotifView.findViewById(R.id.media_guts); View options = mMediaNotifView.findViewById(R.id.qs_media_controls_options); diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java index 0566b2e621db..40c8aadfd5d4 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java @@ -208,9 +208,10 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne * @param bgColor * @param actionsContainer * @param notif + * @param key */ public void addMediaSession(MediaSession.Token token, Icon icon, int iconColor, int bgColor, - View actionsContainer, StatusBarNotification notif) { + View actionsContainer, StatusBarNotification notif, String key) { if (!useQsMediaPlayer(mContext)) { // Shouldn't happen, but just in case Log.e(TAG, "Tried to add media session without player!"); @@ -225,13 +226,12 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne String packageName = notif.getPackageName(); for (QSMediaPlayer p : mMediaPlayers) { if (p.getMediaSessionToken().equals(token)) { - Log.d(TAG, "a player for this session already exists"); + Log.d(TAG, "Found matching player by token " + packageName); player = p; break; - } - - if (packageName.equals(p.getMediaPlayerPackage())) { - Log.d(TAG, "found an old session for this app"); + } else if (packageName.equals(p.getMediaPlayerPackage()) && key.equals(p.getKey())) { + // Also match if it's the same package and notification key + Log.d(TAG, "Found matching player by package " + packageName + ", " + key); player = p; break; } @@ -267,7 +267,7 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne Log.d(TAG, "setting player session"); player.setMediaSession(token, icon, iconColor, bgColor, actionsContainer, - notif.getNotification()); + notif.getNotification(), key); if (mMediaPlayers.size() > 0) { ((View) mMediaCarousel.getParent()).setVisibility(View.VISIBLE); diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickQSMediaPlayer.java b/packages/SystemUI/src/com/android/systemui/qs/QuickQSMediaPlayer.java index 0ba4cb159024..794677912626 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QuickQSMediaPlayer.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QuickQSMediaPlayer.java @@ -67,9 +67,10 @@ public class QuickQSMediaPlayer extends MediaControlPanel { * @param actionsToShow indices of which actions to display in the mini player * (max 3: Notification.MediaStyle.MAX_MEDIA_BUTTONS_IN_COMPACT) * @param contentIntent Intent to send when user taps on the view + * @param key original notification's key */ public void setMediaSession(MediaSession.Token token, Icon icon, int iconColor, int bgColor, - View actionsContainer, int[] actionsToShow, PendingIntent contentIntent) { + View actionsContainer, int[] actionsToShow, PendingIntent contentIntent, String key) { // Only update if this is a different session and currently playing String oldPackage = ""; if (getController() != null) { @@ -84,7 +85,7 @@ public class QuickQSMediaPlayer extends MediaControlPanel { return; } - super.setMediaSession(token, icon, iconColor, bgColor, contentIntent, null); + super.setMediaSession(token, icon, iconColor, bgColor, contentIntent, null, key); LinearLayout parentActionsLayout = (LinearLayout) actionsContainer; int i = 0; 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/recents/OverviewProxyRecentsImpl.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyRecentsImpl.java index 8051998e2530..5bf44c6a3003 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyRecentsImpl.java +++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyRecentsImpl.java @@ -71,13 +71,12 @@ public class OverviewProxyRecentsImpl implements RecentsImplementation { public void onActivityRestartAttempt(ActivityManager.RunningTaskInfo task, boolean homeTaskVisible, boolean clearedTask) { if (task.configuration.windowConfiguration.getWindowingMode() - != WINDOWING_MODE_SPLIT_SCREEN_PRIMARY || !mDividerOptional.isPresent()) { + != WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) { return; } - final Divider divider = mDividerOptional.get(); - if (divider.isMinimized()) { - divider.onUndockingTask(); + if (homeTaskVisible) { + showRecentApps(false /* triggeredFromAltTab */); } } }; 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/row/NotificationConversationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java index a27199370b16..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,7 @@ 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; @@ -33,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; @@ -51,6 +53,7 @@ import android.transition.TransitionManager; import android.transition.TransitionSet; import android.util.AttributeSet; import android.util.Log; +import android.util.Slog; import android.view.View; import android.view.accessibility.AccessibilityEvent; import android.widget.ImageView; @@ -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; @@ -206,6 +210,13 @@ public class NotificationConversationInfo extends LinearLayout implements 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(); @@ -227,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); @@ -264,7 +280,6 @@ public class NotificationConversationInfo extends LinearLayout implements // bindName(); bindPackage(); bindIcon(mNotificationChannel.isImportantConversation()); - } private void bindIcon(boolean important) { @@ -560,10 +575,7 @@ public class NotificationConversationInfo extends LinearLayout implements !mChannelToUpdate.isImportantConversation()); if (mChannelToUpdate.isImportantConversation()) { mChannelToUpdate.setAllowBubbles(true); - int currentPref = - mINotificationManager.getBubblePreferenceForPackage( - mAppPkg, mAppUid); - if (currentPref == BUBBLE_PREFERENCE_NONE) { + if (mAppBubble == BUBBLE_PREFERENCE_NONE) { mINotificationManager.setBubblesAllowed(mAppPkg, mAppUid, BUBBLE_PREFERENCE_SELECTED); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMediaTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMediaTemplateViewWrapper.java index 874d81db0bd2..2da2724aacb2 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMediaTemplateViewWrapper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMediaTemplateViewWrapper.java @@ -193,7 +193,8 @@ public class NotificationMediaTemplateViewWrapper extends NotificationTemplateVi mBackgroundColor, mActions, compactActions, - notif.contentIntent); + notif.contentIntent, + sbn.getKey()); QSPanel bigPanel = ctrl.getNotificationShadeView().findViewById( com.android.systemui.R.id.quick_settings_panel); bigPanel.addMediaSession(token, @@ -201,7 +202,8 @@ public class NotificationMediaTemplateViewWrapper extends NotificationTemplateVi tintColor, mBackgroundColor, mActions, - sbn); + sbn, + sbn.getKey()); } boolean showCompactSeekbar = mMediaManager.getShowCompactMediaSeekbar(); 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/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/media/SeekBarViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/SeekBarViewModelTest.kt index f316d0480fac..28a3d6a32a61 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/SeekBarViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/media/SeekBarViewModelTest.kt @@ -86,7 +86,7 @@ public class SeekBarViewModelTest : SysuiTestCase() { } @Test - fun updateDuration() { + fun updateDurationWithPlayback() { // GIVEN that the duration is contained within the metadata val duration = 12000L val metadata = MediaMetadata.Builder().run { @@ -94,6 +94,12 @@ public class SeekBarViewModelTest : SysuiTestCase() { build() } whenever(mockController.getMetadata()).thenReturn(metadata) + // AND a valid playback state (ie. media session is not destroyed) + val state = PlaybackState.Builder().run { + setState(PlaybackState.STATE_PLAYING, 200L, 1f) + build() + } + whenever(mockController.getPlaybackState()).thenReturn(state) // WHEN the controller is updated viewModel.updateController(mockController, Color.RED) // THEN the duration is extracted @@ -102,6 +108,22 @@ public class SeekBarViewModelTest : SysuiTestCase() { } @Test + fun updateDurationWithoutPlayback() { + // GIVEN that the duration is contained within the metadata + val duration = 12000L + val metadata = MediaMetadata.Builder().run { + putLong(MediaMetadata.METADATA_KEY_DURATION, duration) + build() + } + whenever(mockController.getMetadata()).thenReturn(metadata) + // WHEN the controller is updated + viewModel.updateController(mockController, Color.RED) + // THEN the duration is extracted + assertThat(viewModel.progress.value!!.duration).isEqualTo(duration) + assertThat(viewModel.progress.value!!.enabled).isFalse() + } + + @Test fun updateDurationNegative() { // GIVEN that the duration is negative val duration = -1L @@ -110,6 +132,12 @@ public class SeekBarViewModelTest : SysuiTestCase() { build() } whenever(mockController.getMetadata()).thenReturn(metadata) + // AND a valid playback state (ie. media session is not destroyed) + val state = PlaybackState.Builder().run { + setState(PlaybackState.STATE_PLAYING, 200L, 1f) + build() + } + whenever(mockController.getPlaybackState()).thenReturn(state) // WHEN the controller is updated viewModel.updateController(mockController, Color.RED) // THEN the seek bar is disabled @@ -125,6 +153,12 @@ public class SeekBarViewModelTest : SysuiTestCase() { build() } whenever(mockController.getMetadata()).thenReturn(metadata) + // AND a valid playback state (ie. media session is not destroyed) + val state = PlaybackState.Builder().run { + setState(PlaybackState.STATE_PLAYING, 200L, 1f) + build() + } + whenever(mockController.getPlaybackState()).thenReturn(state) // WHEN the controller is updated viewModel.updateController(mockController, Color.RED) // THEN the seek bar is disabled @@ -372,4 +406,30 @@ public class SeekBarViewModelTest : SysuiTestCase() { // THEN an update task is queued assertThat(fakeExecutor.numPending()).isEqualTo(1) } + + @Test + fun clearSeekBar() { + // GIVEN that the duration is contained within the metadata + val metadata = MediaMetadata.Builder().run { + putLong(MediaMetadata.METADATA_KEY_DURATION, 12000L) + build() + } + whenever(mockController.getMetadata()).thenReturn(metadata) + // AND a valid playback state (ie. media session is not destroyed) + val state = PlaybackState.Builder().run { + setState(PlaybackState.STATE_PLAYING, 200L, 1f) + build() + } + whenever(mockController.getPlaybackState()).thenReturn(state) + // AND the controller has been updated + viewModel.updateController(mockController, Color.RED) + // WHEN the controller is cleared on the event when the session is destroyed + viewModel.clearController() + with(fakeExecutor) { + advanceClockToNext() + runAllReady() + } + // THEN the seek bar is disabled + assertThat(viewModel.progress.value!!.enabled).isFalse() + } } 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 1dc8227e81f4..2b2fe4534c3e 100644 --- a/packages/Tethering/AndroidManifest.xml +++ b/packages/Tethering/AndroidManifest.xml @@ -34,11 +34,14 @@ <uses-permission android:name="android.permission.MODIFY_PHONE_STATE" /> <uses-permission android:name="android.permission.READ_DEVICE_CONFIG" /> <uses-permission android:name="android.permission.READ_NETWORK_USAGE_HISTORY" /> + <uses-permission android:name="android.permission.READ_PHONE_STATE"/> <uses-permission android:name="android.permission.TETHER_PRIVILEGED" /> <uses-permission android:name="android.permission.UPDATE_APP_OPS_STATS" /> <uses-permission android:name="android.permission.UPDATE_DEVICE_STATS" /> <uses-permission android:name="android.permission.WRITE_SETTINGS" /> + <protected-broadcast android:name="com.android.server.connectivity.tethering.DISABLE_TETHERING" /> + <application android:process="com.android.networkstack.process" android:extractNativeLibs="false" diff --git a/packages/Tethering/res/values-mcc204-mnc04/strings.xml b/packages/Tethering/res/values-mcc204-mnc04/strings.xml deleted file mode 100644 index a996b4247a0e..000000000000 --- a/packages/Tethering/res/values-mcc204-mnc04/strings.xml +++ /dev/null @@ -1,30 +0,0 @@ -<?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. ---> -<resources> - <!-- String for no upstream notification title [CHAR LIMIT=200] --> - <string name="no_upstream_notification_title">Hotspot 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 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 name="upstream_roaming_notification_message">Additional charges may apply while roaming</string> - <!-- 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/config.xml b/packages/Tethering/res/values-mcc310-mnc004/config.xml new file mode 100644 index 000000000000..8c627d5df058 --- /dev/null +++ b/packages/Tethering/res/values-mcc310-mnc004/config.xml @@ -0,0 +1,20 @@ +<?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. +--> +<resources> + <!-- Delay(millisecond) to show no upstream notification after there's no Backhaul. Set delay to + "0" for disable this feature. --> + <integer name="delay_to_show_no_upstream_after_no_backhaul">5000</integer> +</resources>
\ No newline at end of file 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/config.xml b/packages/Tethering/res/values-mcc311-mnc480/config.xml new file mode 100644 index 000000000000..8c627d5df058 --- /dev/null +++ b/packages/Tethering/res/values-mcc311-mnc480/config.xml @@ -0,0 +1,20 @@ +<?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. +--> +<resources> + <!-- Delay(millisecond) to show no upstream notification after there's no Backhaul. Set delay to + "0" for disable this feature. --> + <integer name="delay_to_show_no_upstream_after_no_backhaul">5000</integer> +</resources>
\ No newline at end of file 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 430fdc42284d..52aa5bbaffa5 100644 --- a/packages/Tethering/res/values/config.xml +++ b/packages/Tethering/res/values/config.xml @@ -202,4 +202,10 @@ <string name="tethering_notification_title">@string/tethered_notification_title</string> <!-- String for tether enable notification message. --> <string name="tethering_notification_message">@string/tethered_notification_message</string> + + <!-- No upstream notification is shown when there is a downstream but no upstream that is able + to do the tethering. --> + <!-- Delay(millisecond) to show no upstream notification after there's no Backhaul. Set delay to + "-1" for disable this feature. --> + <integer name="delay_to_show_no_upstream_after_no_backhaul">-1</integer> </resources> 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/com/android/networkstack/tethering/EntitlementManager.java b/packages/Tethering/src/com/android/networkstack/tethering/EntitlementManager.java index 4c7b2d49ee9a..049a9f68bbd2 100644 --- a/packages/Tethering/src/com/android/networkstack/tethering/EntitlementManager.java +++ b/packages/Tethering/src/com/android/networkstack/tethering/EntitlementManager.java @@ -38,8 +38,6 @@ import android.content.IntentFilter; import android.net.util.SharedLog; import android.os.Bundle; import android.os.Handler; -import android.os.Looper; -import android.os.Message; import android.os.Parcel; import android.os.PersistableBundle; import android.os.ResultReceiver; @@ -75,11 +73,6 @@ public class EntitlementManager { private final ComponentName mSilentProvisioningService; private static final int MS_PER_HOUR = 60 * 60 * 1000; - private static final int EVENT_START_PROVISIONING = 0; - private static final int EVENT_STOP_PROVISIONING = 1; - private static final int EVENT_UPSTREAM_CHANGED = 2; - private static final int EVENT_MAYBE_RUN_PROVISIONING = 3; - private static final int EVENT_GET_ENTITLEMENT_VALUE = 4; // The ArraySet contains enabled downstream types, ex: // {@link TetheringManager.TETHERING_WIFI} @@ -90,7 +83,7 @@ public class EntitlementManager { private final int mPermissionChangeMessageCode; private final SharedLog mLog; private final SparseIntArray mEntitlementCacheValue; - private final EntitlementHandler mHandler; + private final Handler mHandler; private final StateMachine mTetherMasterSM; // Key: TetheringManager.TETHERING_*(downstream). // Value: TetheringManager.TETHER_ERROR_{NO_ERROR or PROVISION_FAILED}(provisioning result). @@ -112,10 +105,7 @@ public class EntitlementManager { mEntitlementCacheValue = new SparseIntArray(); mTetherMasterSM = tetherMasterSM; mPermissionChangeMessageCode = permissionChangeMessageCode; - final Handler masterHandler = tetherMasterSM.getHandler(); - // Create entitlement's own handler which is associated with TetherMaster thread - // let all entitlement processes run in the same thread. - mHandler = new EntitlementHandler(masterHandler.getLooper()); + mHandler = tetherMasterSM.getHandler(); mContext.registerReceiver(mReceiver, new IntentFilter(ACTION_PROVISIONING_ALARM), null, mHandler); mSilentProvisioningService = ComponentName.unflattenFromString( @@ -172,14 +162,9 @@ public class EntitlementManager { * provisioning app UI if there is one. */ public void startProvisioningIfNeeded(int downstreamType, boolean showProvisioningUi) { - mHandler.sendMessage(mHandler.obtainMessage(EVENT_START_PROVISIONING, - downstreamType, encodeBool(showProvisioningUi))); - } - - private void handleStartProvisioningIfNeeded(int type, boolean showProvisioningUi) { - if (!isValidDownstreamType(type)) return; + if (!isValidDownstreamType(downstreamType)) return; - if (!mCurrentTethers.contains(type)) mCurrentTethers.add(type); + if (!mCurrentTethers.contains(downstreamType)) mCurrentTethers.add(downstreamType); final TetheringConfiguration config = mFetcher.fetchTetheringConfiguration(); if (isTetherProvisioningRequired(config)) { @@ -192,9 +177,9 @@ public class EntitlementManager { // till upstream change to cellular. if (mUsingCellularAsUpstream) { if (showProvisioningUi) { - runUiTetherProvisioning(type, config.activeDataSubId); + runUiTetherProvisioning(downstreamType, config.activeDataSubId); } else { - runSilentTetherProvisioning(type, config.activeDataSubId); + runSilentTetherProvisioning(downstreamType, config.activeDataSubId); } mNeedReRunProvisioningUi = false; } else { @@ -211,10 +196,6 @@ public class EntitlementManager { * @param type tethering type from TetheringManager.TETHERING_{@code *} */ public void stopProvisioningIfNeeded(int type) { - mHandler.sendMessage(mHandler.obtainMessage(EVENT_STOP_PROVISIONING, type, 0)); - } - - private void handleStopProvisioningIfNeeded(int type) { if (!isValidDownstreamType(type)) return; mCurrentTethers.remove(type); @@ -230,11 +211,6 @@ public class EntitlementManager { * @param isCellular whether tethering upstream is cellular. */ public void notifyUpstream(boolean isCellular) { - mHandler.sendMessage(mHandler.obtainMessage( - EVENT_UPSTREAM_CHANGED, encodeBool(isCellular), 0)); - } - - private void handleNotifyUpstream(boolean isCellular) { if (DBG) { mLog.i("notifyUpstream: " + isCellular + ", mCellularUpstreamPermitted: " + mCellularUpstreamPermitted @@ -244,16 +220,17 @@ public class EntitlementManager { if (mUsingCellularAsUpstream) { final TetheringConfiguration config = mFetcher.fetchTetheringConfiguration(); - handleMaybeRunProvisioning(config); + maybeRunProvisioning(config); } } /** Run provisioning if needed */ public void maybeRunProvisioning() { - mHandler.sendMessage(mHandler.obtainMessage(EVENT_MAYBE_RUN_PROVISIONING)); + final TetheringConfiguration config = mFetcher.fetchTetheringConfiguration(); + maybeRunProvisioning(config); } - private void handleMaybeRunProvisioning(final TetheringConfiguration config) { + private void maybeRunProvisioning(final TetheringConfiguration config) { if (mCurrentTethers.size() == 0 || !isTetherProvisioningRequired(config)) { return; } @@ -319,7 +296,7 @@ public class EntitlementManager { } if (mUsingCellularAsUpstream) { - handleMaybeRunProvisioning(config); + maybeRunProvisioning(config); } } @@ -494,46 +471,6 @@ public class EntitlementManager { } }; - private class EntitlementHandler extends Handler { - EntitlementHandler(Looper looper) { - super(looper); - } - - @Override - public void handleMessage(Message msg) { - switch (msg.what) { - case EVENT_START_PROVISIONING: - handleStartProvisioningIfNeeded(msg.arg1, toBool(msg.arg2)); - break; - case EVENT_STOP_PROVISIONING: - handleStopProvisioningIfNeeded(msg.arg1); - break; - case EVENT_UPSTREAM_CHANGED: - handleNotifyUpstream(toBool(msg.arg1)); - break; - case EVENT_MAYBE_RUN_PROVISIONING: - final TetheringConfiguration config = mFetcher.fetchTetheringConfiguration(); - handleMaybeRunProvisioning(config); - break; - case EVENT_GET_ENTITLEMENT_VALUE: - handleRequestLatestTetheringEntitlementValue(msg.arg1, - (ResultReceiver) msg.obj, toBool(msg.arg2)); - break; - default: - mLog.log("Unknown event: " + msg.what); - break; - } - } - } - - private static boolean toBool(int encodedBoolean) { - return encodedBoolean != 0; - } - - private static int encodeBool(boolean b) { - return b ? 1 : 0; - } - private static boolean isValidDownstreamType(int type) { switch (type) { case TETHERING_BLUETOOTH: @@ -644,13 +581,6 @@ public class EntitlementManager { /** Get the last value of the tethering entitlement check. */ public void requestLatestTetheringEntitlementResult(int downstream, ResultReceiver receiver, boolean showEntitlementUi) { - mHandler.sendMessage(mHandler.obtainMessage(EVENT_GET_ENTITLEMENT_VALUE, - downstream, encodeBool(showEntitlementUi), receiver)); - - } - - private void handleRequestLatestTetheringEntitlementValue(int downstream, - ResultReceiver receiver, boolean showEntitlementUi) { if (!isValidDownstreamType(downstream)) { receiver.send(TETHER_ERROR_ENTITLEMENT_UNKNOWN, null); return; diff --git a/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java b/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java index f3cead92be7e..da8bf54718e9 100644 --- a/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java +++ b/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java @@ -257,7 +257,7 @@ public class Tethering { mContext = mDeps.getContext(); mNetd = mDeps.getINetd(mContext); mLooper = mDeps.getTetheringLooper(); - mNotificationUpdater = mDeps.getNotificationUpdater(mContext); + mNotificationUpdater = mDeps.getNotificationUpdater(mContext, mLooper); mPublicSync = new Object(); @@ -337,6 +337,11 @@ public class Tethering { filter.addAction(ACTION_RESTRICT_BACKGROUND_CHANGED); mContext.registerReceiver(mStateReceiver, filter, null, mHandler); + final IntentFilter noUpstreamFilter = new IntentFilter(); + noUpstreamFilter.addAction(TetheringNotificationUpdater.ACTION_DISABLE_TETHERING); + mContext.registerReceiver( + mStateReceiver, noUpstreamFilter, PERMISSION_MAINLINE_NETWORK_STACK, mHandler); + final WifiManager wifiManager = getWifiManager(); if (wifiManager != null) { wifiManager.registerSoftApCallback(mExecutor, new TetheringSoftApCallback()); @@ -855,6 +860,8 @@ public class Tethering { } else if (action.equals(ACTION_RESTRICT_BACKGROUND_CHANGED)) { mLog.log("OBSERVED data saver changed"); handleDataSaverChanged(); + } else if (action.equals(TetheringNotificationUpdater.ACTION_DISABLE_TETHERING)) { + untetherAll(); } } @@ -922,8 +929,10 @@ public class Tethering { case WifiManager.WIFI_AP_STATE_ENABLED: enableWifiIpServingLocked(ifname, ipmode); break; - case WifiManager.WIFI_AP_STATE_DISABLED: case WifiManager.WIFI_AP_STATE_DISABLING: + // We can see this state on the way to disabled. + break; + case WifiManager.WIFI_AP_STATE_DISABLED: case WifiManager.WIFI_AP_STATE_FAILED: default: disableWifiIpServingLocked(ifname, curState); @@ -1944,10 +1953,12 @@ public class Tethering { /** Get the latest value of the tethering entitlement check. */ void requestLatestTetheringEntitlementResult(int type, ResultReceiver receiver, boolean showEntitlementUi) { - if (receiver != null) { + if (receiver == null) return; + + mHandler.post(() -> { mEntitlementMgr.requestLatestTetheringEntitlementResult(type, receiver, showEntitlementUi); - } + }); } /** Register tethering event callback */ @@ -2011,6 +2022,7 @@ public class Tethering { } finally { mTetheringEventCallbacks.finishBroadcast(); } + mNotificationUpdater.onUpstreamNetworkChanged(network); } private void reportConfigurationChanged(TetheringConfigurationParcel config) { diff --git a/packages/Tethering/src/com/android/networkstack/tethering/TetheringDependencies.java b/packages/Tethering/src/com/android/networkstack/tethering/TetheringDependencies.java index 893c5823dce1..9b54b5ff2403 100644 --- a/packages/Tethering/src/com/android/networkstack/tethering/TetheringDependencies.java +++ b/packages/Tethering/src/com/android/networkstack/tethering/TetheringDependencies.java @@ -106,8 +106,9 @@ public abstract class TetheringDependencies { /** * Get a reference to the TetheringNotificationUpdater to be used by tethering. */ - public TetheringNotificationUpdater getNotificationUpdater(@NonNull final Context ctx) { - return new TetheringNotificationUpdater(ctx); + public TetheringNotificationUpdater getNotificationUpdater(@NonNull final Context ctx, + @NonNull final Looper looper) { + return new TetheringNotificationUpdater(ctx, looper); } /** diff --git a/packages/Tethering/src/com/android/networkstack/tethering/TetheringNotificationUpdater.java b/packages/Tethering/src/com/android/networkstack/tethering/TetheringNotificationUpdater.java index 42870560cb5e..ff83fd1e4f1e 100644 --- a/packages/Tethering/src/com/android/networkstack/tethering/TetheringNotificationUpdater.java +++ b/packages/Tethering/src/com/android/networkstack/tethering/TetheringNotificationUpdater.java @@ -19,18 +19,25 @@ package com.android.networkstack.tethering; import static android.net.TetheringManager.TETHERING_BLUETOOTH; import static android.net.TetheringManager.TETHERING_USB; import static android.net.TetheringManager.TETHERING_WIFI; +import static android.text.TextUtils.isEmpty; import android.app.Notification; +import android.app.Notification.Action; import android.app.NotificationChannel; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; +import android.content.res.Configuration; import android.content.res.Resources; +import android.net.Network; +import android.os.Handler; +import android.os.Looper; +import android.os.Message; import android.os.UserHandle; import android.provider.Settings; import android.telephony.SubscriptionManager; -import android.text.TextUtils; +import android.telephony.TelephonyManager; import android.util.Log; import android.util.SparseArray; @@ -39,9 +46,13 @@ import androidx.annotation.DrawableRes; import androidx.annotation.IntDef; import androidx.annotation.IntRange; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import com.android.internal.annotations.VisibleForTesting; +import java.util.Arrays; +import java.util.List; + /** * A class to display tethering-related notifications. * @@ -58,12 +69,22 @@ public class TetheringNotificationUpdater { private static final String WIFI_DOWNSTREAM = "WIFI"; private static final String USB_DOWNSTREAM = "USB"; private static final String BLUETOOTH_DOWNSTREAM = "BT"; + @VisibleForTesting + static final String ACTION_DISABLE_TETHERING = + "com.android.server.connectivity.tethering.DISABLE_TETHERING"; private static final boolean NOTIFY_DONE = true; private static final boolean NO_NOTIFY = false; - // Id to update and cancel tethering notification. Must be unique within the tethering app. - private static final int ENABLE_NOTIFICATION_ID = 1000; + @VisibleForTesting + static final int EVENT_SHOW_NO_UPSTREAM = 1; + // Id to update and cancel enable notification. Must be unique within the tethering app. + @VisibleForTesting + static final int ENABLE_NOTIFICATION_ID = 1000; // Id to update and cancel restricted notification. Must be unique within the tethering app. - private static final int RESTRICTED_NOTIFICATION_ID = 1001; + @VisibleForTesting + static final int RESTRICTED_NOTIFICATION_ID = 1001; + // Id to update and cancel no upstream notification. Must be unique within the tethering app. + @VisibleForTesting + static final int NO_UPSTREAM_NOTIFICATION_ID = 1002; @VisibleForTesting static final int NO_ICON_ID = 0; @VisibleForTesting @@ -71,14 +92,16 @@ public class TetheringNotificationUpdater { private final Context mContext; private final NotificationManager mNotificationManager; private final NotificationChannel mChannel; + private final Handler mHandler; // WARNING : the constructor is called on a different thread. Thread safety therefore - // relies on this value being initialized to 0, and not any other value. If you need + // relies on these values being initialized to 0 or false, and not any other value. If you need // to change this, you will need to change the thread where the constructor is invoked, // or to introduce synchronization. // Downstream type is one of ConnectivityManager.TETHERING_* constants, 0 1 or 2. // This value has to be made 1 2 and 4, and OR'd with the others. private int mDownstreamTypesMask = DOWNSTREAM_NONE; + private boolean mNoUpstream = false; // WARNING : this value is not able to being initialized to 0 and must have volatile because // telephony service is not guaranteed that is up before tethering service starts. If telephony @@ -87,10 +110,30 @@ public class TetheringNotificationUpdater { // INVALID_SUBSCRIPTION_ID. private volatile int mActiveDataSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; - @IntDef({ENABLE_NOTIFICATION_ID, RESTRICTED_NOTIFICATION_ID}) + @IntDef({ENABLE_NOTIFICATION_ID, RESTRICTED_NOTIFICATION_ID, NO_UPSTREAM_NOTIFICATION_ID}) @interface NotificationId {} - public TetheringNotificationUpdater(@NonNull final Context context) { + private static final class MccMncOverrideInfo { + public final List<String> visitedMccMncs; + public final int homeMcc; + public final int homeMnc; + MccMncOverrideInfo(List<String> visitedMccMncs, int mcc, int mnc) { + this.visitedMccMncs = visitedMccMncs; + this.homeMcc = mcc; + this.homeMnc = mnc; + } + } + + private static final SparseArray<MccMncOverrideInfo> sCarrierIdToMccMnc = new SparseArray<>(); + + static { + // VZW + sCarrierIdToMccMnc.put( + 1839, new MccMncOverrideInfo(Arrays.asList(new String[] {"20404"}), 311, 480)); + } + + public TetheringNotificationUpdater(@NonNull final Context context, + @NonNull final Looper looper) { mContext = context; mNotificationManager = (NotificationManager) context.createContextAsUser(UserHandle.ALL, 0) .getSystemService(Context.NOTIFICATION_SERVICE); @@ -99,6 +142,22 @@ public class TetheringNotificationUpdater { context.getResources().getString(R.string.notification_channel_tethering_status), NotificationManager.IMPORTANCE_LOW); mNotificationManager.createNotificationChannel(mChannel); + mHandler = new NotificationHandler(looper); + } + + private class NotificationHandler extends Handler { + NotificationHandler(Looper looper) { + super(looper); + } + + @Override + public void handleMessage(Message msg) { + switch(msg.what) { + case EVENT_SHOW_NO_UPSTREAM: + notifyTetheringNoUpstream(); + break; + } + } } /** Called when downstream has changed */ @@ -106,6 +165,7 @@ public class TetheringNotificationUpdater { if (mDownstreamTypesMask == downstreamTypesMask) return; mDownstreamTypesMask = downstreamTypesMask; updateEnableNotification(); + updateNoUpstreamNotification(); } /** Called when active data subscription id changed */ @@ -113,21 +173,62 @@ public class TetheringNotificationUpdater { if (mActiveDataSubId == subId) return; mActiveDataSubId = subId; updateEnableNotification(); + updateNoUpstreamNotification(); } + /** Called when upstream network changed */ + public void onUpstreamNetworkChanged(@Nullable final Network network) { + final boolean isNoUpstream = (network == null); + if (mNoUpstream == isNoUpstream) return; + mNoUpstream = isNoUpstream; + updateNoUpstreamNotification(); + } + + @NonNull @VisibleForTesting - Resources getResourcesForSubId(@NonNull final Context c, final int subId) { - return SubscriptionManager.getResourcesForSubId(c, subId); + final Handler getHandler() { + return mHandler; + } + + @NonNull + @VisibleForTesting + Resources getResourcesForSubId(@NonNull final Context context, final int subId) { + final Resources res = SubscriptionManager.getResourcesForSubId(context, subId); + final TelephonyManager tm = + ((TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE)) + .createForSubscriptionId(mActiveDataSubId); + final int carrierId = tm.getSimCarrierId(); + final String mccmnc = tm.getSimOperator(); + final MccMncOverrideInfo overrideInfo = sCarrierIdToMccMnc.get(carrierId); + if (overrideInfo != null && overrideInfo.visitedMccMncs.contains(mccmnc)) { + // Re-configure MCC/MNC value to specific carrier to get right resources. + final Configuration config = res.getConfiguration(); + config.mcc = overrideInfo.homeMcc; + config.mnc = overrideInfo.homeMnc; + return context.createConfigurationContext(config).getResources(); + } + return res; } private void updateEnableNotification() { - final boolean tetheringInactive = mDownstreamTypesMask <= DOWNSTREAM_NONE; + final boolean tetheringInactive = mDownstreamTypesMask == DOWNSTREAM_NONE; if (tetheringInactive || setupNotification() == NO_NOTIFY) { clearNotification(ENABLE_NOTIFICATION_ID); } } + private void updateNoUpstreamNotification() { + final boolean tetheringInactive = mDownstreamTypesMask == DOWNSTREAM_NONE; + + if (tetheringInactive + || !mNoUpstream + || setupNoUpstreamNotification() == NO_NOTIFY) { + clearNotification(NO_UPSTREAM_NOTIFICATION_ID); + mHandler.removeMessages(EVENT_SHOW_NO_UPSTREAM); + } + } + @VisibleForTesting void tetheringRestrictionLifted() { clearNotification(RESTRICTED_NOTIFICATION_ID); @@ -142,9 +243,38 @@ public class TetheringNotificationUpdater { final Resources res = getResourcesForSubId(mContext, mActiveDataSubId); final String title = res.getString(R.string.disable_tether_notification_title); final String message = res.getString(R.string.disable_tether_notification_message); + if (isEmpty(title) || isEmpty(message)) return; + + final PendingIntent pi = PendingIntent.getActivity( + mContext.createContextAsUser(UserHandle.CURRENT, 0 /* flags */), + 0 /* requestCode */, + new Intent(Settings.ACTION_TETHER_SETTINGS), + Intent.FLAG_ACTIVITY_NEW_TASK, + null /* options */); + + showNotification(R.drawable.stat_sys_tether_general, title, message, + RESTRICTED_NOTIFICATION_ID, pi, new Action[0]); + } + + private void notifyTetheringNoUpstream() { + final Resources res = getResourcesForSubId(mContext, mActiveDataSubId); + final String title = res.getString(R.string.no_upstream_notification_title); + final String message = res.getString(R.string.no_upstream_notification_message); + final String disableButton = + res.getString(R.string.no_upstream_notification_disable_button); + if (isEmpty(title) || isEmpty(message) || isEmpty(disableButton)) return; + + final Intent intent = new Intent(ACTION_DISABLE_TETHERING); + intent.setPackage(mContext.getPackageName()); + final PendingIntent pi = PendingIntent.getBroadcast( + mContext.createContextAsUser(UserHandle.CURRENT, 0 /* flags */), + 0 /* requestCode */, + intent, + 0 /* flags */); + final Action action = new Action.Builder(NO_ICON_ID, disableButton, pi).build(); showNotification(R.drawable.stat_sys_tether_general, title, message, - RESTRICTED_NOTIFICATION_ID); + NO_UPSTREAM_NOTIFICATION_ID, null /* pendingIntent */, action); } /** @@ -179,12 +309,13 @@ public class TetheringNotificationUpdater { * * @return {@link android.util.SparseArray} with downstream types and icon id info. */ + @NonNull @VisibleForTesting SparseArray<Integer> getIcons(@ArrayRes int id, @NonNull Resources res) { final String[] array = res.getStringArray(id); final SparseArray<Integer> icons = new SparseArray<>(); for (String config : array) { - if (TextUtils.isEmpty(config)) continue; + if (isEmpty(config)) continue; final String[] elements = config.split(";"); if (elements.length != 2) { @@ -204,6 +335,18 @@ public class TetheringNotificationUpdater { return icons; } + private boolean setupNoUpstreamNotification() { + final Resources res = getResourcesForSubId(mContext, mActiveDataSubId); + final int delayToShowUpstreamNotification = + res.getInteger(R.integer.delay_to_show_no_upstream_after_no_backhaul); + + if (delayToShowUpstreamNotification < 0) return NO_NOTIFY; + + mHandler.sendMessageDelayed(mHandler.obtainMessage(EVENT_SHOW_NO_UPSTREAM), + delayToShowUpstreamNotification); + return NOTIFY_DONE; + } + private boolean setupNotification() { final Resources res = getResourcesForSubId(mContext, mActiveDataSubId); final SparseArray<Integer> downstreamIcons = @@ -214,17 +357,22 @@ public class TetheringNotificationUpdater { final String title = res.getString(R.string.tethering_notification_title); final String message = res.getString(R.string.tethering_notification_message); + if (isEmpty(title) || isEmpty(message)) return NO_NOTIFY; - showNotification(iconId, title, message, ENABLE_NOTIFICATION_ID); + final PendingIntent pi = PendingIntent.getActivity( + mContext.createContextAsUser(UserHandle.CURRENT, 0 /* flags */), + 0 /* requestCode */, + new Intent(Settings.ACTION_TETHER_SETTINGS), + Intent.FLAG_ACTIVITY_NEW_TASK, + null /* options */); + + showNotification(iconId, title, message, ENABLE_NOTIFICATION_ID, pi, new Action[0]); return NOTIFY_DONE; } private void showNotification(@DrawableRes final int iconId, @NonNull final String title, - @NonNull final String message, @NotificationId final int id) { - final Intent intent = new Intent(Settings.ACTION_TETHER_SETTINGS); - final PendingIntent pi = PendingIntent.getActivity( - mContext.createContextAsUser(UserHandle.CURRENT, 0), - 0 /* requestCode */, intent, 0 /* flags */, null /* options */); + @NonNull final String message, @NotificationId final int id, @Nullable PendingIntent pi, + @NonNull final Action... actions) { final Notification notification = new Notification.Builder(mContext, mChannel.getId()) .setSmallIcon(iconId) @@ -236,6 +384,7 @@ public class TetheringNotificationUpdater { .setVisibility(Notification.VISIBILITY_PUBLIC) .setCategory(Notification.CATEGORY_STATUS) .setContentIntent(pi) + .setActions(actions) .build(); mNotificationManager.notify(null /* tag */, id, notification); 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 55640db69324..31eaabff5274 100644 --- a/packages/Tethering/tests/unit/AndroidManifest.xml +++ b/packages/Tethering/tests/unit/AndroidManifest.xml @@ -16,6 +16,7 @@ <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.networkstack.tethering.tests.unit"> + <uses-permission android:name="android.permission.READ_PHONE_STATE"/> <uses-permission android:name="android.permission.TETHER_PRIVILEGED"/> <application android:debuggable="true"> diff --git a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringNotificationUpdaterTest.kt b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringNotificationUpdaterTest.kt index 7bff74b25d94..5f8858857c75 100644 --- a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringNotificationUpdaterTest.kt +++ b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringNotificationUpdaterTest.kt @@ -23,14 +23,26 @@ import android.content.res.Resources import android.net.ConnectivityManager.TETHERING_BLUETOOTH import android.net.ConnectivityManager.TETHERING_USB import android.net.ConnectivityManager.TETHERING_WIFI +import android.net.Network +import android.os.Handler +import android.os.HandlerThread +import android.os.Looper import android.os.UserHandle import android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID -import androidx.test.platform.app.InstrumentationRegistry +import android.telephony.TelephonyManager import androidx.test.filters.SmallTest +import androidx.test.platform.app.InstrumentationRegistry import androidx.test.runner.AndroidJUnit4 import com.android.internal.util.test.BroadcastInterceptingContext import com.android.networkstack.tethering.TetheringNotificationUpdater.DOWNSTREAM_NONE +import com.android.networkstack.tethering.TetheringNotificationUpdater.ENABLE_NOTIFICATION_ID +import com.android.networkstack.tethering.TetheringNotificationUpdater.EVENT_SHOW_NO_UPSTREAM +import com.android.networkstack.tethering.TetheringNotificationUpdater.NO_UPSTREAM_NOTIFICATION_ID +import com.android.networkstack.tethering.TetheringNotificationUpdater.RESTRICTED_NOTIFICATION_ID +import com.android.testutils.waitForIdle +import org.junit.After import org.junit.Assert.assertEquals +import org.junit.Assert.fail import org.junit.Before import org.junit.Test import org.junit.runner.RunWith @@ -43,8 +55,8 @@ import org.mockito.Mockito.doReturn import org.mockito.Mockito.never import org.mockito.Mockito.reset import org.mockito.Mockito.times -import org.mockito.Mockito.verifyZeroInteractions import org.mockito.Mockito.verify +import org.mockito.Mockito.verifyZeroInteractions import org.mockito.MockitoAnnotations const val TEST_SUBID = 1 @@ -55,10 +67,13 @@ const val GENERAL_ICON_ID = 4 const val WIFI_MASK = 1 shl TETHERING_WIFI const val USB_MASK = 1 shl TETHERING_USB const val BT_MASK = 1 shl TETHERING_BLUETOOTH -const val TITTLE = "Tethering active" +const val TITLE = "Tethering active" const val MESSAGE = "Tap here to set up." -const val TEST_TITTLE = "Hotspot active" +const val TEST_TITLE = "Hotspot active" const val TEST_MESSAGE = "Tap to set up hotspot." +const val TEST_NO_UPSTREAM_TITLE = "Hotspot has no internet access" +const val TEST_NO_UPSTREAM_MESSAGE = "Device cannot connect to internet." +const val TEST_NO_UPSTREAM_BUTTON = "Turn off hotspot" @RunWith(AndroidJUnit4::class) @SmallTest @@ -67,12 +82,15 @@ class TetheringNotificationUpdaterTest { // should crash if they are used before being initialized. @Mock private lateinit var mockContext: Context @Mock private lateinit var notificationManager: NotificationManager + @Mock private lateinit var telephonyManager: TelephonyManager @Mock private lateinit var defaultResources: Resources @Mock private lateinit var testResources: Resources - // lateinit for this class under test, as it should be reset to a different instance for every - // tests but should always be initialized before use (or the test should crash). + // lateinit for these classes under test, as they should be reset to a different instance for + // every test but should always be initialized before use (or the test should crash). + private lateinit var context: TestContext private lateinit var notificationUpdater: TetheringNotificationUpdater + private lateinit var fakeTetheringThread: HandlerThread private val ENABLE_ICON_CONFIGS = arrayOf( "USB;android.test:drawable/usb", "BT;android.test:drawable/bluetooth", @@ -82,11 +100,19 @@ class TetheringNotificationUpdaterTest { private inner class TestContext(c: Context) : BroadcastInterceptingContext(c) { override fun createContextAsUser(user: UserHandle, flags: Int) = if (user == UserHandle.ALL) mockContext else this + override fun getSystemService(name: String) = + if (name == Context.TELEPHONY_SERVICE) telephonyManager + else super.getSystemService(name) } - private inner class WrappedNotificationUpdater(c: Context) : TetheringNotificationUpdater(c) { + private inner class WrappedNotificationUpdater(c: Context, looper: Looper) + : TetheringNotificationUpdater(c, looper) { override fun getResourcesForSubId(context: Context, subId: Int) = - if (subId == TEST_SUBID) testResources else defaultResources + when (subId) { + TEST_SUBID -> testResources + INVALID_SUBSCRIPTION_ID -> defaultResources + else -> super.getResourcesForSubId(context, subId) + } } private fun setupResources() { @@ -94,12 +120,20 @@ class TetheringNotificationUpdaterTest { .getStringArray(R.array.tethering_notification_icons) doReturn(arrayOf("WIFI;android.test:drawable/wifi")).`when`(testResources) .getStringArray(R.array.tethering_notification_icons) - doReturn(TITTLE).`when`(defaultResources).getString(R.string.tethering_notification_title) + doReturn(5).`when`(testResources) + .getInteger(R.integer.delay_to_show_no_upstream_after_no_backhaul) + doReturn(TITLE).`when`(defaultResources).getString(R.string.tethering_notification_title) doReturn(MESSAGE).`when`(defaultResources) .getString(R.string.tethering_notification_message) - doReturn(TEST_TITTLE).`when`(testResources).getString(R.string.tethering_notification_title) + doReturn(TEST_TITLE).`when`(testResources).getString(R.string.tethering_notification_title) doReturn(TEST_MESSAGE).`when`(testResources) .getString(R.string.tethering_notification_message) + doReturn(TEST_NO_UPSTREAM_TITLE).`when`(testResources) + .getString(R.string.no_upstream_notification_title) + doReturn(TEST_NO_UPSTREAM_MESSAGE).`when`(testResources) + .getString(R.string.no_upstream_notification_message) + doReturn(TEST_NO_UPSTREAM_BUTTON).`when`(testResources) + .getString(R.string.no_upstream_notification_disable_button) doReturn(USB_ICON_ID).`when`(defaultResources) .getIdentifier(eq("android.test:drawable/usb"), any(), any()) doReturn(BT_ICON_ID).`when`(defaultResources) @@ -113,35 +147,61 @@ class TetheringNotificationUpdaterTest { @Before fun setUp() { MockitoAnnotations.initMocks(this) - val context = TestContext(InstrumentationRegistry.getInstrumentation().context) + context = TestContext(InstrumentationRegistry.getInstrumentation().context) doReturn(notificationManager).`when`(mockContext) .getSystemService(Context.NOTIFICATION_SERVICE) - notificationUpdater = WrappedNotificationUpdater(context) + fakeTetheringThread = HandlerThread(this::class.simpleName) + fakeTetheringThread.start() + notificationUpdater = WrappedNotificationUpdater(context, fakeTetheringThread.looper) setupResources() } + @After + fun tearDown() { + fakeTetheringThread.quitSafely() + } + private fun Notification.title() = this.extras.getString(Notification.EXTRA_TITLE) private fun Notification.text() = this.extras.getString(Notification.EXTRA_TEXT) - private fun verifyNotification(iconId: Int = 0, title: String = "", text: String = "") { - verify(notificationManager, never()).cancel(any(), anyInt()) + private fun verifyNotification(iconId: Int, title: String, text: String, id: Int) { + verify(notificationManager, never()).cancel(any(), eq(id)) val notificationCaptor = ArgumentCaptor.forClass(Notification::class.java) verify(notificationManager, times(1)) - .notify(any(), anyInt(), notificationCaptor.capture()) + .notify(any(), eq(id), notificationCaptor.capture()) val notification = notificationCaptor.getValue() assertEquals(iconId, notification.smallIcon.resId) assertEquals(title, notification.title()) assertEquals(text, notification.text()) + } + + private fun verifyNotificationCancelled(id: Int) = + verify(notificationManager, times(1)).cancel(any(), eq(id)) + private val tetheringActiveNotifications = + listOf(NO_UPSTREAM_NOTIFICATION_ID, ENABLE_NOTIFICATION_ID) + + private fun verifyCancelAllTetheringActiveNotifications() { + tetheringActiveNotifications.forEach { + verifyNotificationCancelled(it) + } reset(notificationManager) } - private fun verifyNoNotification() { - verify(notificationManager, times(1)).cancel(any(), anyInt()) - verify(notificationManager, never()).notify(any(), anyInt(), any()) - + private fun verifyOnlyTetheringActiveNotification( + notifyId: Int, + iconId: Int, + title: String, + text: String + ) { + tetheringActiveNotifications.forEach { + when (it) { + notifyId -> verifyNotification(iconId, title, text, notifyId) + else -> verifyNotificationCancelled(it) + } + } reset(notificationManager) } @@ -149,7 +209,7 @@ class TetheringNotificationUpdaterTest { fun testNotificationWithDownstreamChanged() { // Wifi downstream. No notification. notificationUpdater.onDownstreamChanged(WIFI_MASK) - verifyNoNotification() + verifyCancelAllTetheringActiveNotifications() // Same downstream changed. Nothing happened. notificationUpdater.onDownstreamChanged(WIFI_MASK) @@ -157,22 +217,23 @@ class TetheringNotificationUpdaterTest { // Wifi and usb downstreams. Show enable notification notificationUpdater.onDownstreamChanged(WIFI_MASK or USB_MASK) - verifyNotification(GENERAL_ICON_ID, TITTLE, MESSAGE) + verifyOnlyTetheringActiveNotification( + ENABLE_NOTIFICATION_ID, GENERAL_ICON_ID, TITLE, MESSAGE) // Usb downstream. Still show enable notification. notificationUpdater.onDownstreamChanged(USB_MASK) - verifyNotification(USB_ICON_ID, TITTLE, MESSAGE) + verifyOnlyTetheringActiveNotification(ENABLE_NOTIFICATION_ID, USB_ICON_ID, TITLE, MESSAGE) // No downstream. No notification. notificationUpdater.onDownstreamChanged(DOWNSTREAM_NONE) - verifyNoNotification() + verifyCancelAllTetheringActiveNotifications() } @Test fun testNotificationWithActiveDataSubscriptionIdChanged() { // Usb downstream. Showed enable notification with default resource. notificationUpdater.onDownstreamChanged(USB_MASK) - verifyNotification(USB_ICON_ID, TITTLE, MESSAGE) + verifyOnlyTetheringActiveNotification(ENABLE_NOTIFICATION_ID, USB_ICON_ID, TITLE, MESSAGE) // Same subId changed. Nothing happened. notificationUpdater.onActiveDataSubscriptionIdChanged(INVALID_SUBSCRIPTION_ID) @@ -180,15 +241,16 @@ class TetheringNotificationUpdaterTest { // Set test sub id. Clear notification with test resource. notificationUpdater.onActiveDataSubscriptionIdChanged(TEST_SUBID) - verifyNoNotification() + verifyCancelAllTetheringActiveNotifications() // Wifi downstream. Show enable notification with test resource. notificationUpdater.onDownstreamChanged(WIFI_MASK) - verifyNotification(WIFI_ICON_ID, TEST_TITTLE, TEST_MESSAGE) + verifyOnlyTetheringActiveNotification( + ENABLE_NOTIFICATION_ID, WIFI_ICON_ID, TEST_TITLE, TEST_MESSAGE) // No downstream. No notification. notificationUpdater.onDownstreamChanged(DOWNSTREAM_NONE) - verifyNoNotification() + verifyCancelAllTetheringActiveNotifications() } private fun assertIconNumbers(number: Int, configs: Array<String?>) { @@ -227,10 +289,8 @@ class TetheringNotificationUpdaterTest { @Test fun testSetupRestrictedNotification() { - val title = InstrumentationRegistry.getInstrumentation().context.resources - .getString(R.string.disable_tether_notification_title) - val message = InstrumentationRegistry.getInstrumentation().context.resources - .getString(R.string.disable_tether_notification_message) + val title = context.resources.getString(R.string.disable_tether_notification_title) + val message = context.resources.getString(R.string.disable_tether_notification_message) val disallowTitle = "Tether function is disallowed" val disallowMessage = "Please contact your admin" doReturn(title).`when`(defaultResources) @@ -244,18 +304,127 @@ class TetheringNotificationUpdaterTest { // User restrictions on. Show restricted notification. notificationUpdater.notifyTetheringDisabledByRestriction() - verifyNotification(R.drawable.stat_sys_tether_general, title, message) + verifyNotification(R.drawable.stat_sys_tether_general, title, message, + RESTRICTED_NOTIFICATION_ID) + reset(notificationManager) // User restrictions off. Clear notification. notificationUpdater.tetheringRestrictionLifted() - verifyNoNotification() + verifyNotificationCancelled(RESTRICTED_NOTIFICATION_ID) + reset(notificationManager) // Set test sub id. No notification. notificationUpdater.onActiveDataSubscriptionIdChanged(TEST_SUBID) - verifyNoNotification() + verifyCancelAllTetheringActiveNotifications() // User restrictions on again. Show restricted notification with test resource. notificationUpdater.notifyTetheringDisabledByRestriction() - verifyNotification(R.drawable.stat_sys_tether_general, disallowTitle, disallowMessage) + verifyNotification(R.drawable.stat_sys_tether_general, disallowTitle, disallowMessage, + RESTRICTED_NOTIFICATION_ID) + reset(notificationManager) + } + + val MAX_BACKOFF_MS = 200L + /** + * Waits for all messages, including delayed ones, to be processed. + * + * This will wait until the handler has no more messages to be processed including + * delayed ones, or the timeout has expired. It uses an exponential backoff strategy + * to wait longer and longer to consume less CPU, with the max granularity being + * MAX_BACKOFF_MS. + * + * @return true if all messages have been processed including delayed ones, false if timeout + * + * TODO: Move this method to com.android.testutils.HandlerUtils.kt. + */ + private fun Handler.waitForDelayedMessage(what: Int?, timeoutMs: Long) { + fun hasMatchingMessages() = + if (what == null) hasMessagesOrCallbacks() else hasMessages(what) + val expiry = System.currentTimeMillis() + timeoutMs + var delay = 5L + while (System.currentTimeMillis() < expiry && hasMatchingMessages()) { + // None of Handler, Looper, Message and MessageQueue expose any way to retrieve + // the time when the next (let alone the last) message will be processed, so + // short of examining the internals with reflection sleep() is the only solution. + Thread.sleep(delay) + delay = (delay * 2) + .coerceAtMost(expiry - System.currentTimeMillis()) + .coerceAtMost(MAX_BACKOFF_MS) + } + + val timeout = expiry - System.currentTimeMillis() + if (timeout <= 0) fail("Delayed message did not process yet after ${timeoutMs}ms") + waitForIdle(timeout) + } + + @Test + fun testNotificationWithUpstreamNetworkChanged() { + // Set test sub id. No notification. + notificationUpdater.onActiveDataSubscriptionIdChanged(TEST_SUBID) + verifyCancelAllTetheringActiveNotifications() + + // Wifi downstream. Show enable notification with test resource. + notificationUpdater.onDownstreamChanged(WIFI_MASK) + verifyOnlyTetheringActiveNotification( + ENABLE_NOTIFICATION_ID, WIFI_ICON_ID, TEST_TITLE, TEST_MESSAGE) + + // There is no upstream. Show no upstream notification. + notificationUpdater.onUpstreamNetworkChanged(null) + notificationUpdater.handler.waitForDelayedMessage(EVENT_SHOW_NO_UPSTREAM, 500L) + verifyNotification(R.drawable.stat_sys_tether_general, TEST_NO_UPSTREAM_TITLE, + TEST_NO_UPSTREAM_MESSAGE, NO_UPSTREAM_NOTIFICATION_ID) + reset(notificationManager) + + // Same upstream network changed. Nothing happened. + notificationUpdater.onUpstreamNetworkChanged(null) + verifyZeroInteractions(notificationManager) + + // Upstream come back. Clear no upstream notification. + notificationUpdater.onUpstreamNetworkChanged(Network(1000)) + verifyNotificationCancelled(NO_UPSTREAM_NOTIFICATION_ID) + reset(notificationManager) + + // No upstream again. Show no upstream notification. + notificationUpdater.onUpstreamNetworkChanged(null) + notificationUpdater.handler.waitForDelayedMessage(EVENT_SHOW_NO_UPSTREAM, 500L) + verifyNotification(R.drawable.stat_sys_tether_general, TEST_NO_UPSTREAM_TITLE, + TEST_NO_UPSTREAM_MESSAGE, NO_UPSTREAM_NOTIFICATION_ID) + reset(notificationManager) + + // No downstream. No notification. + notificationUpdater.onDownstreamChanged(DOWNSTREAM_NONE) + verifyCancelAllTetheringActiveNotifications() + + // Set R.integer.delay_to_show_no_upstream_after_no_backhaul to 0 and have wifi downstream + // again. Show enable notification only. + doReturn(-1).`when`(testResources) + .getInteger(R.integer.delay_to_show_no_upstream_after_no_backhaul) + notificationUpdater.onDownstreamChanged(WIFI_MASK) + notificationUpdater.handler.waitForDelayedMessage(EVENT_SHOW_NO_UPSTREAM, 500L) + verifyOnlyTetheringActiveNotification( + ENABLE_NOTIFICATION_ID, WIFI_ICON_ID, TEST_TITLE, TEST_MESSAGE) + } + + @Test + fun testGetResourcesForSubId() { + doReturn(telephonyManager).`when`(telephonyManager).createForSubscriptionId(anyInt()) + doReturn(1234).`when`(telephonyManager).getSimCarrierId() + doReturn("000000").`when`(telephonyManager).getSimOperator() + + val subId = -2 // Use invalid subId to avoid getting resource from cache or real subId. + val config = context.resources.configuration + var res = notificationUpdater.getResourcesForSubId(context, subId) + assertEquals(config.mcc, res.configuration.mcc) + assertEquals(config.mnc, res.configuration.mnc) + + doReturn(1839).`when`(telephonyManager).getSimCarrierId() + res = notificationUpdater.getResourcesForSubId(context, subId) + assertEquals(config.mcc, res.configuration.mcc) + assertEquals(config.mnc, res.configuration.mnc) + + doReturn("20404").`when`(telephonyManager).getSimOperator() + res = notificationUpdater.getResourcesForSubId(context, subId) + assertEquals(311, res.configuration.mcc) + assertEquals(480, res.configuration.mnc) } } diff --git a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java index d4be3a26d958..feb99e6b248d 100644 --- a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java +++ b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java @@ -383,7 +383,7 @@ public class TetheringTest { } @Override - public TetheringNotificationUpdater getNotificationUpdater(Context ctx) { + public TetheringNotificationUpdater getNotificationUpdater(Context ctx, Looper looper) { return mNotificationUpdater; } } @@ -1691,6 +1691,18 @@ public class TetheringTest { assertEquals(clientAddrParceled, params.clientAddr); } + @Test + public void testUpstreamNetworkChanged() { + final Tethering.TetherMasterSM stateMachine = (Tethering.TetherMasterSM) + mTetheringDependencies.mUpstreamNetworkMonitorMasterSM; + final UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState(); + when(mUpstreamNetworkMonitor.selectPreferredUpstreamType(any())).thenReturn(upstreamState); + stateMachine.chooseUpstreamType(true); + + verify(mUpstreamNetworkMonitor, times(1)).setCurrentUpstream(eq(upstreamState.network)); + verify(mNotificationUpdater, times(1)).onUpstreamNetworkChanged(eq(upstreamState.network)); + } + // TODO: Test that a request for hotspot mode doesn't interfere with an // already operating tethering mode interface. } 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/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java index 7230b00f87ad..d252f9e69a22 100644 --- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java +++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java @@ -2441,7 +2441,11 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub * accessibility button. * 2) For {@link AccessibilityManager#ACCESSIBILITY_SHORTCUT_KEY} type and service targeting sdk * version <= Q: turns on / off the accessibility service. - * 3) For services targeting sdk version > Q: + * 3) For {@link AccessibilityManager#ACCESSIBILITY_SHORTCUT_KEY} type and service targeting sdk + * version > Q and request accessibility button: turn on the accessibility service if it's + * not in the enabled state. + * (It'll happen when a service is disabled and assigned to shortcut then upgraded.) + * 4) For services targeting sdk version > Q: * a) Turns on / off the accessibility service, if service does not request accessibility * button. * b) Callbacks to accessibility service if service is bounded and requests accessibility @@ -2475,6 +2479,13 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub } return true; } + if (shortcutType == ACCESSIBILITY_SHORTCUT_KEY && targetSdk > Build.VERSION_CODES.Q + && requestA11yButton) { + if (!userState.getEnabledServicesLocked().contains(assignedTarget)) { + enableAccessibilityServiceLocked(assignedTarget, mCurrentUserId); + return true; + } + } // Callbacks to a11y service if it's bounded and requests a11y button. if (serviceConnection == null || !userState.mBoundServices.contains(serviceConnection) diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java index 3d6861898aaf..9d1ad4239a24 100644 --- a/services/autofill/java/com/android/server/autofill/Session.java +++ b/services/autofill/java/com/android/server/autofill/Session.java @@ -2653,6 +2653,11 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState } else if (viewState.id.equals(this.mCurrentViewId) && (viewState.getState() & ViewState.STATE_INLINE_SHOWN) != 0) { requestShowInlineSuggestionsLocked(viewState.getResponse(), filterText); + } else if (viewState.id.equals(this.mCurrentViewId) + && (viewState.getState() & ViewState.STATE_TRIGGERED_AUGMENTED_AUTOFILL) != 0) { + if (!TextUtils.isEmpty(filterText)) { + mInlineSessionController.hideInlineSuggestionsUiLocked(mCurrentViewId); + } } viewState.setState(ViewState.STATE_CHANGED); 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/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java index 31bcceaba889..8ecda8f1a131 100644 --- a/services/core/java/com/android/server/appop/AppOpsService.java +++ b/services/core/java/com/android/server/appop/AppOpsService.java @@ -2830,7 +2830,6 @@ public class AppOpsService extends IAppOpsService.Stub { private int checkOperationImpl(int code, int uid, String packageName, boolean raw) { - verifyIncomingUid(uid); verifyIncomingOp(code); String resolvedPackageName = resolvePackageName(uid, packageName); if (resolvedPackageName == null) { 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 ae22e69f5b1b..f840f2d359d5 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); 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/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/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java index a87fb8b5c301..b4f7cdbd5694 100644 --- a/services/core/java/com/android/server/display/DisplayManagerService.java +++ b/services/core/java/com/android/server/display/DisplayManagerService.java @@ -552,7 +552,8 @@ public final class DisplayManagerService extends SystemService { } if (state == Display.STATE_OFF) { brightnessState = PowerManager.BRIGHTNESS_OFF_FLOAT; - } else if (brightnessState < PowerManager.BRIGHTNESS_MIN || Float.isNaN(brightnessState)) { + } else if (brightnessState != PowerManager.BRIGHTNESS_OFF_FLOAT + && brightnessState < PowerManager.BRIGHTNESS_MIN) { brightnessState = PowerManager.BRIGHTNESS_INVALID_FLOAT; } else if (brightnessState > PowerManager.BRIGHTNESS_MAX) { brightnessState = PowerManager.BRIGHTNESS_MAX; 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/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/location/GeofenceManager.java b/services/core/java/com/android/server/location/GeofenceManager.java index 195b059b7374..095cd146da4f 100644 --- a/services/core/java/com/android/server/location/GeofenceManager.java +++ b/services/core/java/com/android/server/location/GeofenceManager.java @@ -253,7 +253,7 @@ public class GeofenceManager implements LocationListener, PendingIntent.OnFinish int op = CallerIdentity.asAppOp(identity.permissionLevel); if (op >= 0) { if (mAppOps.noteOpNoThrow(AppOpsManager.OP_FINE_LOCATION, identity.uid, - identity.packageName, identity.featureId, null) + identity.packageName, identity.featureId, identity.listenerId) != AppOpsManager.MODE_ALLOWED) { continue; } 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/SystemMediaRoute2Provider.java b/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java index 6e2feeb15e21..1345e3759d2f 100644 --- a/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java +++ b/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java @@ -261,8 +261,10 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { .build(); builder.addSelectedRoute(mSelectedRouteId); - for (MediaRoute2Info route : mBtRouteProvider.getTransferableRoutes()) { - builder.addTransferableRoute(route.getId()); + if (mBtRouteProvider != null) { + for (MediaRoute2Info route : mBtRouteProvider.getTransferableRoutes()) { + builder.addTransferableRoute(route.getId()); + } } RoutingSessionInfo newSessionInfo = builder.setProviderId(mUniqueId).build(); 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/ConditionProviders.java b/services/core/java/com/android/server/notification/ConditionProviders.java index aed29272cada..e98326b620b2 100644 --- a/services/core/java/com/android/server/notification/ConditionProviders.java +++ b/services/core/java/com/android/server/notification/ConditionProviders.java @@ -30,6 +30,7 @@ import android.provider.Settings; import android.service.notification.Condition; import android.service.notification.ConditionProviderService; import android.service.notification.IConditionProvider; +import android.text.TextUtils; import android.util.ArrayMap; import android.util.ArraySet; import android.util.Slog; @@ -54,7 +55,6 @@ public class ConditionProviders extends ManagedServices { private final ArraySet<String> mSystemConditionProviderNames; private final ArraySet<SystemConditionProviderService> mSystemConditionProviders = new ArraySet<>(); - private Callback mCallback; public ConditionProviders(Context context, UserProfiles userProfiles, IPackageManager pm) { @@ -195,6 +195,21 @@ public class ConditionProviders extends ManagedServices { } @Override + protected void loadDefaultsFromConfig() { + String defaultDndAccess = mContext.getResources().getString( + R.string.config_defaultDndAccessPackages); + if (defaultDndAccess != null) { + String[] dnds = defaultDndAccess.split(ManagedServices.ENABLED_SERVICES_SEPARATOR); + for (int i = 0; i < dnds.length; i++) { + if (TextUtils.isEmpty(dnds[i])) { + continue; + } + addDefaultComponentOrPackage(dnds[i]); + } + } + } + + @Override protected void onServiceRemovedLocked(ManagedServiceInfo removed) { if (removed == null) return; for (int i = mRecords.size() - 1; i >= 0; i--) { diff --git a/services/core/java/com/android/server/notification/ManagedServices.java b/services/core/java/com/android/server/notification/ManagedServices.java index 45df3686d056..5d3dc5f19714 100644 --- a/services/core/java/com/android/server/notification/ManagedServices.java +++ b/services/core/java/com/android/server/notification/ManagedServices.java @@ -21,6 +21,7 @@ import static android.content.Context.BIND_AUTO_CREATE; import static android.content.Context.BIND_FOREGROUND_SERVICE; import static android.content.Context.DEVICE_POLICY_SERVICE; import static android.os.UserHandle.USER_ALL; +import static android.os.UserHandle.USER_SYSTEM; import android.annotation.NonNull; import android.app.ActivityManager; @@ -96,6 +97,8 @@ abstract public class ManagedServices { private static final int ON_BINDING_DIED_REBIND_DELAY_MS = 10000; protected static final String ENABLED_SERVICES_SEPARATOR = ":"; + private static final String DB_VERSION_1 = "1"; + /** * List of components and apps that can have running {@link ManagedServices}. @@ -107,7 +110,7 @@ abstract public class ManagedServices { static final String ATT_VERSION = "version"; static final String ATT_DEFAULTS = "defaults"; - static final int DB_VERSION = 1; + static final int DB_VERSION = 2; static final int APPROVAL_BY_PACKAGE = 0; static final int APPROVAL_BY_COMPONENT = 1; @@ -187,17 +190,22 @@ abstract public class ManagedServices { protected void addDefaultComponentOrPackage(String packageOrComponent) { if (!TextUtils.isEmpty(packageOrComponent)) { synchronized (mDefaultsLock) { - ComponentName cn = ComponentName.unflattenFromString(packageOrComponent); - if (cn == null) { + if (mApprovalLevel == APPROVAL_BY_PACKAGE) { mDefaultPackages.add(packageOrComponent); - } else { + return; + } + ComponentName cn = ComponentName.unflattenFromString(packageOrComponent); + if (cn != null && mApprovalLevel == APPROVAL_BY_COMPONENT) { mDefaultPackages.add(cn.getPackageName()); mDefaultComponents.add(cn); + return; } } } } + protected abstract void loadDefaultsFromConfig(); + boolean isDefaultComponentOrPackage(String packageOrComponent) { synchronized (mDefaultsLock) { ComponentName cn = ComponentName.unflattenFromString(packageOrComponent); @@ -504,19 +512,19 @@ abstract public class ManagedServices { void readDefaults(XmlPullParser parser) { String defaultComponents = XmlUtils.readStringAttribute(parser, ATT_DEFAULTS); - if (defaultComponents == null) { - return; - } - String[] components = defaultComponents.split(ENABLED_SERVICES_SEPARATOR); - synchronized (mDefaultsLock) { - for (int i = 0; i < components.length; i++) { - if (!TextUtils.isEmpty(components[i])) { - ComponentName cn = ComponentName.unflattenFromString(components[i]); - if (cn != null) { - mDefaultPackages.add(cn.getPackageName()); - mDefaultComponents.add(cn); - } else { - mDefaultPackages.add(components[i]); + + if (!TextUtils.isEmpty(defaultComponents)) { + String[] components = defaultComponents.split(ENABLED_SERVICES_SEPARATOR); + synchronized (mDefaultsLock) { + for (int i = 0; i < components.length; i++) { + if (!TextUtils.isEmpty(components[i])) { + ComponentName cn = ComponentName.unflattenFromString(components[i]); + if (cn != null) { + mDefaultPackages.add(cn.getPackageName()); + mDefaultComponents.add(cn); + } else { + mDefaultPackages.add(components[i]); + } } } } @@ -531,9 +539,11 @@ abstract public class ManagedServices { throws XmlPullParserException, IOException { // read grants int type; + String version = ""; readDefaults(parser); while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) { String tag = parser.getName(); + version = XmlUtils.readStringAttribute(parser, ATT_VERSION); if (type == XmlPullParser.END_TAG && getConfig().xmlTag.equals(tag)) { break; @@ -561,9 +571,38 @@ abstract public class ManagedServices { } } } + boolean isVersionOne = TextUtils.isEmpty(version) || DB_VERSION_1.equals(version); + if (isVersionOne) { + upgradeToVersionTwo(); + } rebindServices(false, USER_ALL); } + private void upgradeToVersionTwo() { + // check if any defaults are loaded + int defaultsSize = mDefaultComponents.size() + mDefaultPackages.size(); + if (defaultsSize == 0) { + // load defaults from current allowed + if (this.mApprovalLevel == APPROVAL_BY_COMPONENT) { + List<ComponentName> approvedComponents = getAllowedComponents(USER_SYSTEM); + for (int i = 0; i < approvedComponents.size(); i++) { + addDefaultComponentOrPackage(approvedComponents.get(i).flattenToString()); + } + } + if (this.mApprovalLevel == APPROVAL_BY_PACKAGE) { + List<String> approvedPkgs = getAllowedPackages(USER_SYSTEM); + for (int i = 0; i < approvedPkgs.size(); i++) { + addDefaultComponentOrPackage(approvedPkgs.get(i)); + } + } + } + // if no defaults are loaded, then load from config + defaultsSize = mDefaultComponents.size() + mDefaultPackages.size(); + if (defaultsSize == 0) { + loadDefaultsFromConfig(); + } + } + /** * Read extra attributes in the {@link #TAG_MANAGED_SERVICES} tag. */ diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 54efe543a29f..9b02b48f7825 100755 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -108,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; @@ -156,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; @@ -220,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; @@ -291,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; @@ -528,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() { @@ -547,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(); } @@ -555,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() { @@ -577,60 +586,25 @@ public class NotificationManagerService extends SystemService { return a.toArray(new StatusBarNotification[a.size()]); } - } + public void updateHistoryEnabled(@UserIdInt int userId, boolean enabled) { + mEnabled.put(userId, enabled); - void loadDefaultApprovedServices(int userId) { - String defaultListenerAccess = getContext().getResources().getString( - com.android.internal.R.string.config_defaultListenerAccessPackages); - if (defaultListenerAccess != null) { - String[] listeners = - defaultListenerAccess.split(ManagedServices.ENABLED_SERVICES_SEPARATOR); - for (int i = 0; i < listeners.length; i++) { - if (TextUtils.isEmpty(listeners[i])) { - continue; - } - ArraySet<ComponentName> approvedListeners = - mListeners.queryPackageForServices(listeners[i], - MATCH_DIRECT_BOOT_AWARE - | MATCH_DIRECT_BOOT_UNAWARE, userId); - for (int k = 0; k < approvedListeners.size(); k++) { - ComponentName cn = approvedListeners.valueAt(k); - mListeners.addDefaultComponentOrPackage(cn.flattenToString()); + if (!enabled) { + for (int i = mBuffer.size() - 1; i >= 0; i--) { + if (userId == mBuffer.get(i).first.getNormalizedUserId()) { + mBuffer.remove(i); + } } } } + } - String defaultDndAccess = getContext().getResources().getString( - com.android.internal.R.string.config_defaultDndAccessPackages); - if (defaultDndAccess != null) { - String[] dnds = defaultDndAccess.split(ManagedServices.ENABLED_SERVICES_SEPARATOR); - for (int i = 0; i < dnds.length; i++) { - if (TextUtils.isEmpty(dnds[i])) { - continue; - } - mConditionProviders.addDefaultComponentOrPackage(dnds[i]); - } - } + void loadDefaultApprovedServices(int userId) { + mListeners.loadDefaultsFromConfig(); + mConditionProviders.loadDefaultsFromConfig(); - ArraySet<String> assistants = new ArraySet<>(); - String deviceAssistant = DeviceConfig.getProperty( - DeviceConfig.NAMESPACE_SYSTEMUI, - SystemUiDeviceConfigFlags.NAS_DEFAULT_SERVICE); - if (deviceAssistant != null) { - assistants.addAll(Arrays.asList(deviceAssistant.split( - ManagedServices.ENABLED_SERVICES_SEPARATOR))); - } - assistants.addAll(Arrays.asList(getContext().getResources().getString( - com.android.internal.R.string.config_defaultAssistantAccessComponent) - .split(ManagedServices.ENABLED_SERVICES_SEPARATOR))); - for (int i = 0; i < assistants.size(); i++) { - String cnString = assistants.valueAt(i); - if (TextUtils.isEmpty(cnString)) { - continue; - } - mAssistants.addDefaultComponentOrPackage(cnString); - } + mAssistants.loadDefaultsFromConfig(); } protected void allowDefaultApprovedServices(int userId) { @@ -653,11 +627,14 @@ public class NotificationManagerService extends SystemService { DeviceConfig.NAMESPACE_SYSTEMUI, SystemUiDeviceConfigFlags.NAS_DEFAULT_SERVICE); if (overrideDefaultAssistantString != null) { - ComponentName overrideDefaultAssistant = - ComponentName.unflattenFromString(overrideDefaultAssistantString); - if (allowAssistant(userId, overrideDefaultAssistant)) return; + ArraySet<ComponentName> approved = mAssistants.queryPackageForServices( + overrideDefaultAssistantString, + MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, + userId); + for (int i = 0; i < approved.size(); i++) { + if (allowAssistant(userId, approved.valueAt(i))) return; + } } - ArraySet<ComponentName> defaults = mAssistants.getDefaultComponents(); // We should have only one default assistant by default // allowAssistant should execute once in practice @@ -1638,6 +1615,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); @@ -1653,10 +1633,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); } @@ -1681,6 +1663,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); + } + } } } @@ -1959,7 +1949,8 @@ public class NotificationManagerService extends SystemService { mPackageManagerClient, mRankingHandler, mZenModeHelper, - new NotificationChannelLoggerImpl()); + new NotificationChannelLoggerImpl(), + mAppOps); mRankingHelper = new RankingHelper(getContext(), mRankingHandler, mPreferencesHelper, @@ -2300,7 +2291,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); @@ -8568,6 +8560,26 @@ public class NotificationManagerService extends SystemService { private ArrayMap<Integer, Boolean> mUserSetMap = new ArrayMap<>(); private Set<String> mAllowedAdjustments = new ArraySet<>(); + @Override + protected void loadDefaultsFromConfig() { + ArraySet<String> assistants = new ArraySet<>(); + assistants.addAll(Arrays.asList(mContext.getResources().getString( + com.android.internal.R.string.config_defaultAssistantAccessComponent) + .split(ManagedServices.ENABLED_SERVICES_SEPARATOR))); + for (int i = 0; i < assistants.size(); i++) { + String cnString = assistants.valueAt(i); + if (TextUtils.isEmpty(cnString)) { + continue; + } + ArraySet<ComponentName> approved = queryPackageForServices(cnString, + MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, USER_SYSTEM); + for (int k = 0; k < approved.size(); k++) { + ComponentName cn = approved.valueAt(k); + addDefaultComponentOrPackage(cn.flattenToString()); + } + } + } + public NotificationAssistants(Context context, Object lock, UserProfiles up, IPackageManager pm) { super(context, lock, up, pm); @@ -9005,7 +9017,29 @@ public class NotificationManagerService extends SystemService { public NotificationListeners(IPackageManager pm) { super(getContext(), mNotificationLock, mUserProfiles, pm); + } + @Override + protected void loadDefaultsFromConfig() { + String defaultListenerAccess = mContext.getResources().getString( + R.string.config_defaultListenerAccessPackages); + if (defaultListenerAccess != null) { + String[] listeners = + defaultListenerAccess.split(ManagedServices.ENABLED_SERVICES_SEPARATOR); + for (int i = 0; i < listeners.length; i++) { + if (TextUtils.isEmpty(listeners[i])) { + continue; + } + ArraySet<ComponentName> approvedListeners = + this.queryPackageForServices(listeners[i], + MATCH_DIRECT_BOOT_AWARE + | MATCH_DIRECT_BOOT_UNAWARE, USER_SYSTEM); + for (int k = 0; k < approvedListeners.size(); k++) { + ComponentName cn = approvedListeners.valueAt(k); + addDefaultComponentOrPackage(cn.flattenToString()); + } + } + } } @Override 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/PreferencesHelper.java b/services/core/java/com/android/server/notification/PreferencesHelper.java index b3d373ffab3a..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,9 @@ 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; @@ -30,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; @@ -79,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 = ":"; @@ -151,6 +156,7 @@ 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 mBubblesEnabledGlobally = DEFAULT_GLOBAL_ALLOW_BUBBLE; @@ -167,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)) { @@ -195,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(); @@ -220,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, @@ -231,8 +258,7 @@ public class PreferencesHelper implements RankingConfig { parser, ATT_VISIBILITY, DEFAULT_VISIBILITY), XmlUtils.readBooleanAttribute( parser, ATT_SHOW_BADGE, DEFAULT_SHOW_BADGE), - XmlUtils.readIntAttribute( - parser, ATT_ALLOW_BUBBLE, DEFAULT_BUBBLE_PREFERENCE)); + bubblePref); r.importance = XmlUtils.readIntAttribute( parser, ATT_IMPORTANCE, DEFAULT_IMPORTANCE); r.priority = XmlUtils.readIntAttribute( 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/Installer.java b/services/core/java/com/android/server/pm/Installer.java index 9fb468e8db6e..7cee286c4451 100644 --- a/services/core/java/com/android/server/pm/Installer.java +++ b/services/core/java/com/android/server/pm/Installer.java @@ -71,6 +71,8 @@ public class Installer extends SystemService { public static final int DEXOPT_GENERATE_COMPACT_DEX = 1 << 11; /** Indicates that dexopt should generate an app image */ public static final int DEXOPT_GENERATE_APP_IMAGE = 1 << 12; + /** Indicates that dexopt may be run with different performance / priority tuned for restore */ + public static final int DEXOPT_FOR_RESTORE = 1 << 13; // TODO(b/135202722): remove public static final int FLAG_STORAGE_DE = IInstalld.FLAG_STORAGE_DE; public static final int FLAG_STORAGE_CE = IInstalld.FLAG_STORAGE_CE; diff --git a/services/core/java/com/android/server/pm/PackageDexOptimizer.java b/services/core/java/com/android/server/pm/PackageDexOptimizer.java index 65b7cf3eabd1..4b8a24204ca7 100644 --- a/services/core/java/com/android/server/pm/PackageDexOptimizer.java +++ b/services/core/java/com/android/server/pm/PackageDexOptimizer.java @@ -22,6 +22,7 @@ import static com.android.server.pm.Installer.DEXOPT_BOOTCOMPLETE; import static com.android.server.pm.Installer.DEXOPT_DEBUGGABLE; import static com.android.server.pm.Installer.DEXOPT_ENABLE_HIDDEN_API_CHECKS; import static com.android.server.pm.Installer.DEXOPT_FORCE; +import static com.android.server.pm.Installer.DEXOPT_FOR_RESTORE; import static com.android.server.pm.Installer.DEXOPT_GENERATE_APP_IMAGE; import static com.android.server.pm.Installer.DEXOPT_GENERATE_COMPACT_DEX; import static com.android.server.pm.Installer.DEXOPT_IDLE_BACKGROUND_JOB; @@ -32,6 +33,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 +117,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 +136,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."); @@ -699,6 +707,7 @@ public class PackageDexOptimizer { | (options.isDexoptIdleBackgroundJob() ? DEXOPT_IDLE_BACKGROUND_JOB : 0) | (generateCompactDex ? DEXOPT_GENERATE_COMPACT_DEX : 0) | (generateAppImage ? DEXOPT_GENERATE_APP_IMAGE : 0) + | (options.isDexoptInstallForRestore() ? DEXOPT_FOR_RESTORE : 0) | hiddenApiFlag; return adjustDexoptFlags(dexFlags); } 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..d2481b758e82 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -66,6 +66,8 @@ import static android.content.pm.PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE import static android.content.pm.PackageManager.INSTALL_INTERNAL; import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES; import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_NO_CERTIFICATES; +import static android.content.pm.PackageManager.INSTALL_REASON_DEVICE_RESTORE; +import static android.content.pm.PackageManager.INSTALL_REASON_DEVICE_SETUP; import static android.content.pm.PackageManager.INSTALL_SUCCEEDED; import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS; import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK; @@ -94,6 +96,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 +1823,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 +1904,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); @@ -3576,7 +3581,8 @@ public class PackageManagerService extends IPackageManager.Stub // Prepare a supplier of package parser for the staging manager to parse apex file // during the staging installation. final Supplier<PackageParser2> apexParserSupplier = () -> new PackageParser2( - mSeparateProcesses, mOnlyCore, mMetrics, mCacheDir, mPackageParserCallback); + mSeparateProcesses, mOnlyCore, mMetrics, null /* cacheDir */, + mPackageParserCallback); mInstallerService = new PackageInstallerService(mContext, this, apexParserSupplier); final Pair<ComponentName, String> instantAppResolverComponent = getInstantAppResolverLPr(); @@ -13575,12 +13581,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 +14963,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 +16589,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)) { @@ -16670,10 +16712,15 @@ public class PackageManagerService extends IPackageManager.Stub // method because `pkg` may not be in `mPackages` yet. // // Also, don't fail application installs if the dexopt step fails. + int flags = DexoptOptions.DEXOPT_BOOT_COMPLETE + | DexoptOptions.DEXOPT_INSTALL_WITH_DEX_METADATA_FILE; + if (reconciledPkg.installArgs.installReason == INSTALL_REASON_DEVICE_RESTORE + || reconciledPkg.installArgs.installReason == INSTALL_REASON_DEVICE_SETUP) { + flags |= DexoptOptions.DEXOPT_FOR_RESTORE; + } DexoptOptions dexoptOptions = new DexoptOptions(packageName, REASON_INSTALL, - DexoptOptions.DEXOPT_BOOT_COMPLETE - | DexoptOptions.DEXOPT_INSTALL_WITH_DEX_METADATA_FILE); + flags); ScanResult result = reconciledPkg.scanResult; // This mirrors logic from commitReconciledScanResultLocked, where the library files @@ -16911,7 +16958,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/UserRestrictionsUtils.java b/services/core/java/com/android/server/pm/UserRestrictionsUtils.java index c0502b8a068c..0b6024a84f78 100644 --- a/services/core/java/com/android/server/pm/UserRestrictionsUtils.java +++ b/services/core/java/com/android/server/pm/UserRestrictionsUtils.java @@ -211,24 +211,16 @@ public class UserRestrictionsUtils { UserManager.DISALLOW_ADD_USER, UserManager.DISALLOW_BLUETOOTH, UserManager.DISALLOW_BLUETOOTH_SHARING, - UserManager.DISALLOW_CONFIG_BLUETOOTH, UserManager.DISALLOW_CONFIG_CELL_BROADCASTS, - UserManager.DISALLOW_CONFIG_LOCATION, UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS, UserManager.DISALLOW_CONFIG_PRIVATE_DNS, UserManager.DISALLOW_CONFIG_TETHERING, - UserManager.DISALLOW_CONFIG_WIFI, - UserManager.DISALLOW_CONTENT_CAPTURE, - UserManager.DISALLOW_CONTENT_SUGGESTIONS, UserManager.DISALLOW_DATA_ROAMING, - UserManager.DISALLOW_DEBUGGING_FEATURES, UserManager.DISALLOW_SAFE_BOOT, - UserManager.DISALLOW_SHARE_LOCATION, UserManager.DISALLOW_SMS, UserManager.DISALLOW_USB_FILE_TRANSFER, UserManager.DISALLOW_AIRPLANE_MODE, UserManager.DISALLOW_MOUNT_PHYSICAL_MEDIA, - UserManager.DISALLOW_OUTGOING_CALLS, UserManager.DISALLOW_UNMUTE_MICROPHONE ); @@ -237,7 +229,16 @@ public class UserRestrictionsUtils { * set on the parent profile instance to apply them on the personal profile. */ private static final Set<String> PROFILE_OWNER_ORGANIZATION_OWNED_LOCAL_RESTRICTIONS = - Sets.newArraySet(); + Sets.newArraySet( + UserManager.DISALLOW_CONFIG_BLUETOOTH, + UserManager.DISALLOW_CONFIG_LOCATION, + UserManager.DISALLOW_CONFIG_WIFI, + UserManager.DISALLOW_CONTENT_CAPTURE, + UserManager.DISALLOW_CONTENT_SUGGESTIONS, + UserManager.DISALLOW_DEBUGGING_FEATURES, + UserManager.DISALLOW_SHARE_LOCATION, + UserManager.DISALLOW_OUTGOING_CALLS + ); /** * User restrictions that default to {@code true} for managed profile owners. 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..68f38861d7e4 100644 --- a/services/core/java/com/android/server/pm/dex/DexoptOptions.java +++ b/services/core/java/com/android/server/pm/dex/DexoptOptions.java @@ -61,6 +61,10 @@ public final class DexoptOptions { // should get the dex metdata file if present. public static final int DEXOPT_INSTALL_WITH_DEX_METADATA_FILE = 1 << 10; + // When set, indicates that dexopt is being invoked from the install flow during device restore + // or device setup and should be scheduled appropriately. + public static final int DEXOPT_FOR_RESTORE = 1 << 11; // TODO(b/135202722): remove + // The name of package to optimize. private final String mPackageName; @@ -99,7 +103,8 @@ public final class DexoptOptions { DEXOPT_DOWNGRADE | DEXOPT_AS_SHARED_LIBRARY | DEXOPT_IDLE_BACKGROUND_JOB | - DEXOPT_INSTALL_WITH_DEX_METADATA_FILE; + DEXOPT_INSTALL_WITH_DEX_METADATA_FILE | + DEXOPT_FOR_RESTORE; if ((flags & (~validityMask)) != 0) { throw new IllegalArgumentException("Invalid flags : " + Integer.toHexString(flags)); } @@ -155,6 +160,10 @@ public final class DexoptOptions { return (mFlags & DEXOPT_INSTALL_WITH_DEX_METADATA_FILE) != 0; } + public boolean isDexoptInstallForRestore() { + return (mFlags & DEXOPT_FOR_RESTORE) != 0; + } + public String getSplitName() { return mSplitName; } @@ -166,4 +175,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..bacc7acf3dc7 100644 --- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java +++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java @@ -26,6 +26,7 @@ import static android.content.pm.ApplicationInfo.AUTO_REVOKE_DISCOURAGED; import static android.content.pm.PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT; import static android.content.pm.PackageManager.FLAG_PERMISSION_APPLY_RESTRICTION; import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT; +import static android.content.pm.PackageManager.FLAG_PERMISSION_ONE_TIME; import static android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED; import static android.content.pm.PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED; import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKED_COMPAT; @@ -1656,7 +1657,8 @@ public class PermissionManagerService extends IPermissionManager.Stub { final int userSettableMask = FLAG_PERMISSION_USER_SET | FLAG_PERMISSION_USER_FIXED | FLAG_PERMISSION_REVOKED_COMPAT - | FLAG_PERMISSION_REVIEW_REQUIRED; + | FLAG_PERMISSION_REVIEW_REQUIRED + | FLAG_PERMISSION_ONE_TIME; final int policyOrSystemFlags = FLAG_PERMISSION_SYSTEM_FIXED | FLAG_PERMISSION_POLICY_FIXED; @@ -3210,16 +3212,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/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/stats/pull/ProcfsMemoryUtil.java b/services/core/java/com/android/server/stats/pull/ProcfsMemoryUtil.java index 67677c6cf17e..e1e6195ad260 100644 --- a/services/core/java/com/android/server/stats/pull/ProcfsMemoryUtil.java +++ b/services/core/java/com/android/server/stats/pull/ProcfsMemoryUtil.java @@ -41,10 +41,11 @@ public final class ProcfsMemoryUtil { public static MemorySnapshot readMemorySnapshotFromProcfs(int pid) { long[] output = new long[STATUS_KEYS.length]; output[0] = -1; + output[3] = -1; + output[4] = -1; Process.readProcLines("/proc/" + pid + "/status", STATUS_KEYS, output); - if (output[0] == -1 || (output[3] == 0 && output[4] == 0)) { - // Could not open file or anon rss / swap are 0 indicating the process is in a zombie - // state. + if (output[0] == -1 || output[3] == -1 || output[4] == -1) { + // Could not open or parse file. return null; } final MemorySnapshot snapshot = new MemorySnapshot(); diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java index 75d6a090bd3d..4fe58433ddb6 100644 --- a/services/core/java/com/android/server/wm/AccessibilityController.java +++ b/services/core/java/com/android/server/wm/AccessibilityController.java @@ -674,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); @@ -1091,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 @@ -1205,16 +1232,12 @@ final class AccessibilityController { updateUnaccountedSpace(windowState, regionInScreen, unaccountedSpace, skipRemainingWindowsForTasks); focusedWindowAdded |= windowState.isFocused(); - } else if (isUntouchableNavigationBar(windowState)) { + } 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. - final InsetsState insetsState = - dc.getInsetsStateController().getRawInsetsState(); - final Rect displayFrame = - insetsState.getSource(ITYPE_NAVIGATION_BAR).getFrame(); - unaccountedSpace.op(displayFrame, unaccountedSpace, + unaccountedSpace.op(getNavBarInsets(dc), unaccountedSpace, Region.Op.REVERSE_DIFFERENCE); } @@ -1294,18 +1317,6 @@ final class AccessibilityController { return false; } - private boolean isUntouchableNavigationBar(WindowState windowState) { - if (windowState.mAttrs.type != WindowManager.LayoutParams.TYPE_NAVIGATION_BAR) { - return false; - } - - // Gets the touchable region. - Region touchableRegion = mTempRegion1; - windowState.getTouchableRegion(touchableRegion); - - return touchableRegion.isEmpty(); - } - private void updateUnaccountedSpace(WindowState windowState, Region regionInScreen, Region unaccountedSpace, HashSet<Integer> skipRemainingWindowsForTasks) { if (windowState.mAttrs.type diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index e79b804f76f9..521ffa50f869 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -1374,8 +1374,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A final Rect spaceToFill = transformedBounds != null ? transformedBounds : inMultiWindowMode() - ? task.getDisplayedBounds() - : getRootTask().getParent().getDisplayedBounds(); + ? task.getBounds() + : getRootTask().getParent().getBounds(); mLetterbox.layout(spaceToFill, w.getFrameLw(), mTmpPoint); } else if (mLetterbox != null) { mLetterbox.hide(); @@ -6663,17 +6663,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A return super.getBounds(); } - @Override - Rect getDisplayedBounds() { - if (task != null) { - final Rect overrideDisplayedBounds = task.getOverrideDisplayedBounds(); - if (!overrideDisplayedBounds.isEmpty()) { - return overrideDisplayedBounds; - } - } - return getBounds(); - } - @VisibleForTesting @Override Rect getAnimationBounds(int appStackClipMode) { diff --git a/services/core/java/com/android/server/wm/ActivityStack.java b/services/core/java/com/android/server/wm/ActivityStack.java index 8bf46bc7c2e8..5968eede0a27 100644 --- a/services/core/java/com/android/server/wm/ActivityStack.java +++ b/services/core/java/com/android/server/wm/ActivityStack.java @@ -91,7 +91,6 @@ import static com.android.server.wm.TaskProto.ANIMATING_BOUNDS; import static com.android.server.wm.TaskProto.BOUNDS; import static com.android.server.wm.TaskProto.CREATED_BY_ORGANIZER; import static com.android.server.wm.TaskProto.DEFER_REMOVAL; -import static com.android.server.wm.TaskProto.DISPLAYED_BOUNDS; import static com.android.server.wm.TaskProto.DISPLAY_ID; import static com.android.server.wm.TaskProto.FILLS_PARENT; import static com.android.server.wm.TaskProto.LAST_NON_FULLSCREEN_BOUNDS; @@ -660,8 +659,7 @@ class ActivityStack extends Task { setBounds(newBounds); } else if (overrideWindowingMode != WINDOWING_MODE_PINNED) { // For pinned stack, resize is now part of the {@link WindowContainerTransaction} - resize(new Rect(newBounds), null /* configBounds */, - PRESERVE_WINDOWS, true /* deferResume */); + resize(new Rect(newBounds), PRESERVE_WINDOWS, true /* deferResume */); } } if (prevIsAlwaysOnTop != isAlwaysOnTop()) { @@ -835,8 +833,7 @@ class ActivityStack extends Task { } if (!Objects.equals(getRequestedOverrideBounds(), mTmpRect2)) { - resize(mTmpRect2, null /*configBounds*/, - false /*preserveWindows*/, true /*deferResume*/); + resize(mTmpRect2, false /*preserveWindows*/, true /*deferResume*/); } } finally { mAtmService.continueWindowLayout(); @@ -894,9 +891,6 @@ class ActivityStack extends Task { setTaskBounds(mDeferredBounds); setBounds(mDeferredBounds); } - if (mUpdateDisplayedBoundsDeferredCalled) { - setTaskDisplayedBounds(mDeferredDisplayedBounds); - } } } @@ -2966,8 +2960,7 @@ class ActivityStack extends Task { // TODO: Can only be called from special methods in ActivityStackSupervisor. // Need to consolidate those calls points into this resize method so anyone can call directly. - void resize(Rect displayedBounds, Rect configBounds, boolean preserveWindows, - boolean deferResume) { + void resize(Rect displayedBounds, boolean preserveWindows, boolean deferResume) { if (!updateBoundsAllowed(displayedBounds)) { return; } @@ -2979,7 +2972,7 @@ class ActivityStack extends Task { // Update override configurations of all tasks in the stack. final PooledConsumer c = PooledLambda.obtainConsumer( ActivityStack::processTaskResizeBounds, PooledLambda.__(Task.class), - displayedBounds, configBounds); + displayedBounds); forAllTasks(c, true /* traverseTopToBottom */); c.recycle(); @@ -3000,17 +2993,10 @@ class ActivityStack extends Task { } } - private static void processTaskResizeBounds( - Task task, Rect displayedBounds, Rect configBounds) { + private static void processTaskResizeBounds(Task task, Rect displayedBounds) { if (!task.isResizeable()) return; - if (configBounds != null && !configBounds.isEmpty()) { - task.setOverrideDisplayedBounds(displayedBounds); - task.setBounds(configBounds); - } else { - task.setOverrideDisplayedBounds(null); - task.setBounds(displayedBounds); - } + task.setBounds(displayedBounds); } /** @@ -3032,22 +3018,6 @@ class ActivityStack extends Task { task.setBounds(task.isResizeable() ? bounds : null); } - /** Helper to setDisplayedBounds on all child tasks */ - private void setTaskDisplayedBounds(Rect bounds) { - if (!updateDisplayedBoundsAllowed(bounds)) { - return; - } - - final PooledConsumer c = PooledLambda.obtainConsumer(ActivityStack::setTaskDisplayedBounds, - PooledLambda.__(Task.class), bounds); - forAllLeafTasks(c, true /* traverseTopToBottom */); - c.recycle(); - } - - private static void setTaskDisplayedBounds(Task task, Rect bounds) { - task.setOverrideDisplayedBounds(bounds == null || bounds.isEmpty() ? null : bounds); - } - /** * Returns the top-most activity that occludes the given one, or @{code null} if none. */ @@ -3569,8 +3539,8 @@ class ActivityStack extends Task { } @Override - void getRelativeDisplayedPosition(Point outPos) { - super.getRelativeDisplayedPosition(outPos); + void getRelativePosition(Point outPos) { + super.getRelativePosition(outPos); final int outset = getStackOutset(); outPos.x -= outset; outPos.y -= outset; @@ -3581,7 +3551,7 @@ class ActivityStack extends Task { return; } - final Rect stackBounds = getDisplayedBounds(); + final Rect stackBounds = getBounds(); int width = stackBounds.width(); int height = stackBounds.height(); @@ -3776,7 +3746,6 @@ class ActivityStack extends Task { proto.write(FILLS_PARENT, matchParentBounds()); getRawBounds().dumpDebug(proto, BOUNDS); - getOverrideDisplayedBounds().dumpDebug(proto, DISPLAYED_BOUNDS); if (mLastNonFullscreenBounds != null) { mLastNonFullscreenBounds.dumpDebug(proto, LAST_NON_FULLSCREEN_BOUNDS); } diff --git a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java index f924bd4ea194..3bcccedb6de5 100644 --- a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java @@ -1357,7 +1357,7 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks { // still need moveTaskToFrontLocked() below for any transition settings. } if (stack.shouldResizeStackWithLaunchBounds()) { - stack.resize(bounds, null /* configBounds */, !PRESERVE_WINDOWS, !DEFER_RESUME); + stack.resize(bounds, !PRESERVE_WINDOWS, !DEFER_RESUME); } else { // WM resizeTask must be done after the task is moved to the correct stack, // because Task's setBounds() also updates dim layer's bounds, but that has diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java index 7a04894523f5..d92f43b6890c 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java @@ -2786,6 +2786,11 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } final int prevMode = task.getWindowingMode(); + if (prevMode == windowingMode) { + // The task is already in split-screen and with correct windowing mode. + return true; + } + moveTaskToSplitScreenPrimaryTask(task, toTop); return prevMode != task.getWindowingMode(); } diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 36d558312c2f..a47cdc66fbd8 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -26,6 +26,7 @@ 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_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.SCREEN_ORIENTATION_UNSET; @@ -73,7 +74,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; @@ -142,6 +142,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.app.ActivityManager; import android.app.ActivityManagerInternal; +import android.app.WindowConfiguration; import android.content.Context; import android.content.pm.ActivityInfo; import android.content.pm.ActivityInfo.ScreenOrientation; @@ -199,7 +200,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; @@ -540,6 +540,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 */ @@ -3247,6 +3256,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo mInsetsStateController.getSourceProvider(ITYPE_IME).setWindow(win, null /* frameProvider */, null /* imeFrameProvider */); computeImeTarget(true /* updateImeTarget */); + updateImeControlTarget(); } /** @@ -3362,34 +3372,18 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo } } + private boolean isImeControlledByApp() { + return mInputMethodTarget != null && !WindowConfiguration.isSplitScreenWindowingMode( + mInputMethodTarget.getWindowingMode()); + } + boolean isImeAttachedToApp() { - return (mInputMethodTarget != null && mInputMethodTarget.mActivityRecord != null + return isImeControlledByApp() + && mInputMethodTarget.mActivityRecord != null && mInputMethodTarget.getWindowingMode() == WINDOWING_MODE_FULLSCREEN // An activity with override bounds should be letterboxed inside its parent bounds, // so it doesn't fill the screen. - && mInputMethodTarget.mActivityRecord.matchParentBounds()); - } - - /** - * Get IME target that should host IME when this display that is reparented to another - * WindowState. - * IME is never displayed in a child display. - * Use {@link WindowState#getImeControlTarget()} when IME target window - * which originally called - * {@link android.view.inputmethod.InputMethodManager#showSoftInput(View, int)} is known. - * - * @return {@link WindowState} of host that controls IME. - * {@code null} when {@param dc} is not a virtual display. - * @see DisplayContent#reparent - */ - @Nullable - WindowState getImeControlTarget() { - WindowState imeTarget = mInputMethodTarget; - if (imeTarget != null) { - return imeTarget.getImeControlTarget(); - } - - return getInsetsStateController().getImeSourceProvider().getControlTarget().getWindow(); + && mInputMethodTarget.mActivityRecord.matchParentBounds(); } /** @@ -3399,7 +3393,6 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo * * @param target current IME target. * @return {@link WindowState} that can host IME. - * @see DisplayContent#getImeControlTarget() */ WindowState getImeHostOrFallback(WindowState target) { if (target != null && target.getDisplayContent().canShowIme()) { @@ -3426,42 +3419,35 @@ 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; } mInputMethodTarget = target; mInputMethodTargetWaitingAnim = targetWaitingAnim; - assignWindowLayers(false /* setLayoutNeeded */); + assignWindowLayers(true /* 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). - * - * @see #getImeControlTarget() + * 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. */ - void updateImeControlTarget(InsetsControlTarget target) { - if (!isImeAttachedToApp() && mRemoteInsetsControlTarget != null) { - mInputMethodControlTarget = mRemoteInsetsControlTarget; - } else { - // Otherwise, we just use the ime target - mInputMethodControlTarget = target; + void setInputMethodInputTarget(WindowState target) { + if (mInputMethodInputTarget != target) { + mInputMethodInputTarget = target; + updateImeControlTarget(); } + } + + private void updateImeControlTarget() { + mInputMethodControlTarget = computeImeControlTarget(); 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(); @@ -3469,20 +3455,36 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo } /** + * Computes the window where we hand IME control to. + */ + @VisibleForTesting + InsetsControlTarget computeImeControlTarget() { + if (!isImeControlledByApp() && mRemoteInsetsControlTarget != null) { + return mRemoteInsetsControlTarget; + } else { + // Otherwise, we just use the ime target as received from IME. + return mInputMethodInputTarget; + } + } + + /** * Computes the window the IME should be attached to. */ @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() { @@ -4727,6 +4729,11 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo return mWindowContainers.getSurfaceControl(); } + @VisibleForTesting + WindowContainer<?> getImeContainer() { + return mImeWindowsContainers; + } + SurfaceControl getOverlayLayer() { return mOverlayContainers.getSurfaceControl(); } 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/InsetsStateController.java b/services/core/java/com/android/server/wm/InsetsStateController.java index ba14d48d38ea..4ac319ddf6ce 100644 --- a/services/core/java/com/android/server/wm/InsetsStateController.java +++ b/services/core/java/com/android/server/wm/InsetsStateController.java @@ -171,7 +171,7 @@ class InsetsStateController { if (aboveIme) { state = new InsetsState(state); - state.removeSource(ITYPE_IME); + state.setSourceVisible(ITYPE_IME, false); } return state; diff --git a/services/core/java/com/android/server/wm/RecentsAnimation.java b/services/core/java/com/android/server/wm/RecentsAnimation.java index 0a9878dd660b..51053b2e7123 100644 --- a/services/core/java/com/android/server/wm/RecentsAnimation.java +++ b/services/core/java/com/android/server/wm/RecentsAnimation.java @@ -165,17 +165,6 @@ class RecentsAnimation implements RecentsAnimationCallbacks, ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS, "startRecentsActivity(): intent=%s", mTargetIntent); Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "RecentsAnimation#startRecentsActivity"); - // TODO(multi-display) currently only support recents animation in default display. - final DisplayContent dc = - mService.mRootWindowContainer.getDefaultDisplay().mDisplayContent; - if (!mWindowManager.canStartRecentsAnimation()) { - notifyAnimationCancelBeforeStart(recentsAnimationRunner); - ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS, - "Can't start recents animation, nextAppTransition=%s", - dc.mAppTransition.getAppTransition()); - return; - } - // If the activity is associated with the recents stack, then try and get that first ActivityStack targetStack = mDefaultTaskDisplayArea.getStack(WINDOWING_MODE_UNDEFINED, mTargetActivityType); diff --git a/services/core/java/com/android/server/wm/RecentsAnimationController.java b/services/core/java/com/android/server/wm/RecentsAnimationController.java index 54210ae1c0b0..2ce10a74c949 100644 --- a/services/core/java/com/android/server/wm/RecentsAnimationController.java +++ b/services/core/java/com/android/server/wm/RecentsAnimationController.java @@ -898,11 +898,11 @@ public class RecentsAnimationController implements DeathRecipient { TaskAnimationAdapter(Task task, boolean isRecentTaskInvisible) { mTask = task; mIsRecentTaskInvisible = isRecentTaskInvisible; - mBounds.set(mTask.getDisplayedBounds()); + mBounds.set(mTask.getBounds()); mLocalBounds.set(mBounds); Point tmpPos = new Point(); - mTask.getRelativeDisplayedPosition(tmpPos); + mTask.getRelativePosition(tmpPos); mLocalBounds.offsetTo(tmpPos.x, tmpPos.y); } diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java index ee6cc9aa5290..1ffa01c2bd66 100644 --- a/services/core/java/com/android/server/wm/Task.java +++ b/services/core/java/com/android/server/wm/Task.java @@ -52,7 +52,6 @@ import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE; import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE_AND_PIPABLE_DEPRECATED; import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET; -import static android.content.res.Configuration.EMPTY; import static android.content.res.Configuration.ORIENTATION_LANDSCAPE; import static android.content.res.Configuration.ORIENTATION_PORTRAIT; import static android.content.res.Configuration.ORIENTATION_UNDEFINED; @@ -212,7 +211,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}. @@ -354,10 +352,6 @@ class Task extends WindowContainer<WindowContainer> { final Rect mPreparedFrozenBounds = new Rect(); final Configuration mPreparedFrozenMergedConfig = new Configuration(); - // If non-empty, bounds used to display the task during animations/interactions. - // TODO(b/119687367): This member is temporary. - private final Rect mOverrideDisplayedBounds = new Rect(); - // Id of the previous display the stack was on. int mPrevDisplayId = INVALID_DISPLAY; @@ -2729,10 +2723,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; } @@ -2798,29 +2790,6 @@ class Task extends WindowContainer<WindowContainer> { } } - /** - * Displayed bounds are used to set where the task is drawn at any given time. This is - * separate from its actual bounds so that the app doesn't see any meaningful configuration - * changes during transitionary periods. - */ - void setOverrideDisplayedBounds(Rect overrideDisplayedBounds) { - if (overrideDisplayedBounds != null) { - adjustForMinimalTaskDimensions(overrideDisplayedBounds, mOverrideDisplayedBounds); - mOverrideDisplayedBounds.set(overrideDisplayedBounds); - } else { - mOverrideDisplayedBounds.setEmpty(); - } - updateSurfacePosition(); - } - - /** - * Gets the bounds that override where the task is displayed. See - * {@link android.app.IActivityTaskManager#resizeDockedStack} why this is needed. - */ - Rect getOverrideDisplayedBounds() { - return mOverrideDisplayedBounds; - } - boolean isResizeable(boolean checkSupportsPip) { return (mAtmService.mForceResizableActivities || ActivityInfo.isResizeableMode(mResizeMode) || (checkSupportsPip && mSupportsPictureInPicture)); @@ -2854,49 +2823,6 @@ class Task extends WindowContainer<WindowContainer> { mPreparedFrozenMergedConfig.setTo(getConfiguration()); } - /** - * Align the task to the adjusted bounds. - * - * @param adjustedBounds Adjusted bounds to which the task should be aligned. - * @param tempInsetBounds Insets bounds for the task. - * @param alignBottom True if the task's bottom should be aligned to the adjusted - * bounds's bottom; false if the task's top should be aligned - * the adjusted bounds's top. - */ - void alignToAdjustedBounds(Rect adjustedBounds, Rect tempInsetBounds, boolean alignBottom) { - if (!isResizeable() || EMPTY.equals(getRequestedOverrideConfiguration())) { - return; - } - - getBounds(mTmpRect2); - if (alignBottom) { - int offsetY = adjustedBounds.bottom - mTmpRect2.bottom; - mTmpRect2.offset(0, offsetY); - } else { - mTmpRect2.offsetTo(adjustedBounds.left, adjustedBounds.top); - } - if (tempInsetBounds == null || tempInsetBounds.isEmpty()) { - setOverrideDisplayedBounds(null); - setBounds(mTmpRect2); - } else { - setOverrideDisplayedBounds(mTmpRect2); - setBounds(tempInsetBounds); - } - } - - /** - * Gets the current overridden displayed bounds. These will be empty if the task is not - * currently overriding where it is displayed. - */ - @Override - public Rect getDisplayedBounds() { - if (mOverrideDisplayedBounds.isEmpty()) { - return super.getDisplayedBounds(); - } else { - return mOverrideDisplayedBounds; - } - } - @Override void getAnimationFrames(Rect outFrame, Rect outInsets, Rect outStableInsets, Rect outSurfaceInsets) { @@ -3434,7 +3360,6 @@ class Task extends WindowContainer<WindowContainer> { pw.println(prefix + "taskId=" + mTaskId); pw.println(doublePrefix + "mBounds=" + getBounds().toShortString()); pw.println(doublePrefix + "appTokens=" + mChildren); - pw.println(doublePrefix + "mDisplayedBounds=" + mOverrideDisplayedBounds.toShortString()); final String triplePrefix = doublePrefix + " "; final String quadruplePrefix = triplePrefix + " "; @@ -4273,8 +4198,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/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java index 7219164ad2f1..899ab247077a 100644 --- a/services/core/java/com/android/server/wm/WindowContainer.java +++ b/services/core/java/com/android/server/wm/WindowContainer.java @@ -2062,7 +2062,7 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< // TODO: Remove this and use #getBounds() instead once we set an app transition animation // on TaskStack. Rect getAnimationBounds(int appStackClipMode) { - return getDisplayedBounds(); + return getBounds(); } /** @@ -2124,7 +2124,7 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< // Separate position and size for use in animators. mTmpRect.set(getAnimationBounds(appStackClipMode)); if (sHierarchicalAnimations) { - getRelativeDisplayedPosition(mTmpPoint); + getRelativePosition(mTmpPoint); } else { mTmpPoint.set(mTmpRect.left, mTmpRect.top); } @@ -2304,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 @@ -2395,7 +2399,7 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< return; } - getRelativeDisplayedPosition(mTmpPos); + getRelativePosition(mTmpPos); if (mTmpPos.equals(mLastSurfacePosition)) { return; } @@ -2410,16 +2414,6 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< } /** - * Displayed bounds specify where to display this container at. It differs from bounds during - * certain operations (like animation or interactive dragging). - * - * @return the bounds to display this container at. - */ - Rect getDisplayedBounds() { - return getBounds(); - } - - /** * The {@code outFrame} retrieved by this method specifies where the animation will finish * the entrance animation, as the next frame will display the window at these coordinates. In * case of exit animation, this is where the animation will start, as the frame before the @@ -2439,7 +2433,7 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< outSurfaceInsets.setEmpty(); } - void getRelativeDisplayedPosition(Point outPos) { + void getRelativePosition(Point outPos) { // In addition to updateSurfacePosition, we keep other code that sets // position from fighting with the organizer if (isOrganized()) { @@ -2447,11 +2441,11 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< return; } - final Rect dispBounds = getDisplayedBounds(); + final Rect dispBounds = getBounds(); outPos.set(dispBounds.left, dispBounds.top); final WindowContainer parent = getParent(); if (parent != null) { - final Rect parentBounds = parent.getDisplayedBounds(); + final Rect parentBounds = parent.getBounds(); outPos.offset(-parentBounds.left, -parentBounds.top); } } diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 5c7d37baef37..f55a1b3f6ab3 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -1697,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); @@ -2401,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 @@ -2432,6 +2430,7 @@ public class WindowManagerService extends IWindowManager.Stub outSurfaceSize.set(winAnimator.mSurfaceController.getWidth(), winAnimator.mSurfaceController.getHeight()); } + getInsetsSourceControls(win, outActiveControls); } Binder.restoreCallingIdentity(origId); @@ -2446,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; } } } @@ -2789,18 +2797,6 @@ public class WindowManagerService extends IWindowManager.Stub return mRecentsAnimationController; } - /** - * @return Whether the next recents animation can continue to start. Called from - * {@link RecentsAnimation#startRecentsActivity}. - */ - boolean canStartRecentsAnimation() { - // TODO(multi-display): currently only default display support recent activity - if (getDefaultDisplayContentLocked().mAppTransition.isTransitionSet()) { - return false; - } - return true; - } - void cancelRecentsAnimation( @RecentsAnimationController.ReorderMode int reorderMode, String reason) { if (mRecentsAnimationController != null) { @@ -6107,10 +6103,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, @@ -7362,7 +7363,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 d9c0219c4779..8b27667475a9 100644 --- a/services/core/java/com/android/server/wm/WindowOrganizerController.java +++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java @@ -320,7 +320,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub final ActivityStack stack = (ActivityStack) container; if (stack.inPinnedWindowingMode()) { stack.resize(config.windowConfiguration.getBounds(), - null /* configBounds */, PRESERVE_WINDOWS, true /* deferResume */); + PRESERVE_WINDOWS, true /* deferResume */); } } } diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index c11c29b5deb6..2b1f174d1175 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -999,18 +999,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP frame.inset(left, top, right, bottom); } - @Override - public Rect getDisplayedBounds() { - final Task task = getTask(); - if (task != null) { - Rect bounds = task.getOverrideDisplayedBounds(); - if (!bounds.isEmpty()) { - return bounds; - } - } - return super.getDisplayedBounds(); - } - void computeFrame(DisplayFrames displayFrames) { getLayoutingWindowFrames().setDisplayCutout(displayFrames.mDisplayCutout); computeFrameLw(); @@ -1065,7 +1053,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP layoutXDiff = 0; layoutYDiff = 0; } else { - windowFrames.mContainingFrame.set(getDisplayedBounds()); + windowFrames.mContainingFrame.set(getBounds()); if (mActivityRecord != null && !mActivityRecord.mFrozenBounds.isEmpty()) { // If the bounds are frozen, we still want to translate the window freely and only @@ -1223,7 +1211,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP parentLeft = ((WindowState) parent).mWindowFrames.mFrame.left; parentTop = ((WindowState) parent).mWindowFrames.mFrame.top; } else if (parent != null) { - final Rect parentBounds = parent.getDisplayedBounds(); + final Rect parentBounds = parent.getBounds(); parentLeft = parentBounds.left; parentTop = parentBounds.top; } @@ -1469,6 +1457,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 +5238,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) { @@ -5295,7 +5278,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP outPoint.offset(-parent.mWindowFrames.mFrame.left + mTmpPoint.x, -parent.mWindowFrames.mFrame.top + mTmpPoint.y); } else if (parentWindowContainer != null) { - final Rect parentBounds = parentWindowContainer.getDisplayedBounds(); + final Rect parentBounds = parentWindowContainer.getBounds(); outPoint.offset(-parentBounds.left, -parentBounds.top); } @@ -5347,7 +5330,9 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP // this promotion. final WindowState imeTarget = getDisplayContent().mInputMethodTarget; boolean inTokenWithAndAboveImeTarget = imeTarget != null && imeTarget != this - && imeTarget.mToken == mToken && imeTarget.compareTo(this) <= 0; + && imeTarget.mToken == mToken + && getParent() != null + && imeTarget.compareTo(this) <= 0; return inTokenWithAndAboveImeTarget; } return false; diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java index d4470f8334ea..99577077d65d 100644 --- a/services/core/java/com/android/server/wm/WindowStateAnimator.java +++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java @@ -1030,7 +1030,7 @@ class WindowStateAnimator { mTmpPos.x = 0; mTmpPos.y = 0; if (stack != null) { - stack.getRelativeDisplayedPosition(mTmpPos); + stack.getRelativePosition(mTmpPos); } xOffset = -mTmpPos.x; diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java index 2d5c4c1c3b7c..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); @@ -629,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..09d1d3a270ba 100644 --- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java @@ -1986,29 +1986,32 @@ public class DevicePolicyManagerTest extends DpmTestBase { Sets.newSet( UserManager.DISALLOW_CONFIG_DATE_TIME, UserManager.DISALLOW_ADD_USER, - UserManager.DISALLOW_BLUETOOTH, UserManager.DISALLOW_BLUETOOTH_SHARING, - UserManager.DISALLOW_CONFIG_BLUETOOTH, UserManager.DISALLOW_CONFIG_CELL_BROADCASTS, - UserManager.DISALLOW_CONFIG_LOCATION, UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS, UserManager.DISALLOW_CONFIG_PRIVATE_DNS, UserManager.DISALLOW_CONFIG_TETHERING, - UserManager.DISALLOW_CONFIG_WIFI, - UserManager.DISALLOW_CONTENT_CAPTURE, - UserManager.DISALLOW_CONTENT_SUGGESTIONS, UserManager.DISALLOW_DATA_ROAMING, - UserManager.DISALLOW_DEBUGGING_FEATURES, UserManager.DISALLOW_SAFE_BOOT, - UserManager.DISALLOW_SHARE_LOCATION, UserManager.DISALLOW_SMS, UserManager.DISALLOW_USB_FILE_TRANSFER, UserManager.DISALLOW_AIRPLANE_MODE, UserManager.DISALLOW_MOUNT_PHYSICAL_MEDIA, - UserManager.DISALLOW_OUTGOING_CALLS, UserManager.DISALLOW_UNMUTE_MICROPHONE ); + private static final Set<String> PROFILE_OWNER_ORGANIZATION_OWNED_LOCAL_RESTRICTIONS = + Sets.newSet( + UserManager.DISALLOW_CONFIG_BLUETOOTH, + UserManager.DISALLOW_CONFIG_LOCATION, + UserManager.DISALLOW_CONFIG_WIFI, + UserManager.DISALLOW_CONTENT_CAPTURE, + UserManager.DISALLOW_CONTENT_SUGGESTIONS, + UserManager.DISALLOW_DEBUGGING_FEATURES, + UserManager.DISALLOW_SHARE_LOCATION, + UserManager.DISALLOW_OUTGOING_CALLS + ); + public void testSetUserRestriction_asPoOfOrgOwnedDevice() throws Exception { final int MANAGED_PROFILE_ADMIN_UID = UserHandle.getUid(DpmMockContext.CALLER_USER_HANDLE, DpmMockContext.SYSTEM_UID); @@ -2021,7 +2024,10 @@ public class DevicePolicyManagerTest extends DpmTestBase { .thenReturn(new UserInfo(UserHandle.USER_SYSTEM, "user system", 0)); for (String restriction : PROFILE_OWNER_ORGANIZATION_OWNED_GLOBAL_RESTRICTIONS) { - addAndRemoveUserRestrictionOnParentDpm(restriction); + addAndRemoveGlobalUserRestrictionOnParentDpm(restriction); + } + for (String restriction : PROFILE_OWNER_ORGANIZATION_OWNED_LOCAL_RESTRICTIONS) { + addAndRemoveLocalUserRestrictionOnParentDpm(restriction); } parentDpm.setCameraDisabled(admin1, true); @@ -2047,7 +2053,7 @@ public class DevicePolicyManagerTest extends DpmTestBase { reset(getServices().userManagerInternal); } - private void addAndRemoveUserRestrictionOnParentDpm(String restriction) { + private void addAndRemoveGlobalUserRestrictionOnParentDpm(String restriction) { parentDpm.addUserRestriction(admin1, restriction); verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions( eq(DpmMockContext.CALLER_USER_HANDLE), @@ -2063,6 +2069,22 @@ public class DevicePolicyManagerTest extends DpmTestBase { ); } + private void addAndRemoveLocalUserRestrictionOnParentDpm(String restriction) { + parentDpm.addUserRestriction(admin1, restriction); + verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions( + eq(DpmMockContext.CALLER_USER_HANDLE), + MockUtils.checkUserRestrictions(), + MockUtils.checkUserRestrictions(UserHandle.USER_SYSTEM, restriction), + eq(false)); + parentDpm.clearUserRestriction(admin1, restriction); + DpmTestUtils.assertRestrictions( + DpmTestUtils.newRestrictions(), + dpms.getProfileOwnerAdminLocked(DpmMockContext.CALLER_USER_HANDLE) + .getParentActiveAdmin() + .getEffectiveRestrictions() + ); + } + public void testNoDefaultEnabledUserRestrictions() throws Exception { mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS); mContext.callerPermissions.add(permission.MANAGE_USERS); @@ -4841,6 +4863,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/servicestests/src/com/android/server/pm/dex/DexoptOptionsTests.java b/services/tests/servicestests/src/com/android/server/pm/dex/DexoptOptionsTests.java index 62589ebb92fe..22020ad45666 100644 --- a/services/tests/servicestests/src/com/android/server/pm/dex/DexoptOptionsTests.java +++ b/services/tests/servicestests/src/com/android/server/pm/dex/DexoptOptionsTests.java @@ -54,6 +54,7 @@ public class DexoptOptionsTests { assertFalse(opt.isForce()); assertFalse(opt.isDexoptIdleBackgroundJob()); assertFalse(opt.isDexoptInstallWithDexMetadata()); + assertFalse(opt.isDexoptInstallForRestore()); } @Test @@ -67,7 +68,8 @@ public class DexoptOptionsTests { DexoptOptions.DEXOPT_DOWNGRADE | DexoptOptions.DEXOPT_AS_SHARED_LIBRARY | DexoptOptions.DEXOPT_IDLE_BACKGROUND_JOB | - DexoptOptions.DEXOPT_INSTALL_WITH_DEX_METADATA_FILE; + DexoptOptions.DEXOPT_INSTALL_WITH_DEX_METADATA_FILE | + DexoptOptions.DEXOPT_FOR_RESTORE; DexoptOptions opt = new DexoptOptions(mPackageName, mCompilerFilter, flags); assertEquals(mPackageName, opt.getPackageName()); @@ -82,6 +84,7 @@ public class DexoptOptionsTests { assertTrue(opt.isDexoptAsSharedLibrary()); assertTrue(opt.isDexoptIdleBackgroundJob()); assertTrue(opt.isDexoptInstallWithDexMetadata()); + assertTrue(opt.isDexoptInstallForRestore()); } @Test diff --git a/services/tests/servicestests/src/com/android/server/pm/parsing/PackageParserLegacyCoreTest.java b/services/tests/servicestests/src/com/android/server/pm/parsing/PackageParserLegacyCoreTest.java index af89761acf9d..939b7a0beb49 100644 --- a/services/tests/servicestests/src/com/android/server/pm/parsing/PackageParserLegacyCoreTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/parsing/PackageParserLegacyCoreTest.java @@ -35,6 +35,7 @@ import android.os.Build; import android.os.Bundle; import android.os.FileUtils; import android.platform.test.annotations.Presubmit; +import android.util.SparseIntArray; import androidx.test.InstrumentationRegistry; import androidx.test.filters.SmallTest; @@ -542,7 +543,12 @@ public class PackageParserLegacyCoreTest { @Test public void testUsesSdk() throws Exception { - parsePackage("install_uses_sdk.apk_r0", R.raw.install_uses_sdk_r0, x -> x); + ParsedPackage pkg = + parsePackage("install_uses_sdk.apk_r0", R.raw.install_uses_sdk_r0, x -> x); + SparseIntArray minExtVers = pkg.getMinExtensionVersions(); + assertEquals(1, minExtVers.size()); + assertEquals(0, minExtVers.get(10000, -1)); + try { parsePackage("install_uses_sdk.apk_r5", R.raw.install_uses_sdk_r5, x -> x); fail("Expected parsing exception due to incompatible extension SDK version"); 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/ManagedServicesTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java index 7b7470cca85a..28ff9a545513 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java @@ -77,6 +77,7 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.nio.charset.StandardCharsets; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.List; @@ -96,6 +97,10 @@ public class ManagedServicesTest extends UiServiceTestCase { UserInfo mZero = new UserInfo(0, "zero", 0); UserInfo mTen = new UserInfo(10, "ten", 0); + private String mDefaultsString; + private String mVersionString; + private final Set<ComponentName> mDefaults = new ArraySet(); + private ManagedServices mService; private static final String SETTING = "setting"; private static final String SECONDARY_SETTING = "secondary_setting"; @@ -106,8 +111,8 @@ public class ManagedServicesTest extends UiServiceTestCase { private ArrayMap<Integer, String> mExpectedSecondaryComponentNames; // type : user : list of approved - private ArrayMap<Integer, ArrayMap<Integer, String>> mExpectedPrimary = new ArrayMap<>(); - private ArrayMap<Integer, ArrayMap<Integer, String>> mExpectedSecondary = new ArrayMap<>(); + private ArrayMap<Integer, ArrayMap<Integer, String>> mExpectedPrimary; + private ArrayMap<Integer, ArrayMap<Integer, String>> mExpectedSecondary; @Before public void setUp() throws Exception { @@ -132,6 +137,9 @@ public class ManagedServicesTest extends UiServiceTestCase { profileIds.add(12); when(mUserProfiles.getCurrentProfileIds()).thenReturn(profileIds); + mVersionString = "2"; + mExpectedPrimary = new ArrayMap<>(); + mExpectedSecondary = new ArrayMap<>(); mExpectedPrimaryPackages = new ArrayMap<>(); mExpectedPrimaryPackages.put(0, "this.is.a.package.name:another.package"); mExpectedPrimaryPackages.put(10, "this.is.another.package"); @@ -155,6 +163,8 @@ public class ManagedServicesTest extends UiServiceTestCase { "this.is.another.package:component:package"); mExpectedSecondary.put(APPROVAL_BY_PACKAGE, mExpectedSecondaryPackages); mExpectedSecondary.put(APPROVAL_BY_COMPONENT, mExpectedSecondaryComponentNames); + mService = new TestManagedServices(getContext(), mLock, mUserProfiles, + mIpm, APPROVAL_BY_COMPONENT); } @Test @@ -1178,9 +1188,99 @@ public class ManagedServicesTest extends UiServiceTestCase { } } + @Test + public void loadDefaults_noVersionNoDefaults() throws Exception { + resetComponentsAndPackages(); + loadXml(mService); + assertEquals(mService.getDefaultComponents().size(), 0); + } + + @Test + public void loadDefaults_noVersionNoDefaultsOneActive() throws Exception { + resetComponentsAndPackages(); + mService.addDefaultComponentOrPackage("package/class"); + loadXml(mService); + assertEquals(1, mService.getDefaultComponents().size()); + assertTrue(mService.getDefaultComponents() + .contains(ComponentName.unflattenFromString("package/class"))); + } + + @Test + public void loadDefaults_noVersionWithDefaults() throws Exception { + resetComponentsAndPackages(); + mDefaults.add(new ComponentName("default", "class")); + loadXml(mService); + assertEquals(mService.getDefaultComponents(), mDefaults); + } + + @Test + public void loadDefaults_versionOneWithDefaultsWithActive() throws Exception { + resetComponentsAndPackages(); + mDefaults.add(new ComponentName("default", "class")); + mExpectedPrimaryComponentNames.put(0, "package/class"); + mVersionString = "1"; + loadXml(mService); + assertEquals(mService.getDefaultComponents(), + new ArraySet(Arrays.asList(new ComponentName("package", "class")))); + } + + @Test + public void loadDefaults_versionTwoWithDefaultsWithActive() throws Exception { + resetComponentsAndPackages(); + mDefaults.add(new ComponentName("default", "class")); + mDefaultsString = "default/class"; + mExpectedPrimaryComponentNames.put(0, "package/class"); + mVersionString = "2"; + loadXml(mService); + assertEquals(1, mService.getDefaultComponents().size()); + mDefaults.forEach(pkg -> { + assertTrue(mService.getDefaultComponents().contains(pkg)); + }); + } + + @Test + public void loadDefaults_versionOneWithXMLDefaultsWithActive() throws Exception { + resetComponentsAndPackages(); + mDefaults.add(new ComponentName("default", "class")); + mDefaultsString = "xml/class"; + mExpectedPrimaryComponentNames.put(0, "package/class"); + mVersionString = "1"; + loadXml(mService); + assertEquals(mService.getDefaultComponents(), + new ArraySet(Arrays.asList(new ComponentName("xml", "class")))); + } + + @Test + public void loadDefaults_versionTwoWithXMLDefaultsWithActive() throws Exception { + resetComponentsAndPackages(); + mDefaults.add(new ComponentName("default", "class")); + mDefaultsString = "xml/class"; + mExpectedPrimaryComponentNames.put(0, "package/class"); + mVersionString = "2"; + loadXml(mService); + assertEquals(mService.getDefaultComponents(), + new ArraySet(Arrays.asList(new ComponentName("xml", "class")))); + } + + private void resetComponentsAndPackages() { + ArrayMap<Integer, ArrayMap<Integer, String>> empty = new ArrayMap(1); + ArrayMap<Integer, String> emptyPkgs = new ArrayMap(0); + empty.append(mService.mApprovalLevel, emptyPkgs); + mExpectedPrimary = empty; + mExpectedPrimaryComponentNames = emptyPkgs; + mExpectedPrimaryPackages = emptyPkgs; + mExpectedSecondary = empty; + mExpectedSecondaryComponentNames = emptyPkgs; + mExpectedSecondaryPackages = emptyPkgs; + } + private void loadXml(ManagedServices service) throws Exception { final StringBuffer xml = new StringBuffer(); - xml.append("<" + service.getConfig().xmlTag + ">\n"); + String xmlTag = service.getConfig().xmlTag; + xml.append("<" + xmlTag + + (mDefaultsString != null ? " defaults=\"" + mDefaultsString + "\" " : "") + + (mVersionString != null ? " version=\"" + mVersionString + "\" " : "") + + ">\n"); for (int userId : mExpectedPrimary.get(service.mApprovalLevel).keySet()) { xml.append(getXmlEntry( mExpectedPrimary.get(service.mApprovalLevel).get(userId), userId, true)); @@ -1197,7 +1297,7 @@ public class ManagedServicesTest extends UiServiceTestCase { + ManagedServices.ATT_USER_ID + "=\"98\" " + ManagedServices.ATT_IS_PRIMARY + "=\"false\" " + ManagedServices.ATT_APPROVED_LIST + "=\"98\" />\n"); - xml.append("</" + service.getConfig().xmlTag + ">"); + xml.append("</" + xmlTag + ">"); XmlPullParser parser = Xml.newPullParser(); parser.setInput(new BufferedInputStream( @@ -1224,6 +1324,7 @@ public class ManagedServicesTest extends UiServiceTestCase { private void addExpectedServices(final ManagedServices service, final List<String> packages, int userId) { + ManagedServices.Config config = service.getConfig(); when(mPm.queryIntentServicesAsUser(any(), anyInt(), eq(userId))). thenAnswer(new Answer<List<ResolveInfo>>() { @Override @@ -1233,7 +1334,7 @@ public class ManagedServicesTest extends UiServiceTestCase { Intent invocationIntent = (Intent) args[0]; if (invocationIntent != null) { if (invocationIntent.getAction().equals( - service.getConfig().serviceInterface) + config.serviceInterface) && packages.contains(invocationIntent.getPackage())) { List<ResolveInfo> dummyServices = new ArrayList<>(); for (int i = 1; i <= 3; i ++) { @@ -1431,6 +1532,11 @@ public class ManagedServicesTest extends UiServiceTestCase { } @Override + protected void loadDefaultsFromConfig() { + mDefaultComponents.addAll(mDefaults); + } + + @Override protected String getRequiredPermission() { return null; } diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationAssistantsTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationAssistantsTest.java index 88186cdb3873..ab4dc476ff20 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationAssistantsTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationAssistantsTest.java @@ -72,13 +72,13 @@ public class NotificationAssistantsTest extends UiServiceTestCase { Object mLock = new Object(); + UserInfo mZero = new UserInfo(0, "zero", 0); UserInfo mTen = new UserInfo(10, "ten", 0); @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); - getContext().setMockPackageManager(mPm); getContext().addMockSystemService(Context.USER_SERVICE, mUm); mAssistants = spy(mNm.new NotificationAssistants(getContext(), mLock, mUserProfiles, miPm)); @@ -122,7 +122,7 @@ public class NotificationAssistantsTest extends UiServiceTestCase { @Test public void testXmlUpgradeExistingApprovedComponents() throws Exception { - String xml = "<enabled_assistants>" + String xml = "<enabled_assistants version=\"2\" defaults=\"b\\b\">" + "<service_listing approved=\"b/b\" user=\"10\" primary=\"true\" />" + "</enabled_assistants>"; 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 3cd0e92964ec..ecdd9e548e6a 100755 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java @@ -113,6 +113,7 @@ 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; @@ -234,6 +235,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Mock private LauncherApps mLauncherApps; @Mock + private ShortcutServiceInternal mShortcutServiceInternal; + @Mock ActivityManager mActivityManager; @Mock Resources mResources; @@ -466,6 +469,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { mShortcutHelper = mService.getShortcutHelper(); mShortcutHelper.setLauncherApps(mLauncherApps); + mShortcutHelper.setShortcutServiceInternal(mShortcutServiceInternal); // Set the testable bubble extractor RankingHelper rankingHelper = mService.getRankingHelper(); @@ -782,33 +786,16 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { userInfos.add(new UserInfo(0, "", 0)); final ArraySet<ComponentName> validAssistants = new ArraySet<>(); validAssistants.add(ComponentName.unflattenFromString(testComponent)); - final String originalComponent = DeviceConfig.getProperty( - DeviceConfig.NAMESPACE_SYSTEMUI, - SystemUiDeviceConfigFlags.NAS_DEFAULT_SERVICE - ); - DeviceConfig.setProperty( - DeviceConfig.NAMESPACE_SYSTEMUI, - SystemUiDeviceConfigFlags.NAS_DEFAULT_SERVICE, - testComponent, - false - ); when(mActivityManager.isLowRamDevice()).thenReturn(false); when(mAssistants.queryPackageForServices(isNull(), anyInt(), anyInt())) .thenReturn(validAssistants); - when(mAssistants.getDefaultComponents()).thenReturn(new ArraySet<>()); + when(mAssistants.getDefaultComponents()).thenReturn(validAssistants); when(mUm.getEnabledProfiles(anyInt())).thenReturn(userInfos); mService.setDefaultAssistantForUser(userId); verify(mAssistants).setPackageOrComponentEnabled( eq(testComponent), eq(userId), eq(true), eq(true)); - - DeviceConfig.setProperty( - DeviceConfig.NAMESPACE_SYSTEMUI, - SystemUiDeviceConfigFlags.NAS_DEFAULT_SERVICE, - originalComponent, - false - ); } @Test @@ -6088,8 +6075,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(), @@ -6148,8 +6138,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(), @@ -6289,7 +6282,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { mService.loadDefaultApprovedServices(USER_SYSTEM); - verify(mConditionProviders, times(1)).addDefaultComponentOrPackage("test"); + verify(mConditionProviders, times(1)).loadDefaultsFromConfig(); } // TODO: add tests for the rest of the non-empty cases @@ -6492,7 +6485,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 427237c4be0f..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,6 +15,9 @@ */ 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; @@ -50,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; @@ -132,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; @@ -187,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() @@ -1464,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(); @@ -1475,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(); @@ -2241,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, @@ -2253,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, @@ -2349,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)); @@ -2360,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)); @@ -2372,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)); @@ -2384,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 @@ -2402,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 @@ -2417,14 +2434,71 @@ public class PreferencesHelperTest extends UiServiceTestCase { @Test public void testBubblePreference_defaults() throws Exception { - assertEquals(mHelper.getBubblePreference(PKG_O, UID_O), BUBBLE_PREFERENCE_NONE); + 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); - assertEquals(mHelper.getBubblePreference(PKG_O, UID_O), BUBBLE_PREFERENCE_NONE); + 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 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, + mAppOpsManager); + loadStreamXml(baos, false, UserHandle.USER_ALL); + + assertEquals(BUBBLE_PREFERENCE_SELECTED, mHelper.getBubblePreference(PKG_O, UID_O)); + assertEquals(PreferencesHelper.LockableAppFields.USER_LOCKED_BUBBLE, + mHelper.getAppLockedFields(PKG_O, UID_O)); } @Test @@ -2435,7 +2509,8 @@ public class PreferencesHelperTest extends UiServiceTestCase { 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); assertEquals(mHelper.getBubblePreference(PKG_O, UID_O), BUBBLE_PREFERENCE_NONE); @@ -2949,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" @@ -2969,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" @@ -2989,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" @@ -3009,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 bc66fa7ff48d..5bbb4d9e712c 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java @@ -1324,7 +1324,7 @@ public class ActivityRecordTests extends ActivityTestsBase { display.rotateInDifferentOrientationIfNeeded(mActivity); display.mFixedRotationLaunchingApp = mActivity; - displayRotation.updateRotationUnchecked(false /* forceUpdate */); + displayRotation.updateRotationUnchecked(true /* forceUpdate */); assertTrue(displayRotation.isRotatingSeamlessly()); diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java index 4532400e3b34..17dd26ed18e9 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java @@ -89,13 +89,13 @@ public class ActivityTaskManagerServiceTests extends ActivityTestsBase { public void testOnPictureInPictureRequested() throws RemoteException { final ActivityStack stack = new StackBuilder(mRootWindowContainer).build(); final ActivityRecord activity = stack.getBottomMostTask().getTopNonFinishingActivity(); - ClientLifecycleManager lifecycleManager = mService.getLifecycleManager(); - doNothing().when(lifecycleManager).scheduleTransaction(any()); + final ClientLifecycleManager mockLifecycleManager = mock(ClientLifecycleManager.class); + doReturn(mockLifecycleManager).when(mService).getLifecycleManager(); doReturn(true).when(activity).checkEnterPictureInPictureState(anyString(), anyBoolean()); mService.requestPictureInPictureMode(activity.token); - verify(lifecycleManager).scheduleTransaction(mClientTransactionCaptor.capture()); + verify(mockLifecycleManager).scheduleTransaction(mClientTransactionCaptor.capture()); final ClientTransaction transaction = mClientTransactionCaptor.getValue(); // Check that only an enter pip request item callback was scheduled. assertEquals(1, transaction.getCallbacks().size()); 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..daff14992e94 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java @@ -65,6 +65,7 @@ import static com.google.common.truth.Truth.assertThat; import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThat; @@ -84,12 +85,16 @@ import android.platform.test.annotations.Presubmit; import android.util.DisplayMetrics; import android.view.DisplayCutout; import android.view.Gravity; +import android.view.IDisplayWindowInsetsController; import android.view.IDisplayWindowRotationCallback; import android.view.IDisplayWindowRotationController; import android.view.ISystemGestureExclusionListener; import android.view.IWindowManager; +import android.view.InsetsSourceControl; +import android.view.InsetsState; 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; @@ -809,25 +814,19 @@ public class DisplayContentTests extends WindowTestsBase { @Test public void testComputeImeParent_app() throws Exception { - try (final InsetsModeSession session = - new InsetsModeSession(ViewRootImpl.NEW_INSETS_MODE_IME)) { - final DisplayContent dc = createNewDisplay(); - dc.mInputMethodTarget = createWindow(null, TYPE_BASE_APPLICATION, "app"); - assertEquals(dc.mInputMethodTarget.mActivityRecord.getSurfaceControl(), - dc.computeImeParent()); - } + final DisplayContent dc = createNewDisplay(); + dc.mInputMethodTarget = createWindow(null, TYPE_BASE_APPLICATION, "app"); + assertEquals(dc.mInputMethodTarget.mActivityRecord.getSurfaceControl(), + dc.computeImeParent()); } @Test public void testComputeImeParent_app_notFullscreen() throws Exception { - try (final InsetsModeSession session = - new InsetsModeSession(ViewRootImpl.NEW_INSETS_MODE_IME)) { - final DisplayContent dc = createNewDisplay(); - dc.mInputMethodTarget = createWindow(null, TYPE_STATUS_BAR, "app"); - dc.mInputMethodTarget.setWindowingMode( - WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY); - assertEquals(dc.getWindowingLayer(), dc.computeImeParent()); - } + final DisplayContent dc = createNewDisplay(); + dc.mInputMethodTarget = createWindow(null, TYPE_STATUS_BAR, "app"); + dc.mInputMethodTarget.setWindowingMode( + WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY); + assertEquals(dc.getImeContainer().getParentSurfaceControl(), dc.computeImeParent()); } @Test @@ -836,17 +835,67 @@ 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 public void testComputeImeParent_noApp() throws Exception { - try (final InsetsModeSession session = - new InsetsModeSession(ViewRootImpl.NEW_INSETS_MODE_IME)) { - final DisplayContent dc = createNewDisplay(); - dc.mInputMethodTarget = createWindow(null, TYPE_STATUS_BAR, "statusBar"); - assertEquals(dc.getWindowingLayer(), dc.computeImeParent()); - } + final DisplayContent dc = createNewDisplay(); + dc.mInputMethodTarget = createWindow(null, TYPE_STATUS_BAR, "statusBar"); + assertEquals(dc.getImeContainer().getParentSurfaceControl(), dc.computeImeParent()); + } + + @Test + public void testComputeImeControlTarget() throws Exception { + final DisplayContent dc = createNewDisplay(); + dc.setRemoteInsetsController(createDisplayWindowInsetsController()); + dc.mInputMethodInputTarget = createWindow(null, TYPE_BASE_APPLICATION, "app"); + dc.mInputMethodTarget = dc.mInputMethodInputTarget; + assertEquals(dc.mInputMethodInputTarget, dc.computeImeControlTarget()); + } + + @Test + public void testComputeImeControlTarget_splitscreen() throws Exception { + final DisplayContent dc = createNewDisplay(); + dc.mInputMethodInputTarget = createWindow(null, TYPE_BASE_APPLICATION, "app"); + dc.mInputMethodInputTarget.setWindowingMode( + WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY); + dc.mInputMethodTarget = dc.mInputMethodInputTarget; + dc.setRemoteInsetsController(createDisplayWindowInsetsController()); + assertNotEquals(dc.mInputMethodInputTarget, dc.computeImeControlTarget()); + } + + @Test + public void testComputeImeControlTarget_notMatchParentBounds() throws Exception { + spyOn(mAppWindow.mActivityRecord); + doReturn(false).when(mAppWindow.mActivityRecord).matchParentBounds(); + mDisplayContent.mInputMethodInputTarget = mAppWindow; + mDisplayContent.mInputMethodTarget = mDisplayContent.mInputMethodInputTarget; + mDisplayContent.setRemoteInsetsController(createDisplayWindowInsetsController()); + assertEquals(mAppWindow, mDisplayContent.computeImeControlTarget()); + } + + private IDisplayWindowInsetsController createDisplayWindowInsetsController() { + return new IDisplayWindowInsetsController.Stub() { + + @Override + public void insetsChanged(InsetsState insetsState) throws RemoteException { + } + + @Override + public void insetsControlChanged(InsetsState insetsState, + InsetsSourceControl[] insetsSourceControls) throws RemoteException { + } + + @Override + public void showInsets(int i, boolean b) throws RemoteException { + } + + @Override + public void hideInsets(int i, boolean b) throws RemoteException { + } + }; } @Test @@ -1039,6 +1088,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 +1101,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/InsetsStateControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java index 61b74b0c1d0f..9f28f45a05d0 100644 --- a/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java @@ -29,9 +29,11 @@ import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; 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.Mockito.atLeast; import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.spy; @@ -44,7 +46,6 @@ import android.view.InsetsSourceControl; import android.view.InsetsState; import android.view.test.InsetsModeSession; -import androidx.test.filters.FlakyTest; import androidx.test.filters.SmallTest; import org.junit.AfterClass; @@ -153,22 +154,24 @@ public class InsetsStateControllerTest extends WindowTestsBase { @Test public void testStripForDispatch_belowIme() { - final WindowState app = createWindow(null, TYPE_APPLICATION, "app"); - final WindowState ime = createWindow(null, TYPE_APPLICATION, "ime"); + getController().getSourceProvider(ITYPE_IME).setWindow(mImeWindow, null, null); - getController().getSourceProvider(ITYPE_IME).setWindow(ime, null, null); + final WindowState app = createWindow(null, TYPE_APPLICATION, "app"); + app.mBehindIme = true; - assertNotNull(getController().getInsetsForDispatch(app).peekSource(ITYPE_IME)); + getController().getRawInsetsState().setSourceVisible(ITYPE_IME, true); + assertTrue(getController().getInsetsForDispatch(app).getSource(ITYPE_IME).isVisible()); } @Test public void testStripForDispatch_aboveIme() { - final WindowState ime = createWindow(null, TYPE_APPLICATION, "ime"); - final WindowState app = createWindow(null, TYPE_APPLICATION, "app"); + getController().getSourceProvider(ITYPE_IME).setWindow(mImeWindow, null, null); - getController().getSourceProvider(ITYPE_IME).setWindow(ime, null, null); + final WindowState app = createWindow(null, TYPE_APPLICATION, "app"); + app.mBehindIme = false; - assertNull(getController().getInsetsForDispatch(app).peekSource(ITYPE_IME)); + getController().getRawInsetsState().setSourceVisible(ITYPE_IME, true); + assertFalse(getController().getInsetsForDispatch(app).getSource(ITYPE_IME).isVisible()); } @Test @@ -188,11 +191,11 @@ public class InsetsStateControllerTest extends WindowTestsBase { // Adding FLAG_NOT_FOCUSABLE makes app above IME. app.mAttrs.flags |= FLAG_NOT_FOCUSABLE; mDisplayContent.computeImeTarget(true); - mDisplayContent.setLayoutNeeded(); mDisplayContent.applySurfaceChangesTransaction(); - // app won't get IME insets while above IME. - assertNull(getController().getInsetsForDispatch(app).peekSource(ITYPE_IME)); + // app won't get visible IME insets while above IME even when IME is visible. + getController().getRawInsetsState().setSourceVisible(ITYPE_IME, true); + assertFalse(getController().getInsetsForDispatch(app).getSource(ITYPE_IME).isVisible()); // Reset invocation counter. clearInvocations(app); @@ -200,49 +203,49 @@ public class InsetsStateControllerTest extends WindowTestsBase { // Removing FLAG_NOT_FOCUSABLE makes app below IME. app.mAttrs.flags &= ~FLAG_NOT_FOCUSABLE; mDisplayContent.computeImeTarget(true); - mDisplayContent.setLayoutNeeded(); mDisplayContent.applySurfaceChangesTransaction(); // Make sure app got notified. verify(app, atLeast(1)).notifyInsetsChanged(); - // app will get IME insets while below IME. - assertNotNull(getController().getInsetsForDispatch(app).peekSource(ITYPE_IME)); + // app will get visible IME insets while below IME when IME is visible. + getController().getRawInsetsState().setSourceVisible(ITYPE_IME, true); + assertTrue(getController().getInsetsForDispatch(app).getSource(ITYPE_IME).isVisible()); } @Test public void testStripForDispatch_childWindow_altFocusable() { - final WindowState app = createWindow(null, TYPE_APPLICATION, "app"); + getController().getSourceProvider(ITYPE_IME).setWindow(mImeWindow, null, null); + final WindowState app = createWindow(null, TYPE_APPLICATION, "app"); final WindowState child = createWindow(app, TYPE_APPLICATION, "child"); child.mAttrs.flags |= FLAG_ALT_FOCUSABLE_IM; - final WindowState ime = createWindow(null, TYPE_APPLICATION, "ime"); - - // IME cannot be the IME target. - ime.mAttrs.flags |= FLAG_NOT_FOCUSABLE; - - getController().getSourceProvider(ITYPE_IME).setWindow(ime, null, null); + mDisplayContent.computeImeTarget(true); + mDisplayContent.setLayoutNeeded(); + mDisplayContent.applySurfaceChangesTransaction(); - assertNull(getController().getInsetsForDispatch(child).peekSource(ITYPE_IME)); + getController().getRawInsetsState().setSourceVisible(ITYPE_IME, true); + assertTrue(getController().getInsetsForDispatch(app).getSource(ITYPE_IME).isVisible()); + assertFalse(getController().getInsetsForDispatch(child).getSource(ITYPE_IME).isVisible()); } @Test public void testStripForDispatch_childWindow_splitScreen() { - final WindowState app = createWindow(null, TYPE_APPLICATION, "app"); + getController().getSourceProvider(ITYPE_IME).setWindow(mImeWindow, null, null); + final WindowState app = createWindow(null, TYPE_APPLICATION, "app"); final WindowState child = createWindow(app, TYPE_APPLICATION, "child"); child.mAttrs.flags |= FLAG_NOT_FOCUSABLE; child.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY); - final WindowState ime = createWindow(null, TYPE_APPLICATION, "ime"); - - // IME cannot be the IME target. - ime.mAttrs.flags |= FLAG_NOT_FOCUSABLE; - - getController().getSourceProvider(ITYPE_IME).setWindow(ime, null, null); + mDisplayContent.computeImeTarget(true); + mDisplayContent.setLayoutNeeded(); + mDisplayContent.applySurfaceChangesTransaction(); - assertNull(getController().getInsetsForDispatch(child).peekSource(ITYPE_IME)); + getController().getRawInsetsState().setSourceVisible(ITYPE_IME, true); + assertTrue(getController().getInsetsForDispatch(app).getSource(ITYPE_IME).isVisible()); + assertFalse(getController().getInsetsForDispatch(child).getSource(ITYPE_IME).isVisible()); } @Test diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java index 1f6ba7adf114..44ca2cdcb142 100644 --- a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java @@ -79,7 +79,6 @@ public class RecentsAnimationTest extends ActivityTestsBase { mService.mWindowManager.setRecentsAnimationController(mRecentsAnimationController); doNothing().when(mService.mWindowManager).initializeRecentsAnimation( anyInt(), any(), any(), anyInt(), any(), any()); - doReturn(true).when(mService.mWindowManager).canStartRecentsAnimation(); final RecentTasks recentTasks = mService.getRecentTasks(); spyOn(recentTasks); diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskTests.java index ec77be85aebf..473c1c57d625 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TaskTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/TaskTests.java @@ -145,9 +145,5 @@ public class TaskTests extends WindowTestsBase { Rect bounds = new Rect(10, 10, 100, 200); task.setBounds(bounds); assertEquals(new Point(bounds.left, bounds.top), task.getLastSurfacePosition()); - - Rect dispBounds = new Rect(20, 30, 110, 220); - task.setOverrideDisplayedBounds(dispBounds); - assertEquals(new Point(dispBounds.left, dispBounds.top), task.getLastSurfacePosition()); } } diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowFrameTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowFrameTests.java index 7be05a39cbde..eb2aa41192c2 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowFrameTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowFrameTests.java @@ -310,27 +310,6 @@ public class WindowFrameTests extends WindowTestsBase { assertContentFrame(w, new Rect(resolvedTaskBounds.left, resolvedTaskBounds.top, resolvedTaskBounds.right - contentInsetRight, resolvedTaskBounds.bottom - contentInsetBottom)); - - pf.set(0, 0, logicalWidth, logicalHeight); - // If we set displayed bounds, the insets will be computed with the main task bounds - // but the frame will be positioned according to the displayed bounds. - final int insetLeft = logicalWidth / 5; - final int insetTop = logicalHeight / 5; - final int insetRight = insetLeft + (resolvedTaskBounds.right - resolvedTaskBounds.left); - final int insetBottom = insetTop + (resolvedTaskBounds.bottom - resolvedTaskBounds.top); - task.setOverrideDisplayedBounds(resolvedTaskBounds); - task.setBounds(insetLeft, insetTop, insetRight, insetBottom); - windowFrames.setFrames(pf, pf, cf, cf, pf, cf); - w.computeFrameLw(); - assertEquals(resolvedTaskBounds, w.getFrameLw()); - assertEquals(0, w.getRelativeFrameLw().left); - assertEquals(0, w.getRelativeFrameLw().top); - contentInsetRight = insetRight - cfRight; - contentInsetBottom = insetBottom - cfBottom; - assertContentInset(w, 0, 0, contentInsetRight, contentInsetBottom); - assertContentFrame(w, new Rect(resolvedTaskBounds.left, resolvedTaskBounds.top, - resolvedTaskBounds.right - contentInsetRight, - resolvedTaskBounds.bottom - contentInsetBottom)); } @Test @@ -460,33 +439,6 @@ public class WindowFrameTests extends WindowTestsBase { } @Test - @FlakyTest(bugId = 130388666) - public void testDisplayCutout_tempDisplayedBounds() { - // Regular fullscreen task and window - WindowState w = createWindow(); - final Task task = w.getTask(); - task.setBounds(new Rect(0, 0, 1000, 2000)); - task.setOverrideDisplayedBounds(new Rect(0, -500, 1000, 1500)); - w.mAttrs.gravity = Gravity.LEFT | Gravity.TOP; - - final Rect pf = new Rect(0, -500, 1000, 1500); - // Create a display cutout of size 50x50, aligned top-center - final WmDisplayCutout cutout = WmDisplayCutout.computeSafeInsets( - fromBoundingRect(500, 0, 550, 50, BOUNDS_POSITION_TOP), - pf.width(), pf.height()); - - final WindowFrames windowFrames = w.getWindowFrames(); - windowFrames.setFrames(pf, pf, pf, pf, pf, pf); - windowFrames.setDisplayCutout(cutout); - w.computeFrameLw(); - - assertEquals(w.getWmDisplayCutout().getDisplayCutout().getSafeInsetTop(), 50); - assertEquals(w.getWmDisplayCutout().getDisplayCutout().getSafeInsetBottom(), 0); - assertEquals(w.getWmDisplayCutout().getDisplayCutout().getSafeInsetLeft(), 0); - assertEquals(w.getWmDisplayCutout().getDisplayCutout().getSafeInsetRight(), 0); - } - - @Test public void testFreeformContentInsets() { removeGlobalMinSizeRestriction(); // fullscreen task doesn't use bounds for computeFrame diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java index 71b35b62366e..65fb2c0451d8 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java @@ -657,4 +657,16 @@ public class WindowStateTests extends WindowTestsBase { win0.mActivityRecord.getStack().setFocusable(false); assertTrue(win0.cantReceiveTouchInput()); } + + @Test + public void testNeedsRelativeLayeringToIme_notAttached() { + WindowState sameTokenWindow = createWindow(null, TYPE_BASE_APPLICATION, mAppWindow.mToken, + "SameTokenWindow"); + mDisplayContent.mInputMethodTarget = mAppWindow; + sameTokenWindow.mActivityRecord.getStack().setWindowingMode( + WINDOWING_MODE_SPLIT_SCREEN_PRIMARY); + assertTrue(sameTokenWindow.needsRelativeLayeringToIme()); + sameTokenWindow.removeImmediately(); + assertFalse(sameTokenWindow.needsRelativeLayeringToIme()); + } } 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/src/com/google/android/startop/iorap/IorapWorkFlowTest.java b/startop/iorap/functional_tests/src/com/google/android/startop/iorap/IorapWorkFlowTest.java index c35dd3b783b1..5352be6f283f 100644 --- a/startop/iorap/functional_tests/src/com/google/android/startop/iorap/IorapWorkFlowTest.java +++ b/startop/iorap/functional_tests/src/com/google/android/startop/iorap/IorapWorkFlowTest.java @@ -397,7 +397,7 @@ public class IorapWorkFlowTest { public LogcatTimestamp() throws Exception{ long currentTimeMillis = System.currentTimeMillis(); epochTime = String.format( - "%d.%d", currentTimeMillis/1000, currentTimeMillis%1000); + "%d.%03d", currentTimeMillis/1000, currentTimeMillis%1000); Log.i(TAG, "Current logcat timestamp is " + epochTime); } 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/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 545c8a35058f..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> @@ -3084,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. @@ -3703,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); @@ -4134,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/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/android/telephony/data/DataCallResponse.java b/telephony/java/android/telephony/data/DataCallResponse.java index a116c07e2646..242c2e979571 100644 --- a/telephony/java/android/telephony/data/DataCallResponse.java +++ b/telephony/java/android/telephony/data/DataCallResponse.java @@ -80,7 +80,6 @@ public final class DataCallResponse implements Parcelable { private final int mMtu; private final int mMtuV4; private final int mMtuV6; - private final int mVersion; /** * @param cause Data call fail cause. {@link DataFailCause#NONE} indicates no error. @@ -126,9 +125,7 @@ public final class DataCallResponse implements Parcelable { ? new ArrayList<>() : new ArrayList<>(gatewayAddresses); mPcscfAddresses = (pcscfAddresses == null) ? new ArrayList<>() : new ArrayList<>(pcscfAddresses); - mMtu = mtu; - mMtuV4 = mMtuV6 = 0; - mVersion = 0; + mMtu = mMtuV4 = mMtuV6 = mtu; } /** @hide */ @@ -136,7 +133,7 @@ public final class DataCallResponse implements Parcelable { @LinkStatus int linkStatus, @ProtocolType int protocolType, @Nullable String interfaceName, @Nullable List<LinkAddress> addresses, @Nullable List<InetAddress> dnsAddresses, @Nullable List<InetAddress> gatewayAddresses, - @Nullable List<InetAddress> pcscfAddresses, int mtuV4, int mtuV6, int version) { + @Nullable List<InetAddress> pcscfAddresses, int mtu, int mtuV4, int mtuV6) { mCause = cause; mSuggestedRetryTime = suggestedRetryTime; mId = id; @@ -151,10 +148,9 @@ public final class DataCallResponse implements Parcelable { ? new ArrayList<>() : new ArrayList<>(gatewayAddresses); mPcscfAddresses = (pcscfAddresses == null) ? new ArrayList<>() : new ArrayList<>(pcscfAddresses); - mMtu = 0; + mMtu = mtu; mMtuV4 = mtuV4; mMtuV6 = mtuV6; - mVersion = version; } /** @hide */ @@ -177,7 +173,6 @@ public final class DataCallResponse implements Parcelable { mMtu = source.readInt(); mMtuV4 = source.readInt(); mMtuV6 = source.readInt(); - mVersion = source.readInt(); } /** @@ -247,7 +242,7 @@ public final class DataCallResponse implements Parcelable { */ @Deprecated public int getMtu() { - return mVersion < 5 ? mMtu : 0; + return mMtu; } /** @@ -256,7 +251,7 @@ public final class DataCallResponse implements Parcelable { * Zero or negative values means network has either not sent a value or sent an invalid value. */ public int getMtuV4() { - return mVersion < 5 ? 0 : mMtuV4; + return mMtuV4; } /** @@ -264,7 +259,7 @@ public final class DataCallResponse implements Parcelable { * Zero or negative values means network has either not sent a value or sent an invalid value. */ public int getMtuV6() { - return mVersion < 5 ? 0 : mMtuV6; + return mMtuV6; } @NonNull @@ -282,10 +277,9 @@ public final class DataCallResponse implements Parcelable { .append(" dnses=").append(mDnsAddresses) .append(" gateways=").append(mGatewayAddresses) .append(" pcscf=").append(mPcscfAddresses) - .append(" mtu=").append(mMtu) - .append(" mtuV4=").append(mMtuV4) - .append(" mtuV6=").append(mMtuV6) - .append(" version=").append(mVersion) + .append(" mtu=").append(getMtu()) + .append(" mtuV4=").append(getMtuV4()) + .append(" mtuV6=").append(getMtuV6()) .append("}"); return sb.toString(); } @@ -315,15 +309,14 @@ public final class DataCallResponse implements Parcelable { && mPcscfAddresses.containsAll(other.mPcscfAddresses) && mMtu == other.mMtu && mMtuV4 == other.mMtuV4 - && mMtuV6 == other.mMtuV6 - && mVersion == other.mVersion; + && mMtuV6 == other.mMtuV6; } @Override public int hashCode() { return Objects.hash(mCause, mSuggestedRetryTime, mId, mLinkStatus, mProtocolType, mInterfaceName, mAddresses, mDnsAddresses, mGatewayAddresses, mPcscfAddresses, - mMtu, mMtuV4, mMtuV6, mVersion); + mMtu, mMtuV4, mMtuV6); } @Override @@ -346,7 +339,6 @@ public final class DataCallResponse implements Parcelable { dest.writeInt(mMtu); dest.writeInt(mMtuV4); dest.writeInt(mMtuV6); - dest.writeInt(mVersion); } public static final @android.annotation.NonNull Parcelable.Creator<DataCallResponse> CREATOR = @@ -403,8 +395,6 @@ public final class DataCallResponse implements Parcelable { private int mMtuV6; - private int mVersion; - /** * Default constructor for Builder. */ @@ -563,29 +553,14 @@ public final class DataCallResponse implements Parcelable { } /** - * Set the IRadio version for this DataCallResponse - * @hide - */ - public @NonNull Builder setVersion(int version) { - mVersion = version; - return this; - } - - /** * Build the DataCallResponse. * * @return the DataCallResponse object. */ public @NonNull DataCallResponse build() { - if (mVersion >= 5) { - return new DataCallResponse(mCause, mSuggestedRetryTime, mId, mLinkStatus, - mProtocolType, mInterfaceName, mAddresses, mDnsAddresses, mGatewayAddresses, - mPcscfAddresses, mMtuV4, mMtuV6, mVersion); - } else { - return new DataCallResponse(mCause, mSuggestedRetryTime, mId, mLinkStatus, - mProtocolType, mInterfaceName, mAddresses, mDnsAddresses, mGatewayAddresses, - mPcscfAddresses, mMtu); - } + return new DataCallResponse(mCause, mSuggestedRetryTime, mId, mLinkStatus, + mProtocolType, mInterfaceName, mAddresses, mDnsAddresses, mGatewayAddresses, + mPcscfAddresses, mMtu, mMtuV4, mMtuV6); } } } 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/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); diff --git a/tools/stats_log_api_gen/atoms_info_writer.cpp b/tools/stats_log_api_gen/atoms_info_writer.cpp index 5fe94987aa65..b33995017bae 100644 --- a/tools/stats_log_api_gen/atoms_info_writer.cpp +++ b/tools/stats_log_api_gen/atoms_info_writer.cpp @@ -26,51 +26,14 @@ namespace android { namespace stats_log_api_gen { static void write_atoms_info_header_body(FILE* out, const Atoms& atoms) { - fprintf(out, "static int UNSET_VALUE = INT_MAX;\n"); - fprintf(out, "static int FIRST_UID_IN_CHAIN = 0;\n"); - - fprintf(out, "struct StateAtomFieldOptions {\n"); - fprintf(out, " std::vector<int> primaryFields;\n"); - fprintf(out, " int exclusiveField;\n"); - fprintf(out, " int defaultState = UNSET_VALUE;\n"); - fprintf(out, " int resetState = UNSET_VALUE;\n"); - fprintf(out, " bool nested;\n"); - fprintf(out, "};\n"); - fprintf(out, "\n"); - fprintf(out, "struct AtomsInfo {\n"); - fprintf(out, - " const static std::set<int> " - "kTruncatingTimestampAtomBlackList;\n"); fprintf(out, " const static std::set<int> kAtomsWithAttributionChain;\n"); - fprintf(out, - " const static std::map<int, StateAtomFieldOptions> " - "kStateAtomsFieldOptions;\n"); fprintf(out, " const static std::set<int> kWhitelistedAtoms;\n"); fprintf(out, "};\n"); fprintf(out, "const static int kMaxPushedAtomId = %d;\n\n", atoms.maxPushedAtomId); } static void write_atoms_info_cpp_body(FILE* out, const Atoms& atoms) { - std::set<string> kTruncatingAtomNames = {"mobile_radio_power_state_changed", - "audio_state_changed", - "call_state_changed", - "phone_signal_strength_changed", - "mobile_bytes_transfer_by_fg_bg", - "mobile_bytes_transfer"}; - fprintf(out, - "const std::set<int> " - "AtomsInfo::kTruncatingTimestampAtomBlackList = {\n"); - for (AtomDeclSet::const_iterator atomIt = atoms.decls.begin(); atomIt != atoms.decls.end(); - atomIt++) { - if (kTruncatingAtomNames.find((*atomIt)->name) != kTruncatingAtomNames.end()) { - const string constant = make_constant_name((*atomIt)->name); - fprintf(out, " %d, // %s\n", (*atomIt)->code, constant.c_str()); - } - } - - fprintf(out, "};\n"); - fprintf(out, "\n"); fprintf(out, "const std::set<int> AtomsInfo::kAtomsWithAttributionChain = {\n"); for (AtomDeclSet::const_iterator atomIt = atoms.decls.begin(); atomIt != atoms.decls.end(); @@ -100,49 +63,6 @@ static void write_atoms_info_cpp_body(FILE* out, const Atoms& atoms) { fprintf(out, "};\n"); fprintf(out, "\n"); - fprintf(out, - "static std::map<int, StateAtomFieldOptions> " - "getStateAtomFieldOptions() {\n"); - fprintf(out, " std::map<int, StateAtomFieldOptions> options;\n"); - fprintf(out, " StateAtomFieldOptions* opt;\n"); - for (AtomDeclSet::const_iterator atomIt = atoms.decls.begin(); atomIt != atoms.decls.end(); - atomIt++) { - if ((*atomIt)->primaryFields.size() == 0 && (*atomIt)->exclusiveField == 0) { - continue; - } - fprintf(out, - "\n // Adding primary and exclusive fields for atom " - "(%d)%s\n", - (*atomIt)->code, (*atomIt)->name.c_str()); - fprintf(out, " opt = &(options[%d /* %s */]);\n", (*atomIt)->code, - make_constant_name((*atomIt)->name).c_str()); - fprintf(out, " opt->primaryFields.reserve(%lu);\n", (*atomIt)->primaryFields.size()); - for (const auto& field : (*atomIt)->primaryFields) { - fprintf(out, " opt->primaryFields.push_back(%d);\n", field); - } - - fprintf(out, " opt->exclusiveField = %d;\n", (*atomIt)->exclusiveField); - if ((*atomIt)->defaultState != INT_MAX) { - fprintf(out, " opt->defaultState = %d;\n", (*atomIt)->defaultState); - } else { - fprintf(out, " opt->defaultState = UNSET_VALUE;\n"); - } - - if ((*atomIt)->triggerStateReset != INT_MAX) { - fprintf(out, " opt->resetState = %d;\n", (*atomIt)->triggerStateReset); - } else { - fprintf(out, " opt->resetState = UNSET_VALUE;\n"); - } - fprintf(out, " opt->nested = %d;\n", (*atomIt)->nested); - } - - fprintf(out, " return options;\n"); - fprintf(out, "}\n"); - - fprintf(out, - "const std::map<int, StateAtomFieldOptions> " - "AtomsInfo::kStateAtomsFieldOptions = " - "getStateAtomFieldOptions();\n"); } int write_atoms_info_header(FILE* out, const Atoms& atoms, const string& namespaceStr) { |