diff options
184 files changed, 3240 insertions, 1324 deletions
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 5cf5e0b1d182..cbc8ed636ff2 100644 --- a/apex/statsd/service/java/com/android/server/stats/StatsCompanionService.java +++ b/apex/statsd/service/java/com/android/server/stats/StatsCompanionService.java @@ -662,14 +662,19 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { return; } + // Cleann up from previous statsd - cancel any alarms that had been set. Do this here + // instead of in binder death because statsd can come back and set different alarms, or not + // want to set an alarm when it had been set. This guarantees that when we get a new statsd, + // we cancel any alarms before it is able to set them. + cancelAnomalyAlarm(); + cancelPullingAlarm(); + cancelAlarmForSubscriberTriggering(); + if (DEBUG) Log.d(TAG, "Saying hi to statsd"); mStatsManagerService.statsdReady(statsd); try { statsd.statsCompanionReady(); - cancelAnomalyAlarm(); - cancelPullingAlarm(); - BroadcastReceiver appUpdateReceiver = new AppUpdateReceiver(); BroadcastReceiver userUpdateReceiver = new UserUpdateReceiver(); BroadcastReceiver shutdownEventReceiver = new ShutdownEventReceiver(); diff --git a/cmds/statsd/src/StatsLogProcessor.h b/cmds/statsd/src/StatsLogProcessor.h index ffd83ba978f4..7090bd46635d 100644 --- a/cmds/statsd/src/StatsLogProcessor.h +++ b/cmds/statsd/src/StatsLogProcessor.h @@ -307,9 +307,6 @@ private: FRIEND_TEST(GaugeMetricE2eTest, TestRandomSamplePulledEventsWithActivation); FRIEND_TEST(GaugeMetricE2eTest, TestRandomSamplePulledEventsNoCondition); FRIEND_TEST(GaugeMetricE2eTest, TestConditionChangeToTrueSamplePulledEvents); - FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents); - FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents_LateAlarm); - FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents_WithActivation); FRIEND_TEST(AnomalyDetectionE2eTest, TestSlicedCountMetric_single_bucket); FRIEND_TEST(AnomalyDetectionE2eTest, TestSlicedCountMetric_multiple_buckets); @@ -328,6 +325,7 @@ private: FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithSameDeactivation); FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithTwoMetricsTwoDeactivations); + FRIEND_TEST(CountMetricE2eTest, TestInitialConditionChanges); FRIEND_TEST(CountMetricE2eTest, TestSlicedState); FRIEND_TEST(CountMetricE2eTest, TestSlicedStateWithMap); FRIEND_TEST(CountMetricE2eTest, TestMultipleSlicedStates); @@ -345,6 +343,10 @@ private: FRIEND_TEST(DurationMetricE2eTest, TestSlicedStatePrimaryFieldsNotSubsetDimInWhat); FRIEND_TEST(DurationMetricE2eTest, TestWithSlicedStatePrimaryFieldsSubset); + FRIEND_TEST(ValueMetricE2eTest, TestInitialConditionChanges); + FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents); + FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents_LateAlarm); + FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents_WithActivation); FRIEND_TEST(ValueMetricE2eTest, TestInitWithSlicedState); FRIEND_TEST(ValueMetricE2eTest, TestInitWithSlicedState_WithDimensions); FRIEND_TEST(ValueMetricE2eTest, TestInitWithSlicedState_WithIncorrectDimensions); diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto index 8ba52ef06c44..573a84f2fe33 100644 --- a/cmds/statsd/src/atoms.proto +++ b/cmds/statsd/src/atoms.proto @@ -4945,9 +4945,12 @@ message MobileBytesTransferByFgBg { /** * Used for pull network statistics via mobile|wifi networks, and sliced by interesting dimensions. - * Note that data is expected to be sliced into more dimensions in future. In other words, - * the caller must not assume the data is unique when filtering with a set of matching conditions. - * Thus, as the dimension grows, the caller will not be affected. + * Note that the data is expected to be sliced into more dimensions in future. In other words, + * the caller must not assume any row of data is one full report when filtering with a set of + * matching conditions, because future data may represent with multiple rows what is currently + * represented by one. + * To avoid being broken by future slicing, callers must take care to aggregate rows even if they + * query all the existing columns. * * Pulled from: * StatsPullAtomService (using NetworkStatsService to get NetworkStats) @@ -4972,21 +4975,26 @@ message DataUsageBytesTransfer { optional int32 rat_type = 6; // Mcc/Mnc read from sim if the record is for a specific subscription, null indicates the - // record is combined regardless of subscription. + // record is combined across subscriptions. optional string sim_mcc = 7; optional string sim_mnc = 8; + // Allows mobile virtual network operators (MVNOs) to be identified with individual IDs. + // See TelephonyManager#getSimCarrierId. + optional int32 carrier_id = 9; + // Enumeration of opportunistic states with an additional ALL state indicates the record is // combined regardless of the boolean value in its field. enum DataSubscriptionState { + UNKNOWN = 0; // For server side backward compatibility. ALL = 1; OPPORTUNISTIC = 2; NOT_OPPORTUNISTIC = 3; } // Mark whether the subscription is an opportunistic data subscription, and ALL indicates the - // record is combined regardless of opportunistic data subscription. + // record is combined across opportunistic data subscriptions. // See {@link SubscriptionManager#setOpportunistic}. - optional DataSubscriptionState opportunistic_data_sub = 9; + optional DataSubscriptionState opportunistic_data_sub = 10; } /** diff --git a/cmds/statsd/src/metrics/MetricProducer.h b/cmds/statsd/src/metrics/MetricProducer.h index 5fabb5fb6ffc..e86fdf06e836 100644 --- a/cmds/statsd/src/metrics/MetricProducer.h +++ b/cmds/statsd/src/metrics/MetricProducer.h @@ -459,6 +459,7 @@ protected: FRIEND_TEST(CountMetricE2eTest, TestSlicedStateWithMap); FRIEND_TEST(CountMetricE2eTest, TestMultipleSlicedStates); FRIEND_TEST(CountMetricE2eTest, TestSlicedStateWithPrimaryFields); + FRIEND_TEST(CountMetricE2eTest, TestInitialConditionChanges); FRIEND_TEST(DurationMetricE2eTest, TestOneBucket); FRIEND_TEST(DurationMetricE2eTest, TestTwoBuckets); @@ -488,6 +489,7 @@ protected: FRIEND_TEST(ValueMetricE2eTest, TestInitWithSlicedState); FRIEND_TEST(ValueMetricE2eTest, TestInitWithSlicedState_WithDimensions); FRIEND_TEST(ValueMetricE2eTest, TestInitWithSlicedState_WithIncorrectDimensions); + FRIEND_TEST(ValueMetricE2eTest, TestInitialConditionChanges); }; } // namespace statsd diff --git a/cmds/statsd/src/metrics/MetricsManager.h b/cmds/statsd/src/metrics/MetricsManager.h index c30532a39244..ad30a88c5d19 100644 --- a/cmds/statsd/src/metrics/MetricsManager.h +++ b/cmds/statsd/src/metrics/MetricsManager.h @@ -292,9 +292,6 @@ private: FRIEND_TEST(GaugeMetricE2eTest, TestRandomSamplePulledEventsWithActivation); FRIEND_TEST(GaugeMetricE2eTest, TestRandomSamplePulledEventsNoCondition); FRIEND_TEST(GaugeMetricE2eTest, TestConditionChangeToTrueSamplePulledEvents); - FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents); - FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents_LateAlarm); - FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents_WithActivation); FRIEND_TEST(AnomalyDetectionE2eTest, TestSlicedCountMetric_single_bucket); FRIEND_TEST(AnomalyDetectionE2eTest, TestSlicedCountMetric_multiple_buckets); @@ -322,6 +319,7 @@ private: TestActivationOnBootMultipleActivationsDifferentActivationTypes); FRIEND_TEST(StatsLogProcessorTest, TestActivationsPersistAcrossSystemServerRestart); + FRIEND_TEST(CountMetricE2eTest, TestInitialConditionChanges); FRIEND_TEST(CountMetricE2eTest, TestSlicedState); FRIEND_TEST(CountMetricE2eTest, TestSlicedStateWithMap); FRIEND_TEST(CountMetricE2eTest, TestMultipleSlicedStates); @@ -339,6 +337,10 @@ private: FRIEND_TEST(DurationMetricE2eTest, TestWithSlicedStatePrimaryFieldsSuperset); FRIEND_TEST(DurationMetricE2eTest, TestWithSlicedStatePrimaryFieldsSubset); + FRIEND_TEST(ValueMetricE2eTest, TestInitialConditionChanges); + FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents); + FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents_LateAlarm); + FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents_WithActivation); FRIEND_TEST(ValueMetricE2eTest, TestInitWithSlicedState); FRIEND_TEST(ValueMetricE2eTest, TestInitWithSlicedState_WithDimensions); FRIEND_TEST(ValueMetricE2eTest, TestInitWithSlicedState_WithIncorrectDimensions); diff --git a/cmds/statsd/src/statsd_config.proto b/cmds/statsd/src/statsd_config.proto index 7c0057d87ca9..2e6043df0e64 100644 --- a/cmds/statsd/src/statsd_config.proto +++ b/cmds/statsd/src/statsd_config.proto @@ -131,7 +131,7 @@ message SimplePredicate { UNKNOWN = 0; FALSE = 1; } - optional InitialValue initial_value = 5 [default = FALSE]; + optional InitialValue initial_value = 5 [default = UNKNOWN]; optional FieldMatcher dimensions = 6; } diff --git a/cmds/statsd/tests/e2e/CountMetric_e2e_test.cpp b/cmds/statsd/tests/e2e/CountMetric_e2e_test.cpp index 1a7cd5584f3d..04eb40080631 100644 --- a/cmds/statsd/tests/e2e/CountMetric_e2e_test.cpp +++ b/cmds/statsd/tests/e2e/CountMetric_e2e_test.cpp @@ -28,6 +28,92 @@ namespace statsd { #ifdef __ANDROID__ /** + * Tests the initial condition and condition after the first log events for + * count metrics with either a combination condition or simple condition. + * + * Metrics should be initialized with condition kUnknown (given that the + * predicate is using the default InitialValue of UNKNOWN). The condition should + * be updated to either kFalse or kTrue if a condition event is logged for all + * children conditions. + */ +TEST(CountMetricE2eTest, TestInitialConditionChanges) { + // Initialize config. + StatsdConfig config; + config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root. + config.add_default_pull_packages("AID_ROOT"); // Fake puller is registered with root. + + auto syncStartMatcher = CreateSyncStartAtomMatcher(); + *config.add_atom_matcher() = syncStartMatcher; + *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher(); + *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher(); + *config.add_atom_matcher() = CreateBatteryStateNoneMatcher(); + *config.add_atom_matcher() = CreateBatteryStateUsbMatcher(); + + auto screenOnPredicate = CreateScreenIsOnPredicate(); + *config.add_predicate() = screenOnPredicate; + + auto deviceUnpluggedPredicate = CreateDeviceUnpluggedPredicate(); + *config.add_predicate() = deviceUnpluggedPredicate; + + auto screenOnOnBatteryPredicate = config.add_predicate(); + screenOnOnBatteryPredicate->set_id(StringToId("screenOnOnBatteryPredicate")); + screenOnOnBatteryPredicate->mutable_combination()->set_operation(LogicalOperation::AND); + addPredicateToPredicateCombination(screenOnPredicate, screenOnOnBatteryPredicate); + addPredicateToPredicateCombination(deviceUnpluggedPredicate, screenOnOnBatteryPredicate); + + // CountSyncStartWhileScreenOnOnBattery (CombinationCondition) + CountMetric* countMetric1 = config.add_count_metric(); + countMetric1->set_id(StringToId("CountSyncStartWhileScreenOnOnBattery")); + countMetric1->set_what(syncStartMatcher.id()); + countMetric1->set_condition(screenOnOnBatteryPredicate->id()); + countMetric1->set_bucket(FIVE_MINUTES); + + // CountSyncStartWhileOnBattery (SimpleCondition) + CountMetric* countMetric2 = config.add_count_metric(); + countMetric2->set_id(StringToId("CountSyncStartWhileOnBatterySliceScreen")); + countMetric2->set_what(syncStartMatcher.id()); + countMetric2->set_condition(deviceUnpluggedPredicate.id()); + countMetric2->set_bucket(FIVE_MINUTES); + + const uint64_t bucketStartTimeNs = 10000000000; // 0:10 + const uint64_t bucketSizeNs = + TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000000LL; + int uid = 12345; + int64_t cfgId = 98765; + ConfigKey cfgKey(uid, cfgId); + auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey); + + EXPECT_EQ(processor->mMetricsManagers.size(), 1u); + sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second; + EXPECT_TRUE(metricsManager->isConfigValid()); + EXPECT_EQ(2, metricsManager->mAllMetricProducers.size()); + + sp<MetricProducer> metricProducer1 = metricsManager->mAllMetricProducers[0]; + sp<MetricProducer> metricProducer2 = metricsManager->mAllMetricProducers[1]; + + EXPECT_EQ(ConditionState::kUnknown, metricProducer1->mCondition); + EXPECT_EQ(ConditionState::kUnknown, metricProducer2->mCondition); + + auto screenOnEvent = + CreateScreenStateChangedEvent(bucketStartTimeNs + 30, android::view::DISPLAY_STATE_ON); + processor->OnLogEvent(screenOnEvent.get()); + EXPECT_EQ(ConditionState::kUnknown, metricProducer1->mCondition); + EXPECT_EQ(ConditionState::kUnknown, metricProducer2->mCondition); + + auto pluggedUsbEvent = CreateBatteryStateChangedEvent( + bucketStartTimeNs + 50, BatteryPluggedStateEnum::BATTERY_PLUGGED_USB); + processor->OnLogEvent(pluggedUsbEvent.get()); + EXPECT_EQ(ConditionState::kFalse, metricProducer1->mCondition); + EXPECT_EQ(ConditionState::kFalse, metricProducer2->mCondition); + + auto pluggedNoneEvent = CreateBatteryStateChangedEvent( + bucketStartTimeNs + 70, BatteryPluggedStateEnum::BATTERY_PLUGGED_NONE); + processor->OnLogEvent(pluggedNoneEvent.get()); + EXPECT_EQ(ConditionState::kTrue, metricProducer1->mCondition); + EXPECT_EQ(ConditionState::kTrue, metricProducer2->mCondition); +} + +/** * Test a count metric that has one slice_by_state with no primary fields. * * Once the CountMetricProducer is initialized, it has one atom id in @@ -85,7 +171,7 @@ TEST(CountMetricE2eTest, TestSlicedState) { x x x x x x (syncStartEvents) | | (ScreenIsOnEvent) | | (ScreenIsOffEvent) - | (ScreenUnknownEvent) + | (ScreenDozeEvent) */ // Initialize log events - first bucket. std::vector<int> attributionUids1 = {123}; @@ -243,9 +329,8 @@ TEST(CountMetricE2eTest, TestSlicedStateWithMap) { |-----------------------------|-----------------------------|-- x x x x x x x x x (syncStartEvents) -----------------------------------------------------------SCREEN_OFF events - | (ScreenStateUnknownEvent = 0) | | (ScreenStateOffEvent = 1) - | (ScreenStateDozeEvent = 3) + | | (ScreenStateDozeEvent = 3) | (ScreenStateDozeSuspendEvent = 4) -----------------------------------------------------------SCREEN_ON events @@ -262,7 +347,7 @@ TEST(CountMetricE2eTest, TestSlicedStateWithMap) { attributionTags1, "sync_name")); // 0:30 events.push_back(CreateScreenStateChangedEvent( bucketStartTimeNs + 30 * NS_PER_SEC, - android::view::DisplayStateEnum::DISPLAY_STATE_UNKNOWN)); // 0:40 + android::view::DisplayStateEnum::DISPLAY_STATE_DOZE)); // 0:40 events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 60 * NS_PER_SEC, attributionUids1, attributionTags1, "sync_name")); // 1:10 events.push_back(CreateScreenStateChangedEvent( @@ -625,9 +710,8 @@ TEST(CountMetricE2eTest, TestMultipleSlicedStates) { |------------------------|------------------------|-- 1 1 1 1 1 2 1 1 2 (AppCrashEvents) ---------------------------------------------------SCREEN_OFF events - | (ScreenUnknownEvent = 0) | | (ScreenOffEvent = 1) - | (ScreenDozeEvent = 3) + | | (ScreenDozeEvent = 3) ---------------------------------------------------SCREEN_ON events | | (ScreenOnEvent = 2) | (ScreenOnSuspendEvent = 6) @@ -660,7 +744,7 @@ TEST(CountMetricE2eTest, TestMultipleSlicedStates) { CreateAppCrashOccurredEvent(bucketStartTimeNs + 20 * NS_PER_SEC, 1 /*uid*/)); // 0:30 events.push_back(CreateScreenStateChangedEvent( bucketStartTimeNs + 30 * NS_PER_SEC, - android::view::DisplayStateEnum::DISPLAY_STATE_UNKNOWN)); // 0:40 + android::view::DisplayStateEnum::DISPLAY_STATE_DOZE)); // 0:40 events.push_back( CreateAppCrashOccurredEvent(bucketStartTimeNs + 60 * NS_PER_SEC, 1 /*uid*/)); // 1:10 events.push_back(CreateUidProcessStateChangedEvent( diff --git a/cmds/statsd/tests/e2e/ValueMetric_pull_e2e_test.cpp b/cmds/statsd/tests/e2e/ValueMetric_pull_e2e_test.cpp index e595f290ffdf..4d3928277527 100644 --- a/cmds/statsd/tests/e2e/ValueMetric_pull_e2e_test.cpp +++ b/cmds/statsd/tests/e2e/ValueMetric_pull_e2e_test.cpp @@ -63,8 +63,143 @@ StatsdConfig CreateStatsdConfig(bool useCondition = true) { return config; } +StatsdConfig CreateStatsdConfigWithStates() { + StatsdConfig config; + config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root. + config.add_default_pull_packages("AID_ROOT"); // Fake puller is registered with root. + + auto pulledAtomMatcher = CreateSimpleAtomMatcher("TestMatcher", util::SUBSYSTEM_SLEEP_STATE); + *config.add_atom_matcher() = pulledAtomMatcher; + *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher(); + *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher(); + *config.add_atom_matcher() = CreateBatteryStateNoneMatcher(); + *config.add_atom_matcher() = CreateBatteryStateUsbMatcher(); + + auto screenOnPredicate = CreateScreenIsOnPredicate(); + *config.add_predicate() = screenOnPredicate; + + auto screenOffPredicate = CreateScreenIsOffPredicate(); + *config.add_predicate() = screenOffPredicate; + + auto deviceUnpluggedPredicate = CreateDeviceUnpluggedPredicate(); + *config.add_predicate() = deviceUnpluggedPredicate; + + auto screenOnOnBatteryPredicate = config.add_predicate(); + screenOnOnBatteryPredicate->set_id(StringToId("screenOnOnBatteryPredicate")); + screenOnOnBatteryPredicate->mutable_combination()->set_operation(LogicalOperation::AND); + addPredicateToPredicateCombination(screenOnPredicate, screenOnOnBatteryPredicate); + addPredicateToPredicateCombination(deviceUnpluggedPredicate, screenOnOnBatteryPredicate); + + auto screenOffOnBatteryPredicate = config.add_predicate(); + screenOffOnBatteryPredicate->set_id(StringToId("ScreenOffOnBattery")); + screenOffOnBatteryPredicate->mutable_combination()->set_operation(LogicalOperation::AND); + addPredicateToPredicateCombination(screenOffPredicate, screenOffOnBatteryPredicate); + addPredicateToPredicateCombination(deviceUnpluggedPredicate, screenOffOnBatteryPredicate); + + const State screenState = + CreateScreenStateWithSimpleOnOffMap(/*screen on id=*/321, /*screen off id=*/123); + *config.add_state() = screenState; + + // ValueMetricSubsystemSleepWhileScreenOnOnBattery + auto valueMetric1 = config.add_value_metric(); + valueMetric1->set_id(metricId); + valueMetric1->set_what(pulledAtomMatcher.id()); + valueMetric1->set_condition(screenOnOnBatteryPredicate->id()); + *valueMetric1->mutable_value_field() = + CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {4 /* time sleeping field */}); + valueMetric1->set_bucket(FIVE_MINUTES); + valueMetric1->set_use_absolute_value_on_reset(true); + valueMetric1->set_skip_zero_diff_output(false); + valueMetric1->set_max_pull_delay_sec(INT_MAX); + + // ValueMetricSubsystemSleepWhileScreenOffOnBattery + ValueMetric* valueMetric2 = config.add_value_metric(); + valueMetric2->set_id(StringToId("ValueMetricSubsystemSleepWhileScreenOffOnBattery")); + valueMetric2->set_what(pulledAtomMatcher.id()); + valueMetric2->set_condition(screenOffOnBatteryPredicate->id()); + *valueMetric2->mutable_value_field() = + CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {4 /* time sleeping field */}); + valueMetric2->set_bucket(FIVE_MINUTES); + valueMetric2->set_use_absolute_value_on_reset(true); + valueMetric2->set_skip_zero_diff_output(false); + valueMetric2->set_max_pull_delay_sec(INT_MAX); + + // ValueMetricSubsystemSleepWhileOnBatterySliceScreen + ValueMetric* valueMetric3 = config.add_value_metric(); + valueMetric3->set_id(StringToId("ValueMetricSubsystemSleepWhileOnBatterySliceScreen")); + valueMetric3->set_what(pulledAtomMatcher.id()); + valueMetric3->set_condition(deviceUnpluggedPredicate.id()); + *valueMetric3->mutable_value_field() = + CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {4 /* time sleeping field */}); + valueMetric3->add_slice_by_state(screenState.id()); + valueMetric3->set_bucket(FIVE_MINUTES); + valueMetric3->set_use_absolute_value_on_reset(true); + valueMetric3->set_skip_zero_diff_output(false); + valueMetric3->set_max_pull_delay_sec(INT_MAX); + return config; +} + } // namespace +/** + * Tests the initial condition and condition after the first log events for + * value metrics with either a combination condition or simple condition. + * + * Metrics should be initialized with condition kUnknown (given that the + * predicate is using the default InitialValue of UNKNOWN). The condition should + * be updated to either kFalse or kTrue if a condition event is logged for all + * children conditions. + */ +TEST(ValueMetricE2eTest, TestInitialConditionChanges) { + StatsdConfig config = CreateStatsdConfigWithStates(); + int64_t baseTimeNs = getElapsedRealtimeNs(); + int64_t configAddedTimeNs = 10 * 60 * NS_PER_SEC + baseTimeNs; + int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.value_metric(0).bucket()) * 1000000; + + ConfigKey cfgKey; + int32_t tagId = util::SUBSYSTEM_SLEEP_STATE; + auto processor = + CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey, + SharedRefBase::make<FakeSubsystemSleepCallback>(), tagId); + + EXPECT_EQ(processor->mMetricsManagers.size(), 1u); + sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second; + EXPECT_TRUE(metricsManager->isConfigValid()); + EXPECT_EQ(3, metricsManager->mAllMetricProducers.size()); + + // Combination condition metric - screen on and device unplugged + sp<MetricProducer> metricProducer1 = metricsManager->mAllMetricProducers[0]; + // Simple condition metric - device unplugged + sp<MetricProducer> metricProducer2 = metricsManager->mAllMetricProducers[2]; + + EXPECT_EQ(ConditionState::kUnknown, metricProducer1->mCondition); + EXPECT_EQ(ConditionState::kUnknown, metricProducer2->mCondition); + + auto screenOnEvent = + CreateScreenStateChangedEvent(configAddedTimeNs + 30, android::view::DISPLAY_STATE_ON); + processor->OnLogEvent(screenOnEvent.get()); + EXPECT_EQ(ConditionState::kUnknown, metricProducer1->mCondition); + EXPECT_EQ(ConditionState::kUnknown, metricProducer2->mCondition); + + auto screenOffEvent = + CreateScreenStateChangedEvent(configAddedTimeNs + 40, android::view::DISPLAY_STATE_OFF); + processor->OnLogEvent(screenOffEvent.get()); + EXPECT_EQ(ConditionState::kUnknown, metricProducer1->mCondition); + EXPECT_EQ(ConditionState::kUnknown, metricProducer2->mCondition); + + auto pluggedUsbEvent = CreateBatteryStateChangedEvent( + configAddedTimeNs + 50, BatteryPluggedStateEnum::BATTERY_PLUGGED_USB); + processor->OnLogEvent(pluggedUsbEvent.get()); + EXPECT_EQ(ConditionState::kFalse, metricProducer1->mCondition); + EXPECT_EQ(ConditionState::kFalse, metricProducer2->mCondition); + + auto pluggedNoneEvent = CreateBatteryStateChangedEvent( + configAddedTimeNs + 70, BatteryPluggedStateEnum::BATTERY_PLUGGED_NONE); + processor->OnLogEvent(pluggedNoneEvent.get()); + EXPECT_EQ(ConditionState::kFalse, metricProducer1->mCondition); + EXPECT_EQ(ConditionState::kTrue, metricProducer2->mCondition); +} + TEST(ValueMetricE2eTest, TestPulledEvents) { auto config = CreateStatsdConfig(); int64_t baseTimeNs = getElapsedRealtimeNs(); diff --git a/cmds/statsd/tests/statsd_test_util.cpp b/cmds/statsd/tests/statsd_test_util.cpp index 6a7ad1faddea..582df0c1a2a3 100644 --- a/cmds/statsd/tests/statsd_test_util.cpp +++ b/cmds/statsd/tests/statsd_test_util.cpp @@ -169,7 +169,6 @@ AtomMatcher CreateScreenStateChangedAtomMatcher( return atom_matcher; } - AtomMatcher CreateScreenTurnedOnAtomMatcher() { return CreateScreenStateChangedAtomMatcher("ScreenTurnedOn", android::view::DisplayStateEnum::DISPLAY_STATE_ON); @@ -335,22 +334,46 @@ State CreateScreenStateWithOnOffMap(int64_t screenOnId, int64_t screenOffId) { return state; } +State CreateScreenStateWithSimpleOnOffMap(int64_t screenOnId, int64_t screenOffId) { + State state; + state.set_id(StringToId("ScreenStateSimpleOnOff")); + state.set_atom_id(util::SCREEN_STATE_CHANGED); + + auto map = CreateScreenStateSimpleOnOffMap(screenOnId, screenOffId); + *state.mutable_map() = map; + + return state; +} + StateMap_StateGroup CreateScreenStateOnGroup(int64_t screenOnId) { StateMap_StateGroup group; group.set_group_id(screenOnId); - group.add_value(2); - group.add_value(5); - group.add_value(6); + group.add_value(android::view::DisplayStateEnum::DISPLAY_STATE_ON); + group.add_value(android::view::DisplayStateEnum::DISPLAY_STATE_VR); + group.add_value(android::view::DisplayStateEnum::DISPLAY_STATE_ON_SUSPEND); return group; } StateMap_StateGroup CreateScreenStateOffGroup(int64_t screenOffId) { StateMap_StateGroup group; group.set_group_id(screenOffId); - group.add_value(0); - group.add_value(1); - group.add_value(3); - group.add_value(4); + group.add_value(android::view::DisplayStateEnum::DISPLAY_STATE_OFF); + group.add_value(android::view::DisplayStateEnum::DISPLAY_STATE_DOZE); + group.add_value(android::view::DisplayStateEnum::DISPLAY_STATE_DOZE_SUSPEND); + return group; +} + +StateMap_StateGroup CreateScreenStateSimpleOnGroup(int64_t screenOnId) { + StateMap_StateGroup group; + group.set_group_id(screenOnId); + group.add_value(android::view::DisplayStateEnum::DISPLAY_STATE_ON); + return group; +} + +StateMap_StateGroup CreateScreenStateSimpleOffGroup(int64_t screenOffId) { + StateMap_StateGroup group; + group.set_group_id(screenOffId); + group.add_value(android::view::DisplayStateEnum::DISPLAY_STATE_OFF); return group; } @@ -361,6 +384,13 @@ StateMap CreateScreenStateOnOffMap(int64_t screenOnId, int64_t screenOffId) { return map; } +StateMap CreateScreenStateSimpleOnOffMap(int64_t screenOnId, int64_t screenOffId) { + StateMap map; + *map.add_group() = CreateScreenStateSimpleOnGroup(screenOnId); + *map.add_group() = CreateScreenStateSimpleOffGroup(screenOffId); + return map; +} + void addPredicateToPredicateCombination(const Predicate& predicate, Predicate* combinationPredicate) { combinationPredicate->mutable_combination()->add_predicate(predicate.id()); diff --git a/cmds/statsd/tests/statsd_test_util.h b/cmds/statsd/tests/statsd_test_util.h index dc012c5381eb..6a5d5da2895c 100644 --- a/cmds/statsd/tests/statsd_test_util.h +++ b/cmds/statsd/tests/statsd_test_util.h @@ -149,17 +149,30 @@ State CreateUidProcessState(); // Create State proto for overlay state atom. State CreateOverlayState(); +// Create State proto for screen state atom with on/off map. State CreateScreenStateWithOnOffMap(int64_t screenOnId, int64_t screenOffId); +// Create State proto for screen state atom with simple on/off map. +State CreateScreenStateWithSimpleOnOffMap(int64_t screenOnId, int64_t screenOffId); + // Create StateGroup proto for ScreenState ON group StateMap_StateGroup CreateScreenStateOnGroup(int64_t screenOnId); // Create StateGroup proto for ScreenState OFF group StateMap_StateGroup CreateScreenStateOffGroup(int64_t screenOffId); +// Create StateGroup proto for simple ScreenState ON group +StateMap_StateGroup CreateScreenStateSimpleOnGroup(int64_t screenOnId); + +// Create StateGroup proto for simple ScreenState OFF group +StateMap_StateGroup CreateScreenStateSimpleOffGroup(int64_t screenOffId); + // Create StateMap proto for ScreenState ON/OFF map StateMap CreateScreenStateOnOffMap(int64_t screenOnId, int64_t screenOffId); +// Create StateMap proto for simple ScreenState ON/OFF map +StateMap CreateScreenStateSimpleOnOffMap(int64_t screenOnId, int64_t screenOffId); + // Add a predicate to the predicate combination. void addPredicateToPredicateCombination(const Predicate& predicate, Predicate* combination); diff --git a/core/java/android/appwidget/AppWidgetHostView.java b/core/java/android/appwidget/AppWidgetHostView.java index 75ce0dcc1d1d..3fef92b203b6 100644 --- a/core/java/android/appwidget/AppWidgetHostView.java +++ b/core/java/android/appwidget/AppWidgetHostView.java @@ -625,7 +625,10 @@ public class AppWidgetHostView extends FrameLayout { } } defaultView = inflater.inflate(layoutId, this, false); - defaultView.setOnClickListener(this::onDefaultViewClicked); + if (!(defaultView instanceof AdapterView)) { + // AdapterView does not support onClickListener + defaultView.setOnClickListener(this::onDefaultViewClicked); + } } else { Log.w(TAG, "can't inflate defaultView because mInfo is missing"); } diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java index 312e98e77636..d086459080f7 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -127,7 +127,6 @@ import java.util.Iterator; import java.util.List; import java.util.Set; import java.util.UUID; -import java.util.concurrent.atomic.AtomicInteger; /** * Parser for package files (APKs) on disk. This supports apps packaged either @@ -239,11 +238,6 @@ public class PackageParser { public static final boolean LOG_UNSAFE_BROADCASTS = false; - /** - * Total number of packages that were read from the cache. We use it only for logging. - */ - public static final AtomicInteger sCachedPackageReadCount = new AtomicInteger(); - // Set of broadcast actions that are safe for manifest receivers public static final Set<String> SAFE_BROADCASTS = new ArraySet<>(); static { diff --git a/core/java/android/database/DatabaseUtils.java b/core/java/android/database/DatabaseUtils.java index 9b809b86eae9..b978ae559390 100644 --- a/core/java/android/database/DatabaseUtils.java +++ b/core/java/android/database/DatabaseUtils.java @@ -191,6 +191,58 @@ public class DatabaseUtils { } } + /** {@hide} */ + public static long executeInsert(@NonNull SQLiteDatabase db, @NonNull String sql, + @Nullable Object[] bindArgs) throws SQLException { + try (SQLiteStatement st = db.compileStatement(sql)) { + bindArgs(st, bindArgs); + return st.executeInsert(); + } + } + + /** {@hide} */ + public static int executeUpdateDelete(@NonNull SQLiteDatabase db, @NonNull String sql, + @Nullable Object[] bindArgs) throws SQLException { + try (SQLiteStatement st = db.compileStatement(sql)) { + bindArgs(st, bindArgs); + return st.executeUpdateDelete(); + } + } + + /** {@hide} */ + private static void bindArgs(@NonNull SQLiteStatement st, @Nullable Object[] bindArgs) { + if (bindArgs == null) return; + + for (int i = 0; i < bindArgs.length; i++) { + final Object bindArg = bindArgs[i]; + switch (getTypeOfObject(bindArg)) { + case Cursor.FIELD_TYPE_NULL: + st.bindNull(i + 1); + break; + case Cursor.FIELD_TYPE_INTEGER: + st.bindLong(i + 1, ((Number) bindArg).longValue()); + break; + case Cursor.FIELD_TYPE_FLOAT: + st.bindDouble(i + 1, ((Number) bindArg).doubleValue()); + break; + case Cursor.FIELD_TYPE_BLOB: + st.bindBlob(i + 1, (byte[]) bindArg); + break; + case Cursor.FIELD_TYPE_STRING: + default: + if (bindArg instanceof Boolean) { + // Provide compatibility with legacy + // applications which may pass Boolean values in + // bind args. + st.bindLong(i + 1, ((Boolean) bindArg).booleanValue() ? 1 : 0); + } else { + st.bindString(i + 1, bindArg.toString()); + } + break; + } + } + } + /** * Binds the given Object to the given SQLiteProgram using the proper * typing. For example, bind numbers as longs/doubles, and everything else diff --git a/core/java/android/database/sqlite/SQLiteQueryBuilder.java b/core/java/android/database/sqlite/SQLiteQueryBuilder.java index 36ec67ee1471..669d0466fdf2 100644 --- a/core/java/android/database/sqlite/SQLiteQueryBuilder.java +++ b/core/java/android/database/sqlite/SQLiteQueryBuilder.java @@ -626,7 +626,7 @@ public class SQLiteQueryBuilder { Log.d(TAG, sql); } } - return db.executeSql(sql, sqlArgs); + return DatabaseUtils.executeInsert(db, sql, sqlArgs); } /** @@ -702,7 +702,7 @@ public class SQLiteQueryBuilder { Log.d(TAG, sql); } } - return db.executeSql(sql, sqlArgs); + return DatabaseUtils.executeUpdateDelete(db, sql, sqlArgs); } /** @@ -762,7 +762,7 @@ public class SQLiteQueryBuilder { Log.d(TAG, sql); } } - return db.executeSql(sql, sqlArgs); + return DatabaseUtils.executeUpdateDelete(db, sql, sqlArgs); } private void enforceStrictColumns(@Nullable String[] projection) { diff --git a/core/java/android/util/AtomicFile.java b/core/java/android/util/AtomicFile.java index da7503d01428..1dd4cbb403db 100644 --- a/core/java/android/util/AtomicFile.java +++ b/core/java/android/util/AtomicFile.java @@ -227,11 +227,8 @@ public class AtomicFile { } } - if (mNewName.exists()) { - if (!mNewName.delete()) { - Log.e(LOG_TAG, "Failed to delete outdated new file " + mNewName); - } - } + // Don't delete mNewName here - it was okay to call openRead() between startWrite() and + // finishWrite(), and we have to keep supporting it. return new FileInputStream(mBaseName); } diff --git a/core/java/android/view/contentcapture/ContentCaptureSession.java b/core/java/android/view/contentcapture/ContentCaptureSession.java index 39c7210d8dac..301ce9f013e4 100644 --- a/core/java/android/view/contentcapture/ContentCaptureSession.java +++ b/core/java/android/view/contentcapture/ContentCaptureSession.java @@ -166,6 +166,8 @@ public abstract class ContentCaptureSession implements AutoCloseable { public static final int FLUSH_REASON_IDLE_TIMEOUT = 5; /** @hide */ public static final int FLUSH_REASON_TEXT_CHANGE_TIMEOUT = 6; + /** @hide */ + public static final int FLUSH_REASON_SESSION_CONNECTED = 7; /** @hide */ @IntDef(prefix = { "FLUSH_REASON_" }, value = { @@ -174,7 +176,8 @@ public abstract class ContentCaptureSession implements AutoCloseable { FLUSH_REASON_SESSION_STARTED, FLUSH_REASON_SESSION_FINISHED, FLUSH_REASON_IDLE_TIMEOUT, - FLUSH_REASON_TEXT_CHANGE_TIMEOUT + FLUSH_REASON_TEXT_CHANGE_TIMEOUT, + FLUSH_REASON_SESSION_CONNECTED }) @Retention(RetentionPolicy.SOURCE) public @interface FlushReason{} @@ -609,6 +612,8 @@ public abstract class ContentCaptureSession implements AutoCloseable { return "IDLE"; case FLUSH_REASON_TEXT_CHANGE_TIMEOUT: return "TEXT_CHANGE"; + case FLUSH_REASON_SESSION_CONNECTED: + return "CONNECTED"; default: return "UNKOWN-" + reason; } diff --git a/core/java/android/view/contentcapture/MainContentCaptureSession.java b/core/java/android/view/contentcapture/MainContentCaptureSession.java index 893d38dcfde7..6eb71f747be6 100644 --- a/core/java/android/view/contentcapture/MainContentCaptureSession.java +++ b/core/java/android/view/contentcapture/MainContentCaptureSession.java @@ -273,6 +273,8 @@ public final class MainContentCaptureSession extends ContentCaptureSession { } else { mState = resultCode; mDisabled.set(false); + // Flush any pending data immediately as buffering forced until now. + flushIfNeeded(FLUSH_REASON_SESSION_CONNECTED); } if (sVerbose) { Log.v(TAG, "handleSessionStarted() result: id=" + mId + " resultCode=" + resultCode diff --git a/core/java/android/webkit/WebChromeClient.java b/core/java/android/webkit/WebChromeClient.java index f78ec7c439a1..0807f4162162 100644 --- a/core/java/android/webkit/WebChromeClient.java +++ b/core/java/android/webkit/WebChromeClient.java @@ -219,17 +219,34 @@ public class WebChromeClient { } /** - * Tell the client to display a confirm dialog to the user. If the client - * returns {@code true}, WebView will assume that the client will handle the - * confirm dialog and call the appropriate JsResult method. If the - * client returns false, a default value of {@code false} will be returned to - * javascript. The default behavior is to return {@code false}. + * Notify the host application that the web page wants to display a + * JavaScript {@code confirm()} dialog. + * <p>The default behavior if this method returns {@code false} or is not + * overridden is to show a dialog containing the message and suspend + * JavaScript execution until the dialog is dismissed. The default dialog + * will return {@code true} to the JavaScript {@code confirm()} code when + * the user presses the 'confirm' button, and will return {@code false} to + * the JavaScript code when the user presses the 'cancel' button or + * dismisses the dialog. + * <p>To show a custom dialog, the app should return {@code true} from this + * method, in which case the default dialog will not be shown and JavaScript + * execution will be suspended. The app should call + * {@code JsResult.confirm()} or {@code JsResult.cancel()} when the custom + * dialog is dismissed. + * <p>To suppress the dialog and allow JavaScript execution to continue, + * call {@code JsResult.confirm()} or {@code JsResult.cancel()} immediately + * and then return {@code true}. + * <p>Note that if the {@link WebChromeClient} is {@code null}, the default + * dialog will be suppressed and the default value of {@code false} will be + * returned to the JavaScript code immediately. + * * @param view The WebView that initiated the callback. * @param url The url of the page requesting the dialog. * @param message Message to be displayed in the window. * @param result A JsResult used to send the user's response to * javascript. - * @return boolean Whether the client will handle the confirm dialog. + * @return boolean {@code true} if the request is handled or ignored. + * {@code false} if WebView needs to show the default dialog. */ public boolean onJsConfirm(WebView view, String url, String message, JsResult result) { @@ -237,18 +254,33 @@ public class WebChromeClient { } /** - * Tell the client to display a prompt dialog to the user. If the client - * returns {@code true}, WebView will assume that the client will handle the - * prompt dialog and call the appropriate JsPromptResult method. If the - * client returns false, a default value of {@code false} will be returned to to - * javascript. The default behavior is to return {@code false}. + * Notify the host application that the web page wants to display a + * JavaScript {@code prompt()} dialog. + * <p>The default behavior if this method returns {@code false} or is not + * overridden is to show a dialog containing the message and suspend + * JavaScript execution until the dialog is dismissed. Once the dialog is + * dismissed, JavaScript {@code prompt()} will return the string that the + * user typed in, or null if the user presses the 'cancel' button. + * <p>To show a custom dialog, the app should return {@code true} from this + * method, in which case the default dialog will not be shown and JavaScript + * execution will be suspended. The app should call + * {@code JsPromptResult.confirm(result)} when the custom dialog is + * dismissed. + * <p>To suppress the dialog and allow JavaScript execution to continue, + * call {@code JsPromptResult.confirm(result)} immediately and then + * return {@code true}. + * <p>Note that if the {@link WebChromeClient} is {@code null}, the default + * dialog will be suppressed and {@code null} will be returned to the + * JavaScript code immediately. + * * @param view The WebView that initiated the callback. * @param url The url of the page requesting the dialog. * @param message Message to be displayed in the window. * @param defaultValue The default value displayed in the prompt dialog. * @param result A JsPromptResult used to send the user's reponse to * javascript. - * @return boolean Whether the client will handle the prompt dialog. + * @return boolean {@code true} if the request is handled or ignored. + * {@code false} if WebView needs to show the default dialog. */ public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) { diff --git a/core/proto/android/view/imefocuscontroller.proto b/core/proto/android/view/imefocuscontroller.proto new file mode 100644 index 000000000000..ff9dee69207b --- /dev/null +++ b/core/proto/android/view/imefocuscontroller.proto @@ -0,0 +1,30 @@ +/* + * 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. + */ + +syntax = "proto2"; + +package android.view; + +option java_multiple_files = true; + +/** + * Represents a {@link android.view.ImeFocusController} object. + */ +message ImeFocusControllerProto { + optional bool has_ime_focus = 1; + optional string served_view = 2; + optional string next_served_view = 3; +}
\ No newline at end of file diff --git a/core/proto/android/view/imeinsetssourceconsumer.proto b/core/proto/android/view/imeinsetssourceconsumer.proto new file mode 100644 index 000000000000..680916345a31 --- /dev/null +++ b/core/proto/android/view/imeinsetssourceconsumer.proto @@ -0,0 +1,31 @@ +/* + * 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. + */ + +syntax = "proto2"; + +import "frameworks/base/core/proto/android/view/inputmethod/editorinfo.proto"; + +package android.view; + +option java_multiple_files = true; + +/** + * Represents a {@link android.view.ImeInsetsSourceConsumer} object. + */ +message ImeInsetsSourceConsumerProto { + optional .android.view.inputmethod.EditorInfoProto focused_editor = 1; + optional bool is_requested_visible_awaiting_control = 2; +}
\ No newline at end of file diff --git a/core/proto/android/view/inputmethod/editorinfo.proto b/core/proto/android/view/inputmethod/editorinfo.proto new file mode 100644 index 000000000000..f93096f9d395 --- /dev/null +++ b/core/proto/android/view/inputmethod/editorinfo.proto @@ -0,0 +1,33 @@ +/* + * 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. + */ + +syntax = "proto2"; + +package android.view.inputmethod; + +option java_multiple_files = true; + +/** + * Represents a {@link android.view.inputmethod.EditorInfo} object. + */ +message EditorInfoProto { + optional int32 input_type = 1; + optional int32 ime_options = 2; + optional string private_ime_options = 3; + optional string package_name = 4; + optional int32 field_id = 5; + optional int32 target_input_method_user_id = 6; +}
\ No newline at end of file diff --git a/core/proto/android/view/inputmethod/inputmethodeditortrace.proto b/core/proto/android/view/inputmethod/inputmethodeditortrace.proto new file mode 100644 index 000000000000..732213966014 --- /dev/null +++ b/core/proto/android/view/inputmethod/inputmethodeditortrace.proto @@ -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. + */ + +syntax = "proto2"; +option java_outer_classname = "InputMethodEditorTraceProto"; + +package android.view.inputmethod; + +import "frameworks/base/core/proto/android/view/inputmethod/inputmethodmanager.proto"; +import "frameworks/base/core/proto/android/view/viewrootimpl.proto"; +import "frameworks/base/core/proto/android/view/insetscontroller.proto"; +import "frameworks/base/core/proto/android/view/insetssourceconsumer.proto"; +import "frameworks/base/core/proto/android/view/imeinsetssourceconsumer.proto"; +import "frameworks/base/core/proto/android/view/inputmethod/editorinfo.proto"; +import "frameworks/base/core/proto/android/view/imefocuscontroller.proto"; + +/** + * Represents a file full of input method editor trace entries. + * Encoded, it should start with 0x9 0x49 0x4d 0x45 0x54 0x52 0x41 0x43 0x45 (.IMETRACE), such + * that they can be easily identified. + */ +message InputMethodEditorTraceFileProto { + + /* constant; MAGIC_NUMBER = (long) MAGIC_NUMBER_H << 32 | MagicNumber.MAGIC_NUMBER_L + (this is needed because enums have to be 32 bits and there's no nice way to put 64bit + constants into .proto files.) */ + enum MagicNumber { + INVALID = 0; + MAGIC_NUMBER_L = 0x54454d49; /* IMET (little-endian ASCII) */ + MAGIC_NUMBER_H = 0x45434152; /* RACE (little-endian ASCII) */ + } + + /* Must be the first field to allow winscope to auto-detect the dump type. Set to value + in MagicNumber */ + optional fixed64 magic_number = 1; + repeated InputMethodEditorProto entry = 2; +} + +/* one input method editor dump entry. */ +message InputMethodEditorProto { + + /* required: elapsed realtime in nanos since boot of when this entry was logged */ + optional fixed64 elapsed_realtime_nanos = 1; + optional ClientSideProto client_side_dump = 2; + + /* groups together the dump from ime related client side classes */ + message ClientSideProto { + optional InputMethodManagerProto input_method_manager = 1; + optional ViewRootImplProto view_root_impl = 2; + optional InsetsControllerProto insets_controller = 3; + optional InsetsSourceConsumerProto insets_source_consumer = 4; + optional ImeInsetsSourceConsumerProto ime_insets_source_consumer = 5; + optional EditorInfoProto editor_info = 6; + optional ImeFocusControllerProto ime_focus_controller = 7; + } +}
\ No newline at end of file diff --git a/core/proto/android/view/inputmethod/inputmethodmanager.proto b/core/proto/android/view/inputmethod/inputmethodmanager.proto new file mode 100644 index 000000000000..9fed0ef95a27 --- /dev/null +++ b/core/proto/android/view/inputmethod/inputmethodmanager.proto @@ -0,0 +1,32 @@ +/* + * 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. + */ + +syntax = "proto2"; + +package android.view.inputmethod; + +option java_multiple_files = true; + +/** + * Represents a {@link android.view.inputmethod.InputMethodManager} object. + */ +message InputMethodManagerProto { + optional string cur_id = 1; + optional bool fullscreen_mode = 2; + optional int32 display_id = 3; + optional bool active = 4; + optional bool served_connecting = 5; +}
\ No newline at end of file diff --git a/core/proto/android/view/insetsanimationcontrolimpl.proto b/core/proto/android/view/insetsanimationcontrolimpl.proto new file mode 100644 index 000000000000..6eec37b8298e --- /dev/null +++ b/core/proto/android/view/insetsanimationcontrolimpl.proto @@ -0,0 +1,35 @@ +/* + * 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. + */ + +syntax = "proto2"; + +package android.view; + +option java_multiple_files = true; + +/** + * Represents a {@link android.view.InsetsAnimationControlImpl} object. + */ +message InsetsAnimationControlImplProto { + optional bool is_cancelled = 1; + optional bool is_finished = 2; + optional string tmp_matrix = 3; + optional string pending_insets = 4; + optional float pending_fraction = 5; + optional bool shown_on_finish = 6; + optional float current_alpha = 7; + optional float pending_alpha = 8; +}
\ No newline at end of file diff --git a/core/proto/android/view/insetscontroller.proto b/core/proto/android/view/insetscontroller.proto new file mode 100644 index 000000000000..a8bf431ce156 --- /dev/null +++ b/core/proto/android/view/insetscontroller.proto @@ -0,0 +1,32 @@ +/* + * 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. + */ + +syntax = "proto2"; + +import "frameworks/base/core/proto/android/view/insetsstate.proto"; +import "frameworks/base/core/proto/android/view/insetsanimationcontrolimpl.proto"; + +package android.view; + +option java_multiple_files = true; + +/** + * Represents a {@link android.view.InsetsController} object. + */ +message InsetsControllerProto { + optional InsetsStateProto state = 1; + repeated InsetsAnimationControlImplProto control = 2; +}
\ No newline at end of file diff --git a/core/proto/android/view/insetssource.proto b/core/proto/android/view/insetssource.proto new file mode 100644 index 000000000000..41b9f432a0ed --- /dev/null +++ b/core/proto/android/view/insetssource.proto @@ -0,0 +1,33 @@ +/* + * 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. + */ + +syntax = "proto2"; + +import "frameworks/base/core/proto/android/graphics/rect.proto"; + +package android.view; + +option java_multiple_files = true; + +/** + * Represents a {@link android.view.InsetsSource} object. + */ +message InsetsSourceProto { + optional string type = 1; + optional .android.graphics.RectProto frame = 2; + optional .android.graphics.RectProto visible_frame = 3; + optional bool visible = 4; +}
\ No newline at end of file diff --git a/core/proto/android/view/insetssourceconsumer.proto b/core/proto/android/view/insetssourceconsumer.proto new file mode 100644 index 000000000000..487e06c1ccdf --- /dev/null +++ b/core/proto/android/view/insetssourceconsumer.proto @@ -0,0 +1,36 @@ +/* + * 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. + */ + +syntax = "proto2"; + +import "frameworks/base/core/proto/android/view/insetssourcecontrol.proto"; +import "frameworks/base/core/proto/android/graphics/rect.proto"; + +package android.view; + +option java_multiple_files = true; + +/** + * Represents a {@link android.view.InsetsSourceConsumer} object. + */ +message InsetsSourceConsumerProto { + optional string internal_insets_type = 1; + optional bool has_window_focus = 2; + optional bool is_requested_visible = 3; + optional InsetsSourceControlProto source_control = 4; + optional .android.graphics.RectProto pending_frame = 5; + optional .android.graphics.RectProto pending_visible_frame = 6; +}
\ No newline at end of file diff --git a/core/proto/android/view/insetssourcecontrol.proto b/core/proto/android/view/insetssourcecontrol.proto new file mode 100644 index 000000000000..3ac3cbfafaff --- /dev/null +++ b/core/proto/android/view/insetssourcecontrol.proto @@ -0,0 +1,33 @@ +/* + * 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. + */ + +syntax = "proto2"; + +import "frameworks/base/core/proto/android/graphics/point.proto"; +import "frameworks/base/core/proto/android/view/surfacecontrol.proto"; + +package android.view; + +option java_multiple_files = true; + +/** + * Represents a {@link android.view.InsetsSourceControl} object. + */ +message InsetsSourceControlProto { + optional string type = 1; + optional .android.graphics.PointProto position = 2; + optional SurfaceControlProto leash = 3; +}
\ No newline at end of file diff --git a/core/proto/android/view/insetsstate.proto b/core/proto/android/view/insetsstate.proto new file mode 100644 index 000000000000..9e9933d72c6c --- /dev/null +++ b/core/proto/android/view/insetsstate.proto @@ -0,0 +1,32 @@ +/* + * 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. + */ + +syntax = "proto2"; + +import "frameworks/base/core/proto/android/view/insetssource.proto"; +import "frameworks/base/core/proto/android/graphics/rect.proto"; + +package android.view; + +option java_multiple_files = true; + +/** + * Represents a {@link android.view.InsetsState} object. + */ +message InsetsStateProto { + repeated InsetsSourceProto sources = 1; + optional .android.graphics.RectProto display_frame = 2; +}
\ No newline at end of file diff --git a/core/proto/android/view/viewrootimpl.proto b/core/proto/android/view/viewrootimpl.proto new file mode 100644 index 000000000000..0abe5e0624e3 --- /dev/null +++ b/core/proto/android/view/viewrootimpl.proto @@ -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. + */ + +syntax = "proto2"; + +import "frameworks/base/core/proto/android/graphics/rect.proto"; +import "frameworks/base/core/proto/android/view/displaycutout.proto"; +import "frameworks/base/core/proto/android/view/windowlayoutparams.proto"; + +package android.view; + +option java_multiple_files = true; + +/** + * Represents a {@link android.view.ViewRootImpl} object. + */ +message ViewRootImplProto { + optional string view = 1; + optional int32 display_id = 2; + optional bool app_visible = 3; + optional int32 width = 4; + optional int32 height = 5; + optional bool is_animating = 6; + optional .android.graphics.RectProto visible_rect = 7; + optional bool is_drawing = 8; + optional bool added = 9; + optional .android.graphics.RectProto win_frame = 10; + optional DisplayCutoutProto pending_display_cutout = 11; + optional string last_window_insets = 12; + optional string soft_input_mode = 13; + optional int32 scroll_y = 14; + optional int32 cur_scroll_y = 15; + optional bool removed = 16; + optional .android.view.WindowLayoutParamsProto window_attributes = 17; +}
\ No newline at end of file diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index fe7b0ae83c01..ac808df7ef5d 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -42,6 +42,7 @@ <item><xliff:g id="id">@string/status_bar_phone_evdo_signal</xliff:g></item> <item><xliff:g id="id">@string/status_bar_phone_signal</xliff:g></item> <item><xliff:g id="id">@string/status_bar_secure</xliff:g></item> + <item><xliff:g id="id">@string/status_bar_media</xliff:g></item> <item><xliff:g id="id">@string/status_bar_managed_profile</xliff:g></item> <item><xliff:g id="id">@string/status_bar_cast</xliff:g></item> <item><xliff:g id="id">@string/status_bar_screen_record</xliff:g></item> @@ -96,6 +97,7 @@ <string translatable="false" name="status_bar_airplane">airplane</string> <string translatable="false" name="status_bar_sensors_off">sensors_off</string> <string translatable="false" name="status_bar_screen_record">screen_record</string> + <string translatable="false" name="status_bar_media">media</string> <!-- Flag indicating whether the surface flinger has limited alpha compositing functionality in hardware. If set, the window diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 7744e9e9a8a7..758a4f7baffc 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -2916,6 +2916,7 @@ <java-symbol type="string" name="status_bar_camera" /> <java-symbol type="string" name="status_bar_sensors_off" /> <java-symbol type="string" name="status_bar_screen_record" /> + <java-symbol type="string" name="status_bar_media" /> <!-- Locale picker --> <java-symbol type="id" name="locale_search_menu" /> diff --git a/graphics/java/android/graphics/PorterDuff.java b/graphics/java/android/graphics/PorterDuff.java index 1275cb9ca4f9..eb940e2f9017 100644 --- a/graphics/java/android/graphics/PorterDuff.java +++ b/graphics/java/android/graphics/PorterDuff.java @@ -30,8 +30,6 @@ public class PorterDuff { /** * {@usesMathJax} * - * <h3>Porter-Duff</h3> - * * <p>The name of the parent class is an homage to the work of Thomas Porter and * Tom Duff, presented in their seminal 1984 paper titled "Compositing Digital Images". * In this paper, the authors describe 12 compositing operators that govern how to diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml index 1729027d9613..66787c2a8663 100644 --- a/packages/SettingsLib/res/values-af/strings.xml +++ b/packages/SettingsLib/res/values-af/strings.xml @@ -553,6 +553,7 @@ <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Gedeaktiveer"</string> <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Geaktiveer"</string> <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Jou toestel moet herselflaai om hierdie verandering toe te pas. Herselflaai nou of kanselleer."</string> - <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) --> + <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"Werk-<xliff:g id="APP_NAME">%s</xliff:g>"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> <skip /> </resources> diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml index fad7a82aae30..ead0ebfa73bd 100644 --- a/packages/SettingsLib/res/values-am/strings.xml +++ b/packages/SettingsLib/res/values-am/strings.xml @@ -553,6 +553,7 @@ <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"ተሰናክሏል"</string> <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"ነቅቷል"</string> <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"የእርስዎን መሣሪያ ይህ ለው ለማመልከት እንደገና መነሣት አለበት። አሁን እንደገና ያስነሡ ወይም ይተዉት።"</string> - <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) --> + <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"የስራ <xliff:g id="APP_NAME">%s</xliff:g>"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> <skip /> </resources> diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml index b3cc83282d7f..c1f4fd95813f 100644 --- a/packages/SettingsLib/res/values-ar/strings.xml +++ b/packages/SettingsLib/res/values-ar/strings.xml @@ -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> @@ -279,7 +279,7 @@ <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">"اسم مضيف مزوّد \"نظام أسماء النطاقات الخاص\""</string> - <string name="private_dns_mode_provider_hostname_hint" msgid="6564868953748514595">"يُرجى إدخال اسم مضيف \"مزوّد نظام أسماء النطاقات\""</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">"زيادة مستوى تسجيل Wi-Fi، وعرض لكل SSID RSSI في منتقي Wi-Fi"</string> @@ -318,10 +318,10 @@ <string name="hdcp_checking_title" msgid="3155692785074095986">"التحقق من HDCP"</string> <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"تعيين سلوك التحقق من HDCP"</string> <string name="debug_debugging_category" msgid="535341063709248842">"تصحيح الأخطاء"</string> - <string name="debug_app" msgid="8903350241392391766">"تحديد التطبيق لتصحيحه"</string> + <string name="debug_app" msgid="8903350241392391766">"اختيار التطبيق لتصحيحه"</string> <string name="debug_app_not_set" msgid="1934083001283807188">"لم يتم تعيين تطبيق لتصحيحه"</string> <string name="debug_app_set" msgid="6599535090477753651">"تطبيق التصحيح: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> - <string name="select_application" msgid="2543228890535466325">"تحديد تطبيق"</string> + <string name="select_application" msgid="2543228890535466325">"اختيار تطبيق"</string> <string name="no_application" msgid="9038334538870247690">"لا شيء"</string> <string name="wait_for_debugger" msgid="7461199843335409809">"انتظار برنامج التصحيح"</string> <string name="wait_for_debugger_summary" msgid="6846330006113363286">"ينتظر التطبيق قيد التصحيح انضمام برنامج التصحيح قبل التنفيذ"</string> @@ -557,6 +557,7 @@ <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"غير مفعّل"</string> <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"مفعّل"</string> <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"يجب إعادة تشغيل جهازك ليتم تطبيق هذا التغيير. يمكنك إعادة التشغيل الآن أو إلغاء التغيير."</string> - <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) --> + <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"<xliff:g id="APP_NAME">%s</xliff:g> المخصّص للعمل"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> <skip /> </resources> diff --git a/packages/SettingsLib/res/values-as/strings.xml b/packages/SettingsLib/res/values-as/strings.xml index ad344c3803bc..b5d642a9ae8f 100644 --- a/packages/SettingsLib/res/values-as/strings.xml +++ b/packages/SettingsLib/res/values-as/strings.xml @@ -549,14 +549,11 @@ <string name="guest_new_guest" msgid="3482026122932643557">"অতিথি যোগ কৰক"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"অতিথি আঁতৰাওক"</string> <string name="guest_nickname" msgid="6332276931583337261">"অতিথি"</string> - <!-- no translation found for cached_apps_freezer_device_default (2616594131750144342) --> - <skip /> - <!-- no translation found for cached_apps_freezer_disabled (4816382260660472042) --> - <skip /> - <!-- no translation found for cached_apps_freezer_enabled (8866703500183051546) --> - <skip /> - <!-- no translation found for cached_apps_freezer_reboot_dialog_text (695330563489230096) --> - <skip /> - <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) --> + <string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"ডিভাইচ ডিফ’ল্ট"</string> + <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"অক্ষম কৰা আছে"</string> + <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"সক্ষম কৰা আছে"</string> + <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"এই সলনিটো কার্যকৰী হ’বলৈ আপোনাৰ ডিভাইচটো ৰিবুট কৰিবই লাগিব। এতিয়াই ৰিবুট কৰক অথবা বাতিল কৰক।"</string> + <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"কৰ্মস্থান <xliff:g id="APP_NAME">%s</xliff:g>"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> <skip /> </resources> diff --git a/packages/SettingsLib/res/values-az/strings.xml b/packages/SettingsLib/res/values-az/strings.xml index ab7ea8c96d07..aecaf704b02f 100644 --- a/packages/SettingsLib/res/values-az/strings.xml +++ b/packages/SettingsLib/res/values-az/strings.xml @@ -155,7 +155,7 @@ <string name="launch_defaults_some" msgid="3631650616557252926">"Bəzi susmaya görələr təyin edilib"</string> <string name="launch_defaults_none" msgid="8049374306261262709">"Susmaya görələr təyin edilməyib."</string> <string name="tts_settings" msgid="8130616705989351312">"Mətndən-danışığa parametrləri"</string> - <string name="tts_settings_title" msgid="7602210956640483039">"Mətndən-nitqə çıxışı"</string> + <string name="tts_settings_title" msgid="7602210956640483039">"Mətndən-nitqə daxiletmə"</string> <string name="tts_default_rate_title" msgid="3964187817364304022">"Nitq diapazonu"</string> <string name="tts_default_rate_summary" msgid="3781937042151716987">"Mətnin səsləndirilmə sürəti"</string> <string name="tts_default_pitch_title" msgid="6988592215554485479">"Pitç"</string> @@ -553,6 +553,7 @@ <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Deaktiv"</string> <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Aktiv"</string> <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Bu dəyişikliyin tətbiq edilməsi üçün cihaz yenidən başladılmalıdır. İndi yenidən başladın və ya ləğv edin."</string> - <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) --> + <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"İş <xliff:g id="APP_NAME">%s</xliff:g>"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> <skip /> </resources> diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml index da47bf27f5c7..092bd42e60ce 100644 --- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml +++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml @@ -554,6 +554,7 @@ <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Onemogućeno"</string> <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Omogućeno"</string> <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Morate da restartujete uređaj da bi se ova promena primenila. Restartujte ga odmah ili otkažite."</string> - <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) --> + <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"<xliff:g id="APP_NAME">%s</xliff:g> za posao"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> <skip /> </resources> diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml index 2761d47c001a..d610973d891c 100644 --- a/packages/SettingsLib/res/values-be/strings.xml +++ b/packages/SettingsLib/res/values-be/strings.xml @@ -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> @@ -555,6 +555,7 @@ <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Выключана"</string> <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Уключана"</string> <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Перазагрузіце прыладу, каб прымяніць гэта змяненне. Перазагрузіце ці скасуйце."</string> - <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) --> + <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"<xliff:g id="APP_NAME">%s</xliff:g> (праца)"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> <skip /> </resources> diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml index 8150710f0db9..5c3fe75857dc 100644 --- a/packages/SettingsLib/res/values-bg/strings.xml +++ b/packages/SettingsLib/res/values-bg/strings.xml @@ -419,7 +419,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> @@ -554,4 +554,6 @@ <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Активирано"</string> <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"За да бъде приложена тази промяна, устройството ви трябва да бъде рестартирано. Рестартирайте сега или анулирайте."</string> <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"<xliff:g id="APP_NAME">%s</xliff:g> за работа"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml index 7bae6eef1aaa..27d370714a0d 100644 --- a/packages/SettingsLib/res/values-bn/strings.xml +++ b/packages/SettingsLib/res/values-bn/strings.xml @@ -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> @@ -485,7 +485,7 @@ <string name="ims_reg_title" msgid="8197592958123671062">"IMS রেজিস্ট্রেশনের স্থিতি"</string> <string name="ims_reg_status_registered" msgid="884916398194885457">"রেজিস্টার করা"</string> <string name="ims_reg_status_not_registered" msgid="2989287366045704694">"রেজিস্টার করা নয়"</string> - <string name="status_unavailable" msgid="5279036186589861608">"অনুপলব্ধ"</string> + <string name="status_unavailable" msgid="5279036186589861608">"অনুপলভ্য"</string> <string name="wifi_status_mac_randomized" msgid="466382542497832189">"MAC র্যান্ডমাইজ করা হয়েছে"</string> <plurals name="wifi_tether_connected_summary" formatted="false" msgid="6317236306047306139"> <item quantity="one">%1$dটি ডিভাইস কানেক্ট</item> @@ -549,14 +549,11 @@ <string name="guest_new_guest" msgid="3482026122932643557">"অতিথি যোগ করুন"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"অতিথি সরান"</string> <string name="guest_nickname" msgid="6332276931583337261">"অতিথি"</string> - <!-- no translation found for cached_apps_freezer_device_default (2616594131750144342) --> - <skip /> - <!-- no translation found for cached_apps_freezer_disabled (4816382260660472042) --> - <skip /> - <!-- no translation found for cached_apps_freezer_enabled (8866703500183051546) --> - <skip /> - <!-- no translation found for cached_apps_freezer_reboot_dialog_text (695330563489230096) --> - <skip /> - <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) --> + <string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"ডিভাইসের ডিফল্ট"</string> + <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"বন্ধ করা আছে"</string> + <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"চালু করা আছে"</string> + <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"এই পরিবর্তনটি প্রয়োগ করার জন্য আপনার ডিভাইসটি অবশ্যই রিবুট করতে হবে। এখন রিবুট করুন বা বাতিল করুন।"</string> + <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"অফিস <xliff:g id="APP_NAME">%s</xliff:g>"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> <skip /> </resources> diff --git a/packages/SettingsLib/res/values-bs/arrays.xml b/packages/SettingsLib/res/values-bs/arrays.xml index 6489cefdc551..6595c226a171 100644 --- a/packages/SettingsLib/res/values-bs/arrays.xml +++ b/packages/SettingsLib/res/values-bs/arrays.xml @@ -40,7 +40,7 @@ <item msgid="8339720953594087771">"Povezivanje na mrežu <xliff:g id="NETWORK_NAME">%1$s</xliff:g>..."</item> <item msgid="3028983857109369308">"Autentifikacija s mrežom <xliff:g id="NETWORK_NAME">%1$s</xliff:g>…"</item> <item msgid="4287401332778341890">"Dobivanje IP adrese iz mreže <xliff:g id="NETWORK_NAME">%1$s</xliff:g>…"</item> - <item msgid="1043944043827424501">"Povezano na mrežu <xliff:g id="NETWORK_NAME">%1$s</xliff:g>"</item> + <item msgid="1043944043827424501">"Povezano s mrežom <xliff:g id="NETWORK_NAME">%1$s</xliff:g>"</item> <item msgid="7445993821842009653">"Suspendirano"</item> <item msgid="1175040558087735707">"Prekidanje veze s mrežom <xliff:g id="NETWORK_NAME">%1$s</xliff:g>…"</item> <item msgid="699832486578171722">"Isključen"</item> diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml index fe7f8c165864..a9d9e7025236 100644 --- a/packages/SettingsLib/res/values-bs/strings.xml +++ b/packages/SettingsLib/res/values-bs/strings.xml @@ -452,7 +452,7 @@ <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Brzo punjenje"</string> <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Sporo punjenje"</string> <string name="battery_info_status_discharging" msgid="6962689305413556485">"Ne puni se"</string> - <string name="battery_info_status_not_charging" msgid="8330015078868707899">"Priključen, trenutno se ne može puniti"</string> + <string name="battery_info_status_not_charging" msgid="8330015078868707899">"Priključeno, trenutno se ne može puniti"</string> <string name="battery_info_status_full" msgid="4443168946046847468">"Puna"</string> <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Pod kontrolom administratora"</string> <string name="disabled" msgid="8017887509554714950">"Onemogućeno"</string> @@ -554,5 +554,7 @@ <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Onemogućeno"</string> <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Omogućeno"</string> <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Morate ponovo pokrenuti uređaj da se ova promjena primijeni. Ponovo pokrenite odmah ili otkažite."</string> - <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"<xliff:g id="APP_NAME">%s</xliff:g> za posao"</string> + <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"Poslovna aplikacija <xliff:g id="APP_NAME">%s</xliff:g>"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml index 7dad950c5d47..5ed0f1b2d3ca 100644 --- a/packages/SettingsLib/res/values-ca/strings.xml +++ b/packages/SettingsLib/res/values-ca/strings.xml @@ -222,7 +222,7 @@ <string name="adb_device_fingerprint_title_format" msgid="291504822917843701">"Empremta digital del dispositiu: <xliff:g id="FINGERPRINT_PARAM">%1$s</xliff:g>"</string> <string name="adb_wireless_connection_failed_title" msgid="664211177427438438">"No s\'ha pogut connectar"</string> <string name="adb_wireless_connection_failed_message" msgid="9213896700171602073">"Assegura\'t que <xliff:g id="DEVICE_NAME">%1$s</xliff:g> estigui connectat a la xarxa correcta"</string> - <string name="adb_pairing_device_dialog_title" msgid="7141739231018530210">"Vincular amb el dispositiu"</string> + <string name="adb_pairing_device_dialog_title" msgid="7141739231018530210">"Vincula amb el dispositiu"</string> <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> @@ -553,6 +553,7 @@ <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Desactivat"</string> <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Activat"</string> <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Has de reiniciar el teu dispositiu perquè s\'apliquin els canvis. Reinicia\'l ara o cancel·la."</string> - <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) --> + <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"<xliff:g id="APP_NAME">%s</xliff:g> de la feina"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> <skip /> </resources> diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml index 51548f55e430..d4d37353fb82 100644 --- a/packages/SettingsLib/res/values-cs/strings.xml +++ b/packages/SettingsLib/res/values-cs/strings.xml @@ -555,6 +555,7 @@ <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Vypnuto"</string> <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Zapnuto"</string> <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Aby se tato změna projevila, je třeba zařízení restartovat. Restartujte zařízení nebo zrušte akci."</string> - <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) --> + <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"Pracovní <xliff:g id="APP_NAME">%s</xliff:g>"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> <skip /> </resources> diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml index 88f8e92d8093..89dbf2581746 100644 --- a/packages/SettingsLib/res/values-da/strings.xml +++ b/packages/SettingsLib/res/values-da/strings.xml @@ -433,7 +433,7 @@ <string name="power_discharge_by" msgid="4113180890060388350">"Bør holde indtil ca. <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">"Bør holde indtil ca. <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Indtil <xliff:g id="TIME">%1$s</xliff:g>"</string> - <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Enheden løber muligvis tør for batteri inden <xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Batteriet aflades muligvis inden <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Der er mindre end <xliff:g id="THRESHOLD">%1$s</xliff:g> tilbage"</string> <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Der er mindre end <xliff:g id="THRESHOLD">%1$s</xliff:g> tilbage (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Der er mere end <xliff:g id="TIME_REMAINING">%1$s</xliff:g> tilbage (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -553,6 +553,7 @@ <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Deaktiveret"</string> <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Aktiveret"</string> <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Din enhed skal genstartes for at denne enhed bliver anvendt. Genstart nu, eller annuller."</string> - <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) --> + <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"<xliff:g id="APP_NAME">%s</xliff:g> – arbejde"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> <skip /> </resources> diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml index edd15806c2ed..c2030b162e56 100644 --- a/packages/SettingsLib/res/values-de/strings.xml +++ b/packages/SettingsLib/res/values-de/strings.xml @@ -231,7 +231,7 @@ <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="6014121407143607851">"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 das 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> @@ -507,7 +507,7 @@ <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Dauer"</string> <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Jedes Mal fragen"</string> <string name="zen_mode_forever" msgid="3339224497605461291">"Bis zur Deaktivierung"</string> - <string name="time_unit_just_now" msgid="3006134267292728099">"gerade eben"</string> + <string name="time_unit_just_now" msgid="3006134267292728099">"Gerade eben"</string> <string name="media_transfer_this_device_name" msgid="2716555073132169240">"Smartphone-Lautsprecher"</string> <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Verbindung kann nicht hergestellt werden. Schalte das Gerät aus & und wieder ein."</string> <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Netzbetriebenes Audiogerät"</string> @@ -553,6 +553,7 @@ <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Deaktiviert"</string> <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Aktiviert"</string> <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Damit diese Änderung übernommen wird, musst du dein Gerät neu starten. Du kannst es jetzt neu starten oder den Vorgang abbrechen."</string> - <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) --> + <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"<xliff:g id="APP_NAME">%s</xliff:g> (geschäftlich)"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> <skip /> </resources> diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml index c5c0e074f6f8..bfc183e40a53 100644 --- a/packages/SettingsLib/res/values-el/strings.xml +++ b/packages/SettingsLib/res/values-el/strings.xml @@ -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> @@ -554,4 +554,6 @@ <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Ενεργή"</string> <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Για να εφαρμοστεί αυτή η αλλαγή, θα πρέπει να επανεκκινήσετε τη συσκευή σας. Επανεκκίνηση τώρα ή ακύρωση."</string> <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"Εργασία <xliff:g id="APP_NAME">%s</xliff:g>"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml index a1c8b041dab2..9d869ba30717 100644 --- a/packages/SettingsLib/res/values-en-rAU/strings.xml +++ b/packages/SettingsLib/res/values-en-rAU/strings.xml @@ -229,7 +229,7 @@ <string name="adb_wireless_qrcode_summary" msgid="8051414549011801917">"Pair device over Wi‑Fi by scanning a QR code"</string> <string name="adb_wireless_verifying_qrcode_text" msgid="6123192424916029207">"Pairing device…"</string> <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_ip_addr_preference_title" msgid="8335132107715311730">"IP address and port"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"Scan 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> @@ -554,4 +554,6 @@ <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Enabled"</string> <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Your device must be rebooted for this change to apply. Reboot now or cancel."</string> <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"Work <xliff:g id="APP_NAME">%s</xliff:g>"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-en-rCA/strings.xml b/packages/SettingsLib/res/values-en-rCA/strings.xml index a1c8b041dab2..9d869ba30717 100644 --- a/packages/SettingsLib/res/values-en-rCA/strings.xml +++ b/packages/SettingsLib/res/values-en-rCA/strings.xml @@ -229,7 +229,7 @@ <string name="adb_wireless_qrcode_summary" msgid="8051414549011801917">"Pair device over Wi‑Fi by scanning a QR code"</string> <string name="adb_wireless_verifying_qrcode_text" msgid="6123192424916029207">"Pairing device…"</string> <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_ip_addr_preference_title" msgid="8335132107715311730">"IP address and port"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"Scan 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> @@ -554,4 +554,6 @@ <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Enabled"</string> <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Your device must be rebooted for this change to apply. Reboot now or cancel."</string> <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"Work <xliff:g id="APP_NAME">%s</xliff:g>"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml index a1c8b041dab2..9d869ba30717 100644 --- a/packages/SettingsLib/res/values-en-rGB/strings.xml +++ b/packages/SettingsLib/res/values-en-rGB/strings.xml @@ -229,7 +229,7 @@ <string name="adb_wireless_qrcode_summary" msgid="8051414549011801917">"Pair device over Wi‑Fi by scanning a QR code"</string> <string name="adb_wireless_verifying_qrcode_text" msgid="6123192424916029207">"Pairing device…"</string> <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_ip_addr_preference_title" msgid="8335132107715311730">"IP address and port"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"Scan 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> @@ -554,4 +554,6 @@ <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Enabled"</string> <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Your device must be rebooted for this change to apply. Reboot now or cancel."</string> <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"Work <xliff:g id="APP_NAME">%s</xliff:g>"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml index a1c8b041dab2..9d869ba30717 100644 --- a/packages/SettingsLib/res/values-en-rIN/strings.xml +++ b/packages/SettingsLib/res/values-en-rIN/strings.xml @@ -229,7 +229,7 @@ <string name="adb_wireless_qrcode_summary" msgid="8051414549011801917">"Pair device over Wi‑Fi by scanning a QR code"</string> <string name="adb_wireless_verifying_qrcode_text" msgid="6123192424916029207">"Pairing device…"</string> <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_ip_addr_preference_title" msgid="8335132107715311730">"IP address and port"</string> <string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"Scan 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> @@ -554,4 +554,6 @@ <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Enabled"</string> <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Your device must be rebooted for this change to apply. Reboot now or cancel."</string> <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"Work <xliff:g id="APP_NAME">%s</xliff:g>"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-en-rXC/strings.xml b/packages/SettingsLib/res/values-en-rXC/strings.xml index 38ac8f1fc554..77658243864e 100644 --- a/packages/SettingsLib/res/values-en-rXC/strings.xml +++ b/packages/SettingsLib/res/values-en-rXC/strings.xml @@ -554,4 +554,6 @@ <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Enabled"</string> <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Your device must be rebooted for this change to apply. Reboot now or cancel."</string> <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"Work <xliff:g id="APP_NAME">%s</xliff:g>"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml index c6d0d56d409b..6a76bebc78ee 100644 --- a/packages/SettingsLib/res/values-es-rUS/strings.xml +++ b/packages/SettingsLib/res/values-es-rUS/strings.xml @@ -61,7 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"Media"</string> <string name="speed_label_fast" msgid="2677719134596044051">"Rápida"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"Muy rápida"</string> - <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Vencido"</string> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Vencida"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g>/<xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"Desconectado"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Desconectando…"</string> @@ -153,7 +153,7 @@ <string name="unknown" msgid="3544487229740637809">"Desconocido"</string> <string name="running_process_item_user_label" msgid="3988506293099805796">"Usuario: <xliff:g id="USER_NAME">%1$s</xliff:g>"</string> <string name="launch_defaults_some" msgid="3631650616557252926">"Configuraciones predeterminadas establecidas"</string> - <string name="launch_defaults_none" msgid="8049374306261262709">"No hay configuraciones predeterminadas establecidas."</string> + <string name="launch_defaults_none" msgid="8049374306261262709">"No se establecieron configuraciones predeterminadas"</string> <string name="tts_settings" msgid="8130616705989351312">"Configuración de texto a voz"</string> <string name="tts_settings_title" msgid="7602210956640483039">"Salida de texto a voz"</string> <string name="tts_default_rate_title" msgid="3964187817364304022">"Velocidad de voz"</string> @@ -213,7 +213,7 @@ <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="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_title" msgid="1122590300445142904">"Vincular dispositivo con código de sincronización"</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> <string name="adb_wireless_device_connected_summary" msgid="3039660790249148713">"Conectado actualmente"</string> @@ -235,7 +235,7 @@ <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> - <string name="bugreport_in_power_summary" msgid="1885529649381831775">"Mostrar un botón en el menú de encendido para realizar un informe de errores"</string> + <string name="bugreport_in_power_summary" msgid="1885529649381831775">"Muestra un botón en el menú de encendido para realizar un informe de errores"</string> <string name="keep_screen_on" msgid="1187161672348797558">"Permanecer activo"</string> <string name="keep_screen_on_summary" msgid="1510731514101925829">"La pantalla nunca quedará inactiva mientras el dispositivo se esté cargando."</string> <string name="bt_hci_snoop_log" msgid="7291287955649081448">"Registro de Bluetooth HCI"</string> @@ -331,7 +331,7 @@ <string name="media_category" msgid="8122076702526144053">"Multimedia"</string> <string name="debug_monitoring_category" msgid="1597387133765424994">"Supervisión"</string> <string name="strict_mode" msgid="889864762140862437">"Modo estricto"</string> - <string name="strict_mode_summary" msgid="1838248687233554654">"Destello por op. de apps en la conversación principal"</string> + <string name="strict_mode_summary" msgid="1838248687233554654">"Destello por op. de apps en el subproceso principal"</string> <string name="pointer_location" msgid="7516929526199520173">"Ubicación del puntero"</string> <string name="pointer_location_summary" msgid="957120116989798464">"Superponer capa en pant. para mostrar puntos tocados"</string> <string name="show_touches" msgid="8437666942161289025">"Mostrar presiones"</string> @@ -553,6 +553,7 @@ <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Inhabilitado"</string> <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Habilitado"</string> <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Debes reiniciar el dispositivo para que se aplique el cambio. Reinícialo ahora o cancela la acción."</string> - <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) --> + <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"<xliff:g id="APP_NAME">%s</xliff:g> de trabajo"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> <skip /> </resources> diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml index 55b5cabc8e31..010b85b86df3 100644 --- a/packages/SettingsLib/res/values-es/strings.xml +++ b/packages/SettingsLib/res/values-es/strings.xml @@ -61,7 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"Media"</string> <string name="speed_label_fast" msgid="2677719134596044051">"Rápida"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"Muy rápida"</string> - <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Caducado"</string> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Caducada"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g>/<xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"Desconectado"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Desconectando…"</string> @@ -506,7 +506,7 @@ <string name="alarm_template_far" msgid="6382760514842998629">"Fecha: <xliff:g id="WHEN">%1$s</xliff:g>"</string> <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="zen_mode_forever" msgid="3339224497605461291">"Hasta que lo desactives"</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> @@ -553,6 +553,7 @@ <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Inhabilitado"</string> <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Habilitado"</string> <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Es necesario reiniciar tu dispositivo para que se apliquen los cambios. Reiniciar ahora o cancelar."</string> - <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) --> + <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"<xliff:g id="APP_NAME">%s</xliff:g> de trabajo"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> <skip /> </resources> diff --git a/packages/SettingsLib/res/values-et/strings.xml b/packages/SettingsLib/res/values-et/strings.xml index 5a115909d076..ad2a56152452 100644 --- a/packages/SettingsLib/res/values-et/strings.xml +++ b/packages/SettingsLib/res/values-et/strings.xml @@ -419,7 +419,7 @@ <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ärvikorrigeerimine võimaldab kohandada seadmes kuvatavaid värve"</string> + <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1284746051652993443">"Värvide korrigeerimine 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> @@ -553,6 +553,7 @@ <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Keelatud"</string> <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Lubatud"</string> <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Selle muudatuse rakendamiseks tuleb seade taaskäivitada. Taaskäivitage kohe või tühistage."</string> - <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) --> + <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"Töö: <xliff:g id="APP_NAME">%s</xliff:g>"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> <skip /> </resources> diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml index 1aed7e84ded3..1ceb738914f2 100644 --- a/packages/SettingsLib/res/values-eu/strings.xml +++ b/packages/SettingsLib/res/values-eu/strings.xml @@ -554,4 +554,6 @@ <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Gaituta"</string> <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Aldaketa aplikatzeko, berrabiarazi egin behar da gailua. Berrabiaraz ezazu orain, edo utzi bertan behera."</string> <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"Laneko <xliff:g id="APP_NAME">%s</xliff:g>"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-fa/arrays.xml b/packages/SettingsLib/res/values-fa/arrays.xml index 3b05075c1d75..94caa747c829 100644 --- a/packages/SettingsLib/res/values-fa/arrays.xml +++ b/packages/SettingsLib/res/values-fa/arrays.xml @@ -40,7 +40,7 @@ <item msgid="8339720953594087771">"در حال اتصال به <xliff:g id="NETWORK_NAME">%1$s</xliff:g>…"</item> <item msgid="3028983857109369308">"در حال راستیآزمایی با <xliff:g id="NETWORK_NAME">%1$s</xliff:g>..."</item> <item msgid="4287401332778341890">"درحال دریافت نشانی IP از <xliff:g id="NETWORK_NAME">%1$s</xliff:g>…"</item> - <item msgid="1043944043827424501">"متصل شد به <xliff:g id="NETWORK_NAME">%1$s</xliff:g>"</item> + <item msgid="1043944043827424501">"به <xliff:g id="NETWORK_NAME">%1$s</xliff:g> متصل شد"</item> <item msgid="7445993821842009653">"معلق"</item> <item msgid="1175040558087735707">"اتصال قطع شد از <xliff:g id="NETWORK_NAME">%1$s</xliff:g>..."</item> <item msgid="699832486578171722">"اتصال قطع شد"</item> diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml index a46d8cddb53d..d3f1c56cd1d7 100644 --- a/packages/SettingsLib/res/values-fa/strings.xml +++ b/packages/SettingsLib/res/values-fa/strings.xml @@ -94,12 +94,12 @@ <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"صدای HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string> <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"صدای HD"</string> <string name="bluetooth_profile_hearing_aid" msgid="58154575573984914">"سمعکها"</string> - <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"متصل به سمعکها"</string> + <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="8191273236809964030">"به سمعک متصل شد"</string> <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"به رسانه صوتی متصل شد"</string> <string name="bluetooth_headset_profile_summary_connected" msgid="2420981566026949688">"به تلفن صوتی متصل شد"</string> <string name="bluetooth_opp_profile_summary_connected" msgid="2393521801478157362">"به سرور انتقال فایل متصل شد"</string> <string name="bluetooth_map_profile_summary_connected" msgid="4141725591784669181">"به نقشه متصل شد"</string> - <string name="bluetooth_sap_profile_summary_connected" msgid="1280297388033001037">"متصل به SAP"</string> + <string name="bluetooth_sap_profile_summary_connected" msgid="1280297388033001037">"به SAP متصل شد"</string> <string name="bluetooth_opp_profile_summary_not_connected" msgid="3959741824627764954">"به سرور انتقال فایل متصل نیست"</string> <string name="bluetooth_hid_profile_summary_connected" msgid="3923653977051684833">"به دستگاه ورودی متصل شد"</string> <string name="bluetooth_pan_user_profile_summary_connected" msgid="380469653827505727">"برای دسترسی به اینترنت، به دستگاه متصل شد"</string> @@ -553,6 +553,7 @@ <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"غیرفعال"</string> <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"فعال"</string> <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"برای اعمال این تغییر، دستگاهتان باید راهاندازی مجدد شود. اکنون راهاندازی مجدد کنید یا لغو کنید."</string> - <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) --> + <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"<xliff:g id="APP_NAME">%s</xliff:g> محل کار"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> <skip /> </resources> diff --git a/packages/SettingsLib/res/values-fi/arrays.xml b/packages/SettingsLib/res/values-fi/arrays.xml index af278cb35fd4..edfd951c0fa6 100644 --- a/packages/SettingsLib/res/values-fi/arrays.xml +++ b/packages/SettingsLib/res/values-fi/arrays.xml @@ -156,7 +156,7 @@ <item msgid="5001852592115448348">", aktiivinen (puhelin)"</item> </string-array> <string-array name="select_logd_size_titles"> - <item msgid="1191094707770726722">"Ei käytössä"</item> + <item msgid="1191094707770726722">"Ei päällä"</item> <item msgid="7839165897132179888">"64 kt"</item> <item msgid="2715700596495505626">"256 kt"</item> <item msgid="7099386891713159947">"1 Mt"</item> @@ -164,13 +164,13 @@ <item msgid="8243549501764402572">"16 Mt"</item> </string-array> <string-array name="select_logd_size_lowram_titles"> - <item msgid="1145807928339101085">"Ei käytössä"</item> + <item msgid="1145807928339101085">"Ei päällä"</item> <item msgid="4064786181089783077">"64 kt"</item> <item msgid="3052710745383602630">"256 kt"</item> <item msgid="3691785423374588514">"1 Mt"</item> </string-array> <string-array name="select_logd_size_summaries"> - <item msgid="409235464399258501">"Ei käytössä"</item> + <item msgid="409235464399258501">"Ei päällä"</item> <item msgid="4195153527464162486">"64 kt / lokipuskuri"</item> <item msgid="7464037639415220106">"256 kt / lokipuskuri"</item> <item msgid="8539423820514360724">"1 Mt / lokipuskuri"</item> @@ -178,13 +178,13 @@ <item msgid="7892098981256010498">"16 Mt / lokipuskuri"</item> </string-array> <string-array name="select_logpersist_titles"> - <item msgid="704720725704372366">"Ei käytössä"</item> + <item msgid="704720725704372366">"Ei päällä"</item> <item msgid="6014837961827347618">"Kaikki"</item> <item msgid="7387060437894578132">"Kaikki paitsi radio"</item> <item msgid="7300881231043255746">"vain kernel"</item> </string-array> <string-array name="select_logpersist_summaries"> - <item msgid="97587758561106269">"Ei käytössä"</item> + <item msgid="97587758561106269">"Ei päällä"</item> <item msgid="7126170197336963369">"Kaikki lokipuskurit"</item> <item msgid="7167543126036181392">"Kaikki paitsi radiolokipuskurit"</item> <item msgid="5135340178556563979">"vain kernel-lokipuskuri"</item> @@ -247,7 +247,7 @@ <item msgid="5023908510820531131">"Kohteessa <xliff:g id="AS_TYPED_COMMAND">adb shell dumpsys gfxinfo</xliff:g>"</item> </string-array> <string-array name="debug_hw_overdraw_entries"> - <item msgid="1968128556747588800">"Ei käytössä"</item> + <item msgid="1968128556747588800">"Ei päällä"</item> <item msgid="3033215374382962216">"Näytä päällekkäiset alueet"</item> <item msgid="3474333938380896988">"Näytä alueet puna-vihersokeille näkyvinä"</item> </string-array> diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml index 8e82cb2b6f47..5ab01c4b51b4 100644 --- a/packages/SettingsLib/res/values-fi/strings.xml +++ b/packages/SettingsLib/res/values-fi/strings.xml @@ -153,7 +153,7 @@ <string name="unknown" msgid="3544487229740637809">"Tuntematon"</string> <string name="running_process_item_user_label" msgid="3988506293099805796">"Käyttäjä: <xliff:g id="USER_NAME">%1$s</xliff:g>"</string> <string name="launch_defaults_some" msgid="3631650616557252926">"Joitakin oletuksia on asetettu"</string> - <string name="launch_defaults_none" msgid="8049374306261262709">"Oletuksia ei asetettu"</string> + <string name="launch_defaults_none" msgid="8049374306261262709">"Ei oletuksia valittuina"</string> <string name="tts_settings" msgid="8130616705989351312">"Tekstistä puheeksi -asetukset"</string> <string name="tts_settings_title" msgid="7602210956640483039">"Tekstistä puheeksi -toisto"</string> <string name="tts_default_rate_title" msgid="3964187817364304022">"Puheen nopeus"</string> @@ -397,7 +397,7 @@ <item msgid="1282170165150762976">"Digitaaliselle sisällölle parhaiten sopivat värit"</item> </string-array> <string name="inactive_apps_title" msgid="5372523625297212320">"Valmiustilasovellukset"</string> - <string name="inactive_app_inactive_summary" msgid="3161222402614236260">"Ei käytössä. Ota käyttöön koskettamalla."</string> + <string name="inactive_app_inactive_summary" msgid="3161222402614236260">"Ei päällä. Ota käyttöön koskettamalla."</string> <string name="inactive_app_active_summary" msgid="8047630990208722344">"Aktiivinen. Vaihda koskettamalla."</string> <string name="standby_bucket_summary" msgid="5128193447550429600">"Sovelluksen valmiusluokka: <xliff:g id="BUCKET"> %s</xliff:g>"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"Käynnissä olevat palvelut"</string> @@ -533,8 +533,8 @@ <string name="user_add_user_title" msgid="5457079143694924885">"Lisätäänkö uusi käyttäjä?"</string> <string name="user_add_user_message_long" msgid="1527434966294733380">"Voit jakaa tämän laitteen muiden kanssa luomalla lisää käyttäjiä. Kullakin käyttäjällä on oma tilansa, jota he voivat muokata esimerkiksi omilla sovelluksilla ja taustakuvilla. Käyttäjät voivat myös muokata laiteasetuksia, kuten Wi‑Fi-asetuksia, jotka vaikuttavat laitteen kaikkiin käyttäjiin.\n\nKun lisäät uuden käyttäjän, hänen tulee määrittää oman tilansa asetukset.\n\nKaikki käyttäjät voivat päivittää muiden käyttäjien sovelluksia. Esteettömyysominaisuuksia tai ‑palveluita ei välttämättä siirretä uudelle käyttäjälle."</string> <string name="user_add_user_message_short" msgid="3295959985795716166">"Kun lisäät uuden käyttäjän, hänen tulee määrittää oman tilansa asetukset.\n\nKaikki käyttäjät voivat päivittää sovelluksia muille käyttäjille."</string> - <string name="user_setup_dialog_title" msgid="8037342066381939995">"Määritetäänkö käyttäjän asetukset nyt?"</string> - <string name="user_setup_dialog_message" msgid="269931619868102841">"Varmista, että käyttäjä voi vastaanottaa laitteen ja määrittää oman tilansa."</string> + <string name="user_setup_dialog_title" msgid="8037342066381939995">"Lisätäänkö käyttäjä nyt?"</string> + <string name="user_setup_dialog_message" msgid="269931619868102841">"Varmista, että käyttäjä voi ottaa laitteen nyt ja määrittää oman tilansa."</string> <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"Määritetäänkö profiilin asetukset nyt?"</string> <string name="user_setup_button_setup_now" msgid="1708269547187760639">"Määritä nyt"</string> <string name="user_setup_button_setup_later" msgid="8712980133555493516">"Ei nyt"</string> @@ -553,6 +553,7 @@ <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Ei käytössä"</string> <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Käytössä"</string> <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Laitteesi on käynnistettävä uudelleen, jotta muutos tulee voimaan. Käynnistä uudelleen nyt tai peruuta."</string> - <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) --> + <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"<xliff:g id="APP_NAME">%s</xliff:g> (työ)"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> <skip /> </resources> diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml index a1444444eedd..26e50421cad8 100644 --- a/packages/SettingsLib/res/values-fr-rCA/strings.xml +++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml @@ -195,7 +195,7 @@ </string-array> <string name="choose_profile" msgid="343803890897657450">"Sélectionnez un profil"</string> <string name="category_personal" msgid="6236798763159385225">"Personnel"</string> - <string name="category_work" msgid="4014193632325996115">"Travail"</string> + <string name="category_work" msgid="4014193632325996115">"Professionnel"</string> <string name="development_settings_title" msgid="140296922921597393">"Options pour les concepteurs"</string> <string name="development_settings_enable" msgid="4285094651288242183">"Activer les options pour les concepteurs"</string> <string name="development_settings_summary" msgid="8718917813868735095">"Définir les options pour le développement de l\'application"</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="6014121407143607851">"Associer un appareil par Wi-Fi en numérisant un code QR"</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Associer l\'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> @@ -496,7 +496,7 @@ <string name="cancel" msgid="5665114069455378395">"Annuler"</string> <string name="okay" msgid="949938843324579502">"OK"</string> <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Activer"</string> - <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Activer la fonction « Ne pas déranger »"</string> + <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Activer le mode Ne pas déranger"</string> <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Jamais"</string> <string name="zen_interruption_level_priority" msgid="5392140786447823299">"Priorités seulement"</string> <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string> @@ -554,4 +554,6 @@ <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Activé"</string> <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Votre appareil doit être redémarré pour que ce changement prenne effet. Redémarrez-le maintenant ou annulez la modification."</string> <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"<xliff:g id="APP_NAME">%s</xliff:g> (travail)"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml index f7bfad8c2567..b8fc50dc028b 100644 --- a/packages/SettingsLib/res/values-fr/strings.xml +++ b/packages/SettingsLib/res/values-fr/strings.xml @@ -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="6014121407143607851">"Associer l\'appareil via le Wi‑Fi à l\'aide d\'un code QR"</string> + <string name="adb_wireless_qrcode_pairing_description" msgid="6014121407143607851">"Associez 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> @@ -433,7 +433,7 @@ <string name="power_discharge_by" msgid="4113180890060388350">"Devrait durer jusqu\'à environ <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">"Devrait durer jusqu\'à environ <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Jusqu\'à <xliff:g id="TIME">%1$s</xliff:g>"</string> - <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"La batterie risque d\'être épuisée à <xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"La batterie risque d\'être épuisée d\'ici <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Il reste moins de <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Il reste moins de <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="446388082266121894">"Il reste plus de <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -553,6 +553,7 @@ <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Désactivé"</string> <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Activé"</string> <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Vous devez redémarrer l\'appareil pour que cette modification soit appliquée. Redémarrez maintenant ou annulez l\'opération."</string> - <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) --> + <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"<xliff:g id="APP_NAME">%s</xliff:g> (travail)"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> <skip /> </resources> diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml index 08d2eae5c4ae..8dc58ef6f32f 100644 --- a/packages/SettingsLib/res/values-gl/strings.xml +++ b/packages/SettingsLib/res/values-gl/strings.xml @@ -207,7 +207,7 @@ <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 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="enable_adb_wireless_summary" msgid="7344391423657093011">"Modo de depuración de erros ao conectarse á wifi"</string> <string name="adb_wireless_error" msgid="721958772149779856">"Produciuse un erro"</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> @@ -553,6 +553,7 @@ <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Desactivado"</string> <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Activado"</string> <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"É necesario reiniciar o teu dispositivo para aplicar este cambio. Reiníciao agora ou cancela o cambio."</string> - <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) --> + <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"Aplicación <xliff:g id="APP_NAME">%s</xliff:g> do traballo"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> <skip /> </resources> diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml index b88126bf99be..9f69a2c0fa20 100644 --- a/packages/SettingsLib/res/values-gu/strings.xml +++ b/packages/SettingsLib/res/values-gu/strings.xml @@ -468,7 +468,7 @@ <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="screen_zoom_summary_small" msgid="6050633151263074260">"નાનું"</string> - <string name="screen_zoom_summary_default" msgid="1888865694033865408">"ડિફોલ્ટ"</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> @@ -534,7 +534,7 @@ <string name="user_add_user_message_long" msgid="1527434966294733380">"તમે વધારાના વપરાશકર્તાઓ બનાવીને અન્ય લોકો સાથે આ ડિવાઇસને શેર કરી શકો છો. દરેક વપરાશકર્તા પાસે તેમની પોતાની સ્પેસ છે, જેને તેઓ ઍપ, વૉલપેપર, વગેરે સાથે કસ્ટમાઇઝ કરી શકે છે. વપરાશકર્તાઓ પ્રત્યેક વ્યક્તિને અસર કરતી હોય તેવી ડિવાઇસ સેટિંગ જેમ કે વાઇ-ફાઇને પણ સમાયોજિત કરી શકે છે.\n\nજ્યારે તમે કોઈ નવા વપરાશકર્તાને ઉમેરો છો, ત્યારે તે વ્યક્તિને તેમની સ્પેસ સેટ કરવાની જરૂર પડે છે.\n\nકોઈપણ વપરાશકર્તા અન્ય બધા વપરાશકર્તાઓ માટે ઍપને અપડેટ કરી શકે છે. નવા વપરાશકર્તાને ઍક્સેસિબિલિટી સેટિંગ અને સેવાઓ ટ્રાન્સફર ન પણ થાય."</string> <string name="user_add_user_message_short" msgid="3295959985795716166">"જ્યારે તમે કોઈ નવા વપરાશકર્તાને ઉમેરો છો, ત્યારે તે વ્યક્તિને તેમનું સ્થાન સેટ અપ કરવાની જરૂર પડે છે.\n\nકોઈપણ વપરાશકર્તા બધા અન્ય વપરાશકર્તાઓ માટે એપ્લિકેશન્સને અપડેટ કરી શકે છે."</string> <string name="user_setup_dialog_title" msgid="8037342066381939995">"અત્યારે જ વપરાશકર્તાને સેટ અપ કરીએ?"</string> - <string name="user_setup_dialog_message" msgid="269931619868102841">"ખાતરી કરો કે વ્યક્તિ ઉપકરણ લેવા અને તેમના સ્થાનનું સેટ અપ કરવા માટે ઉપલબ્ધ છે"</string> + <string name="user_setup_dialog_message" msgid="269931619868102841">"ખાતરી કરો કે વ્યક્તિ ડિવાઇસ લેવા અને તેમના સ્થાનનું સેટ અપ કરવા માટે ઉપલબ્ધ છે"</string> <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"હવે પ્રોફાઇલ સેટ કરીએ?"</string> <string name="user_setup_button_setup_now" msgid="1708269547187760639">"હવે સેટ કરો"</string> <string name="user_setup_button_setup_later" msgid="8712980133555493516">"હમણાં નહીં"</string> @@ -549,14 +549,11 @@ <string name="guest_new_guest" msgid="3482026122932643557">"અતિથિ ઉમેરો"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"અતિથિને કાઢી નાખો"</string> <string name="guest_nickname" msgid="6332276931583337261">"અતિથિ"</string> - <!-- no translation found for cached_apps_freezer_device_default (2616594131750144342) --> - <skip /> - <!-- no translation found for cached_apps_freezer_disabled (4816382260660472042) --> - <skip /> - <!-- no translation found for cached_apps_freezer_enabled (8866703500183051546) --> - <skip /> - <!-- no translation found for cached_apps_freezer_reboot_dialog_text (695330563489230096) --> - <skip /> - <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) --> + <string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"ડિવાઇસ ડિફૉલ્ટ"</string> + <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"બંધ છે"</string> + <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"ચાલુ છે"</string> + <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"આ ફેરફારને લાગુ કરવા માટે તમારા ડિવાઇસને રીબૂટ કરવાની જરૂર છે. હમણાં જ રીબૂટ કરો કે રદ કરો."</string> + <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"ઑફિસ <xliff:g id="APP_NAME">%s</xliff:g>"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> <skip /> </resources> diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml index 7dda73de114f..dc8e28bb9df2 100644 --- a/packages/SettingsLib/res/values-hi/strings.xml +++ b/packages/SettingsLib/res/values-hi/strings.xml @@ -284,7 +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="1210663439867489931">"जब यह मोड चालू होता है, तब नेटवर्क से कनेक्ट होने पर हर बार इस डिवाइस का MAC पता बदल सकता है. ऐसा तब होता है, जब डिवाइस किसी ऐसे नेटवर्क से जुड़ता है जिस पर MAC पते को बिना किसी तय नियम के बदलने की सुविधा चालू होती है."</string> + <string name="wifi_enhanced_mac_randomization_summary" msgid="1210663439867489931">"जब यह मोड चालू होता है, तब नेटवर्क से कनेक्ट होने पर हर बार इस डिवाइस का मैक पता बदल सकता है. ऐसा तब होता है, जब डिवाइस किसी ऐसे नेटवर्क से जुड़ता है जिस पर मैक पते को बिना किसी तय नियम के बदलने की सुविधा चालू होती है."</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> @@ -418,7 +418,7 @@ <string name="daltonizer_mode_deuteranomaly" msgid="3507284319584683963">"लाल-हरे रंग की पहचान न कर पाना (लाल-हरा)"</string> <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_title" msgid="1810693571332381974">"रंग में सुधार करने की सुविधा"</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> @@ -553,6 +553,7 @@ <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"बंद है"</string> <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"चालू है"</string> <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"बदली गई सेटिंग को लागू करने के लिए, अपने डिवाइस को फिर से चालू करें. डिवाइस को फिर से चालू करें या रद्द करें."</string> - <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) --> + <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"ऑफ़िस वाला <xliff:g id="APP_NAME">%s</xliff:g>"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> <skip /> </resources> diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml index 1db40a8e8da5..f8878396d867 100644 --- a/packages/SettingsLib/res/values-hr/strings.xml +++ b/packages/SettingsLib/res/values-hr/strings.xml @@ -251,7 +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="wifi_enhanced_mac_randomization" msgid="5437378364995776979">"Nasum. odabir MAC-a poboljšan Wi‑Fijem"</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> @@ -534,8 +534,8 @@ <string name="user_add_user_title" msgid="5457079143694924885">"Dodati novog korisnika?"</string> <string name="user_add_user_message_long" msgid="1527434966294733380">"Da biste ovaj uređaj dijelili s drugima, možete napraviti dodatne korisnike. Svaki korisnik ima svoj prostor koji može prilagoditi pomoću vlastitih aplikacija, pozadine i tako dalje. Korisnici mogu prilagoditi i postavke uređaja koje utječu na sve ostale korisnike, na primjer Wi‑Fi.\n\nKada dodate novog korisnika, ta osoba mora postaviti svoj prostor.\n\nBilo koji korisnik može ažurirati aplikacije za sve ostale korisnike. Postavke i usluge pristupačnosti možda se neće prenijeti na novog korisnika."</string> <string name="user_add_user_message_short" msgid="3295959985795716166">"Kada dodate novog korisnika, ta osoba mora postaviti vlastiti prostor.\n\nBilo koji korisnik može ažurirati aplikacije za sve ostale korisnike."</string> - <string name="user_setup_dialog_title" msgid="8037342066381939995">"Postaviti korisnika sada?"</string> - <string name="user_setup_dialog_message" msgid="269931619868102841">"Provjerite može li osoba uzeti uređaj i postaviti svoj prostor"</string> + <string name="user_setup_dialog_title" msgid="8037342066381939995">"Želite li postaviti korisnika?"</string> + <string name="user_setup_dialog_message" msgid="269931619868102841">"Uređaj morate dati toj osobi da sama postavi svoj prostor"</string> <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"Želite li sada postaviti profil?"</string> <string name="user_setup_button_setup_now" msgid="1708269547187760639">"Postavi sada"</string> <string name="user_setup_button_setup_later" msgid="8712980133555493516">"Ne sad"</string> @@ -555,4 +555,6 @@ <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Omogućeno"</string> <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Uređaj se mora ponovno pokrenuti da bi se ta promjena primijenila. Ponovo pokrenite uređaj odmah ili odustanite."</string> <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"<xliff:g id="APP_NAME">%s</xliff:g> za posao"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml index 4b2132be42d9..d7d269406f84 100644 --- a/packages/SettingsLib/res/values-hu/strings.xml +++ b/packages/SettingsLib/res/values-hu/strings.xml @@ -433,7 +433,7 @@ <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_suggestion_battery_run_out" msgid="6332089307827787087">"Az akkumulátor lemerülhet: <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Kevesebb mint <xliff:g id="THRESHOLD">%1$s</xliff:g> van hátra"</string> <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Kevesebb mint <xliff:g id="THRESHOLD">%1$s</xliff:g> van hátra (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Több mint <xliff:g id="TIME_REMAINING">%1$s</xliff:g> van hátra (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -553,6 +553,7 @@ <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Letiltva"</string> <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Engedélyezve"</string> <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Az eszközt újra kell indítani, hogy a módosítás megtörténjen. Indítsa újra most, vagy vesse el a módosítást."</string> - <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) --> + <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"Munkahelyi <xliff:g id="APP_NAME">%s</xliff:g>"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> <skip /> </resources> diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml index 11da054325f1..a5ef6b557e4b 100644 --- a/packages/SettingsLib/res/values-hy/strings.xml +++ b/packages/SettingsLib/res/values-hy/strings.xml @@ -433,7 +433,7 @@ <string name="power_discharge_by" msgid="4113180890060388350">"Լիցքը (<xliff:g id="LEVEL">%2$s</xliff:g>) պետք է որ բավականացնի մինչև <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only" msgid="92545648425937000">"Լիցքը պետք է որ բավականացնի մինչև <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Մինչև <xliff:g id="TIME">%1$s</xliff:g>"</string> - <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Մարտկոցի լիցքը կարող է սպառվել մինչև <xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Լիցքը կարող է սպառվել մինչև <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Մնացել է <xliff:g id="THRESHOLD">%1$s</xliff:g>-ից քիչ"</string> <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Մնացել է <xliff:g id="THRESHOLD">%1$s</xliff:g>-ից քիչ (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Մնացել է ավելի քան <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -452,7 +452,7 @@ <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> + <string name="battery_info_status_not_charging" msgid="8330015078868707899">"Միացված է հոսանքին, այս պահին չի կարող լիցքավորվել"</string> <string name="battery_info_status_full" msgid="4443168946046847468">"Լիցքավորված է"</string> <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Վերահսկվում է ադմինիստրատորի կողմից"</string> <string name="disabled" msgid="8017887509554714950">"Կասեցված է"</string> @@ -553,6 +553,7 @@ <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Անջատված է"</string> <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Միացված է"</string> <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Սարքն անհրաժեշտ է վերագործարկել, որպեսզի փոփոխությունը կիրառվի։ Վերագործարկեք հիմա կամ չեղարկեք փոփոխությունը։"</string> - <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) --> + <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"Աշխատանքային <xliff:g id="APP_NAME">%s</xliff:g>"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> <skip /> </resources> diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml index 3b02fbfcc010..04ca2f69cc61 100644 --- a/packages/SettingsLib/res/values-in/strings.xml +++ b/packages/SettingsLib/res/values-in/strings.xml @@ -195,7 +195,7 @@ </string-array> <string name="choose_profile" msgid="343803890897657450">"Pilih profil"</string> <string name="category_personal" msgid="6236798763159385225">"Pribadi"</string> - <string name="category_work" msgid="4014193632325996115">"Kantor"</string> + <string name="category_work" msgid="4014193632325996115">"Kerja"</string> <string name="development_settings_title" msgid="140296922921597393">"Opsi developer"</string> <string name="development_settings_enable" msgid="4285094651288242183">"Aktifkan opsi developer"</string> <string name="development_settings_summary" msgid="8718917813868735095">"Menyetel opsi untuk pengembangan apl"</string> @@ -433,7 +433,7 @@ <string name="power_discharge_by" msgid="4113180890060388350">"Akan bertahan kira-kira sampai pukul <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">"Akan bertahan kira-kira sampai pukul <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Hingga <xliff:g id="TIME">%1$s</xliff:g>"</string> - <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Baterai mungkin habis pada <xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Baterai mungkin habis pada pukul <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Tersisa kurang dari <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Tersisa kurang dari <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="446388082266121894">"Tersisa lebih dari <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -553,6 +553,7 @@ <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Nonaktif"</string> <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Aktif"</string> <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Perangkat Anda harus di-reboot agar perubahan ini diterapkan. Reboot sekarang atau batalkan."</string> - <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) --> + <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"<xliff:g id="APP_NAME">%s</xliff:g> kerja"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> <skip /> </resources> diff --git a/packages/SettingsLib/res/values-is/strings.xml b/packages/SettingsLib/res/values-is/strings.xml index 6560de0d4a28..ce60eb50031d 100644 --- a/packages/SettingsLib/res/values-is/strings.xml +++ b/packages/SettingsLib/res/values-is/strings.xml @@ -553,6 +553,7 @@ <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Slökkt"</string> <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Virkt"</string> <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Endurræsa þarf tækið til að þessi breyting taki gildi. Endurræstu núna eða hættu við."</string> - <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) --> + <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"<xliff:g id="APP_NAME">%s</xliff:g> í vinnu"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> <skip /> </resources> diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml index ece0ba489ebc..bef644b60a3b 100644 --- a/packages/SettingsLib/res/values-it/strings.xml +++ b/packages/SettingsLib/res/values-it/strings.xml @@ -553,6 +553,7 @@ <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Non attivo"</string> <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Attivo"</string> <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Devi riavviare il dispositivo per applicare questa modifica. Riavvia ora o annulla."</string> - <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) --> + <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"App <xliff:g id="APP_NAME">%s</xliff:g> di lavoro"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> <skip /> </resources> diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml index 23e701dfe709..ed796326c708 100644 --- a/packages/SettingsLib/res/values-iw/strings.xml +++ b/packages/SettingsLib/res/values-iw/strings.xml @@ -555,6 +555,7 @@ <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"מושבת"</string> <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"מופעל"</string> <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"צריך להפעיל מחדש את המכשיר כדי להחיל את השינוי. יש להפעיל מחדש עכשיו או לבטל."</string> - <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) --> + <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"<xliff:g id="APP_NAME">%s</xliff:g> של עבודה"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> <skip /> </resources> diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml index 764072280202..3f08a6ac83e2 100644 --- a/packages/SettingsLib/res/values-ja/strings.xml +++ b/packages/SettingsLib/res/values-ja/strings.xml @@ -210,7 +210,7 @@ <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">"利用可能なデバイスを確認して使用するには、ワイヤレス デバッグを ON にしてください"</string> <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"QR コードによるデバイスのペア設定"</string> <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"QR コードスキャナを使って新しいデバイスをペア設定します"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"ペア設定コードによるデバイスのペア設定"</string> @@ -235,7 +235,7 @@ <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> - <string name="bugreport_in_power_summary" msgid="1885529649381831775">"電源メニューにバグレポートを取得するボタンを表示する"</string> + <string name="bugreport_in_power_summary" msgid="1885529649381831775">"電源ボタン メニューにバグレポートを取得するボタンを表示する"</string> <string name="keep_screen_on" msgid="1187161672348797558">"スリープモードにしない"</string> <string name="keep_screen_on_summary" msgid="1510731514101925829">"充電中に画面をスリープにしない"</string> <string name="bt_hci_snoop_log" msgid="7291287955649081448">"Bluetooth HCI スヌープログ"</string> @@ -553,6 +553,7 @@ <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"無効"</string> <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"有効"</string> <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"この変更を適用するには、デバイスの再起動が必要です。今すぐ再起動してください。キャンセルすることもできます。"</string> - <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) --> + <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"仕事の<xliff:g id="APP_NAME">%s</xliff:g>"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> <skip /> </resources> diff --git a/packages/SettingsLib/res/values-ka/strings.xml b/packages/SettingsLib/res/values-ka/strings.xml index 985188fa63d5..2ebc3ee32c38 100644 --- a/packages/SettingsLib/res/values-ka/strings.xml +++ b/packages/SettingsLib/res/values-ka/strings.xml @@ -554,4 +554,6 @@ <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"ჩართული"</string> <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"ამ ცვლილების ასამოქმედებლად თქვენი მოწყობილობა უნდა გადაიტვირთოს. გადატვირთეთ ახლავე ან გააუქმეთ."</string> <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"სამსახურის <xliff:g id="APP_NAME">%s</xliff:g>"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml index a5308e492c28..91e548830ee9 100644 --- a/packages/SettingsLib/res/values-kk/strings.xml +++ b/packages/SettingsLib/res/values-kk/strings.xml @@ -42,7 +42,7 @@ <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> <string name="tap_to_sign_up" msgid="5356397741063740395">"Тіркелу үшін түртіңіз."</string> - <string name="wifi_connected_no_internet" msgid="5087420713443350646">"Интернетпен байланыс жоқ."</string> + <string name="wifi_connected_no_internet" msgid="5087420713443350646">"Интернетпен байланыс жоқ"</string> <string name="private_dns_broken" msgid="1984159464346556931">"Жеке DNS серверіне кіру мүмкін емес."</string> <string name="wifi_limited_connection" msgid="1184778285475204682">"Шектеулі байланыс"</string> <string name="wifi_status_no_internet" msgid="3799933875988829048">"Интернетпен байланыс жоқ"</string> @@ -61,7 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"Орташа"</string> <string name="speed_label_fast" msgid="2677719134596044051">"Жылдам"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"Өте жылдам"</string> - <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Мерзімі өтті."</string> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Мерзімі өтті"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"Ажыратылған"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Ажыратылуда…"</string> @@ -553,6 +553,7 @@ <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Өшірулі"</string> <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Қосулы"</string> <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Бұл өзгеріс күшіне енуі үшін, құрылғыны қайта жүктеу керек. Қазір қайта жүктеңіз не бас тартыңыз."</string> - <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) --> + <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"<xliff:g id="APP_NAME">%s</xliff:g> (жұмыс)"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> <skip /> </resources> diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml index 0ff48e11f86e..143f5f90a457 100644 --- a/packages/SettingsLib/res/values-km/strings.xml +++ b/packages/SettingsLib/res/values-km/strings.xml @@ -445,8 +445,8 @@ <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_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%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_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> @@ -537,7 +537,7 @@ <string name="user_setup_dialog_message" msgid="269931619868102841">"សូមប្រាកដថាអ្នកប្រើប្រាស់នេះអាចយកឧបករណ៍ និងរៀបចំទំហំផ្ទុករបស់គេបាន"</string> <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"រៀបចំប្រវត្តិរូបឥឡូវ?"</string> <string name="user_setup_button_setup_now" msgid="1708269547187760639">"រៀបចំឥឡូវ"</string> - <string name="user_setup_button_setup_later" msgid="8712980133555493516">"កុំអាល"</string> + <string name="user_setup_button_setup_later" msgid="8712980133555493516">"កុំទាន់"</string> <string name="user_add_user_type_title" msgid="551279664052914497">"បន្ថែម"</string> <string name="user_new_user_name" msgid="60979820612818840">"អ្នកប្រើថ្មី"</string> <string name="user_new_profile_name" msgid="2405500423304678841">"ប្រវត្តិរូបថ្មី"</string> @@ -553,6 +553,7 @@ <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"បានបិទ"</string> <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"បានបើក"</string> <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"ត្រូវតែចាប់ផ្ដើមឧបករណ៍របស់អ្នកឡើងវិញ ទើបការផ្លាស់ប្ដូរនេះត្រូវបានអនុវត្ត។ ចាប់ផ្ដើមឡើងវិញឥឡូវនេះ ឬបោះបង់។"</string> - <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) --> + <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"<xliff:g id="APP_NAME">%s</xliff:g> សម្រាប់ការងារ"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> <skip /> </resources> diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml index 52e3b994a424..1df141ca9d9b 100644 --- a/packages/SettingsLib/res/values-kn/strings.xml +++ b/packages/SettingsLib/res/values-kn/strings.xml @@ -549,14 +549,11 @@ <string name="guest_new_guest" msgid="3482026122932643557">"ಅತಿಥಿಯನ್ನು ಸೇರಿಸಿ"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"ಅತಿಥಿಯನ್ನು ತೆಗೆದುಹಾಕಿ"</string> <string name="guest_nickname" msgid="6332276931583337261">"ಅತಿಥಿ"</string> - <!-- no translation found for cached_apps_freezer_device_default (2616594131750144342) --> - <skip /> - <!-- no translation found for cached_apps_freezer_disabled (4816382260660472042) --> - <skip /> - <!-- no translation found for cached_apps_freezer_enabled (8866703500183051546) --> - <skip /> - <!-- no translation found for cached_apps_freezer_reboot_dialog_text (695330563489230096) --> - <skip /> - <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) --> + <string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"ಸಾಧನದ ಡೀಫಾಲ್ಟ್"</string> + <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string> + <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"ಸಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string> + <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"ಈ ಬದಲಾವಣೆ ಅನ್ವಯವಾಗಲು ನಿಮ್ಮ ಸಾಧನವನ್ನು ರೀಬೂಟ್ ಮಾಡಬೇಕು. ಇದೀಗ ರೀಬೂಟ್ ಮಾಡಿ ಅಥವಾ ರದ್ದುಗೊಳಿಸಿ."</string> + <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"ಉದ್ಯೋಗ <xliff:g id="APP_NAME">%s</xliff:g>"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> <skip /> </resources> diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml index b8d587b9f884..86e165027652 100644 --- a/packages/SettingsLib/res/values-ko/strings.xml +++ b/packages/SettingsLib/res/values-ko/strings.xml @@ -495,7 +495,7 @@ <string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"시간 줄이기"</string> <string name="cancel" msgid="5665114069455378395">"취소"</string> <string name="okay" msgid="949938843324579502">"확인"</string> - <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"켜기"</string> + <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"사용 설정"</string> <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"방해 금지 모드 사용 설정"</string> <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"사용 안함"</string> <string name="zen_interruption_level_priority" msgid="5392140786447823299">"중요 알림만 허용"</string> @@ -530,7 +530,7 @@ <string name="user_add_profile_item_summary" msgid="5418602404308968028">"내 계정의 앱 및 콘텐츠에 대한 액세스를 제한할 수 있습니다."</string> <string name="user_add_user_item_title" msgid="2394272381086965029">"사용자"</string> <string name="user_add_profile_item_title" msgid="3111051717414643029">"제한된 프로필"</string> - <string name="user_add_user_title" msgid="5457079143694924885">"새 사용자를 추가할까요?"</string> + <string name="user_add_user_title" msgid="5457079143694924885">"신규 사용자를 추가할까요?"</string> <string name="user_add_user_message_long" msgid="1527434966294733380">"추가 사용자를 만들어 다른 사용자와 기기를 공유할 수 있습니다. 각 사용자는 앱, 배경화면 등으로 맞춤설정할 수 있는 자신만의 공간을 갖게 됩니다. 또한 모든 사용자에게 영향을 미치는 Wi‑Fi와 같은 기기 설정도 조정할 수 있습니다.\n\n추가된 신규 사용자는 자신의 공간을 설정해야 합니다.\n\n모든 사용자가 앱을 업데이트할 수 있으며, 업데이트는 다른 사용자에게도 적용됩니다. 접근성 설정 및 서비스는 신규 사용자에게 이전되지 않을 수도 있습니다."</string> <string name="user_add_user_message_short" msgid="3295959985795716166">"추가된 새로운 사용자는 자신의 공간을 설정해야 합니다.\n\n모든 사용자는 다른 사용자들을 위하여 앱을 업데이트할 수 있습니다."</string> <string name="user_setup_dialog_title" msgid="8037342066381939995">"지금 사용자를 설정하시겠습니까?"</string> @@ -553,6 +553,7 @@ <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"사용 중지됨"</string> <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"사용 설정됨"</string> <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"변경사항을 적용하려면 기기를 재부팅해야 합니다. 지금 재부팅하거나 취소하세요."</string> - <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) --> + <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"직장용 <xliff:g id="APP_NAME">%s</xliff:g>"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> <skip /> </resources> diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml index 3c57c790d04a..925f4a706f70 100644 --- a/packages/SettingsLib/res/values-ky/strings.xml +++ b/packages/SettingsLib/res/values-ky/strings.xml @@ -224,7 +224,7 @@ <string name="adb_wireless_connection_failed_message" msgid="9213896700171602073">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> туура тармакка туташып турганын текшериңиз"</string> <string name="adb_pairing_device_dialog_title" msgid="7141739231018530210">"Түзмөктү жупташтыруу"</string> <string name="adb_pairing_device_dialog_pairing_code_label" msgid="3639239786669722731">"Wi‑Fi жупташтыруучу коду"</string> - <string name="adb_pairing_device_dialog_failed_title" msgid="3426758947882091735">"Жупташтырылган жок"</string> + <string name="adb_pairing_device_dialog_failed_title" msgid="3426758947882091735">"Туташкан жок"</string> <string name="adb_pairing_device_dialog_failed_msg" msgid="6611097519661997148">"Түзмөк бир тармакка туташып турушу керек."</string> <string name="adb_wireless_qrcode_summary" msgid="8051414549011801917">"QR кодун скандап, түзмөктү Wi‑Fi аркылуу жупташтырыңыз"</string> <string name="adb_wireless_verifying_qrcode_text" msgid="6123192424916029207">"Түзмөк жупташтырылууда…"</string> @@ -302,7 +302,7 @@ <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_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> @@ -445,8 +445,8 @@ <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_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%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_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> @@ -553,6 +553,7 @@ <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Өчүк"</string> <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Күйүк"</string> <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Бул өзгөртүүнү колдонуу үчүн түзмөктү өчүрүп күйгүзүңүз. Азыр өчүрүп күйгүзүңүз же жокко чыгарыңыз."</string> - <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) --> + <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"Жумуш <xliff:g id="APP_NAME">%s</xliff:g>"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> <skip /> </resources> diff --git a/packages/SettingsLib/res/values-lo/strings.xml b/packages/SettingsLib/res/values-lo/strings.xml index 02f73b50d2b2..3bf1996591f5 100644 --- a/packages/SettingsLib/res/values-lo/strings.xml +++ b/packages/SettingsLib/res/values-lo/strings.xml @@ -554,4 +554,6 @@ <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"ເປີດການນຳໃຊ້ແລ້ວ"</string> <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"ທ່ານຕ້ອງປິດເປີດອຸປະກອນຄືນໃໝ່ເພື່ອນຳໃຊ້ການປ່ຽນແປງນີ້. ປິດເປີດໃໝ່ດຽວນີ້ ຫຼື ຍົກເລີກ."</string> <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"ບ່ອນເຮັດວຽກ <xliff:g id="APP_NAME">%s</xliff:g>"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml index dc6347acb4c1..153c9956dc84 100644 --- a/packages/SettingsLib/res/values-lt/strings.xml +++ b/packages/SettingsLib/res/values-lt/strings.xml @@ -555,6 +555,7 @@ <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Išjungta"</string> <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Įgalinta"</string> <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Kad pakeitimas būtų pritaikytas, įrenginį reikia paleisti iš naujo. Dabar paleiskite iš naujo arba atšaukite."</string> - <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) --> + <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"Darbo „<xliff:g id="APP_NAME">%s</xliff:g>“"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> <skip /> </resources> diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml index 0a185d0d5640..f6e7f35d9211 100644 --- a/packages/SettingsLib/res/values-lv/strings.xml +++ b/packages/SettingsLib/res/values-lv/strings.xml @@ -168,7 +168,7 @@ <string name="tts_play_example_summary" msgid="634044730710636383">"Atskaņot īsu runas sintēzes demonstrāciju"</string> <string name="tts_install_data_title" msgid="1829942496472751703">"Instalēt balss datus"</string> <string name="tts_install_data_summary" msgid="3608874324992243851">"Instalēt runas sintēzei nepieciešamos balss datus"</string> - <string name="tts_engine_security_warning" msgid="3372432853837988146">"Lietojot šo runas sintēzes programmu, var tikt apkopots viss ierunātais teksts, tostarp tāda personīgā informācija kā paroles un kredītkaršu numuri. Tā ir no <xliff:g id="TTS_PLUGIN_ENGINE_NAME">%s</xliff:g> programmas. Vai iespējot šīs runas sintēzes programmas lietošanu?"</string> + <string name="tts_engine_security_warning" msgid="3372432853837988146">"Lietojot šo runas sintēzes programmu, var tikt vākts viss ierunātais teksts, tostarp tāda personīgā informācija kā paroles un kredītkaršu numuri. Tā ir no <xliff:g id="TTS_PLUGIN_ENGINE_NAME">%s</xliff:g> programmas. Vai iespējot šīs runas sintēzes programmas lietošanu?"</string> <string name="tts_engine_network_required" msgid="8722087649733906851">"Lai izmantotu teksta pārveidošanu runā šajā valodā, ir nepieciešams aktīvs tīkla savienojums."</string> <string name="tts_default_sample_string" msgid="6388016028292967973">"Šis ir runas sintēzes piemērs."</string> <string name="tts_status_title" msgid="8190784181389278640">"Noklusējuma valodas statuss"</string> @@ -554,6 +554,7 @@ <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Atspējots"</string> <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Iespējots"</string> <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Lai šīs izmaiņas tiktu piemērotas, nepieciešama ierīces atkārtota palaišana. Atkārtoti palaidiet to tūlīt vai atceliet izmaiņas."</string> - <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) --> + <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"Darbā: <xliff:g id="APP_NAME">%s</xliff:g>"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> <skip /> </resources> diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml index e0cc38de584a..d55f1aff6f96 100644 --- a/packages/SettingsLib/res/values-mk/strings.xml +++ b/packages/SettingsLib/res/values-mk/strings.xml @@ -553,6 +553,7 @@ <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Оневозможено"</string> <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Овозможено"</string> <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"За да се примени променава, уредот мора да се рестартира. Рестартирајте сега или откажете."</string> - <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) --> + <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"Работна <xliff:g id="APP_NAME">%s</xliff:g>"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> <skip /> </resources> diff --git a/packages/SettingsLib/res/values-ml/strings.xml b/packages/SettingsLib/res/values-ml/strings.xml index 1a3f06830bab..c5267d6b5b0a 100644 --- a/packages/SettingsLib/res/values-ml/strings.xml +++ b/packages/SettingsLib/res/values-ml/strings.xml @@ -549,14 +549,11 @@ <string name="guest_new_guest" msgid="3482026122932643557">"അതിഥിയെ ചേർക്കുക"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"അതിഥിയെ നീക്കം ചെയ്യുക"</string> <string name="guest_nickname" msgid="6332276931583337261">"അതിഥി"</string> - <!-- no translation found for cached_apps_freezer_device_default (2616594131750144342) --> - <skip /> - <!-- no translation found for cached_apps_freezer_disabled (4816382260660472042) --> - <skip /> - <!-- no translation found for cached_apps_freezer_enabled (8866703500183051546) --> - <skip /> - <!-- no translation found for cached_apps_freezer_reboot_dialog_text (695330563489230096) --> - <skip /> - <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) --> + <string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"ഉപകരണത്തിന്റെ ഡിഫോൾട്ട് പ്രവർത്തനം"</string> + <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"പ്രവർത്തനരഹിതമാക്കി"</string> + <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"പ്രവർത്തനക്ഷമമാക്കി"</string> + <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"ഈ മാറ്റം ബാധകമാകുന്നതിന് നിങ്ങളുടെ ഉപകരണം റീബൂട്ട് ചെയ്യേണ്ടതുണ്ട്. ഇപ്പോൾ റീബൂട്ട് ചെയ്യുകയോ റദ്ദാക്കുകയോ ചെയ്യുക."</string> + <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"ഔദ്യോഗികം <xliff:g id="APP_NAME">%s</xliff:g>"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> <skip /> </resources> diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml index a342862afe59..0a01f8480d0c 100644 --- a/packages/SettingsLib/res/values-mn/strings.xml +++ b/packages/SettingsLib/res/values-mn/strings.xml @@ -419,7 +419,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> @@ -553,6 +553,7 @@ <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Идэвхгүй болгосон"</string> <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Идэвхжүүлсэн"</string> <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Энэ өөрчлөлтийг хэрэгжүүлэхийн тулд таны төхөөрөмжийг дахин асаах ёстой. Одоо дахин асаах эсвэл болино уу."</string> - <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) --> + <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"Ажлын <xliff:g id="APP_NAME">%s</xliff:g>"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> <skip /> </resources> diff --git a/packages/SettingsLib/res/values-mr/strings.xml b/packages/SettingsLib/res/values-mr/strings.xml index 0895cd4dfdaf..075c748f1bb7 100644 --- a/packages/SettingsLib/res/values-mr/strings.xml +++ b/packages/SettingsLib/res/values-mr/strings.xml @@ -243,7 +243,7 @@ <string name="oem_unlock_enable" msgid="5334869171871566731">"OEM अनलॉक करणे"</string> <string name="oem_unlock_enable_summary" msgid="5857388174390953829">"बूटलोडर अनलॉक करण्यासाठी अनुमती द्या"</string> <string name="confirm_enable_oem_unlock_title" msgid="8249318129774367535">"OEM अनलॉक करण्यास अनुमती द्यायची?"</string> - <string name="confirm_enable_oem_unlock_text" msgid="854131050791011970">"चेतावणी: हे सेटिंग चालू असताना या डिव्हाइस वर डिव्हाइस संरक्षण वैशिष्ट्ये काम करणार नाहीत."</string> + <string name="confirm_enable_oem_unlock_text" msgid="854131050791011970">"चेतावणी: हे सेटिंग सुरू असताना या डिव्हाइस वर डिव्हाइस संरक्षण वैशिष्ट्ये काम करणार नाहीत."</string> <string name="mock_location_app" msgid="6269380172542248304">"बनावट स्थान अॅप निवडा"</string> <string name="mock_location_app_not_set" msgid="6972032787262831155">"कोणताही बनावट स्थान अॅप सेट केला नाही"</string> <string name="mock_location_app_set" msgid="4706722469342913843">"बनावट स्थान अॅप: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> @@ -298,7 +298,7 @@ <string name="allow_mock_location" msgid="2102650981552527884">"बनावट स्थानांना अनुमती द्या"</string> <string name="allow_mock_location_summary" msgid="179780881081354579">"बनावट स्थानांना अनुमती द्या"</string> <string name="debug_view_attributes" msgid="3539609843984208216">"दृश्य विशेषता तपासणी सुरू करा"</string> - <string name="mobile_data_always_on_summary" msgid="1112156365594371019">"वाय-फाय चालू असतानाही मोबाइल डेटा नेहमी सुरू ठेवा (नेटवर्क जलदरीत्या स्विच करण्यासाठी)."</string> + <string name="mobile_data_always_on_summary" msgid="1112156365594371019">"वाय-फाय सुरू असतानाही मोबाइल डेटा नेहमी सुरू ठेवा (नेटवर्क जलदरीत्या स्विच करण्यासाठी)."</string> <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> @@ -409,7 +409,7 @@ <string name="convert_to_file_encryption_enabled" msgid="840757431284311754">"रूपांतरित करा..."</string> <string name="convert_to_file_encryption_done" msgid="8965831011811180627">"फाईल आधीपासून एंक्रिप्ट होती"</string> <string name="title_convert_fbe" msgid="5780013350366495149">"फाईल आधारित कूटबद्धीकरणावर रूपांतरित करणे"</string> - <string name="convert_to_fbe_warning" msgid="34294381569282109">"फाईल आधारित कूटबद्धीकरणावर डेटा विभाजक रूपांतरित करा.\n !!चेतावणी!! हे आपल्या सर्व डेटास मिटवेल.\n हे वैशिष्ट्य अल्फा आहे आणि कदाचित योग्यरित्या कार्य करू शकत नाही.\n सुरु ठेवण्यासाठी \'पुसा आणि रूपांतरित करा...\' दाबा."</string> + <string name="convert_to_fbe_warning" msgid="34294381569282109">"फाईल आधारित कूटबद्धीकरणावर डेटा विभाजक रूपांतरित करा.\n !!चेतावणी!! हे आपल्या सर्व डेटास मिटवेल.\n हे वैशिष्ट्य अल्फा आहे आणि कदाचित योग्यरित्या कार्य करू शकत नाही.\n सुरू ठेवण्यासाठी \'पुसा आणि रूपांतरित करा...\' दाबा."</string> <string name="button_convert_fbe" msgid="1159861795137727671">"पुसा आणि रुपांतरित करा..."</string> <string name="picture_color_mode" msgid="1013807330552931903">"चित्र रंग मोड"</string> <string name="picture_color_mode_desc" msgid="151780973768136200">"sRGB वापरा"</string> @@ -495,8 +495,8 @@ <string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"कमी वेळ."</string> <string name="cancel" msgid="5665114069455378395">"रद्द करा"</string> <string name="okay" msgid="949938843324579502">"ठीक आहे"</string> - <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"चालू करा"</string> - <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"व्यत्यय आणू नका चालू करा"</string> + <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"सुरू करा"</string> + <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"व्यत्यय आणू नका सुरू करा"</string> <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"कधीही नाही"</string> <string name="zen_interruption_level_priority" msgid="5392140786447823299">"केवळ प्राधान्य"</string> <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string> @@ -549,14 +549,11 @@ <string name="guest_new_guest" msgid="3482026122932643557">"अतिथी जोडा"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"अतिथी काढून टाका"</string> <string name="guest_nickname" msgid="6332276931583337261">"अतिथी"</string> - <!-- no translation found for cached_apps_freezer_device_default (2616594131750144342) --> - <skip /> - <!-- no translation found for cached_apps_freezer_disabled (4816382260660472042) --> - <skip /> - <!-- no translation found for cached_apps_freezer_enabled (8866703500183051546) --> - <skip /> - <!-- no translation found for cached_apps_freezer_reboot_dialog_text (695330563489230096) --> - <skip /> - <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) --> + <string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"डिव्हाइस डीफॉल्ट"</string> + <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"बंद केले आहे"</string> + <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"सुरू केले आहे"</string> + <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"हा बदल लागू करण्यासाठी तुमचे डिव्हाइस रीबूट करणे आवश्यक आहे. आता रीबूट करा किंवा रद्द करा."</string> + <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"कार्य <xliff:g id="APP_NAME">%s</xliff:g>"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> <skip /> </resources> diff --git a/packages/SettingsLib/res/values-ms/strings.xml b/packages/SettingsLib/res/values-ms/strings.xml index a1c67826b69c..cdf32a7b39ce 100644 --- a/packages/SettingsLib/res/values-ms/strings.xml +++ b/packages/SettingsLib/res/values-ms/strings.xml @@ -553,6 +553,7 @@ <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Dilumpuhkan"</string> <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Didayakan"</string> <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Peranti anda mesti dibut semula supaya perubahan ini berlaku. But semula sekarang atau batalkan."</string> - <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) --> + <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"Kerja <xliff:g id="APP_NAME">%s</xliff:g>"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> <skip /> </resources> diff --git a/packages/SettingsLib/res/values-my/strings.xml b/packages/SettingsLib/res/values-my/strings.xml index 0edc10073e70..2bd3b450238f 100644 --- a/packages/SettingsLib/res/values-my/strings.xml +++ b/packages/SettingsLib/res/values-my/strings.xml @@ -153,7 +153,7 @@ <string name="unknown" msgid="3544487229740637809">"မသိ"</string> <string name="running_process_item_user_label" msgid="3988506293099805796">"အသုံးပြုသူ- <xliff:g id="USER_NAME">%1$s</xliff:g>"</string> <string name="launch_defaults_some" msgid="3631650616557252926">"မူရင်းအချို့ သတ်မှတ်ပြီး"</string> - <string name="launch_defaults_none" msgid="8049374306261262709">"ပုံမှန်သတ်မှတ်ထားခြင်းမရှိ"</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_default_rate_title" msgid="3964187817364304022">"စကားပြောနှုန်း"</string> @@ -553,6 +553,7 @@ <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"ပိတ်ထားသည်"</string> <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"ဖွင့်ထားသည်"</string> <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"ဤအပြောင်းအလဲ ထည့်သွင်းရန် သင့်စက်ကို ပြန်လည်စတင်ရမည်။ ယခု ပြန်လည်စတင်ပါ သို့မဟုတ် ပယ်ဖျက်ပါ။"</string> - <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) --> + <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"အလုပ် <xliff:g id="APP_NAME">%s</xliff:g>"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> <skip /> </resources> diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml index d6830700338a..de5bed63b70a 100644 --- a/packages/SettingsLib/res/values-nb/strings.xml +++ b/packages/SettingsLib/res/values-nb/strings.xml @@ -553,6 +553,7 @@ <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Slått av"</string> <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Slått på"</string> <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Enheten din må startes på nytt for at denne endringen skal tre i kraft. Start på nytt nå eller avbryt."</string> - <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) --> + <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"Jobb-<xliff:g id="APP_NAME">%s</xliff:g>"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> <skip /> </resources> diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml index ee22c60dc0c2..bfe295a4066a 100644 --- a/packages/SettingsLib/res/values-ne/strings.xml +++ b/packages/SettingsLib/res/values-ne/strings.xml @@ -399,7 +399,7 @@ <string name="inactive_apps_title" msgid="5372523625297212320">"स्ट्यान्डबाई एपहरू"</string> <string name="inactive_app_inactive_summary" msgid="3161222402614236260">"निष्क्रिय। टगल गर्न ट्याप गर्नुहोस्।"</string> <string name="inactive_app_active_summary" msgid="8047630990208722344">"सक्रिय। टगल गर्न ट्याप गर्नुहोस्।"</string> - <string name="standby_bucket_summary" msgid="5128193447550429600">"अनुप्रयोगको स्ट्यान्डबाई अवस्था:<xliff:g id="BUCKET"> %s</xliff:g>"</string> + <string name="standby_bucket_summary" msgid="5128193447550429600">"एपको स्ट्यान्डबाई अवस्था:<xliff:g id="BUCKET"> %s</xliff:g>"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"चलिरहेका सेवाहरू"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"हाल चालु भइरहेका सेवाहरू हेर्नुहोस् र नियन्त्रण गर्नुहोस्"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"WebView कार्यान्वयन"</string> @@ -549,14 +549,11 @@ <string name="guest_new_guest" msgid="3482026122932643557">"अतिथि थप्नुहोस्"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"अतिथि हटाउनुहोस्"</string> <string name="guest_nickname" msgid="6332276931583337261">"अतिथि"</string> - <!-- no translation found for cached_apps_freezer_device_default (2616594131750144342) --> - <skip /> - <!-- no translation found for cached_apps_freezer_disabled (4816382260660472042) --> - <skip /> - <!-- no translation found for cached_apps_freezer_enabled (8866703500183051546) --> - <skip /> - <!-- no translation found for cached_apps_freezer_reboot_dialog_text (695330563489230096) --> - <skip /> - <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) --> + <string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"पूर्वनिर्धारित यन्त्र"</string> + <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"असक्षम पारिएको छ"</string> + <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"सक्षम पारिएको छ"</string> + <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"यो परिवर्तन लागू गर्न तपाईंको यन्त्र अनिवार्य रूपमा रिबुट गर्नु पर्छ। अहिले रिबुट गर्नुहोस् वा रद्द गर्नुहोस्।"</string> + <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"कार्यालयको प्रोफाइल <xliff:g id="APP_NAME">%s</xliff:g>"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> <skip /> </resources> diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml index dc5f8f2909c1..a82271981fca 100644 --- a/packages/SettingsLib/res/values-nl/strings.xml +++ b/packages/SettingsLib/res/values-nl/strings.xml @@ -554,4 +554,6 @@ <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Ingeschakeld"</string> <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Je apparaat moet opnieuw worden opgestart om deze wijziging toe te passen. Start nu opnieuw op of annuleer de wijziging."</string> <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"<xliff:g id="APP_NAME">%s</xliff:g> voor werk"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-or/strings.xml b/packages/SettingsLib/res/values-or/strings.xml index 18cc9e3bd382..ab9fbc364f43 100644 --- a/packages/SettingsLib/res/values-or/strings.xml +++ b/packages/SettingsLib/res/values-or/strings.xml @@ -235,7 +235,7 @@ <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> - <string name="bugreport_in_power_summary" msgid="1885529649381831775">"ବଗ୍ ରିପୋର୍ଟ ଦେବାପାଇଁ ପାୱାର୍ ମେନୁରେ ଏକ ବଟନ୍ ଦେଖନ୍ତୁ"</string> + <string name="bugreport_in_power_summary" msgid="1885529649381831775">"ବଗ୍ ରିପୋର୍ଟ ଦେବା ପାଇଁ ପାୱାର୍ ମେନୁରେ ଏକ ବଟନ୍ ଦେଖାନ୍ତୁ"</string> <string name="keep_screen_on" msgid="1187161672348797558">"ଜାଗ୍ରତ ରଖନ୍ତୁ"</string> <string name="keep_screen_on_summary" msgid="1510731514101925829">"ଚାର୍ଜ ହେବାବେଳେ ସ୍କ୍ରୀନ୍ ଆଦୌ ବନ୍ଦ ହେବନାହିଁ"</string> <string name="bt_hci_snoop_log" msgid="7291287955649081448">"ବ୍ଲୁଟୂଥ୍ HCI ସ୍ନୁପ୍ ଲଗ୍ ସକ୍ଷମ କରନ୍ତୁ"</string> @@ -245,7 +245,7 @@ <string name="confirm_enable_oem_unlock_title" msgid="8249318129774367535">"OEM ଅନଲକ୍ କରିବା ଅନୁମତି ଦେବେ?"</string> <string name="confirm_enable_oem_unlock_text" msgid="854131050791011970">"ଚେତାବନୀ: ଏହି ସେଟିଙ୍ଗ ଚାଲୁ ଥିବାବେଳେ ଡିଭାଇସ୍ର ସୁରକ୍ଷା ବୈଶିଷ୍ଟ୍ୟ କାମ କରିବ ନାହିଁ"</string> <string name="mock_location_app" msgid="6269380172542248304">"ମକ୍ ଲୋକେସନ୍ ଆପ୍ର ଚୟନ କରନ୍ତୁ"</string> - <string name="mock_location_app_not_set" msgid="6972032787262831155">"କୌଣସି ନକଲି ଲୋକେଶନ ଆପ୍ ସେଟ୍ କରାଯାଇନାହିଁ"</string> + <string name="mock_location_app_not_set" msgid="6972032787262831155">"କୌଣସି ମକ୍ ଲୋକେସନ ଆପ୍ ସେଟ୍ କରାଯାଇନାହିଁ"</string> <string name="mock_location_app_set" msgid="4706722469342913843">"ମକ୍ ଲୋକେସନ୍ ଆପ୍: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> <string name="debug_networking_category" msgid="6829757985772659599">"ନେଟ୍ୱର୍କିଙ୍ଗ"</string> <string name="wifi_display_certification" msgid="1805579519992520381">"ୱାୟରଲେସ୍ ଡିସ୍ପ୍ଲେ ସାର୍ଟିଫିକେସନ୍"</string> @@ -549,14 +549,11 @@ <string name="guest_new_guest" msgid="3482026122932643557">"ଅତିଥି ଯୋଗ କରନ୍ତୁ"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"ଅତିଥିଙ୍କୁ କାଢ଼ି ଦିଅନ୍ତୁ"</string> <string name="guest_nickname" msgid="6332276931583337261">"ଅତିଥି"</string> - <!-- no translation found for cached_apps_freezer_device_default (2616594131750144342) --> - <skip /> - <!-- no translation found for cached_apps_freezer_disabled (4816382260660472042) --> - <skip /> - <!-- no translation found for cached_apps_freezer_enabled (8866703500183051546) --> - <skip /> - <!-- no translation found for cached_apps_freezer_reboot_dialog_text (695330563489230096) --> - <skip /> - <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) --> + <string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"ଡିଭାଇସ୍ ଡିଫଲ୍ଟ"</string> + <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"ଅକ୍ଷମ କରାଯାଇଛି"</string> + <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"ସକ୍ଷମ କରାଯାଇଛି"</string> + <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"ଏହି ପରିବର୍ତ୍ତନ ଲାଗୁ କରିବା ପାଇଁ ଆପଣଙ୍କ ଡିଭାଇସକୁ ନିଶ୍ଚିତ ରୂପେ ରିବୁଟ୍ କରାଯିବା ଆବଶ୍ୟକ। ବର୍ତ୍ତମାନ ରିବୁଟ୍ କରନ୍ତୁ କିମ୍ବା ବାତିଲ୍ କରନ୍ତୁ।"</string> + <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"ୱାର୍କ <xliff:g id="APP_NAME">%s</xliff:g>"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> <skip /> </resources> diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml index b502f3fa25e6..35d8cbab0b36 100644 --- a/packages/SettingsLib/res/values-pa/strings.xml +++ b/packages/SettingsLib/res/values-pa/strings.xml @@ -549,14 +549,11 @@ <string name="guest_new_guest" msgid="3482026122932643557">"ਮਹਿਮਾਨ ਸ਼ਾਮਲ ਕਰੋ"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"ਮਹਿਮਾਨ ਹਟਾਓ"</string> <string name="guest_nickname" msgid="6332276931583337261">"ਮਹਿਮਾਨ"</string> - <!-- no translation found for cached_apps_freezer_device_default (2616594131750144342) --> - <skip /> - <!-- no translation found for cached_apps_freezer_disabled (4816382260660472042) --> - <skip /> - <!-- no translation found for cached_apps_freezer_enabled (8866703500183051546) --> - <skip /> - <!-- no translation found for cached_apps_freezer_reboot_dialog_text (695330563489230096) --> - <skip /> - <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) --> + <string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"ਪੂਰਵ-ਨਿਰਧਾਰਤ ਡੀਵਾਈਸ"</string> + <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"ਬੰਦ ਕੀਤਾ ਗਿਆ"</string> + <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"ਚਾਲੂ ਕੀਤਾ ਗਿਆ"</string> + <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"ਇਸ ਤਬਦੀਲੀ ਨੂੰ ਲਾਗੂ ਕਰਨ ਲਈ ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਨੂੰ ਰੀਬੂਟ ਕਰਨਾ ਲਾਜ਼ਮੀ ਹੈ। ਹੁਣੇ ਰੀਬੂਟ ਕਰੋ ਜਾਂ ਰੱਦ ਕਰੋ।"</string> + <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"ਕੰਮ <xliff:g id="APP_NAME">%s</xliff:g>"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> <skip /> </resources> diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml index 8a29bf0f4431..54ed131797a9 100644 --- a/packages/SettingsLib/res/values-pl/strings.xml +++ b/packages/SettingsLib/res/values-pl/strings.xml @@ -195,7 +195,7 @@ </string-array> <string name="choose_profile" msgid="343803890897657450">"Wybierz profil"</string> <string name="category_personal" msgid="6236798763159385225">"Osobiste"</string> - <string name="category_work" msgid="4014193632325996115">"Do pracy"</string> + <string name="category_work" msgid="4014193632325996115">"Służbowe"</string> <string name="development_settings_title" msgid="140296922921597393">"Opcje programistyczne"</string> <string name="development_settings_enable" msgid="4285094651288242183">"Włącz opcje dla programistów"</string> <string name="development_settings_summary" msgid="8718917813868735095">"Ustaw opcje związane z programowaniem aplikacji."</string> @@ -555,6 +555,7 @@ <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Wyłączono"</string> <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Włączono"</string> <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Wprowadzenie zmiany wymaga ponownego uruchomienia urządzenia. Uruchom ponownie teraz lub anuluj."</string> - <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) --> + <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"<xliff:g id="APP_NAME">%s</xliff:g> (do pracy)"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> <skip /> </resources> diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml index 58a13cdd1999..c6dc1d3376b9 100644 --- a/packages/SettingsLib/res/values-pt-rBR/strings.xml +++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml @@ -61,7 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"Média"</string> <string name="speed_label_fast" msgid="2677719134596044051">"Rápida"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"Muito rápida"</string> - <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Expirado"</string> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Expirada"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"Desconectado"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Desconectando…"</string> @@ -554,4 +554,6 @@ <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Ativado"</string> <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"É necessário reinicializar o dispositivo para que a mudança seja aplicada. Faça isso agora ou cancele."</string> <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"App <xliff:g id="APP_NAME">%s</xliff:g> de trabalho"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml index ca851516bec9..999e684f124d 100644 --- a/packages/SettingsLib/res/values-pt-rPT/strings.xml +++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml @@ -212,9 +212,9 @@ <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="7130694277228970888">"Sincronize novos dispositivos com o leitor de códigos QR."</string> + <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"Sincroniza 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_pair_method_code_summary" msgid="6370414511333685185">"Sincroniza novos dispositivos através do código de seis dígitos."</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"Dispositivos sincronizados"</string> <string name="adb_wireless_device_connected_summary" msgid="3039660790249148713">"Atualmente ligado."</string> <string name="adb_wireless_device_details_title" msgid="7129369670526565786">"Detalhes do dispositivo"</string> @@ -554,4 +554,6 @@ <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Ativada"</string> <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"É necessário reiniciar o dispositivo para aplicar esta alteração. Reinicie agora ou cancele."</string> <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"<xliff:g id="APP_NAME">%s</xliff:g> de trabalho"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml index 58a13cdd1999..c6dc1d3376b9 100644 --- a/packages/SettingsLib/res/values-pt/strings.xml +++ b/packages/SettingsLib/res/values-pt/strings.xml @@ -61,7 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"Média"</string> <string name="speed_label_fast" msgid="2677719134596044051">"Rápida"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"Muito rápida"</string> - <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Expirado"</string> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Expirada"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"Desconectado"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Desconectando…"</string> @@ -554,4 +554,6 @@ <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Ativado"</string> <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"É necessário reinicializar o dispositivo para que a mudança seja aplicada. Faça isso agora ou cancele."</string> <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"App <xliff:g id="APP_NAME">%s</xliff:g> de trabalho"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml index f967c8ca8d6b..ba2f36fc5c1d 100644 --- a/packages/SettingsLib/res/values-ro/strings.xml +++ b/packages/SettingsLib/res/values-ro/strings.xml @@ -554,6 +554,7 @@ <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Dezactivat"</string> <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Activat"</string> <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Pentru ca modificarea să se aplice, trebuie să reporniți dispozitivul. Reporniți-l acum sau anulați."</string> - <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) --> + <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"<xliff:g id="APP_NAME">%s</xliff:g> de serviciu"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> <skip /> </resources> diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml index e41b3b7cf587..8ec387584c5a 100644 --- a/packages/SettingsLib/res/values-ru/strings.xml +++ b/packages/SettingsLib/res/values-ru/strings.xml @@ -210,7 +210,7 @@ <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">"Чтобы посмотреть и использовать доступные устройства, включите отладку по 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="7130694277228970888">"Подключение новых устройств с помощью сканера QR-кодов"</string> <string name="adb_pair_method_code_title" msgid="1122590300445142904">"Подключить устройство с помощью кода подключения"</string> @@ -223,7 +223,7 @@ <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> <string name="adb_pairing_device_dialog_title" msgid="7141739231018530210">"Подключение к устройству"</string> - <string name="adb_pairing_device_dialog_pairing_code_label" msgid="3639239786669722731">"Код подключения к сети Wi‑Fi"</string> + <string name="adb_pairing_device_dialog_pairing_code_label" msgid="3639239786669722731">"Код подключения по сети Wi‑Fi"</string> <string name="adb_pairing_device_dialog_failed_title" msgid="3426758947882091735">"Не удалось подключить устройство"</string> <string name="adb_pairing_device_dialog_failed_msg" msgid="6611097519661997148">"Устройство должно быть подключено к той же самой сети."</string> <string name="adb_wireless_qrcode_summary" msgid="8051414549011801917">"Подключение устройства через Wi‑Fi с использованием QR-кода"</string> @@ -555,6 +555,7 @@ <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Отключено"</string> <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Включено"</string> <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Чтобы изменение вступило в силу, необходимо перезапустить устройство. Вы можете сделать это сейчас или позже."</string> - <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) --> + <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"Рабочее приложение \"<xliff:g id="APP_NAME">%s</xliff:g>\""</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> <skip /> </resources> diff --git a/packages/SettingsLib/res/values-si/strings.xml b/packages/SettingsLib/res/values-si/strings.xml index 571098554562..01c36349bb8f 100644 --- a/packages/SettingsLib/res/values-si/strings.xml +++ b/packages/SettingsLib/res/values-si/strings.xml @@ -553,6 +553,7 @@ <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"අබල කළා"</string> <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"සබලයි"</string> <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"මෙම වෙනස යෙදීමට ඔබේ උපාංගය නැවත පණ ගැන්විය යුතුය. දැන් නැවත පණ ගන්වන්න හෝ අවලංගු කරන්න."</string> - <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) --> + <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"කාර්යාල <xliff:g id="APP_NAME">%s</xliff:g>"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> <skip /> </resources> diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml index b3848a9dfc11..b5cbf435f356 100644 --- a/packages/SettingsLib/res/values-sk/strings.xml +++ b/packages/SettingsLib/res/values-sk/strings.xml @@ -61,7 +61,7 @@ <string name="speed_label_medium" msgid="9078405312828606976">"Stredná"</string> <string name="speed_label_fast" msgid="2677719134596044051">"Rýchla"</string> <string name="speed_label_very_fast" msgid="8215718029533182439">"Veľmi rýchla"</string> - <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Platnosť vypršala"</string> + <string name="wifi_passpoint_expired" msgid="6540867261754427561">"Vypršalo"</string> <string name="preference_summary_default_combination" msgid="2644094566845577901">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string> <string name="bluetooth_disconnected" msgid="7739366554710388701">"Odpojený"</string> <string name="bluetooth_disconnecting" msgid="7638892134401574338">"Prebieha odpájanie..."</string> @@ -195,7 +195,7 @@ </string-array> <string name="choose_profile" msgid="343803890897657450">"Výber profilu"</string> <string name="category_personal" msgid="6236798763159385225">"Osobné"</string> - <string name="category_work" msgid="4014193632325996115">"Práca"</string> + <string name="category_work" msgid="4014193632325996115">"Pracovné"</string> <string name="development_settings_title" msgid="140296922921597393">"Pre vývojárov"</string> <string name="development_settings_enable" msgid="4285094651288242183">"Povolenie možností vývojára"</string> <string name="development_settings_summary" msgid="8718917813868735095">"Možnosti nastavenia vývoja aplikácií"</string> @@ -508,7 +508,7 @@ <string name="alarm_template_far" msgid="6382760514842998629">"o <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Trvanie"</string> <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Vždy sa opýtať"</string> - <string name="zen_mode_forever" msgid="3339224497605461291">"Dokiaľ túto funkciu nevypnete"</string> + <string name="zen_mode_forever" msgid="3339224497605461291">"Dokým funkciu nevypnete"</string> <string name="time_unit_just_now" msgid="3006134267292728099">"Teraz"</string> <string name="media_transfer_this_device_name" msgid="2716555073132169240">"Reproduktor telefónu"</string> <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Pri pripájaní sa vyskytol problém. Zariadenie vypnite a znova zapnite."</string> @@ -555,6 +555,7 @@ <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Vypnuté"</string> <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Zapnuté"</string> <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Táto zmena sa uplatní až po reštartovaní zariadenia. Zariadenie reštartujte alebo zmenu zrušte."</string> - <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) --> + <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"Pracovná aplikácia <xliff:g id="APP_NAME">%s</xliff:g>"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> <skip /> </resources> diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml index 658c1923656d..86cccb859e27 100644 --- a/packages/SettingsLib/res/values-sl/strings.xml +++ b/packages/SettingsLib/res/values-sl/strings.xml @@ -214,7 +214,7 @@ <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"Seznanjanje naprave s kodo 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_pair_method_code_summary" msgid="6370414511333685185">"Seznanitev novih naprav s šestmestno kodo"</string> <string name="adb_paired_devices_title" msgid="5268997341526217362">"Seznanjene naprave"</string> <string name="adb_wireless_device_connected_summary" msgid="3039660790249148713">"Trenutno povezano"</string> <string name="adb_wireless_device_details_title" msgid="7129369670526565786">"Podrobnosti o napravi"</string> @@ -509,7 +509,7 @@ <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Trajanje"</string> <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Vedno vprašaj"</string> <string name="zen_mode_forever" msgid="3339224497605461291">"Dokler ne izklopite"</string> - <string name="time_unit_just_now" msgid="3006134267292728099">"pravkar"</string> + <string name="time_unit_just_now" msgid="3006134267292728099">"Pravkar"</string> <string name="media_transfer_this_device_name" msgid="2716555073132169240">"Zvočnik telefona"</string> <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Težava pri povezovanju. Napravo izklopite in znova vklopite."</string> <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Žična zvočna naprava"</string> @@ -556,4 +556,6 @@ <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Omogočeno"</string> <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Napravo je treba znova zagnati, da bo ta sprememba uveljavljena. Znova zaženite zdaj ali prekličite."</string> <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"<xliff:g id="APP_NAME">%s</xliff:g> za delo"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-sq/strings.xml b/packages/SettingsLib/res/values-sq/strings.xml index 17d2d502d386..bd3353cfc2d3 100644 --- a/packages/SettingsLib/res/values-sq/strings.xml +++ b/packages/SettingsLib/res/values-sq/strings.xml @@ -207,7 +207,7 @@ <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 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="enable_adb_wireless_summary" msgid="7344391423657093011">"Modaliteti 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 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> @@ -446,7 +446,7 @@ <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 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="power_charging_duration" msgid="5005740040558984057">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> derisa të karikohet"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"I panjohur"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"Po karikohet"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Po ngarkon me shpejtësi"</string> @@ -553,6 +553,7 @@ <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Joaktiv"</string> <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Aktiv"</string> <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Pajisja jote duhet të riniset që ky ndryshim të zbatohet. Rinise tani ose anuloje."</string> - <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) --> + <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"<xliff:g id="APP_NAME">%s</xliff:g> për punën"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> <skip /> </resources> diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml index e0a7d0b28ccd..29f23b48d5e0 100644 --- a/packages/SettingsLib/res/values-sr/strings.xml +++ b/packages/SettingsLib/res/values-sr/strings.xml @@ -554,6 +554,7 @@ <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Онемогућено"</string> <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Омогућено"</string> <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Морате да рестартујете уређај да би се ова промена применила. Рестартујте га одмах или откажите."</string> - <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) --> + <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"<xliff:g id="APP_NAME">%s</xliff:g> за посао"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> <skip /> </resources> diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml index f6745b2ebf3c..a40100e83f51 100644 --- a/packages/SettingsLib/res/values-sv/strings.xml +++ b/packages/SettingsLib/res/values-sv/strings.xml @@ -183,19 +183,19 @@ <string name="tts_reset_speech_pitch_title" msgid="7149398585468413246">"Återställ tonhöjden för tal"</string> <string name="tts_reset_speech_pitch_summary" msgid="6822904157021406449">"Återställ tonhöjden för talad text till standardinställningen."</string> <string-array name="tts_rate_entries"> - <item msgid="9004239613505400644">"Mycket långsamt"</item> - <item msgid="1815382991399815061">"Långsamt"</item> - <item msgid="3075292553049300105">"Normalt"</item> - <item msgid="1158955023692670059">"Snabbt"</item> + <item msgid="9004239613505400644">"Mycket långsam"</item> + <item msgid="1815382991399815061">"Långsam"</item> + <item msgid="3075292553049300105">"Normal"</item> + <item msgid="1158955023692670059">"Snabb"</item> <item msgid="5664310435707146591">"Snabbare"</item> - <item msgid="5491266922147715962">"Mycket snabbt"</item> - <item msgid="7659240015901486196">"Supersnabbt"</item> - <item msgid="7147051179282410945">"Turbosnabbt"</item> + <item msgid="5491266922147715962">"Mycket snabb"</item> + <item msgid="7659240015901486196">"Supersnabb"</item> + <item msgid="7147051179282410945">"Turbosnabb"</item> <item msgid="581904787661470707">"Snabbast"</item> </string-array> <string name="choose_profile" msgid="343803890897657450">"Välj profil"</string> - <string name="category_personal" msgid="6236798763159385225">"Personligt"</string> - <string name="category_work" msgid="4014193632325996115">"Arbetet"</string> + <string name="category_personal" msgid="6236798763159385225">"Privat"</string> + <string name="category_work" msgid="4014193632325996115">"Jobb"</string> <string name="development_settings_title" msgid="140296922921597393">"Utvecklaralternativ"</string> <string name="development_settings_enable" msgid="4285094651288242183">"Aktivera utvecklaralternativ"</string> <string name="development_settings_summary" msgid="8718917813868735095">"Ange alternativ för apputveckling"</string> @@ -213,9 +213,9 @@ <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="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> + <string name="adb_pair_method_code_title" msgid="1122590300445142904">"Parkoppla enheten med en parkopplingskod"</string> + <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"Parkoppla nya enheter med en sexsiffrig kod"</string> + <string name="adb_paired_devices_title" msgid="5268997341526217362">"Parkopplade enheter"</string> <string name="adb_wireless_device_connected_summary" msgid="3039660790249148713">"Anslutna just nu"</string> <string name="adb_wireless_device_details_title" msgid="7129369670526565786">"Enhetsinformation"</string> <string name="adb_device_forget" msgid="193072400783068417">"Glöm"</string> @@ -553,6 +553,7 @@ <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Inaktiverat"</string> <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Aktiverat"</string> <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Enheten måste startas om för att ändringen ska börja gälla. Starta om nu eller avbryt."</string> - <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) --> + <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"<xliff:g id="APP_NAME">%s</xliff:g> för arbetet"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> <skip /> </resources> diff --git a/packages/SettingsLib/res/values-sw/arrays.xml b/packages/SettingsLib/res/values-sw/arrays.xml index a29b74e6d17d..af3935694cdc 100644 --- a/packages/SettingsLib/res/values-sw/arrays.xml +++ b/packages/SettingsLib/res/values-sw/arrays.xml @@ -40,7 +40,7 @@ <item msgid="8339720953594087771">"Inaunganisha kwa <xliff:g id="NETWORK_NAME">%1$s</xliff:g>…"</item> <item msgid="3028983857109369308">"Uhalalishaji kwa <xliff:g id="NETWORK_NAME">%1$s</xliff:g>…"</item> <item msgid="4287401332778341890">"Inamiliki anwani ya IP kutoka <xliff:g id="NETWORK_NAME">%1$s</xliff:g>…"</item> - <item msgid="1043944043827424501">" Umeunganishwa kwa<xliff:g id="NETWORK_NAME">%1$s</xliff:g>"</item> + <item msgid="1043944043827424501">"Umeunganishwa kwa <xliff:g id="NETWORK_NAME">%1$s</xliff:g>"</item> <item msgid="7445993821842009653">"Imesimamishwa"</item> <item msgid="1175040558087735707">"inakatisha muunganisho kutoka <xliff:g id="NETWORK_NAME">%1$s</xliff:g>…"</item> <item msgid="699832486578171722">"Muunganisho Umekatika"</item> diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml index 7df39d5ded33..fedf1c85946c 100644 --- a/packages/SettingsLib/res/values-sw/strings.xml +++ b/packages/SettingsLib/res/values-sw/strings.xml @@ -195,7 +195,7 @@ </string-array> <string name="choose_profile" msgid="343803890897657450">"Chagua wasifu"</string> <string name="category_personal" msgid="6236798763159385225">"Ya Kibinafsi"</string> - <string name="category_work" msgid="4014193632325996115">"Kazini"</string> + <string name="category_work" msgid="4014193632325996115">"Ya Kazini"</string> <string name="development_settings_title" msgid="140296922921597393">"Chaguo za wasanidi"</string> <string name="development_settings_enable" msgid="4285094651288242183">"Washa chaguo za wasanidi programu"</string> <string name="development_settings_summary" msgid="8718917813868735095">"Weka chaguo kwa ajili ya maendeleo ya programu"</string> @@ -485,7 +485,7 @@ <string name="ims_reg_title" msgid="8197592958123671062">"Hali ya usajili wa IMS"</string> <string name="ims_reg_status_registered" msgid="884916398194885457">"Imesajiliwa"</string> <string name="ims_reg_status_not_registered" msgid="2989287366045704694">"Haijasajiliwa"</string> - <string name="status_unavailable" msgid="5279036186589861608">"Haipatikani"</string> + <string name="status_unavailable" msgid="5279036186589861608">"Hamna"</string> <string name="wifi_status_mac_randomized" msgid="466382542497832189">"Imechagua anwani ya MAC kwa nasibu"</string> <plurals name="wifi_tether_connected_summary" formatted="false" msgid="6317236306047306139"> <item quantity="other">Imeunganisha vifaa %1$d</item> @@ -553,6 +553,7 @@ <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Imezimwa"</string> <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Imewashwa"</string> <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Ni lazima uwashe tena kifaa chako ili mabadiliko haya yatekelezwe. Washa tena sasa au ughairi."</string> - <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) --> + <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"Ya kazini <xliff:g id="APP_NAME">%s</xliff:g>"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> <skip /> </resources> diff --git a/packages/SettingsLib/res/values-ta/strings.xml b/packages/SettingsLib/res/values-ta/strings.xml index fa922ea8804b..345f0a7c560d 100644 --- a/packages/SettingsLib/res/values-ta/strings.xml +++ b/packages/SettingsLib/res/values-ta/strings.xml @@ -553,6 +553,7 @@ <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"முடக்கப்பட்டது"</string> <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"இயக்கப்பட்டது"</string> <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"இந்த மாற்றங்கள் செயல்படுத்தப்பட உங்கள் சாதனத்தை மறுபடி தொடங்க வேண்டும். இப்போதே மறுபடி தொடங்கவும் அல்லது ரத்துசெய்யவும்."</string> - <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) --> + <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"பணியிடம் <xliff:g id="APP_NAME">%s</xliff:g>"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> <skip /> </resources> diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml index 0e36c5fe53cf..c4fda01c19d2 100644 --- a/packages/SettingsLib/res/values-te/strings.xml +++ b/packages/SettingsLib/res/values-te/strings.xml @@ -153,9 +153,9 @@ <string name="unknown" msgid="3544487229740637809">"తెలియదు"</string> <string name="running_process_item_user_label" msgid="3988506293099805796">"వినియోగదారు: <xliff:g id="USER_NAME">%1$s</xliff:g>"</string> <string name="launch_defaults_some" msgid="3631650616557252926">"కొన్ని డిఫాల్ట్లు సెట్ చేయబడ్డాయి"</string> - <string name="launch_defaults_none" msgid="8049374306261262709">"ఆటోమేటిక్ ఆప్షన్లు వేటినీ సెట్ చేయలేదు"</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> @@ -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> @@ -229,7 +229,7 @@ <string name="adb_wireless_qrcode_summary" msgid="8051414549011801917">"QR కోడ్ను స్కాన్ చేయడం ద్వారా Wi-Fiని ఉపయోగించి పరికరాన్ని పెయిర్ చెయ్యండి"</string> <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_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="6014121407143607851">"QR కోడ్ను స్కాన్ చేయడం ద్వారా Wi-Fiని ఉపయోగించి పరికరాన్ని పెయిర్ చెయ్యండి"</string> <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"దయచేసి Wi-Fi నెట్వర్క్కు కనెక్ట్ చేయండి"</string> @@ -418,8 +418,8 @@ <string name="daltonizer_mode_deuteranomaly" msgid="3507284319584683963">"డ్యూటెరానోమలీ (ఎరుపు-ఆకుపచ్చ)"</string> <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_title" msgid="1810693571332381974">"కలర్ సరిచేయడం"</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> @@ -533,7 +533,7 @@ <string name="user_add_user_title" msgid="5457079143694924885">"కొత్త వినియోగదారుని జోడించాలా?"</string> <string name="user_add_user_message_long" msgid="1527434966294733380">"అదనపు యూజర్లను సృష్టించడం ద్వారా మీరు ఈ దేవైజ్ను ఇతరులతో షేర్ చేయవచ్చు. ప్రతి యూజర్కు వారికంటూ ప్రత్యేక స్థలం ఉంటుంది, వారు ఆ స్థలాన్ని యాప్లు, వాల్పేపర్ మొదలైనవాటితో అనుకూలీకరించవచ్చు. యూజర్లు ప్రతి ఒక్కరిపై ప్రభావం చూపే Wi‑Fi వంటి పరికర సెట్టింగ్లను కూడా సర్దుబాటు చేయవచ్చు.\n\nమీరు కొత్త యూజర్ ను జోడించినప్పుడు, ఆ వ్యక్తి వారికంటూ స్వంత స్థలం సెట్ చేసుకోవాలి.\n\nఏ వినియోగదారు అయినా మిగిలిన అందరు యూజర్ల కోసం యాప్లను అప్డేట్ చేయవచ్చు. యాక్సెస్ సామర్ధ్యం సెట్టింగ్లు మరియు సేవలు కొత్త యూజర్కి బదిలీ కాకపోవచ్చు."</string> <string name="user_add_user_message_short" msgid="3295959985795716166">"మీరు కొత్త వినియోగదారుని జోడించినప్పుడు, ఆ వ్యక్తి తన స్థలాన్ని సెటప్ చేసుకోవాలి.\n\nఏ వినియోగదారు అయినా మిగతా అందరు వినియోగదారుల కోసం యాప్లను అప్డేట్ చేయగలరు."</string> - <string name="user_setup_dialog_title" msgid="8037342066381939995">"ఇప్పుడు వినియోగదారుని సెటప్ చేయాలా?"</string> + <string name="user_setup_dialog_title" msgid="8037342066381939995">"యూజర్ను ఇప్పుడే సెటప్ చేయాలా?"</string> <string name="user_setup_dialog_message" msgid="269931619868102841">"పరికరాన్ని తీసుకోవడానికి వ్యక్తి అందుబాటులో ఉన్నారని నిర్ధారించుకొని, ఆపై వారికి నిల్వ స్థలాన్ని సెటప్ చేయండి"</string> <string name="user_setup_profile_dialog_message" msgid="4788197052296962620">"ఇప్పుడు ప్రొఫైల్ను సెటప్ చేయాలా?"</string> <string name="user_setup_button_setup_now" msgid="1708269547187760639">"ఇప్పుడే సెటప్ చేయి"</string> @@ -549,14 +549,11 @@ <string name="guest_new_guest" msgid="3482026122932643557">"అతిథిని జోడించండి"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"అతిథిని తీసివేయండి"</string> <string name="guest_nickname" msgid="6332276931583337261">"అతిథి"</string> - <!-- no translation found for cached_apps_freezer_device_default (2616594131750144342) --> - <skip /> - <!-- no translation found for cached_apps_freezer_disabled (4816382260660472042) --> - <skip /> - <!-- no translation found for cached_apps_freezer_enabled (8866703500183051546) --> - <skip /> - <!-- no translation found for cached_apps_freezer_reboot_dialog_text (695330563489230096) --> - <skip /> - <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) --> + <string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"పరికర ఆటోమేటిక్ సెట్టింగ్"</string> + <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"డిజేబుల్ చేయబడింది"</string> + <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"ఎనేబుల్ చేయబడింది"</string> + <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"ఈ మార్పును వర్తింపజేయాలంటే మీరు మీ పరికరాన్ని తప్పనిసరిగా రీబూట్ చేయాలి. ఇప్పుడే రీబూట్ చేయండి లేదా రద్దు చేయండి."</string> + <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"ఆఫీసు <xliff:g id="APP_NAME">%s</xliff:g>"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> <skip /> </resources> diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml index 0e958e908ac3..a9032ebf4fd2 100644 --- a/packages/SettingsLib/res/values-th/strings.xml +++ b/packages/SettingsLib/res/values-th/strings.xml @@ -553,6 +553,7 @@ <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"ปิดใช้"</string> <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"เปิดใช้"</string> <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"คุณต้องรีบูตอุปกรณ์เพื่อให้การเปลี่ยนแปลงนี้มีผล รีบูตเลยหรือยกเลิก"</string> - <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) --> + <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"<xliff:g id="APP_NAME">%s</xliff:g> ในโปรไฟล์งาน"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> <skip /> </resources> diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml index 5ce89ebc4c25..712c06bbea74 100644 --- a/packages/SettingsLib/res/values-tl/strings.xml +++ b/packages/SettingsLib/res/values-tl/strings.xml @@ -433,7 +433,7 @@ <string name="power_discharge_by" msgid="4113180890060388350">"Tatagal dapat nang hanggang humigit-kumulang <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">"Tatagal hanggang mga <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharge_by_only_short" msgid="5883041507426914446">"Hanggang <xliff:g id="TIME">%1$s</xliff:g>"</string> - <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Posibleng maubos ang baterya sa loob ng <xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"Baka maubos ang baterya sa loob ng <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"Wala nang <xliff:g id="THRESHOLD">%1$s</xliff:g> ang natitira"</string> <string name="power_remaining_less_than_duration" msgid="318215464914990578">"Wala nang <xliff:g id="THRESHOLD">%1$s</xliff:g> ang natitira (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"Mahigit <xliff:g id="TIME_REMAINING">%1$s</xliff:g> pa ang natitira (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -553,6 +553,7 @@ <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Naka-disable"</string> <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Na-enable"</string> <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Dapat i-reboot ang iyong device para mailapat ang pagbabagong ito. Mag-reboot ngayon o kanselahin."</string> - <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) --> + <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"<xliff:g id="APP_NAME">%s</xliff:g> sa Trabaho"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> <skip /> </resources> diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml index 1e887d19f8ee..8818498bbcfd 100644 --- a/packages/SettingsLib/res/values-tr/strings.xml +++ b/packages/SettingsLib/res/values-tr/strings.xml @@ -553,6 +553,7 @@ <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Devre dışı"</string> <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Etkin"</string> <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Bu değişikliğin geçerli olması için cihazının yeniden başlatılması gerekir. Şimdi yeniden başlatın veya iptal edin."</string> - <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) --> + <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"<xliff:g id="APP_NAME">%s</xliff:g> (İş)"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> <skip /> </resources> diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml index a95105b72fb1..f6568e3dbb5e 100644 --- a/packages/SettingsLib/res/values-uk/strings.xml +++ b/packages/SettingsLib/res/values-uk/strings.xml @@ -226,12 +226,12 @@ <string name="adb_pairing_device_dialog_pairing_code_label" msgid="3639239786669722731">"Код підключення Wi‑Fi"</string> <string name="adb_pairing_device_dialog_failed_title" msgid="3426758947882091735">"Помилка підключення"</string> <string name="adb_pairing_device_dialog_failed_msg" msgid="6611097519661997148">"Переконайтеся, що пристрій підключено до тієї ж мережі."</string> - <string name="adb_wireless_qrcode_summary" msgid="8051414549011801917">"Підключати пристрій через Wi‑Fi за допомогою QR-коду"</string> + <string name="adb_wireless_qrcode_summary" msgid="8051414549011801917">"Підключіть пристрій через Wi‑Fi за допомогою QR-коду"</string> <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="6014121407143607851">"Підключати пристрій через 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> @@ -555,6 +555,7 @@ <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Вимкнено"</string> <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Увімкнено"</string> <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Щоб застосувати ці зміни, перезапустіть пристрій. Перезапустіть пристрій або скасуйте зміни."</string> - <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) --> + <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"Робочий додаток <xliff:g id="APP_NAME">%s</xliff:g>"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> <skip /> </resources> diff --git a/packages/SettingsLib/res/values-ur/arrays.xml b/packages/SettingsLib/res/values-ur/arrays.xml index e056c1c1ecc1..377650351bc5 100644 --- a/packages/SettingsLib/res/values-ur/arrays.xml +++ b/packages/SettingsLib/res/values-ur/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-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml index 463c1617b1a6..f13f8fb40847 100644 --- a/packages/SettingsLib/res/values-ur/strings.xml +++ b/packages/SettingsLib/res/values-ur/strings.xml @@ -433,7 +433,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> - <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"<xliff:g id="TIME">%1$s</xliff:g> تک بیٹری ختم ہو سکتی ہے"</string> + <string name="power_suggestion_battery_run_out" msgid="6332089307827787087">"<xliff:g id="TIME">%1$s</xliff:g> تک بیٹری ختم ہو سکتی ہے"</string> <string name="power_remaining_less_than_duration_only" msgid="8956656616031395152">"<xliff:g id="THRESHOLD">%1$s</xliff:g> سے کم باقی ہے"</string> <string name="power_remaining_less_than_duration" msgid="318215464914990578">"<xliff:g id="THRESHOLD">%1$s</xliff:g> سے کم باقی ہے (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> سے زیادہ باقی ہے (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> @@ -549,14 +549,11 @@ <string name="guest_new_guest" msgid="3482026122932643557">"مہمان کو شامل کریں"</string> <string name="guest_exit_guest" msgid="5908239569510734136">"مہمان کو ہٹائیں"</string> <string name="guest_nickname" msgid="6332276931583337261">"مہمان"</string> - <!-- no translation found for cached_apps_freezer_device_default (2616594131750144342) --> - <skip /> - <!-- no translation found for cached_apps_freezer_disabled (4816382260660472042) --> - <skip /> - <!-- no translation found for cached_apps_freezer_enabled (8866703500183051546) --> - <skip /> - <!-- no translation found for cached_apps_freezer_reboot_dialog_text (695330563489230096) --> - <skip /> - <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) --> + <string name="cached_apps_freezer_device_default" msgid="2616594131750144342">"آلہ ڈیفالٹ"</string> + <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"غیر فعال"</string> + <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"فعال"</string> + <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"اس تبدیلی کو لاگو کرنے کے ليے آپ کے آلہ کو ریبوٹ کرنا ضروری ہے۔ ابھی ریبوٹ کریں یا منسوخ کریں۔"</string> + <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"دفتر <xliff:g id="APP_NAME">%s</xliff:g>"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> <skip /> </resources> diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml index 762a246a4453..7b8f627ac0db 100644 --- a/packages/SettingsLib/res/values-uz/strings.xml +++ b/packages/SettingsLib/res/values-uz/strings.xml @@ -553,6 +553,7 @@ <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Yoqilmagan"</string> <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Yoniq"</string> <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Oʻzgarishlar qurilma oʻchib yonganda bajariladi. Hoziroq oʻchib yoqish yoki bekor qilish."</string> - <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) --> + <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"Ish <xliff:g id="APP_NAME">%s</xliff:g>"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> <skip /> </resources> diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml index 12241f152dd5..35cecc1a7b9f 100644 --- a/packages/SettingsLib/res/values-vi/strings.xml +++ b/packages/SettingsLib/res/values-vi/strings.xml @@ -553,6 +553,7 @@ <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Đã tắt"</string> <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Đã bật"</string> <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Bạn phải khởi động lại thiết bị để áp dụng sự thay đổi này. Hãy khởi động lại ngay hoặc hủy."</string> - <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) --> + <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"<xliff:g id="APP_NAME">%s</xliff:g> dành cho công việc"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> <skip /> </resources> diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml index 0a3ca12b8dd1..c69ea2d4b668 100644 --- a/packages/SettingsLib/res/values-zh-rCN/strings.xml +++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml @@ -419,7 +419,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> @@ -553,6 +553,7 @@ <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"已停用"</string> <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"已启用"</string> <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"设备必须重新启动才能应用此更改。您可以立即重新启动或取消。"</string> - <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) --> + <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"工作资料中的<xliff:g id="APP_NAME">%s</xliff:g>"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> <skip /> </resources> diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml index 495cc224c5b6..b0324d9a2f46 100644 --- a/packages/SettingsLib/res/values-zh-rHK/strings.xml +++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml @@ -222,7 +222,7 @@ <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> - <string name="adb_pairing_device_dialog_title" msgid="7141739231018530210">"與裝置配對"</string> + <string name="adb_pairing_device_dialog_title" msgid="7141739231018530210">"配對裝置"</string> <string name="adb_pairing_device_dialog_pairing_code_label" msgid="3639239786669722731">"Wi-Fi 配對碼"</string> <string name="adb_pairing_device_dialog_failed_title" msgid="3426758947882091735">"配對失敗"</string> <string name="adb_pairing_device_dialog_failed_msg" msgid="6611097519661997148">"請確認裝置已連線至相同的網絡。"</string> @@ -452,7 +452,7 @@ <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> + <string name="battery_info_status_not_charging" msgid="8330015078868707899">"已連接電源插頭,但目前無法充電"</string> <string name="battery_info_status_full" msgid="4443168946046847468">"電量已滿"</string> <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"已由管理員停用"</string> <string name="disabled" msgid="8017887509554714950">"已停用"</string> @@ -553,6 +553,7 @@ <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"已停用"</string> <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"已啟用"</string> <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"您的裝置必須重新開機,才能套用此變更。請立即重新開機或取消。"</string> - <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) --> + <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"工作設定檔入面嘅「<xliff:g id="APP_NAME">%s</xliff:g>」"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> <skip /> </resources> diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml index 94452683deca..0574c7ecf626 100644 --- a/packages/SettingsLib/res/values-zh-rTW/strings.xml +++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml @@ -553,6 +553,7 @@ <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"已停用"</string> <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"已啟用"</string> <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"裝置必須重新啟動才能套用這項變更。請立即重新啟動或取消變更。"</string> - <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) --> + <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"工作資料夾中的<xliff:g id="APP_NAME">%s</xliff:g>"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> <skip /> </resources> diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml index 86698f4134f0..b60553a052e4 100644 --- a/packages/SettingsLib/res/values-zu/strings.xml +++ b/packages/SettingsLib/res/values-zu/strings.xml @@ -553,6 +553,7 @@ <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Ikhutshaziwe"</string> <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Inikwe amandla"</string> <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Kufanele idivayisi yakho iqaliswe ukuze lolu shintsho lusebenze. Qalisa manje noma khansela."</string> - <!-- no translation found for accessibility_work_profile_app_description (5470883112342119165) --> + <string name="accessibility_work_profile_app_description" msgid="5470883112342119165">"Umsebenzi we-<xliff:g id="APP_NAME">%s</xliff:g>"</string> + <!-- no translation found for media_transfer_wired_usb_device_name (7699141088423210903) --> <skip /> </resources> diff --git a/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java b/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java index 9e8c70fcc000..197e34df22a8 100644 --- a/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java +++ b/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java @@ -145,15 +145,16 @@ public class LocalMediaManager implements BluetoothCallback { /** * Connect the MediaDevice to transfer media * @param connectDevice the MediaDevice + * @return {@code true} if successfully call, otherwise return {@code false} */ - public void connectDevice(MediaDevice connectDevice) { + public boolean connectDevice(MediaDevice connectDevice) { MediaDevice device = null; synchronized (mMediaDevicesLock) { device = getMediaDeviceById(mMediaDevices, connectDevice.getId()); } if (device == null) { Log.w(TAG, "connectDevice() connectDevice not in the list!"); - return; + return false; } if (device instanceof BluetoothMediaDevice) { final CachedBluetoothDevice cachedDevice = @@ -162,13 +163,13 @@ public class LocalMediaManager implements BluetoothCallback { mOnTransferBluetoothDevice = connectDevice; device.setState(MediaDeviceState.STATE_CONNECTING); cachedDevice.connect(); - return; + return true; } } if (device == mCurrentConnectedDevice) { Log.d(TAG, "connectDevice() this device all ready connected! : " + device.getName()); - return; + return false; } if (mCurrentConnectedDevice != null) { @@ -181,6 +182,7 @@ public class LocalMediaManager implements BluetoothCallback { } else { device.connect(); } + return true; } void dispatchSelectedDeviceStateChanged(MediaDevice device, @MediaDeviceState int state) { diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/LocalMediaManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/LocalMediaManagerTest.java index 365a16c50b99..517071b5511f 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/LocalMediaManagerTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/LocalMediaManagerTest.java @@ -141,7 +141,7 @@ public class LocalMediaManagerTest { when(currentDevice.getId()).thenReturn(TEST_CURRENT_DEVICE_ID); mLocalMediaManager.registerCallback(mCallback); - mLocalMediaManager.connectDevice(device); + assertThat(mLocalMediaManager.connectDevice(device)).isTrue(); verify(currentDevice).disconnect(); verify(device).connect(); @@ -154,7 +154,7 @@ public class LocalMediaManagerTest { mLocalMediaManager.mCurrentConnectedDevice = mInfoMediaDevice1; mLocalMediaManager.registerCallback(mCallback); - mLocalMediaManager.connectDevice(mInfoMediaDevice2); + assertThat(mLocalMediaManager.connectDevice(mInfoMediaDevice2)).isTrue(); assertThat(mInfoMediaDevice2.getState()).isEqualTo(LocalMediaManager.MediaDeviceState .STATE_CONNECTING); @@ -167,7 +167,7 @@ public class LocalMediaManagerTest { mLocalMediaManager.mCurrentConnectedDevice = mInfoMediaDevice1; mLocalMediaManager.registerCallback(mCallback); - mLocalMediaManager.connectDevice(mInfoMediaDevice1); + assertThat(mLocalMediaManager.connectDevice(mInfoMediaDevice1)).isFalse(); assertThat(mInfoMediaDevice1.getState()).isNotEqualTo(LocalMediaManager.MediaDeviceState .STATE_CONNECTING); @@ -185,7 +185,7 @@ public class LocalMediaManagerTest { when(cachedDevice.isBusy()).thenReturn(false); mLocalMediaManager.registerCallback(mCallback); - mLocalMediaManager.connectDevice(device); + assertThat(mLocalMediaManager.connectDevice(device)).isTrue(); verify(cachedDevice).connect(); } diff --git a/packages/SystemUI/res/drawable/stat_sys_media.xml b/packages/SystemUI/res/drawable/stat_sys_media.xml new file mode 100644 index 000000000000..d48db7bd0d28 --- /dev/null +++ b/packages/SystemUI/res/drawable/stat_sys_media.xml @@ -0,0 +1,31 @@ +<!-- + ~ Copyright (C) 2020 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> + +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24"> + <path + android:pathData="M5,7.81l0,8.38l6,-4.19z" + android:fillColor="#000000"/> + <path + android:pathData="M13,8h2v8h-2z" + android:fillColor="#000000"/> + <path + android:pathData="M17,8h2v8h-2z" + android:fillColor="#000000"/> +</vector> diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index 8bbcfa0e7898..de483179a92a 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -790,6 +790,9 @@ <!-- Accessibility text describing sensors off active. [CHAR LIMIT=NONE] --> <string name="accessibility_sensors_off_active">Sensors off active</string> + <!-- Accessibility text describing that media is playing. [CHAR LIMIT=NONE] --> + <string name="accessibility_media_active">Media is active</string> + <!-- Content description of the clear button in the notification panel for accessibility (not shown on the screen). [CHAR LIMIT=NONE] --> <string name="accessibility_clear_all">Clear all notifications.</string> diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/IOverviewProxy.aidl b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/IOverviewProxy.aidl index 0350f2d47569..114472b15f02 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/IOverviewProxy.aidl +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/IOverviewProxy.aidl @@ -16,6 +16,7 @@ package com.android.systemui.shared.recents; +import android.graphics.Rect; import android.graphics.Region; import android.os.Bundle; import android.view.MotionEvent; @@ -69,4 +70,9 @@ oneway interface IOverviewProxy { * Sent when some system ui state changes. */ void onSystemUiStateChanged(int stateFlags) = 16; + + /** + * Sent when the split screen is resized + */ + void onSplitScreenSecondaryBoundsChanged(in Rect bounds, in Rect insets) = 17; } diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinatorImpl.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinatorImpl.kt index 9055479c47fe..10e913743224 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinatorImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinatorImpl.kt @@ -58,7 +58,7 @@ class ControlActionCoordinatorImpl @Inject constructor( override fun toggle(cvh: ControlViewHolder, templateId: String, isChecked: Boolean) { bouncerOrRun { - val effect = if (isChecked) Vibrations.toggleOnEffect else Vibrations.toggleOffEffect + val effect = if (!isChecked) Vibrations.toggleOnEffect else Vibrations.toggleOffEffect vibrate(effect) cvh.action(BooleanAction(templateId, !isChecked)) } diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt index 52d564da7890..3aa417ab904b 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt @@ -59,6 +59,7 @@ import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.globalactions.GlobalActionsPopupMenu import com.android.systemui.plugins.ActivityStarter +import com.android.systemui.statusbar.phone.ShadeController import com.android.systemui.statusbar.policy.KeyguardStateController import com.android.systemui.util.concurrency.DelayableExecutor import dagger.Lazy @@ -79,7 +80,8 @@ class ControlsUiControllerImpl @Inject constructor ( @Main val sharedPreferences: SharedPreferences, val controlActionCoordinator: ControlActionCoordinator, private val activityStarter: ActivityStarter, - private val keyguardStateController: KeyguardStateController + private val keyguardStateController: KeyguardStateController, + private val shadeController: ShadeController ) : ControlsUiController { companion object { @@ -254,14 +256,11 @@ class ControlsUiControllerImpl @Inject constructor ( intent.putExtra(ControlsUiController.EXTRA_ANIMATE, true) dismissGlobalActions.run() - if (!keyguardStateController.isUnlocked()) { - activityStarter.dismissKeyguardThenExecute({ - context.startActivity(intent) - true - }, null, true) - } else { + activityStarter.dismissKeyguardThenExecute({ + shadeController.collapsePanel(false) context.startActivity(intent) - } + true + }, null, true) } private fun showControlsView(items: List<SelectionItem>) { diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/Vibrations.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/Vibrations.kt index a97113cc598b..c0f6aabe2427 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/ui/Vibrations.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/ui/Vibrations.kt @@ -20,7 +20,7 @@ import android.os.VibrationEffect import android.os.VibrationEffect.Composition.PRIMITIVE_TICK object Vibrations { - private const val TOGGLE_TICK_COUNT = 12 + private const val TOGGLE_TICK_COUNT = 40 val toggleOnEffect = initToggleOnEffect() val toggleOffEffect = initToggleOffEffect() @@ -29,6 +29,7 @@ object Vibrations { private fun initToggleOnEffect(): VibrationEffect { val composition = VibrationEffect.startComposition() + composition.addPrimitive(PRIMITIVE_TICK, 0.05f, 200) var i = 0 while (i++ < TOGGLE_TICK_COUNT) { composition.addPrimitive(PRIMITIVE_TICK, 0.05f, 0) @@ -43,7 +44,7 @@ object Vibrations { composition.addPrimitive(PRIMITIVE_TICK, 0.05f, 100) var i = 0 while (i++ < TOGGLE_TICK_COUNT) { - composition?.addPrimitive(PRIMITIVE_TICK, 0.05f, 0) + composition.addPrimitive(PRIMITIVE_TICK, 0.05f, 0) } return composition.compose() } diff --git a/packages/SystemUI/src/com/android/systemui/media/KeyguardMediaController.kt b/packages/SystemUI/src/com/android/systemui/media/KeyguardMediaController.kt index 524c6955ba4a..4ee4ad46d4c7 100644 --- a/packages/SystemUI/src/com/android/systemui/media/KeyguardMediaController.kt +++ b/packages/SystemUI/src/com/android/systemui/media/KeyguardMediaController.kt @@ -67,5 +67,4 @@ class KeyguardMediaController @Inject constructor( statusBarStateController.state == StatusBarState.FULLSCREEN_USER_SWITCHER) view?.visibility = if (shouldBeVisible) View.VISIBLE else View.GONE } -} - +}
\ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/media/LocalMediaManagerFactory.kt b/packages/SystemUI/src/com/android/systemui/media/LocalMediaManagerFactory.kt new file mode 100644 index 000000000000..94a0835f22f8 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/media/LocalMediaManagerFactory.kt @@ -0,0 +1,40 @@ +/* + * 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.media + +import android.content.Context + +import com.android.settingslib.bluetooth.LocalBluetoothManager +import com.android.settingslib.media.InfoMediaManager +import com.android.settingslib.media.LocalMediaManager + +import javax.inject.Inject + +/** + * Factory to create [LocalMediaManager] objects. + */ +class LocalMediaManagerFactory @Inject constructor( + private val context: Context, + private val localBluetoothManager: LocalBluetoothManager? +) { + /** Creates a [LocalMediaManager] for the given package. */ + fun create(packageName: String): LocalMediaManager { + return InfoMediaManager(context, packageName, null, localBluetoothManager).run { + LocalMediaManager(context, localBluetoothManager, this, packageName) + } + } +} diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java index 1691c53386d6..f90798bd30b8 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java +++ b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java @@ -41,7 +41,6 @@ import android.util.Log; import android.view.View; import android.widget.ImageButton; import android.widget.ImageView; -import android.widget.LinearLayout; import android.widget.SeekBar; import android.widget.TextView; @@ -56,14 +55,11 @@ import androidx.core.graphics.drawable.RoundedBitmapDrawable; import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory; import com.android.settingslib.Utils; -import com.android.settingslib.media.LocalMediaManager; -import com.android.settingslib.media.MediaDevice; import com.android.settingslib.media.MediaOutputSliceConstants; import com.android.settingslib.widget.AdaptiveIcon; import com.android.systemui.R; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.qs.QSMediaBrowser; -import com.android.systemui.util.Assert; import com.android.systemui.util.concurrency.DelayableExecutor; import org.jetbrains.annotations.NotNull; @@ -77,7 +73,6 @@ import java.util.concurrent.Executor; */ public class MediaControlPanel { private static final String TAG = "MediaControlPanel"; - @Nullable private final LocalMediaManager mLocalMediaManager; // Button IDs for QS controls static final int[] ACTION_IDS = { @@ -100,7 +95,6 @@ public class MediaControlPanel { private MediaSession.Token mToken; private MediaController mController; private int mBackgroundColor; - private MediaDevice mDevice; protected ComponentName mServiceComponent; private boolean mIsRegistered = false; private List<KeyFrames> mKeyFrames; @@ -113,7 +107,6 @@ public class MediaControlPanel { public static final String MEDIA_PREFERENCE_KEY = "browser_components"; private SharedPreferences mSharedPrefs; private boolean mCheckedForResumption = false; - private boolean mIsRemotePlayback; private QSMediaBrowser mQSMediaBrowser; private final MediaController.Callback mSessionCallback = new MediaController.Callback() { @@ -122,7 +115,6 @@ public class MediaControlPanel { Log.d(TAG, "session destroyed"); mController.unregisterCallback(mSessionCallback); clearControls(); - makeInactive(); } @Override public void onPlaybackStateChanged(PlaybackState state) { @@ -130,31 +122,6 @@ public class MediaControlPanel { if (s == PlaybackState.STATE_NONE) { Log.d(TAG, "playback state change will trigger resumption, state=" + state); clearControls(); - makeInactive(); - } - } - }; - - private final LocalMediaManager.DeviceCallback mDeviceCallback = - new LocalMediaManager.DeviceCallback() { - @Override - public void onDeviceListUpdate(List<MediaDevice> devices) { - if (mLocalMediaManager == null) { - return; - } - MediaDevice currentDevice = mLocalMediaManager.getCurrentConnectedDevice(); - // Check because this can be called several times while changing devices - if (mDevice == null || !mDevice.equals(currentDevice)) { - mDevice = currentDevice; - updateDevice(mDevice); - } - } - - @Override - public void onSelectedDeviceStateChanged(MediaDevice device, int state) { - if (mDevice == null || !mDevice.equals(device)) { - mDevice = device; - updateDevice(mDevice); } } }; @@ -162,16 +129,13 @@ public class MediaControlPanel { /** * Initialize a new control panel * @param context - * @param routeManager Manager used to listen for device change events. * @param foregroundExecutor foreground executor * @param backgroundExecutor background executor, used for processing artwork * @param activityStarter activity starter */ - public MediaControlPanel(Context context, @Nullable LocalMediaManager routeManager, - Executor foregroundExecutor, DelayableExecutor backgroundExecutor, - ActivityStarter activityStarter) { + public MediaControlPanel(Context context, Executor foregroundExecutor, + DelayableExecutor backgroundExecutor, ActivityStarter activityStarter) { mContext = context; - mLocalMediaManager = routeManager; mForegroundExecutor = foregroundExecutor; mBackgroundExecutor = backgroundExecutor; mActivityStarter = activityStarter; @@ -183,7 +147,6 @@ public class MediaControlPanel { if (mSeekBarObserver != null) { mSeekBarViewModel.getProgress().removeObserver(mSeekBarObserver); } - makeInactive(); } private void loadDimens() { @@ -228,7 +191,7 @@ public class MediaControlPanel { mLayoutAnimationHelper = new LayoutAnimationHelper(motionView); GoneChildrenHideHelper.clipGoneChildrenOnLayout(motionView); mKeyFrames = motionView.getDefinedTransitions().get(0).getKeyFrameList(); - mSeekBarObserver = new SeekBarObserver(motionView); + mSeekBarObserver = new SeekBarObserver(vh); mSeekBarViewModel.getProgress().observeForever(mSeekBarObserver); SeekBar bar = vh.getSeekBar(); bar.setOnSeekBarChangeListener(mSeekBarViewModel.getSeekBarListener()); @@ -318,30 +281,67 @@ public class MediaControlPanel { artistText.setText(data.getArtist()); // Transfer chip - if (mLocalMediaManager != null) { - mViewHolder.getSeamless().setVisibility(View.VISIBLE); - setVisibleAndAlpha(collapsedSet, R.id.media_seamless, true /*visible */); - setVisibleAndAlpha(expandedSet, R.id.media_seamless, true /*visible */); - updateDevice(mLocalMediaManager.getCurrentConnectedDevice()); - mViewHolder.getSeamless().setOnClickListener(v -> { - final Intent intent = new Intent() - .setAction(MediaOutputSliceConstants.ACTION_MEDIA_OUTPUT) - .putExtra(MediaOutputSliceConstants.EXTRA_PACKAGE_NAME, - mController.getPackageName()) - .putExtra(MediaOutputSliceConstants.KEY_MEDIA_SESSION_TOKEN, mToken); - mActivityStarter.startActivity(intent, false, true /* dismissShade */, - Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); - }); - } else { - Log.d(TAG, "LocalMediaManager is null. Not binding output chip for pkg=" + pkgName); - } + mViewHolder.getSeamless().setVisibility(View.VISIBLE); + setVisibleAndAlpha(collapsedSet, R.id.media_seamless, true /*visible */); + setVisibleAndAlpha(expandedSet, R.id.media_seamless, true /*visible */); + mViewHolder.getSeamless().setOnClickListener(v -> { + final Intent intent = new Intent() + .setAction(MediaOutputSliceConstants.ACTION_MEDIA_OUTPUT) + .putExtra(MediaOutputSliceConstants.EXTRA_PACKAGE_NAME, + mController.getPackageName()) + .putExtra(MediaOutputSliceConstants.KEY_MEDIA_SESSION_TOKEN, mToken); + mActivityStarter.startActivity(intent, false, true /* dismissShade */, + Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); + }); + final boolean isRemotePlayback; PlaybackInfo playbackInfo = mController.getPlaybackInfo(); if (playbackInfo != null) { - mIsRemotePlayback = playbackInfo.getPlaybackType() == PlaybackInfo.PLAYBACK_TYPE_REMOTE; + isRemotePlayback = playbackInfo.getPlaybackType() == PlaybackInfo.PLAYBACK_TYPE_REMOTE; } else { Log.d(TAG, "PlaybackInfo was null. Defaulting to local playback."); - mIsRemotePlayback = false; + isRemotePlayback = false; + } + + ImageView iconView = mViewHolder.getSeamlessIcon(); + TextView deviceName = mViewHolder.getSeamlessText(); + + // Update the outline color + RippleDrawable bkgDrawable = (RippleDrawable) mViewHolder.getSeamless().getBackground(); + GradientDrawable rect = (GradientDrawable) bkgDrawable.getDrawable(0); + rect.setStroke(2, deviceName.getCurrentTextColor()); + rect.setColor(Color.TRANSPARENT); + + if (isRemotePlayback) { + mViewHolder.getSeamless().setEnabled(false); + // TODO(b/156875717): setEnabled should cause the alpha to change. + mViewHolder.getSeamless().setAlpha(0.38f); + iconView.setImageResource(R.drawable.ic_hardware_speaker); + iconView.setVisibility(View.VISIBLE); + deviceName.setText(R.string.media_seamless_remote_device); + } else if (data.getDevice() != null && data.getDevice().getIcon() != null + && data.getDevice().getName() != null) { + mViewHolder.getSeamless().setEnabled(true); + mViewHolder.getSeamless().setAlpha(1f); + Drawable icon = data.getDevice().getIcon(); + iconView.setVisibility(View.VISIBLE); + + if (icon instanceof AdaptiveIcon) { + AdaptiveIcon aIcon = (AdaptiveIcon) icon; + aIcon.setBackgroundColor(mBackgroundColor); + iconView.setImageDrawable(aIcon); + } else { + iconView.setImageDrawable(icon); + } + deviceName.setText(data.getDevice().getName()); + } else { + // Reset to default + Log.w(TAG, "device is null. Not binding output chip."); + mViewHolder.getSeamless().setEnabled(true); + mViewHolder.getSeamless().setAlpha(1f); + iconView.setVisibility(View.GONE); + deviceName.setText(com.android.internal.R.string.ext_media_seamless_action); } + List<Integer> actionsWhenCollapsed = data.getActionsToShowInCompact(); // Media controls int i = 0; @@ -382,8 +382,6 @@ public class MediaControlPanel { // Set up long press menu // TODO: b/156036025 bring back media guts - makeActive(); - // Update both constraint sets to regenerate the animation. mViewHolder.getPlayer().updateState(R.id.collapsed, collapsedSet); mViewHolder.getPlayer().updateState(R.id.expanded, expandedSet); @@ -515,60 +513,6 @@ public class MediaControlPanel { } /** - * Update the current device information - * @param device device information to display - */ - private void updateDevice(MediaDevice device) { - mForegroundExecutor.execute(() -> { - updateChipInternal(device); - }); - } - - private void updateChipInternal(MediaDevice device) { - if (mViewHolder == null) { - return; - } - ImageView iconView = mViewHolder.getSeamlessIcon(); - TextView deviceName = mViewHolder.getSeamlessText(); - - // Update the outline color - LinearLayout viewLayout = (LinearLayout) mViewHolder.getSeamless(); - RippleDrawable bkgDrawable = (RippleDrawable) viewLayout.getBackground(); - GradientDrawable rect = (GradientDrawable) bkgDrawable.getDrawable(0); - rect.setStroke(2, deviceName.getCurrentTextColor()); - rect.setColor(Color.TRANSPARENT); - - if (mIsRemotePlayback) { - mViewHolder.getSeamless().setEnabled(false); - mViewHolder.getSeamless().setAlpha(0.38f); - iconView.setImageResource(R.drawable.ic_hardware_speaker); - iconView.setVisibility(View.VISIBLE); - deviceName.setText(R.string.media_seamless_remote_device); - } else if (device != null) { - mViewHolder.getSeamless().setEnabled(true); - mViewHolder.getSeamless().setAlpha(1f); - Drawable icon = device.getIcon(); - iconView.setVisibility(View.VISIBLE); - - if (icon instanceof AdaptiveIcon) { - AdaptiveIcon aIcon = (AdaptiveIcon) icon; - aIcon.setBackgroundColor(mBackgroundColor); - iconView.setImageDrawable(aIcon); - } else { - iconView.setImageDrawable(icon); - } - deviceName.setText(device.getName()); - } else { - // Reset to default - Log.d(TAG, "device is null. Not binding output chip."); - mViewHolder.getSeamless().setEnabled(true); - mViewHolder.getSeamless().setAlpha(1f); - iconView.setVisibility(View.GONE); - deviceName.setText(com.android.internal.R.string.ext_media_seamless_action); - } - } - - /** * Puts controls into a resumption state if possible, or calls removePlayer if no component was * found that could resume playback */ @@ -642,27 +586,6 @@ public class MediaControlPanel { set.setAlpha(actionId, visible ? 1.0f : 0.0f); } - private void makeActive() { - Assert.isMainThread(); - if (!mIsRegistered) { - if (mLocalMediaManager != null) { - mLocalMediaManager.registerCallback(mDeviceCallback); - mLocalMediaManager.startScan(); - } - mIsRegistered = true; - } - } - - private void makeInactive() { - Assert.isMainThread(); - if (mIsRegistered) { - if (mLocalMediaManager != null) { - mLocalMediaManager.stopScan(); - mLocalMediaManager.unregisterCallback(mDeviceCallback); - } - mIsRegistered = false; - } - } /** * Verify that we can connect to the given component with a MediaBrowser, and if so, add that * component to the list of resumption components diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaData.kt b/packages/SystemUI/src/com/android/systemui/media/MediaData.kt index 85965d03a096..41d411019921 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaData.kt +++ b/packages/SystemUI/src/com/android/systemui/media/MediaData.kt @@ -34,7 +34,8 @@ data class MediaData( val actionsToShowInCompact: List<Int>, val packageName: String?, val token: MediaSession.Token?, - val clickIntent: PendingIntent? + val clickIntent: PendingIntent?, + val device: MediaDeviceData? ) /** State of a media action. */ @@ -43,3 +44,9 @@ data class MediaAction( val intent: PendingIntent?, val contentDescription: CharSequence? ) + +/** State of the media device. */ +data class MediaDeviceData( + val icon: Drawable?, + val name: String? +) diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaDataCombineLatest.kt b/packages/SystemUI/src/com/android/systemui/media/MediaDataCombineLatest.kt new file mode 100644 index 000000000000..cce9838bb8e2 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/media/MediaDataCombineLatest.kt @@ -0,0 +1,81 @@ +/* + * 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.media + +import javax.inject.Inject +import javax.inject.Singleton + +/** + * Combines updates from [MediaDataManager] with [MediaDeviceManager]. + */ +@Singleton +class MediaDataCombineLatest @Inject constructor( + private val dataSource: MediaDataManager, + private val deviceSource: MediaDeviceManager +) { + private val listeners: MutableSet<MediaDataManager.Listener> = mutableSetOf() + private val entries: MutableMap<String, Pair<MediaData?, MediaDeviceData?>> = mutableMapOf() + + init { + dataSource.addListener(object : MediaDataManager.Listener { + override fun onMediaDataLoaded(key: String, data: MediaData) { + entries[key] = data to entries[key]?.second + update(key) + } + override fun onMediaDataRemoved(key: String) { + remove(key) + } + }) + deviceSource.addListener(object : MediaDeviceManager.Listener { + override fun onMediaDeviceChanged(key: String, data: MediaDeviceData?) { + entries[key] = entries[key]?.first to data + update(key) + } + override fun onKeyRemoved(key: String) { + remove(key) + } + }) + } + + /** + * Add a listener for [MediaData] changes that has been combined with latest [MediaDeviceData]. + */ + fun addListener(listener: MediaDataManager.Listener) = listeners.add(listener) + + /** + * Remove a listener registered with addListener. + */ + fun removeListener(listener: MediaDataManager.Listener) = listeners.remove(listener) + + private fun update(key: String) { + val (entry, device) = entries[key] ?: null to null + if (entry != null && device != null) { + val data = entry.copy(device = device) + listeners.forEach { + it.onMediaDataLoaded(key, data) + } + } + } + + private fun remove(key: String) { + entries.remove(key)?.let { + listeners.forEach { + it.onMediaDataRemoved(key) + } + } + } +} diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt index 90c558a1ee97..8cbe3ecf5387 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt +++ b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt @@ -55,7 +55,19 @@ private const val LUMINOSITY_THRESHOLD = 0.05f private const val SATURATION_MULTIPLIER = 0.8f private val LOADING = MediaData(false, 0, null, null, null, null, null, - emptyList(), emptyList(), null, null, null) + emptyList(), emptyList(), null, null, null, null) + +fun isMediaNotification(sbn: StatusBarNotification): Boolean { + if (!sbn.notification.hasMediaSession()) { + return false + } + val notificationStyle = sbn.notification.notificationStyle + if (Notification.DecoratedMediaCustomViewStyle::class.java.equals(notificationStyle) || + Notification.MediaStyle::class.java.equals(notificationStyle)) { + return true + } + return false +} /** * A class that facilitates management and loading of Media Data, ready for binding. @@ -65,14 +77,14 @@ class MediaDataManager @Inject constructor( private val context: Context, private val mediaControllerFactory: MediaControllerFactory, @Background private val backgroundExecutor: Executor, - @Main private val foregroundExcecutor: Executor + @Main private val foregroundExecutor: Executor ) { private val listeners: MutableSet<Listener> = mutableSetOf() private val mediaEntries: LinkedHashMap<String, MediaData> = LinkedHashMap() fun onNotificationAdded(key: String, sbn: StatusBarNotification) { - if (isMediaNotification(sbn)) { + if (Utils.useQsMediaPlayer(context) && isMediaNotification(sbn)) { if (!mediaEntries.containsKey(key)) { mediaEntries.put(key, LOADING) } @@ -201,10 +213,10 @@ class MediaDataManager @Inject constructor( } } - foregroundExcecutor.execute { + foregroundExecutor.execute { onMediaDataLoaded(key, MediaData(true, bgColor, app, smallIconDrawable, artist, song, artWorkIcon, actionIcons, actionsToShowCollapsed, sbn.packageName, token, - notif.contentIntent)) + notif.contentIntent, null)) } } @@ -270,25 +282,10 @@ class MediaDataManager @Inject constructor( } } - private fun isMediaNotification(sbn: StatusBarNotification): Boolean { - if (!Utils.useQsMediaPlayer(context)) { - return false - } - if (!sbn.notification.hasMediaSession()) { - return false - } - val notificationStyle = sbn.notification.notificationStyle - if (Notification.DecoratedMediaCustomViewStyle::class.java.equals(notificationStyle) || - Notification.MediaStyle::class.java.equals(notificationStyle)) { - return true - } - return false - } - /** * Are there any media notifications active? */ - fun hasActiveMedia() = mediaEntries.size > 0 + fun hasActiveMedia() = mediaEntries.isNotEmpty() fun hasAnyMedia(): Boolean { // TODO: implement this when we implemented resumption diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaDeviceManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaDeviceManager.kt new file mode 100644 index 000000000000..2d16e2930365 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/media/MediaDeviceManager.kt @@ -0,0 +1,117 @@ +/* + * 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.media + +import android.content.Context +import android.service.notification.StatusBarNotification +import com.android.settingslib.media.LocalMediaManager +import com.android.settingslib.media.MediaDevice +import com.android.systemui.dagger.qualifiers.Main +import java.util.concurrent.Executor +import javax.inject.Inject +import javax.inject.Singleton + +/** + * Provides information about the route (ie. device) where playback is occurring. + */ +@Singleton +class MediaDeviceManager @Inject constructor( + private val context: Context, + private val localMediaManagerFactory: LocalMediaManagerFactory, + private val featureFlag: MediaFeatureFlag, + @Main private val fgExecutor: Executor +) { + private val listeners: MutableSet<Listener> = mutableSetOf() + private val entries: MutableMap<String, Token> = mutableMapOf() + + /** + * Add a listener for changes to the media route (ie. device). + */ + fun addListener(listener: Listener) = listeners.add(listener) + + /** + * Remove a listener that has been registered with addListener. + */ + fun removeListener(listener: Listener) = listeners.remove(listener) + + fun onNotificationAdded(key: String, sbn: StatusBarNotification) { + if (featureFlag.enabled && isMediaNotification(sbn)) { + var tok = entries[key] + if (tok == null) { + tok = Token(key, localMediaManagerFactory.create(sbn.packageName)) + entries[key] = tok + tok.start() + } + } else { + onNotificationRemoved(key) + } + } + + fun onNotificationRemoved(key: String) { + val token = entries.remove(key) + token?.stop() + token?.let { + listeners.forEach { + it.onKeyRemoved(key) + } + } + } + + private fun processDevice(key: String, device: MediaDevice?) { + val data = MediaDeviceData(device?.icon, device?.name) + listeners.forEach { + it.onMediaDeviceChanged(key, data) + } + } + + interface Listener { + /** Called when the route has changed for a given notification. */ + fun onMediaDeviceChanged(key: String, data: MediaDeviceData?) + /** Called when the notification was removed. */ + fun onKeyRemoved(key: String) + } + + private inner class Token( + val key: String, + val localMediaManager: LocalMediaManager + ) : LocalMediaManager.DeviceCallback { + private var current: MediaDevice? = null + set(value) { + if (value != field) { + field = value + processDevice(key, value) + } + } + fun start() { + localMediaManager.registerCallback(this) + localMediaManager.startScan() + current = localMediaManager.getCurrentConnectedDevice() + } + fun stop() { + localMediaManager.stopScan() + localMediaManager.unregisterCallback(this) + } + override fun onDeviceListUpdate(devices: List<MediaDevice>?) = fgExecutor.execute { + current = localMediaManager.getCurrentConnectedDevice() + } + override fun onSelectedDeviceStateChanged(device: MediaDevice, state: Int) { + fgExecutor.execute { + current = device + } + } + } +} diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaFeatureFlag.kt b/packages/SystemUI/src/com/android/systemui/media/MediaFeatureFlag.kt new file mode 100644 index 000000000000..75eb33da64d8 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/media/MediaFeatureFlag.kt @@ -0,0 +1,29 @@ +/* + * 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.media + +import android.content.Context +import com.android.systemui.util.Utils +import javax.inject.Inject + +/** + * Provides access to the current value of the feature flag. + */ +class MediaFeatureFlag @Inject constructor(private val context: Context) { + val enabled + get() = Utils.useQsMediaPlayer(context) +} diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaHost.kt b/packages/SystemUI/src/com/android/systemui/media/MediaHost.kt index 6e7b6bcb7502..240e44cb8db4 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaHost.kt +++ b/packages/SystemUI/src/com/android/systemui/media/MediaHost.kt @@ -26,8 +26,8 @@ class MediaHost @Inject constructor( /** * Get the current Media state. This also updates the location on screen */ - val currentState : MediaState - get () { + val currentState: MediaState + get() { hostView.getLocationOnScreen(tmpLocationOnScreen) var left = tmpLocationOnScreen[0] + hostView.paddingLeft var top = tmpLocationOnScreen[1] + hostView.paddingTop @@ -37,11 +37,11 @@ class MediaHost @Inject constructor( // the above could return negative widths, which is wrong if (right < left) { left = 0 - right = 0; + right = 0 } if (bottom < top) { bottom = 0 - top = 0; + top = 0 } state.boundsOnScreen.set(left, top, right, bottom) return state @@ -64,7 +64,7 @@ class MediaHost @Inject constructor( * transitions. */ fun init(@MediaLocation location: Int) { - this.location = location; + this.location = location hostView = mediaHierarchyManager.register(this) hostView.addOnAttachStateChangeListener(object : OnAttachStateChangeListener { override fun onViewAttachedToWindow(v: View?) { @@ -95,7 +95,7 @@ class MediaHost @Inject constructor( override var showsOnlyActiveMedia: Boolean = false override val boundsOnScreen: Rect = Rect() - override fun copy() : MediaState { + override fun copy(): MediaState { val mediaHostState = MediaHostState() mediaHostState.expansion = expansion mediaHostState.showsOnlyActiveMedia = showsOnlyActiveMedia @@ -104,7 +104,7 @@ class MediaHost @Inject constructor( return mediaHostState } - override fun interpolate(other: MediaState, amount: Float) : MediaState { + override fun interpolate(other: MediaState, amount: Float): MediaState { val result = MediaHostState() result.expansion = MathUtils.lerp(expansion, other.expansion, amount) val left = MathUtils.lerp(boundsOnScreen.left.toFloat(), @@ -121,10 +121,10 @@ class MediaHost @Inject constructor( if (other is MediaHostState) { result.measurementInput = other.measurementInput } - } else { + } else { result.measurementInput } - return result + return result } override fun getMeasuringInput(input: MeasurementInput): MediaMeasurementInput { @@ -138,8 +138,8 @@ interface MediaState { var expansion: Float var showsOnlyActiveMedia: Boolean val boundsOnScreen: Rect - fun copy() : MediaState - fun interpolate(other: MediaState, amount: Float) : MediaState + fun copy(): MediaState + fun interpolate(other: MediaState, amount: Float): MediaState fun getMeasuringInput(input: MeasurementInput): MediaMeasurementInput } /** @@ -147,7 +147,8 @@ interface MediaState { */ data class MediaMeasurementInput( private val viewInput: MeasurementInput, - val expansion: Float) : MeasurementInput by viewInput { + val expansion: Float +) : MeasurementInput by viewInput { override fun sameAs(input: MeasurementInput?): Boolean { if (!(input is MediaMeasurementInput)) { @@ -155,5 +156,4 @@ data class MediaMeasurementInput( } return width == input.width && expansion == input.expansion } -} - +}
\ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaViewManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaViewManager.kt index 8db9dcc1ecec..17e8404fe705 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaViewManager.kt +++ b/packages/SystemUI/src/com/android/systemui/media/MediaViewManager.kt @@ -6,9 +6,6 @@ import android.view.View import android.view.ViewGroup import android.widget.HorizontalScrollView import android.widget.LinearLayout -import com.android.settingslib.bluetooth.LocalBluetoothManager -import com.android.settingslib.media.InfoMediaManager -import com.android.settingslib.media.LocalMediaManager import com.android.systemui.R import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.dagger.qualifiers.Main @@ -30,10 +27,9 @@ class MediaViewManager @Inject constructor( private val context: Context, @Main private val foregroundExecutor: Executor, @Background private val backgroundExecutor: DelayableExecutor, - private val localBluetoothManager: LocalBluetoothManager?, private val visualStabilityManager: VisualStabilityManager, private val activityStarter: ActivityStarter, - mediaManager: MediaDataManager + mediaManager: MediaDataCombineLatest ) { private var playerWidth: Int = 0 private var playerWidthPlusPadding: Int = 0 @@ -42,7 +38,7 @@ class MediaViewManager @Inject constructor( val mediaCarousel: HorizontalScrollView private val mediaContent: ViewGroup private val mediaPlayers: MutableMap<String, MediaControlPanel> = mutableMapOf() - private val visualStabilityCallback : VisualStabilityManager.Callback + private val visualStabilityCallback: VisualStabilityManager.Callback private var activeMediaIndex: Int = 0 private var needsReordering: Boolean = false private var scrollIntoCurrentMedia: Int = 0 @@ -151,15 +147,8 @@ class MediaViewManager @Inject constructor( private fun updateView(key: String, data: MediaData) { var existingPlayer = mediaPlayers[key] if (existingPlayer == null) { - // Set up listener for device changes - // TODO: integrate with MediaTransferManager? - val imm = InfoMediaManager(context, data.packageName, - null /* notification */, localBluetoothManager) - val routeManager = LocalMediaManager(context, localBluetoothManager, - imm, data.packageName) - - existingPlayer = MediaControlPanel(context, routeManager, foregroundExecutor, - backgroundExecutor, activityStarter) + existingPlayer = MediaControlPanel(context, foregroundExecutor, backgroundExecutor, + activityStarter) existingPlayer.attach(PlayerViewHolder.create(LayoutInflater.from(context), mediaContent)) mediaPlayers[key] = existingPlayer diff --git a/packages/SystemUI/src/com/android/systemui/media/SeekBarObserver.kt b/packages/SystemUI/src/com/android/systemui/media/SeekBarObserver.kt index 110b08c4b808..cd8ed265bd53 100644 --- a/packages/SystemUI/src/com/android/systemui/media/SeekBarObserver.kt +++ b/packages/SystemUI/src/com/android/systemui/media/SeekBarObserver.kt @@ -16,58 +16,41 @@ package com.android.systemui.media -import android.content.res.ColorStateList -import android.graphics.Color import android.text.format.DateUtils -import android.view.View -import android.widget.SeekBar -import android.widget.TextView import androidx.annotation.UiThread import androidx.lifecycle.Observer -import com.android.systemui.R - /** * Observer for changes from SeekBarViewModel. * * <p>Updates the seek bar views in response to changes to the model. */ -class SeekBarObserver(view: View) : Observer<SeekBarViewModel.Progress> { - - private val seekBarView: SeekBar - private val elapsedTimeView: TextView - private val totalTimeView: TextView - - init { - seekBarView = view.findViewById(R.id.media_progress_bar) - elapsedTimeView = view.findViewById(R.id.media_elapsed_time) - totalTimeView = view.findViewById(R.id.media_total_time) - } +class SeekBarObserver(private val holder: PlayerViewHolder) : Observer<SeekBarViewModel.Progress> { /** Updates seek bar views when the data model changes. */ @UiThread override fun onChanged(data: SeekBarViewModel.Progress) { if (!data.enabled) { - seekBarView.setEnabled(false) - seekBarView.getThumb().setAlpha(0) - seekBarView.setProgress(0) - elapsedTimeView.setText("") - totalTimeView.setText("") + holder.seekBar.setEnabled(false) + holder.seekBar.getThumb().setAlpha(0) + holder.seekBar.setProgress(0) + holder.elapsedTimeView.setText("") + holder.totalTimeView.setText("") return } - seekBarView.getThumb().setAlpha(if (data.seekAvailable) 255 else 0) - seekBarView.setEnabled(data.seekAvailable) + holder.seekBar.getThumb().setAlpha(if (data.seekAvailable) 255 else 0) + holder.seekBar.setEnabled(data.seekAvailable) data.elapsedTime?.let { - seekBarView.setProgress(it) - elapsedTimeView.setText(DateUtils.formatElapsedTime( + holder.seekBar.setProgress(it) + holder.elapsedTimeView.setText(DateUtils.formatElapsedTime( it / DateUtils.SECOND_IN_MILLIS)) } data.duration?.let { - seekBarView.setMax(it) - totalTimeView.setText(DateUtils.formatElapsedTime( + holder.seekBar.setMax(it) + holder.totalTimeView.setText(DateUtils.formatElapsedTime( it / DateUtils.SECOND_IN_MILLIS)) } } diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java index 34a9e28b943a..b272b60f3593 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java +++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java @@ -842,7 +842,26 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis Log.e(TAG_OPS, "Failed to get overview proxy for assistant visibility."); } } catch (RemoteException e) { - Log.e(TAG_OPS, "Failed to call onAssistantVisibilityChanged()", e); + Log.e(TAG_OPS, "Failed to call notifyAssistantVisibilityChanged()", e); + } + } + + /** + * Notifies the Launcher of split screen size changes + * @param secondaryWindowBounds Bounds of the secondary window including the insets + * @param secondaryWindowInsets stable insets received by the secondary window + */ + public void notifySplitScreenBoundsChanged( + Rect secondaryWindowBounds, Rect secondaryWindowInsets) { + try { + if (mOverviewProxy != null) { + mOverviewProxy.onSplitScreenSecondaryBoundsChanged( + secondaryWindowBounds, secondaryWindowInsets); + } else { + Log.e(TAG_OPS, "Failed to get overview proxy for split screen bounds."); + } + } catch (RemoteException e) { + Log.e(TAG_OPS, "Failed to call onSplitScreenSecondaryBoundsChanged()", e); } } diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java b/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java index cdd1280dd86c..379bb9d247db 100644 --- a/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java +++ b/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java @@ -18,15 +18,10 @@ package com.android.systemui.stackdivider; import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; import static android.content.res.Configuration.ORIENTATION_LANDSCAPE; -import static android.content.res.Configuration.SCREEN_HEIGHT_DP_UNDEFINED; -import static android.content.res.Configuration.SCREEN_WIDTH_DP_UNDEFINED; import static android.view.Display.DEFAULT_DISPLAY; import static com.android.systemui.shared.system.WindowManagerWrapper.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY; -import android.animation.Animator; -import android.animation.AnimatorListenerAdapter; -import android.animation.ValueAnimator; import android.app.ActivityManager; import android.app.ActivityTaskManager; import android.content.Context; @@ -36,15 +31,11 @@ import android.os.Handler; import android.provider.Settings; import android.util.Slog; import android.view.LayoutInflater; -import android.view.SurfaceControl; import android.view.View; -import android.window.TaskOrganizer; import android.window.WindowContainerToken; import android.window.WindowContainerTransaction; import android.window.WindowOrganizer; -import androidx.annotation.Nullable; - import com.android.internal.policy.DividerSnapAlgorithm; import com.android.systemui.R; import com.android.systemui.SystemUI; @@ -81,7 +72,6 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks, static final boolean DEBUG = false; static final int DEFAULT_APP_TRANSITION_DURATION = 336; - static final float ADJUSTED_NONFOCUS_DIM = 0.3f; private final Optional<Lazy<Recents>> mRecentsOptionalLazy; @@ -139,303 +129,7 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks, } }; - private class DividerImeController implements DisplayImeController.ImePositionProcessor { - /** - * These are the y positions of the top of the IME surface when it is hidden and when it is - * shown respectively. These are NOT necessarily the top of the visible IME itself. - */ - private int mHiddenTop = 0; - private int mShownTop = 0; - - // The following are target states (what we are curretly animating towards). - /** - * {@code true} if, at the end of the animation, the split task positions should be - * adjusted by height of the IME. This happens when the secondary split is the IME target. - */ - private boolean mTargetAdjusted = false; - /** - * {@code true} if, at the end of the animation, the IME should be shown/visible - * regardless of what has focus. - */ - private boolean mTargetShown = false; - private float mTargetPrimaryDim = 0.f; - private float mTargetSecondaryDim = 0.f; - - // The following are the current (most recent) states set during animation - /** {@code true} if the secondary split has IME focus. */ - private boolean mSecondaryHasFocus = false; - /** The dimming currently applied to the primary/secondary splits. */ - private float mLastPrimaryDim = 0.f; - private float mLastSecondaryDim = 0.f; - /** The most recent y position of the top of the IME surface */ - private int mLastAdjustTop = -1; - - // The following are states reached last time an animation fully completed. - /** {@code true} if the IME was shown/visible by the last-completed animation. */ - private boolean mImeWasShown = false; - /** {@code true} if the split positions were adjusted by the last-completed animation. */ - private boolean mAdjusted = false; - - /** - * When some aspect of split-screen needs to animate independent from the IME, - * this will be non-null and control split animation. - */ - @Nullable - private ValueAnimator mAnimation = null; - - private boolean mPaused = true; - private boolean mPausedTargetAdjusted = false; - - private boolean getSecondaryHasFocus(int displayId) { - WindowContainerToken imeSplit = TaskOrganizer.getImeTarget(displayId); - return imeSplit != null - && (imeSplit.asBinder() == mSplits.mSecondary.token.asBinder()); - } - - private void updateDimTargets() { - final boolean splitIsVisible = !mView.isHidden(); - mTargetPrimaryDim = (mSecondaryHasFocus && mTargetShown && splitIsVisible) - ? ADJUSTED_NONFOCUS_DIM : 0.f; - mTargetSecondaryDim = (!mSecondaryHasFocus && mTargetShown && splitIsVisible) - ? ADJUSTED_NONFOCUS_DIM : 0.f; - } - - @Override - public void onImeStartPositioning(int displayId, int hiddenTop, int shownTop, - boolean imeShouldShow, SurfaceControl.Transaction t) { - if (!isDividerVisible()) { - return; - } - final boolean splitIsVisible = !mView.isHidden(); - mSecondaryHasFocus = getSecondaryHasFocus(displayId); - final boolean targetAdjusted = splitIsVisible && imeShouldShow && mSecondaryHasFocus - && !mSplitLayout.mDisplayLayout.isLandscape(); - mHiddenTop = hiddenTop; - mShownTop = shownTop; - mTargetShown = imeShouldShow; - if (mLastAdjustTop < 0) { - mLastAdjustTop = imeShouldShow ? hiddenTop : shownTop; - } else if (mLastAdjustTop != (imeShouldShow ? mShownTop : mHiddenTop)) { - if (mTargetAdjusted != targetAdjusted && targetAdjusted == mAdjusted) { - // Check for an "interruption" of an existing animation. In this case, we - // need to fake-flip the last-known state direction so that the animation - // completes in the other direction. - mAdjusted = mTargetAdjusted; - } else if (targetAdjusted && mTargetAdjusted && mAdjusted) { - // Already fully adjusted for IME, but IME height has changed; so, force-start - // an async animation to the new IME height. - mAdjusted = false; - } - } - if (mPaused) { - mPausedTargetAdjusted = targetAdjusted; - if (DEBUG) Slog.d(TAG, " ime starting but paused " + dumpState()); - return; - } - mTargetAdjusted = targetAdjusted; - updateDimTargets(); - if (DEBUG) Slog.d(TAG, " ime starting. vis:" + splitIsVisible + " " + dumpState()); - if (mAnimation != null || (mImeWasShown && imeShouldShow - && mTargetAdjusted != mAdjusted)) { - // We need to animate adjustment independently of the IME position, so - // start our own animation to drive adjustment. This happens when a - // different split's editor has gained focus while the IME is still visible. - startAsyncAnimation(); - } - if (splitIsVisible) { - // If split is hidden, we don't want to trigger any relayouts that would cause the - // divider to show again. - updateImeAdjustState(); - } - } - - private void updateImeAdjustState() { - // Reposition the server's secondary split position so that it evaluates - // insets properly. - WindowContainerTransaction wct = new WindowContainerTransaction(); - if (mTargetAdjusted) { - mSplitLayout.updateAdjustedBounds(mShownTop, mHiddenTop, mShownTop); - wct.setBounds(mSplits.mSecondary.token, mSplitLayout.mAdjustedSecondary); - // "Freeze" the configuration size so that the app doesn't get a config - // or relaunch. This is required because normally nav-bar contributes - // to configuration bounds (via nondecorframe). - Rect adjustAppBounds = new Rect(mSplits.mSecondary.configuration - .windowConfiguration.getAppBounds()); - adjustAppBounds.offset(0, mSplitLayout.mAdjustedSecondary.top - - mSplitLayout.mSecondary.top); - wct.setAppBounds(mSplits.mSecondary.token, adjustAppBounds); - wct.setScreenSizeDp(mSplits.mSecondary.token, - mSplits.mSecondary.configuration.screenWidthDp, - mSplits.mSecondary.configuration.screenHeightDp); - - wct.setBounds(mSplits.mPrimary.token, mSplitLayout.mAdjustedPrimary); - adjustAppBounds = new Rect(mSplits.mPrimary.configuration - .windowConfiguration.getAppBounds()); - adjustAppBounds.offset(0, mSplitLayout.mAdjustedPrimary.top - - mSplitLayout.mPrimary.top); - wct.setAppBounds(mSplits.mPrimary.token, adjustAppBounds); - wct.setScreenSizeDp(mSplits.mPrimary.token, - mSplits.mPrimary.configuration.screenWidthDp, - mSplits.mPrimary.configuration.screenHeightDp); - } else { - wct.setBounds(mSplits.mSecondary.token, mSplitLayout.mSecondary); - wct.setAppBounds(mSplits.mSecondary.token, null); - wct.setScreenSizeDp(mSplits.mSecondary.token, - SCREEN_WIDTH_DP_UNDEFINED, SCREEN_HEIGHT_DP_UNDEFINED); - wct.setBounds(mSplits.mPrimary.token, mSplitLayout.mPrimary); - wct.setAppBounds(mSplits.mPrimary.token, null); - wct.setScreenSizeDp(mSplits.mPrimary.token, - SCREEN_WIDTH_DP_UNDEFINED, SCREEN_HEIGHT_DP_UNDEFINED); - } - - WindowOrganizer.applyTransaction(wct); - - // Update all the adjusted-for-ime states - if (!mPaused) { - mView.setAdjustedForIme(mTargetShown, mTargetShown - ? DisplayImeController.ANIMATION_DURATION_SHOW_MS - : DisplayImeController.ANIMATION_DURATION_HIDE_MS); - } - setAdjustedForIme(mTargetShown && !mPaused); - } - - @Override - public void onImePositionChanged(int displayId, int imeTop, - SurfaceControl.Transaction t) { - if (mAnimation != null || !isDividerVisible() || mPaused) { - // Not synchronized with IME anymore, so return. - return; - } - final float fraction = ((float) imeTop - mHiddenTop) / (mShownTop - mHiddenTop); - final float progress = mTargetShown ? fraction : 1.f - fraction; - onProgress(progress, t); - } - - @Override - public void onImeEndPositioning(int displayId, boolean cancelled, - SurfaceControl.Transaction t) { - if (mAnimation != null || !isDividerVisible() || mPaused) { - // Not synchronized with IME anymore, so return. - return; - } - onEnd(cancelled, t); - } - - private void onProgress(float progress, SurfaceControl.Transaction t) { - if (mTargetAdjusted != mAdjusted && !mPaused) { - final float fraction = mTargetAdjusted ? progress : 1.f - progress; - mLastAdjustTop = (int) (fraction * mShownTop + (1.f - fraction) * mHiddenTop); - mSplitLayout.updateAdjustedBounds(mLastAdjustTop, mHiddenTop, mShownTop); - mView.resizeSplitSurfaces(t, mSplitLayout.mAdjustedPrimary, - mSplitLayout.mAdjustedSecondary); - } - final float invProg = 1.f - progress; - mView.setResizeDimLayer(t, true /* primary */, - mLastPrimaryDim * invProg + progress * mTargetPrimaryDim); - mView.setResizeDimLayer(t, false /* primary */, - mLastSecondaryDim * invProg + progress * mTargetSecondaryDim); - } - - private void onEnd(boolean cancelled, SurfaceControl.Transaction t) { - if (!cancelled) { - onProgress(1.f, t); - mAdjusted = mTargetAdjusted; - mImeWasShown = mTargetShown; - mLastAdjustTop = mAdjusted ? mShownTop : mHiddenTop; - mLastPrimaryDim = mTargetPrimaryDim; - mLastSecondaryDim = mTargetSecondaryDim; - } - } - - private void startAsyncAnimation() { - if (mAnimation != null) { - mAnimation.cancel(); - } - mAnimation = ValueAnimator.ofFloat(0.f, 1.f); - mAnimation.setDuration(DisplayImeController.ANIMATION_DURATION_SHOW_MS); - if (mTargetAdjusted != mAdjusted) { - final float fraction = - ((float) mLastAdjustTop - mHiddenTop) / (mShownTop - mHiddenTop); - final float progress = mTargetAdjusted ? fraction : 1.f - fraction; - mAnimation.setCurrentFraction(progress); - } - - mAnimation.addUpdateListener(animation -> { - SurfaceControl.Transaction t = mTransactionPool.acquire(); - float value = (float) animation.getAnimatedValue(); - onProgress(value, t); - t.apply(); - mTransactionPool.release(t); - }); - mAnimation.setInterpolator(DisplayImeController.INTERPOLATOR); - mAnimation.addListener(new AnimatorListenerAdapter() { - private boolean mCancel = false; - @Override - public void onAnimationCancel(Animator animation) { - mCancel = true; - } - @Override - public void onAnimationEnd(Animator animation) { - SurfaceControl.Transaction t = mTransactionPool.acquire(); - onEnd(mCancel, t); - t.apply(); - mTransactionPool.release(t); - mAnimation = null; - } - }); - mAnimation.start(); - } - - private String dumpState() { - return "top:" + mHiddenTop + "->" + mShownTop - + " adj:" + mAdjusted + "->" + mTargetAdjusted + "(" + mLastAdjustTop + ")" - + " shw:" + mImeWasShown + "->" + mTargetShown - + " dims:" + mLastPrimaryDim + "," + mLastSecondaryDim - + "->" + mTargetPrimaryDim + "," + mTargetSecondaryDim - + " shf:" + mSecondaryHasFocus + " desync:" + (mAnimation != null) - + " paus:" + mPaused + "[" + mPausedTargetAdjusted + "]"; - } - - /** Completely aborts/resets adjustment state */ - public void pause(int displayId) { - if (DEBUG) Slog.d(TAG, "ime pause posting " + dumpState()); - mHandler.post(() -> { - if (DEBUG) Slog.d(TAG, "ime pause run posted " + dumpState()); - if (mPaused) { - return; - } - mPaused = true; - mPausedTargetAdjusted = mTargetAdjusted; - mTargetAdjusted = false; - mTargetPrimaryDim = mTargetSecondaryDim = 0.f; - updateImeAdjustState(); - startAsyncAnimation(); - if (mAnimation != null) { - mAnimation.end(); - } - }); - } - - public void resume(int displayId) { - if (DEBUG) Slog.d(TAG, "ime resume posting " + dumpState()); - mHandler.post(() -> { - if (DEBUG) Slog.d(TAG, "ime resume run posted " + dumpState()); - if (!mPaused) { - return; - } - mPaused = false; - mTargetAdjusted = mPausedTargetAdjusted; - updateDimTargets(); - if ((mTargetAdjusted != mAdjusted) && !mMinimized && mView != null) { - // End unminimize animations since they conflict with adjustment animations. - mView.finishAnimations(); - } - updateImeAdjustState(); - startAsyncAnimation(); - }); - } - } - private final DividerImeController mImePositionProcessor = new DividerImeController(); + private final DividerImeController mImePositionProcessor; private TaskStackChangeListener mActivityRestartListener = new TaskStackChangeListener() { @Override @@ -465,6 +159,7 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks, mRecentsOptionalLazy = recentsOptionalLazy; mForcedResizableController = new ForcedResizableInfoActivityController(context, this); mTransactionPool = transactionPool; + mImePositionProcessor = new DividerImeController(mSplits, mTransactionPool, mHandler); } @Override @@ -830,6 +525,10 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks, } } + SplitDisplayLayout getSplitLayout() { + return mSplitLayout; + } + /** @return the container token for the secondary split root task. */ public WindowContainerToken getSecondaryRoot() { if (mSplits == null || mSplits.mSecondary == null) { diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerImeController.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerImeController.java new file mode 100644 index 000000000000..533fd5fa6352 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerImeController.java @@ -0,0 +1,368 @@ +/* + * 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.stackdivider; + +import static android.content.res.Configuration.SCREEN_HEIGHT_DP_UNDEFINED; +import static android.content.res.Configuration.SCREEN_WIDTH_DP_UNDEFINED; + +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; +import android.animation.ValueAnimator; +import android.graphics.Rect; +import android.os.Handler; +import android.util.Slog; +import android.view.SurfaceControl; +import android.window.TaskOrganizer; +import android.window.WindowContainerToken; +import android.window.WindowContainerTransaction; +import android.window.WindowOrganizer; + +import androidx.annotation.Nullable; + +import com.android.systemui.TransactionPool; +import com.android.systemui.wm.DisplayImeController; + +class DividerImeController implements DisplayImeController.ImePositionProcessor { + private static final String TAG = "DividerImeController"; + private static final boolean DEBUG = Divider.DEBUG; + + private static final float ADJUSTED_NONFOCUS_DIM = 0.3f; + + private final SplitScreenTaskOrganizer mSplits; + private final TransactionPool mTransactionPool; + private final Handler mHandler; + + /** + * These are the y positions of the top of the IME surface when it is hidden and when it is + * shown respectively. These are NOT necessarily the top of the visible IME itself. + */ + private int mHiddenTop = 0; + private int mShownTop = 0; + + // The following are target states (what we are curretly animating towards). + /** + * {@code true} if, at the end of the animation, the split task positions should be + * adjusted by height of the IME. This happens when the secondary split is the IME target. + */ + private boolean mTargetAdjusted = false; + /** + * {@code true} if, at the end of the animation, the IME should be shown/visible + * regardless of what has focus. + */ + private boolean mTargetShown = false; + private float mTargetPrimaryDim = 0.f; + private float mTargetSecondaryDim = 0.f; + + // The following are the current (most recent) states set during animation + /** {@code true} if the secondary split has IME focus. */ + private boolean mSecondaryHasFocus = false; + /** The dimming currently applied to the primary/secondary splits. */ + private float mLastPrimaryDim = 0.f; + private float mLastSecondaryDim = 0.f; + /** The most recent y position of the top of the IME surface */ + private int mLastAdjustTop = -1; + + // The following are states reached last time an animation fully completed. + /** {@code true} if the IME was shown/visible by the last-completed animation. */ + private boolean mImeWasShown = false; + /** {@code true} if the split positions were adjusted by the last-completed animation. */ + private boolean mAdjusted = false; + + /** + * When some aspect of split-screen needs to animate independent from the IME, + * this will be non-null and control split animation. + */ + @Nullable + private ValueAnimator mAnimation = null; + + private boolean mPaused = true; + private boolean mPausedTargetAdjusted = false; + + DividerImeController(SplitScreenTaskOrganizer splits, TransactionPool pool, Handler handler) { + mSplits = splits; + mTransactionPool = pool; + mHandler = handler; + } + + private DividerView getView() { + return mSplits.mDivider.getView(); + } + + private SplitDisplayLayout getLayout() { + return mSplits.mDivider.getSplitLayout(); + } + + private boolean isDividerVisible() { + return mSplits.mDivider.isDividerVisible(); + } + + private boolean getSecondaryHasFocus(int displayId) { + WindowContainerToken imeSplit = TaskOrganizer.getImeTarget(displayId); + return imeSplit != null + && (imeSplit.asBinder() == mSplits.mSecondary.token.asBinder()); + } + + private void updateDimTargets() { + final boolean splitIsVisible = !getView().isHidden(); + mTargetPrimaryDim = (mSecondaryHasFocus && mTargetShown && splitIsVisible) + ? ADJUSTED_NONFOCUS_DIM : 0.f; + mTargetSecondaryDim = (!mSecondaryHasFocus && mTargetShown && splitIsVisible) + ? ADJUSTED_NONFOCUS_DIM : 0.f; + } + + @Override + public void onImeStartPositioning(int displayId, int hiddenTop, int shownTop, + boolean imeShouldShow, SurfaceControl.Transaction t) { + if (!isDividerVisible()) { + return; + } + final boolean splitIsVisible = !getView().isHidden(); + mSecondaryHasFocus = getSecondaryHasFocus(displayId); + final boolean targetAdjusted = splitIsVisible && imeShouldShow && mSecondaryHasFocus + && !getLayout().mDisplayLayout.isLandscape(); + mHiddenTop = hiddenTop; + mShownTop = shownTop; + mTargetShown = imeShouldShow; + if (mLastAdjustTop < 0) { + mLastAdjustTop = imeShouldShow ? hiddenTop : shownTop; + } else if (mLastAdjustTop != (imeShouldShow ? mShownTop : mHiddenTop)) { + if (mTargetAdjusted != targetAdjusted && targetAdjusted == mAdjusted) { + // Check for an "interruption" of an existing animation. In this case, we + // need to fake-flip the last-known state direction so that the animation + // completes in the other direction. + mAdjusted = mTargetAdjusted; + } else if (targetAdjusted && mTargetAdjusted && mAdjusted) { + // Already fully adjusted for IME, but IME height has changed; so, force-start + // an async animation to the new IME height. + mAdjusted = false; + } + } + if (mPaused) { + mPausedTargetAdjusted = targetAdjusted; + if (DEBUG) Slog.d(TAG, " ime starting but paused " + dumpState()); + return; + } + mTargetAdjusted = targetAdjusted; + updateDimTargets(); + if (DEBUG) Slog.d(TAG, " ime starting. vis:" + splitIsVisible + " " + dumpState()); + if (mAnimation != null || (mImeWasShown && imeShouldShow + && mTargetAdjusted != mAdjusted)) { + // We need to animate adjustment independently of the IME position, so + // start our own animation to drive adjustment. This happens when a + // different split's editor has gained focus while the IME is still visible. + startAsyncAnimation(); + } + if (splitIsVisible) { + // If split is hidden, we don't want to trigger any relayouts that would cause the + // divider to show again. + updateImeAdjustState(); + } + } + + private void updateImeAdjustState() { + // Reposition the server's secondary split position so that it evaluates + // insets properly. + WindowContainerTransaction wct = new WindowContainerTransaction(); + final SplitDisplayLayout splitLayout = getLayout(); + if (mTargetAdjusted) { + splitLayout.updateAdjustedBounds(mShownTop, mHiddenTop, mShownTop); + wct.setBounds(mSplits.mSecondary.token, splitLayout.mAdjustedSecondary); + // "Freeze" the configuration size so that the app doesn't get a config + // or relaunch. This is required because normally nav-bar contributes + // to configuration bounds (via nondecorframe). + Rect adjustAppBounds = new Rect(mSplits.mSecondary.configuration + .windowConfiguration.getAppBounds()); + adjustAppBounds.offset(0, splitLayout.mAdjustedSecondary.top + - splitLayout.mSecondary.top); + wct.setAppBounds(mSplits.mSecondary.token, adjustAppBounds); + wct.setScreenSizeDp(mSplits.mSecondary.token, + mSplits.mSecondary.configuration.screenWidthDp, + mSplits.mSecondary.configuration.screenHeightDp); + + wct.setBounds(mSplits.mPrimary.token, splitLayout.mAdjustedPrimary); + adjustAppBounds = new Rect(mSplits.mPrimary.configuration + .windowConfiguration.getAppBounds()); + adjustAppBounds.offset(0, splitLayout.mAdjustedPrimary.top + - splitLayout.mPrimary.top); + wct.setAppBounds(mSplits.mPrimary.token, adjustAppBounds); + wct.setScreenSizeDp(mSplits.mPrimary.token, + mSplits.mPrimary.configuration.screenWidthDp, + mSplits.mPrimary.configuration.screenHeightDp); + } else { + wct.setBounds(mSplits.mSecondary.token, splitLayout.mSecondary); + wct.setAppBounds(mSplits.mSecondary.token, null); + wct.setScreenSizeDp(mSplits.mSecondary.token, + SCREEN_WIDTH_DP_UNDEFINED, SCREEN_HEIGHT_DP_UNDEFINED); + wct.setBounds(mSplits.mPrimary.token, splitLayout.mPrimary); + wct.setAppBounds(mSplits.mPrimary.token, null); + wct.setScreenSizeDp(mSplits.mPrimary.token, + SCREEN_WIDTH_DP_UNDEFINED, SCREEN_HEIGHT_DP_UNDEFINED); + } + + WindowOrganizer.applyTransaction(wct); + + // Update all the adjusted-for-ime states + if (!mPaused) { + final DividerView view = getView(); + if (view != null) { + view.setAdjustedForIme(mTargetShown, mTargetShown + ? DisplayImeController.ANIMATION_DURATION_SHOW_MS + : DisplayImeController.ANIMATION_DURATION_HIDE_MS); + } + } + mSplits.mDivider.setAdjustedForIme(mTargetShown && !mPaused); + } + + @Override + public void onImePositionChanged(int displayId, int imeTop, + SurfaceControl.Transaction t) { + if (mAnimation != null || !isDividerVisible() || mPaused) { + // Not synchronized with IME anymore, so return. + return; + } + final float fraction = ((float) imeTop - mHiddenTop) / (mShownTop - mHiddenTop); + final float progress = mTargetShown ? fraction : 1.f - fraction; + onProgress(progress, t); + } + + @Override + public void onImeEndPositioning(int displayId, boolean cancelled, + SurfaceControl.Transaction t) { + if (mAnimation != null || !isDividerVisible() || mPaused) { + // Not synchronized with IME anymore, so return. + return; + } + onEnd(cancelled, t); + } + + private void onProgress(float progress, SurfaceControl.Transaction t) { + final DividerView view = getView(); + if (mTargetAdjusted != mAdjusted && !mPaused) { + final SplitDisplayLayout splitLayout = getLayout(); + final float fraction = mTargetAdjusted ? progress : 1.f - progress; + mLastAdjustTop = (int) (fraction * mShownTop + (1.f - fraction) * mHiddenTop); + splitLayout.updateAdjustedBounds(mLastAdjustTop, mHiddenTop, mShownTop); + view.resizeSplitSurfaces(t, splitLayout.mAdjustedPrimary, + splitLayout.mAdjustedSecondary); + } + final float invProg = 1.f - progress; + view.setResizeDimLayer(t, true /* primary */, + mLastPrimaryDim * invProg + progress * mTargetPrimaryDim); + view.setResizeDimLayer(t, false /* primary */, + mLastSecondaryDim * invProg + progress * mTargetSecondaryDim); + } + + private void onEnd(boolean cancelled, SurfaceControl.Transaction t) { + if (!cancelled) { + onProgress(1.f, t); + mAdjusted = mTargetAdjusted; + mImeWasShown = mTargetShown; + mLastAdjustTop = mAdjusted ? mShownTop : mHiddenTop; + mLastPrimaryDim = mTargetPrimaryDim; + mLastSecondaryDim = mTargetSecondaryDim; + } + } + + private void startAsyncAnimation() { + if (mAnimation != null) { + mAnimation.cancel(); + } + mAnimation = ValueAnimator.ofFloat(0.f, 1.f); + mAnimation.setDuration(DisplayImeController.ANIMATION_DURATION_SHOW_MS); + if (mTargetAdjusted != mAdjusted) { + final float fraction = + ((float) mLastAdjustTop - mHiddenTop) / (mShownTop - mHiddenTop); + final float progress = mTargetAdjusted ? fraction : 1.f - fraction; + mAnimation.setCurrentFraction(progress); + } + + mAnimation.addUpdateListener(animation -> { + SurfaceControl.Transaction t = mTransactionPool.acquire(); + float value = (float) animation.getAnimatedValue(); + onProgress(value, t); + t.apply(); + mTransactionPool.release(t); + }); + mAnimation.setInterpolator(DisplayImeController.INTERPOLATOR); + mAnimation.addListener(new AnimatorListenerAdapter() { + private boolean mCancel = false; + @Override + public void onAnimationCancel(Animator animation) { + mCancel = true; + } + @Override + public void onAnimationEnd(Animator animation) { + SurfaceControl.Transaction t = mTransactionPool.acquire(); + onEnd(mCancel, t); + t.apply(); + mTransactionPool.release(t); + mAnimation = null; + } + }); + mAnimation.start(); + } + + private String dumpState() { + return "top:" + mHiddenTop + "->" + mShownTop + + " adj:" + mAdjusted + "->" + mTargetAdjusted + "(" + mLastAdjustTop + ")" + + " shw:" + mImeWasShown + "->" + mTargetShown + + " dims:" + mLastPrimaryDim + "," + mLastSecondaryDim + + "->" + mTargetPrimaryDim + "," + mTargetSecondaryDim + + " shf:" + mSecondaryHasFocus + " desync:" + (mAnimation != null) + + " paus:" + mPaused + "[" + mPausedTargetAdjusted + "]"; + } + + /** Completely aborts/resets adjustment state */ + public void pause(int displayId) { + if (DEBUG) Slog.d(TAG, "ime pause posting " + dumpState()); + mHandler.post(() -> { + if (DEBUG) Slog.d(TAG, "ime pause run posted " + dumpState()); + if (mPaused) { + return; + } + mPaused = true; + mPausedTargetAdjusted = mTargetAdjusted; + mTargetAdjusted = false; + mTargetPrimaryDim = mTargetSecondaryDim = 0.f; + updateImeAdjustState(); + startAsyncAnimation(); + if (mAnimation != null) { + mAnimation.end(); + } + }); + } + + public void resume(int displayId) { + if (DEBUG) Slog.d(TAG, "ime resume posting " + dumpState()); + mHandler.post(() -> { + if (DEBUG) Slog.d(TAG, "ime resume run posted " + dumpState()); + if (!mPaused) { + return; + } + mPaused = false; + mTargetAdjusted = mPausedTargetAdjusted; + updateDimTargets(); + final DividerView view = getView(); + if ((mTargetAdjusted != mAdjusted) && !mSplits.mDivider.isMinimized() && view != null) { + // End unminimize animations since they conflict with adjustment animations. + view.finishAnimations(); + } + updateImeAdjustState(); + startAsyncAnimation(); + }); + } +} diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java index db89cea385b7..8ca50cdddf71 100644 --- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java +++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java @@ -19,7 +19,6 @@ package com.android.systemui.stackdivider; import static android.view.PointerIcon.TYPE_HORIZONTAL_DOUBLE_ARROW; import static android.view.PointerIcon.TYPE_VERTICAL_DOUBLE_ARROW; import static android.view.WindowManager.DOCKED_RIGHT; -import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING; import android.animation.AnimationHandler; import android.animation.Animator; @@ -39,7 +38,6 @@ import android.os.RemoteException; import android.util.AttributeSet; import android.util.Slog; import android.view.Display; -import android.view.InsetsState; import android.view.MotionEvent; import android.view.PointerIcon; import android.view.SurfaceControl; @@ -48,10 +46,8 @@ import android.view.VelocityTracker; import android.view.View; import android.view.View.OnTouchListener; import android.view.ViewConfiguration; -import android.view.ViewRootImpl; import android.view.ViewTreeObserver.InternalInsetsInfo; import android.view.ViewTreeObserver.OnComputeInternalInsetsListener; -import android.view.WindowInsets; import android.view.WindowManager; import android.view.accessibility.AccessibilityNodeInfo; import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction; @@ -65,9 +61,10 @@ import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.policy.DividerSnapAlgorithm; import com.android.internal.policy.DividerSnapAlgorithm.SnapTarget; import com.android.internal.policy.DockedDividerUtils; +import com.android.systemui.Dependency; import com.android.systemui.Interpolators; import com.android.systemui.R; -import com.android.systemui.shared.system.WindowManagerWrapper; +import com.android.systemui.recents.OverviewProxyService; import com.android.systemui.statusbar.FlingAnimationUtils; import java.util.function.Consumer; @@ -120,7 +117,6 @@ public class DividerView extends FrameLayout implements OnTouchListener, private int mStartY; private int mStartPosition; private int mDockSide; - private final int[] mTempInt2 = new int[2]; private boolean mMoving; private int mTouchSlop; private boolean mBackgroundLifted; @@ -148,7 +144,6 @@ public class DividerView extends FrameLayout implements OnTouchListener, private FlingAnimationUtils mFlingAnimationUtils; private SplitDisplayLayout mSplitLayout; private DividerCallbacks mCallback; - private final Rect mStableInsets = new Rect(); private final AnimationHandler mAnimationHandler = new AnimationHandler(); private boolean mGrowRecents; @@ -336,29 +331,6 @@ public class DividerView extends FrameLayout implements OnTouchListener, } @Override - public WindowInsets onApplyWindowInsets(WindowInsets insets) { - if (isAttachedToWindow() - && ViewRootImpl.sNewInsetsMode == ViewRootImpl.NEW_INSETS_MODE_FULL) { - // Our window doesn't cover entire display, so we use the display frame to re-calculate - // the insets. - final InsetsState state = getWindowInsetsController().getState(); - insets = state.calculateInsets(state.getDisplayFrame(), - null /* ignoringVisibilityState */, insets.isRound(), - insets.shouldAlwaysConsumeSystemBars(), insets.getDisplayCutout(), - 0 /* legacySystemUiFlags */, - SOFT_INPUT_ADJUST_NOTHING, null /* typeSideMap */); - } - if (mStableInsets.left != insets.getStableInsetLeft() - || mStableInsets.top != insets.getStableInsetTop() - || mStableInsets.right != insets.getStableInsetRight() - || mStableInsets.bottom != insets.getStableInsetBottom()) { - mStableInsets.set(insets.getStableInsetLeft(), insets.getStableInsetTop(), - insets.getStableInsetRight(), insets.getStableInsetBottom()); - } - return super.onApplyWindowInsets(insets); - } - - @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); if (mFirstLayout) { @@ -381,6 +353,7 @@ public class DividerView extends FrameLayout implements OnTouchListener, if (changed) { mWindowManagerProxy.setTouchRegion(new Rect(mHandle.getLeft(), mHandle.getTop(), mHandle.getRight(), mHandle.getBottom())); + notifySplitScreenBoundsChanged(); } } @@ -405,19 +378,7 @@ public class DividerView extends FrameLayout implements OnTouchListener, } public Rect getNonMinimizedSplitScreenSecondaryBounds() { - calculateBoundsForPosition(mSnapTargetBeforeMinimized.position, - DockedDividerUtils.invertDockSide(mDockSide), mOtherTaskRect); - mOtherTaskRect.bottom -= mStableInsets.bottom; - switch (mDockSide) { - case WindowManager.DOCKED_LEFT: - mOtherTaskRect.top += mStableInsets.top; - mOtherTaskRect.right -= mStableInsets.right; - break; - case WindowManager.DOCKED_RIGHT: - mOtherTaskRect.top += mStableInsets.top; - mOtherTaskRect.left += mStableInsets.left; - break; - } + mOtherTaskRect.set(mSplitLayout.mSecondary); return mOtherTaskRect; } @@ -681,6 +642,7 @@ public class DividerView extends FrameLayout implements OnTouchListener, saveSnapTargetBeforeMinimized(saveTarget); } } + notifySplitScreenBoundsChanged(); }; anim.addListener(new AnimatorListenerAdapter() { @@ -713,6 +675,25 @@ public class DividerView extends FrameLayout implements OnTouchListener, return anim; } + private void notifySplitScreenBoundsChanged() { + mOtherTaskRect.set(mSplitLayout.mSecondary); + + mTmpRect.set(mSplitLayout.mDisplayLayout.stableInsets()); + switch (mSplitLayout.getPrimarySplitSide()) { + case WindowManager.DOCKED_LEFT: + mTmpRect.left = 0; + break; + case WindowManager.DOCKED_RIGHT: + mTmpRect.right = 0; + break; + case WindowManager.DOCKED_TOP: + mTmpRect.top = 0; + break; + } + Dependency.get(OverviewProxyService.class) + .notifySplitScreenBoundsChanged(mOtherTaskRect, mTmpRect); + } + private void cancelFlingAnimation() { if (mCurrentAnimator != null) { mCurrentAnimator.cancel(); @@ -846,8 +827,7 @@ public class DividerView extends FrameLayout implements OnTouchListener, mDockedStackMinimized = minimized; if (mSplitLayout.mDisplayLayout.rotation() != mDefaultDisplay.getRotation()) { // Splitscreen to minimize is about to starts after rotating landscape to seascape, - // update insets, display info and snap algorithm targets - WindowManagerWrapper.getInstance().getStableInsets(mStableInsets); + // update display info and snap algorithm targets repositionSnapTargetBeforeMinimized(); } if (mIsInMinimizeInteraction != minimized || mCurrentAnimator != null) { @@ -1149,7 +1129,7 @@ public class DividerView extends FrameLayout implements OnTouchListener, // Move a right-docked-app to line up with the divider while dragging it if (mDockSide == DOCKED_RIGHT) { - mDockedTaskRect.offset(Math.max(position, mStableInsets.left - mDividerSize) + mDockedTaskRect.offset(Math.max(position, -mDividerSize) - mDockedTaskRect.left + mDividerSize, 0); } resizeSplitSurfaces(t, mDockedRect, mDockedTaskRect, mOtherRect, @@ -1164,7 +1144,7 @@ public class DividerView extends FrameLayout implements OnTouchListener, // Move a docked app if from the right in position with the divider up to insets if (mDockSide == DOCKED_RIGHT) { - mDockedTaskRect.offset(Math.max(position, mStableInsets.left - mDividerSize) + mDockedTaskRect.offset(Math.max(position, -mDividerSize) - mDockedTaskRect.left + mDividerSize, 0); } calculateBoundsForPosition(taskPosition, DockedDividerUtils.invertDockSide(mDockSide), @@ -1180,7 +1160,7 @@ public class DividerView extends FrameLayout implements OnTouchListener, // Move a right-docked-app to line up with the divider while dragging it if (mDockSide == DOCKED_RIGHT) { - mDockedTaskRect.offset(position - mStableInsets.left + mDividerSize, 0); + mDockedTaskRect.offset(position + mDividerSize, 0); } resizeSplitSurfaces(t, mDockedRect, mDockedTaskRect, mOtherRect, mOtherTaskRect); } else if (taskPosition != TASK_POSITION_SAME) { @@ -1238,34 +1218,10 @@ public class DividerView extends FrameLayout implements OnTouchListener, float fraction = getSnapAlgorithm().calculateDismissingFraction(position); fraction = Math.max(0, Math.min(fraction, 1f)); fraction = DIM_INTERPOLATOR.getInterpolation(fraction); - if (hasInsetsAtDismissTarget(dismissTarget)) { - - // Less darkening with system insets. - fraction *= 0.8f; - } return fraction; } /** - * @return true if and only if there are system insets at the location of the dismiss target - */ - private boolean hasInsetsAtDismissTarget(SnapTarget dismissTarget) { - if (isHorizontalDivision()) { - if (dismissTarget == getSnapAlgorithm().getDismissStartTarget()) { - return mStableInsets.top != 0; - } else { - return mStableInsets.bottom != 0; - } - } else { - if (dismissTarget == getSnapAlgorithm().getDismissStartTarget()) { - return mStableInsets.left != 0; - } else { - return mStableInsets.right != 0; - } - } - } - - /** * When the snap target is dismissing one side, make sure that the dismissing side doesn't get * 0 size. */ diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java index 9f4932e74eaa..8ed69d8fb982 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java @@ -16,6 +16,7 @@ package com.android.systemui.statusbar; import static com.android.systemui.statusbar.StatusBarState.KEYGUARD; +import static com.android.systemui.statusbar.notification.NotificationEntryManager.UNDEFINED_DISMISS_REASON; import static com.android.systemui.statusbar.phone.StatusBar.DEBUG_MEDIA_FAKE_ARTWORK; import static com.android.systemui.statusbar.phone.StatusBar.ENABLE_LOCKSCREEN_WALLPAPER; import static com.android.systemui.statusbar.phone.StatusBar.SHOW_LOCKSCREEN_MEDIA_ARTWORK; @@ -44,8 +45,6 @@ import android.util.Log; import android.view.View; import android.widget.ImageView; -import androidx.annotation.NonNull; - import com.android.internal.config.sysui.SystemUiDeviceConfigFlags; import com.android.internal.statusbar.NotificationVisibility; import com.android.systemui.Dependency; @@ -53,8 +52,8 @@ import com.android.systemui.Dumpable; import com.android.systemui.Interpolators; import com.android.systemui.colorextraction.SysuiColorExtractor; import com.android.systemui.dagger.qualifiers.Main; -import com.android.systemui.media.MediaData; import com.android.systemui.media.MediaDataManager; +import com.android.systemui.media.MediaDeviceManager; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.dagger.StatusBarModule; import com.android.systemui.statusbar.notification.NotificationEntryListener; @@ -70,6 +69,7 @@ import com.android.systemui.statusbar.phone.StatusBar; import com.android.systemui.statusbar.policy.KeyguardStateController; import com.android.systemui.util.DeviceConfigProxy; import com.android.systemui.util.Utils; +import com.android.systemui.util.concurrency.DelayableExecutor; import java.io.FileDescriptor; import java.io.PrintWriter; @@ -79,7 +79,7 @@ import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Set; -import java.util.concurrent.Executor; +import java.util.concurrent.TimeUnit; import dagger.Lazy; @@ -90,6 +90,7 @@ import dagger.Lazy; public class NotificationMediaManager implements Dumpable { private static final String TAG = "NotificationMediaManager"; public static final boolean DEBUG_MEDIA = false; + private static final long PAUSED_MEDIA_TIMEOUT = TimeUnit.MINUTES.toMillis(10); private final StatusBarStateController mStatusBarStateController = Dependency.get(StatusBarStateController.class); @@ -106,6 +107,7 @@ public class NotificationMediaManager implements Dumpable { } private final NotificationEntryManager mEntryManager; + private final MediaDataManager mMediaDataManager; @Nullable private Lazy<NotificationShadeWindowController> mNotificationShadeWindowController; @@ -117,7 +119,7 @@ public class NotificationMediaManager implements Dumpable { @Nullable private LockscreenWallpaper mLockscreenWallpaper; - private final Executor mMainExecutor; + private final DelayableExecutor mMainExecutor; private final Context mContext; private final MediaSessionManager mMediaSessionManager; @@ -130,6 +132,7 @@ public class NotificationMediaManager implements Dumpable { private MediaController mMediaController; private String mMediaNotificationKey; private MediaMetadata mMediaMetadata; + private Runnable mMediaTimeoutCancellation; private BackDropView mBackdrop; private ImageView mBackdropFront; @@ -159,11 +162,36 @@ public class NotificationMediaManager implements Dumpable { if (DEBUG_MEDIA) { Log.v(TAG, "DEBUG_MEDIA: onPlaybackStateChanged: " + state); } + if (mMediaTimeoutCancellation != null) { + mMediaTimeoutCancellation.run(); + mMediaTimeoutCancellation = null; + } if (state != null) { if (!isPlaybackActive(state.getState())) { clearCurrentMediaNotification(); } findAndUpdateMediaNotifications(); + scheduleMediaTimeout(state); + } + } + + private void scheduleMediaTimeout(PlaybackState state) { + final NotificationEntry entry; + synchronized (mEntryManager) { + entry = mEntryManager.getActiveNotificationUnfiltered(mMediaNotificationKey); + } + if (entry != null) { + if (!isPlayingState(state.getState())) { + mMediaTimeoutCancellation = mMainExecutor.executeDelayed(() -> { + synchronized (mEntryManager) { + if (mMediaNotificationKey == null) { + return; + } + mEntryManager.removeNotification(mMediaNotificationKey, null, + UNDEFINED_DISMISS_REASON); + } + }, PAUSED_MEDIA_TIMEOUT); + } } } @@ -189,9 +217,10 @@ public class NotificationMediaManager implements Dumpable { NotificationEntryManager notificationEntryManager, MediaArtworkProcessor mediaArtworkProcessor, KeyguardBypassController keyguardBypassController, - @Main Executor mainExecutor, + @Main DelayableExecutor mainExecutor, DeviceConfigProxy deviceConfig, - MediaDataManager mediaDataManager) { + MediaDataManager mediaDataManager, + MediaDeviceManager mediaDeviceManager) { mContext = context; mMediaArtworkProcessor = mediaArtworkProcessor; mKeyguardBypassController = keyguardBypassController; @@ -205,17 +234,20 @@ public class NotificationMediaManager implements Dumpable { mNotificationShadeWindowController = notificationShadeWindowController; mEntryManager = notificationEntryManager; mMainExecutor = mainExecutor; + mMediaDataManager = mediaDataManager; notificationEntryManager.addNotificationEntryListener(new NotificationEntryListener() { @Override public void onPendingEntryAdded(NotificationEntry entry) { mediaDataManager.onNotificationAdded(entry.getKey(), entry.getSbn()); + mediaDeviceManager.onNotificationAdded(entry.getKey(), entry.getSbn()); } @Override public void onPreEntryUpdated(NotificationEntry entry) { mediaDataManager.onNotificationAdded(entry.getKey(), entry.getSbn()); + mediaDeviceManager.onNotificationAdded(entry.getKey(), entry.getSbn()); } @Override @@ -236,6 +268,7 @@ public class NotificationMediaManager implements Dumpable { int reason) { onNotificationRemoved(entry.getKey()); mediaDataManager.onNotificationRemoved(entry.getKey()); + mediaDeviceManager.onNotificationRemoved(entry.getKey()); } }); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/dagger/StatusBarDependenciesModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/dagger/StatusBarDependenciesModule.java index b08eb9fafe41..ac2a9c118672 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/dagger/StatusBarDependenciesModule.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/dagger/StatusBarDependenciesModule.java @@ -24,6 +24,7 @@ import com.android.internal.statusbar.IStatusBarService; import com.android.systemui.bubbles.BubbleController; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.media.MediaDataManager; +import com.android.systemui.media.MediaDeviceManager; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.ActionClickLogger; import com.android.systemui.statusbar.CommandQueue; @@ -47,6 +48,7 @@ import com.android.systemui.statusbar.phone.StatusBar; import com.android.systemui.statusbar.policy.RemoteInputUriController; import com.android.systemui.tracing.ProtoTracer; import com.android.systemui.util.DeviceConfigProxy; +import com.android.systemui.util.concurrency.DelayableExecutor; import java.util.concurrent.Executor; @@ -98,9 +100,10 @@ public interface StatusBarDependenciesModule { NotificationEntryManager notificationEntryManager, MediaArtworkProcessor mediaArtworkProcessor, KeyguardBypassController keyguardBypassController, - @Main Executor mainExecutor, + @Main DelayableExecutor mainExecutor, DeviceConfigProxy deviceConfigProxy, - MediaDataManager mediaDataManager) { + MediaDataManager mediaDataManager, + MediaDeviceManager mediaDeviceManager) { return new NotificationMediaManager( context, statusBarLazy, @@ -110,7 +113,8 @@ public interface StatusBarDependenciesModule { keyguardBypassController, mainExecutor, deviceConfigProxy, - mediaDataManager); + mediaDataManager, + mediaDeviceManager); } /** */ diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotifBindPipeline.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotifBindPipeline.java index 3ee267362bc0..90d30dcf38ab 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotifBindPipeline.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotifBindPipeline.java @@ -154,12 +154,14 @@ public final class NotifBindPipeline { * the real work once rather than repeatedly start and cancel it. */ private void requestPipelineRun(NotificationEntry entry) { + mLogger.logRequestPipelineRun(entry.getKey()); + final BindEntry bindEntry = getBindEntry(entry); if (bindEntry.row == null) { // Row is not managed yet but may be soon. Stop for now. + mLogger.logRequestPipelineRowNotSet(entry.getKey()); return; } - mLogger.logRequestPipelineRun(entry.getKey()); // Abort any existing pipeline run mStage.abortStage(entry, bindEntry.row); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotifBindPipelineLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotifBindPipelineLogger.kt index 199730427aec..f26598db27a5 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotifBindPipelineLogger.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotifBindPipelineLogger.kt @@ -18,6 +18,7 @@ package com.android.systemui.statusbar.notification.row import com.android.systemui.log.LogBuffer import com.android.systemui.log.LogLevel.INFO +import com.android.systemui.log.LogLevel.WARNING import com.android.systemui.log.dagger.NotificationLog import javax.inject.Inject @@ -48,6 +49,14 @@ class NotifBindPipelineLogger @Inject constructor( }) } + fun logRequestPipelineRowNotSet(notifKey: String) { + buffer.log(TAG, WARNING, { + str1 = notifKey + }, { + "Row is not set so pipeline will not run. notif = $str1" + }) + } + fun logStartPipeline(notifKey: String) { buffer.log(TAG, INFO, { str1 = notifKey diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java index e9849ec84987..9925909c3e16 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java @@ -64,6 +64,7 @@ import com.android.systemui.statusbar.policy.SmartReplyView; import java.io.FileDescriptor; import java.io.PrintWriter; +import java.util.ArrayList; /** * A frame layout containing the actual payload of the notification, including the contracted, @@ -518,9 +519,12 @@ public class NotificationContentView extends FrameLayout { protected void onVisibilityChanged(View changedView, int visibility) { super.onVisibilityChanged(changedView, visibility); updateVisibility(); - if (visibility != VISIBLE) { + if (visibility != VISIBLE && !mOnContentViewInactiveListeners.isEmpty()) { // View is no longer visible so all content views are inactive. - for (Runnable r : mOnContentViewInactiveListeners.values()) { + // Clone list as runnables may modify the list of listeners + ArrayList<Runnable> listeners = new ArrayList<>( + mOnContentViewInactiveListeners.values()); + for (Runnable r : listeners) { r.run(); } mOnContentViewInactiveListeners.clear(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java index 3db4b6f7ffbb..e33cc6027c4f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java @@ -5983,6 +5983,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd // ANIMATION_TYPE_ADD new AnimationFilter() + .animateAlpha() .animateHeight() .animateTopInset() .animateY() @@ -5991,6 +5992,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd // ANIMATION_TYPE_REMOVE new AnimationFilter() + .animateAlpha() .animateHeight() .animateTopInset() .animateY() diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java index a065b74bda99..2a4475bbe6b5 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java @@ -46,6 +46,8 @@ import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.dagger.qualifiers.DisplayId; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.dagger.qualifiers.UiBackground; +import com.android.systemui.media.MediaData; +import com.android.systemui.media.MediaDataManager; import com.android.systemui.qs.tiles.DndTile; import com.android.systemui.qs.tiles.RotationLockTile; import com.android.systemui.screenrecord.RecordingController; @@ -80,14 +82,14 @@ import javax.inject.Inject; */ public class PhoneStatusBarPolicy implements BluetoothController.Callback, - CommandQueue.Callbacks, - RotationLockControllerCallback, - Listener, - ZenModeController.Callback, - DeviceProvisionedListener, - KeyguardStateController.Callback, - LocationController.LocationChangeCallback, - RecordingController.RecordingStateChangeCallback { + CommandQueue.Callbacks, + RotationLockControllerCallback, + Listener, + ZenModeController.Callback, + DeviceProvisionedListener, + KeyguardStateController.Callback, + LocationController.LocationChangeCallback, + RecordingController.RecordingStateChangeCallback, MediaDataManager.Listener { private static final String TAG = "PhoneStatusBarPolicy"; private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); @@ -108,6 +110,7 @@ public class PhoneStatusBarPolicy private final String mSlotLocation; private final String mSlotSensorsOff; private final String mSlotScreenRecord; + private final String mSlotMedia; private final int mDisplayId; private final SharedPreferences mSharedPreferences; private final DateFormatUtil mDateFormatUtil; @@ -135,6 +138,7 @@ public class PhoneStatusBarPolicy private final SensorPrivacyController mSensorPrivacyController; private final RecordingController mRecordingController; private final RingerModeTracker mRingerModeTracker; + private final MediaDataManager mMediaDataManager; private boolean mZenVisible; private boolean mVolumeVisible; @@ -159,6 +163,7 @@ public class PhoneStatusBarPolicy SensorPrivacyController sensorPrivacyController, IActivityManager iActivityManager, AlarmManager alarmManager, UserManager userManager, RecordingController recordingController, + MediaDataManager mediaDataManager, @Nullable TelecomManager telecomManager, @DisplayId int displayId, @Main SharedPreferences sharedPreferences, DateFormatUtil dateFormatUtil, RingerModeTracker ringerModeTracker) { @@ -185,6 +190,7 @@ public class PhoneStatusBarPolicy mUiBgExecutor = uiBgExecutor; mTelecomManager = telecomManager; mRingerModeTracker = ringerModeTracker; + mMediaDataManager = mediaDataManager; mSlotCast = resources.getString(com.android.internal.R.string.status_bar_cast); mSlotHotspot = resources.getString(com.android.internal.R.string.status_bar_hotspot); @@ -202,6 +208,7 @@ public class PhoneStatusBarPolicy mSlotSensorsOff = resources.getString(com.android.internal.R.string.status_bar_sensors_off); mSlotScreenRecord = resources.getString( com.android.internal.R.string.status_bar_screen_record); + mSlotMedia = resources.getString(com.android.internal.R.string.status_bar_media); mDisplayId = displayId; mSharedPreferences = sharedPreferences; @@ -280,6 +287,11 @@ public class PhoneStatusBarPolicy mIconController.setIconVisibility(mSlotSensorsOff, mSensorPrivacyController.isSensorPrivacyEnabled()); + // play/pause icon when media is active + mIconController.setIcon(mSlotMedia, R.drawable.stat_sys_media, + mResources.getString(R.string.accessibility_media_active)); + mIconController.setIconVisibility(mSlotMedia, mMediaDataManager.hasActiveMedia()); + // screen record mIconController.setIcon(mSlotScreenRecord, R.drawable.stat_sys_screen_record, null); mIconController.setIconVisibility(mSlotScreenRecord, false); @@ -296,6 +308,7 @@ public class PhoneStatusBarPolicy mSensorPrivacyController.addCallback(mSensorPrivacyListener); mLocationController.addCallback(this); mRecordingController.addCallback(this); + mMediaDataManager.addListener(this); mCommandQueue.addCallback(this); } @@ -700,4 +713,18 @@ public class PhoneStatusBarPolicy if (DEBUG) Log.d(TAG, "screenrecord: hiding icon"); mHandler.post(() -> mIconController.setIconVisibility(mSlotScreenRecord, false)); } + + @Override + public void onMediaDataLoaded(String key, MediaData data) { + updateMediaIcon(); + } + + @Override + public void onMediaDataRemoved(String key) { + updateMediaIcon(); + } + + private void updateMediaIcon() { + mIconController.setIconVisibility(mSlotMedia, mMediaDataManager.hasActiveMedia()); + } } diff --git a/packages/SystemUI/src/com/android/systemui/wm/DisplayImeController.java b/packages/SystemUI/src/com/android/systemui/wm/DisplayImeController.java index c7e9accce093..2968b92f51b7 100644 --- a/packages/SystemUI/src/com/android/systemui/wm/DisplayImeController.java +++ b/packages/SystemUI/src/com/android/systemui/wm/DisplayImeController.java @@ -178,6 +178,7 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged ValueAnimator mAnimation = null; int mRotation = Surface.ROTATION_0; boolean mImeShowing = false; + final Rect mImeFrame = new Rect(); PerDisplay(int displayId, int initialRotation) { mDisplayId = displayId; @@ -254,8 +255,8 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged } } - private int imeTop(InsetsSource imeSource, float surfaceOffset) { - return imeSource.getFrame().top + (int) surfaceOffset; + private int imeTop(float surfaceOffset) { + return mImeFrame.top + (int) surfaceOffset; } private void startAnimation(final boolean show, final boolean forceRestart) { @@ -263,6 +264,11 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged if (imeSource == null || mImeSourceControl == null) { return; } + // Set frame, but only if the new frame isn't empty -- this maintains continuity + final Rect newFrame = imeSource.getFrame(); + if (newFrame.height() != 0) { + mImeFrame.set(newFrame); + } mHandler.post(() -> { if (DEBUG) { Slog.d(TAG, "Run startAnim show:" + show + " was:" @@ -284,7 +290,7 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged } final float defaultY = mImeSourceControl.getSurfacePosition().y; final float x = mImeSourceControl.getSurfacePosition().x; - final float hiddenY = defaultY + imeSource.getFrame().height(); + final float hiddenY = defaultY + mImeFrame.height(); final float shownY = defaultY; final float startY = show ? hiddenY : shownY; final float endY = show ? shownY : hiddenY; @@ -306,7 +312,7 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged SurfaceControl.Transaction t = mTransactionPool.acquire(); float value = (float) animation.getAnimatedValue(); t.setPosition(mImeSourceControl.getLeash(), x, value); - dispatchPositionChanged(mDisplayId, imeTop(imeSource, value), t); + dispatchPositionChanged(mDisplayId, imeTop(value), t); t.apply(); mTransactionPool.release(t); }); @@ -319,11 +325,11 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged t.setPosition(mImeSourceControl.getLeash(), x, startY); if (DEBUG) { Slog.d(TAG, "onAnimationStart d:" + mDisplayId + " top:" - + imeTop(imeSource, hiddenY) + "->" + imeTop(imeSource, shownY) + + imeTop(hiddenY) + "->" + imeTop(shownY) + " showing:" + (mAnimationDirection == DIRECTION_SHOW)); } - dispatchStartPositioning(mDisplayId, imeTop(imeSource, hiddenY), - imeTop(imeSource, shownY), mAnimationDirection == DIRECTION_SHOW, + dispatchStartPositioning(mDisplayId, imeTop(hiddenY), + imeTop(shownY), mAnimationDirection == DIRECTION_SHOW, t); if (mAnimationDirection == DIRECTION_SHOW) { t.show(mImeSourceControl.getLeash()); diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt new file mode 100644 index 000000000000..e8fb41a18ce9 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt @@ -0,0 +1,210 @@ +/* + * 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.media + +import android.content.res.ColorStateList +import android.graphics.Color +import android.graphics.drawable.GradientDrawable +import android.graphics.drawable.RippleDrawable +import android.media.MediaMetadata +import android.media.session.MediaSession +import android.media.session.PlaybackState +import android.testing.AndroidTestingRunner +import android.testing.TestableLooper +import android.view.ViewGroup +import android.widget.FrameLayout +import android.widget.ImageButton +import android.widget.ImageView +import android.widget.SeekBar +import android.widget.TextView + +import androidx.constraintlayout.motion.widget.MotionLayout +import androidx.constraintlayout.motion.widget.MotionScene +import androidx.constraintlayout.widget.ConstraintSet +import androidx.test.filters.SmallTest + +import com.android.systemui.R +import com.android.systemui.SysuiTestCase +import com.android.systemui.plugins.ActivityStarter +import com.android.systemui.util.concurrency.FakeExecutor +import com.android.systemui.util.time.FakeSystemClock + +import com.google.common.truth.Truth.assertThat + +import org.junit.After +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mock +import org.mockito.Mockito.mock +import org.mockito.Mockito.`when` as whenever + +import java.util.ArrayList + +private const val KEY = "TEST_KEY" +private const val APP = "APP" +private const val BG_COLOR = Color.RED +private const val PACKAGE = "PKG" +private const val ARTIST = "ARTIST" +private const val TITLE = "TITLE" +private const val DEVICE_NAME = "DEVICE_NAME" +private const val SESSION_KEY = "SESSION_KEY" +private const val SESSION_ARTIST = "SESSION_ARTIST" +private const val SESSION_TITLE = "SESSION_TITLE" + +@SmallTest +@RunWith(AndroidTestingRunner::class) +@TestableLooper.RunWithLooper(setAsMainLooper = true) +public class MediaControlPanelTest : SysuiTestCase() { + + private lateinit var player: MediaControlPanel + + private lateinit var fgExecutor: FakeExecutor + private lateinit var bgExecutor: FakeExecutor + @Mock private lateinit var activityStarter: ActivityStarter + + @Mock private lateinit var holder: PlayerViewHolder + @Mock private lateinit var motion: MotionLayout + private lateinit var background: TextView + private lateinit var appIcon: ImageView + private lateinit var appName: TextView + private lateinit var albumView: ImageView + private lateinit var titleText: TextView + private lateinit var artistText: TextView + private lateinit var seamless: ViewGroup + private lateinit var seamlessIcon: ImageView + private lateinit var seamlessText: TextView + private lateinit var seekBar: SeekBar + private lateinit var elapsedTimeView: TextView + private lateinit var totalTimeView: TextView + private lateinit var action0: ImageButton + private lateinit var action1: ImageButton + private lateinit var action2: ImageButton + private lateinit var action3: ImageButton + private lateinit var action4: ImageButton + + private lateinit var session: MediaSession + + @Before + fun setUp() { + fgExecutor = FakeExecutor(FakeSystemClock()) + bgExecutor = FakeExecutor(FakeSystemClock()) + + activityStarter = mock(ActivityStarter::class.java) + + player = MediaControlPanel(context, fgExecutor, bgExecutor, activityStarter) + + // Mock out a view holder for the player to attach to. + holder = mock(PlayerViewHolder::class.java) + motion = mock(MotionLayout::class.java) + val trans: ArrayList<MotionScene.Transition> = ArrayList() + trans.add(mock(MotionScene.Transition::class.java)) + whenever(motion.definedTransitions).thenReturn(trans) + val constraintSet = mock(ConstraintSet::class.java) + whenever(motion.getConstraintSet(R.id.expanded)).thenReturn(constraintSet) + whenever(motion.getConstraintSet(R.id.collapsed)).thenReturn(constraintSet) + whenever(holder.player).thenReturn(motion) + background = TextView(context) + whenever(holder.background).thenReturn(background) + appIcon = ImageView(context) + whenever(holder.appIcon).thenReturn(appIcon) + appName = TextView(context) + whenever(holder.appName).thenReturn(appName) + albumView = ImageView(context) + whenever(holder.albumView).thenReturn(albumView) + titleText = TextView(context) + whenever(holder.titleText).thenReturn(titleText) + artistText = TextView(context) + whenever(holder.artistText).thenReturn(artistText) + seamless = FrameLayout(context) + val seamlessBackground = mock(RippleDrawable::class.java) + seamless.setBackground(seamlessBackground) + whenever(seamlessBackground.getDrawable(0)).thenReturn(mock(GradientDrawable::class.java)) + whenever(holder.seamless).thenReturn(seamless) + seamlessIcon = ImageView(context) + whenever(holder.seamlessIcon).thenReturn(seamlessIcon) + seamlessText = TextView(context) + whenever(holder.seamlessText).thenReturn(seamlessText) + seekBar = SeekBar(context) + whenever(holder.seekBar).thenReturn(seekBar) + elapsedTimeView = TextView(context) + whenever(holder.elapsedTimeView).thenReturn(elapsedTimeView) + totalTimeView = TextView(context) + whenever(holder.totalTimeView).thenReturn(totalTimeView) + action0 = ImageButton(context) + whenever(holder.action0).thenReturn(action0) + action1 = ImageButton(context) + whenever(holder.action1).thenReturn(action1) + action2 = ImageButton(context) + whenever(holder.action2).thenReturn(action2) + action3 = ImageButton(context) + whenever(holder.action3).thenReturn(action3) + action4 = ImageButton(context) + whenever(holder.action4).thenReturn(action4) + + // Create media session + val metadataBuilder = MediaMetadata.Builder().apply { + putString(MediaMetadata.METADATA_KEY_ARTIST, SESSION_ARTIST) + putString(MediaMetadata.METADATA_KEY_TITLE, SESSION_TITLE) + } + val playbackBuilder = PlaybackState.Builder().apply { + setState(PlaybackState.STATE_PAUSED, 6000L, 1f) + setActions(PlaybackState.ACTION_PLAY) + } + session = MediaSession(context, SESSION_KEY).apply { + setMetadata(metadataBuilder.build()) + setPlaybackState(playbackBuilder.build()) + } + session.setActive(true) + } + + @After + fun tearDown() { + session.release() + player.onDestroy() + } + + @Test + fun bindWhenUnattached() { + val state = MediaData(true, BG_COLOR, APP, null, ARTIST, TITLE, null, emptyList(), + emptyList(), PACKAGE, null, null, MediaDeviceData(null, DEVICE_NAME)) + player.bind(state) + assertThat(player.isPlaying()).isFalse() + } + + @Test + fun bindText() { + player.attach(holder) + val state = MediaData(true, BG_COLOR, APP, null, ARTIST, TITLE, null, emptyList(), + emptyList(), PACKAGE, session.getSessionToken(), null, + MediaDeviceData(null, DEVICE_NAME)) + player.bind(state) + assertThat(appName.getText()).isEqualTo(APP) + assertThat(titleText.getText()).isEqualTo(TITLE) + assertThat(artistText.getText()).isEqualTo(ARTIST) + } + + @Test + fun bindBackgroundColor() { + player.attach(holder) + val state = MediaData(true, BG_COLOR, APP, null, ARTIST, TITLE, null, emptyList(), + emptyList(), PACKAGE, session.getSessionToken(), null, + MediaDeviceData(null, DEVICE_NAME)) + player.bind(state) + assertThat(background.getBackgroundTintList()).isEqualTo(ColorStateList.valueOf(BG_COLOR)) + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataCombineLatestTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataCombineLatestTest.java new file mode 100644 index 000000000000..64a180f8aaab --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataCombineLatestTest.java @@ -0,0 +1,161 @@ +/* + * 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.media; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; + +import android.graphics.Color; +import android.testing.AndroidTestingRunner; +import android.testing.TestableLooper; + +import androidx.test.filters.SmallTest; + +import com.android.systemui.SysuiTestCase; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; + +import java.util.ArrayList; + +@SmallTest +@RunWith(AndroidTestingRunner.class) +@TestableLooper.RunWithLooper +public class MediaDataCombineLatestTest extends SysuiTestCase { + + private static final String KEY = "TEST_KEY"; + private static final String APP = "APP"; + private static final String PACKAGE = "PKG"; + private static final int BG_COLOR = Color.RED; + private static final String ARTIST = "ARTIST"; + private static final String TITLE = "TITLE"; + private static final String DEVICE_NAME = "DEVICE_NAME"; + + private MediaDataCombineLatest mManager; + + @Mock private MediaDataManager mDataSource; + @Mock private MediaDeviceManager mDeviceSource; + @Mock private MediaDataManager.Listener mListener; + + private MediaDataManager.Listener mDataListener; + private MediaDeviceManager.Listener mDeviceListener; + + private MediaData mMediaData; + private MediaDeviceData mDeviceData; + + @Before + public void setUp() { + mDataSource = mock(MediaDataManager.class); + mDeviceSource = mock(MediaDeviceManager.class); + mListener = mock(MediaDataManager.Listener.class); + + mManager = new MediaDataCombineLatest(mDataSource, mDeviceSource); + + mDataListener = captureDataListener(); + mDeviceListener = captureDeviceListener(); + + mManager.addListener(mListener); + + mMediaData = new MediaData(true, BG_COLOR, APP, null, ARTIST, TITLE, null, + new ArrayList<>(), new ArrayList<>(), PACKAGE, null, null, null); + mDeviceData = new MediaDeviceData(null, DEVICE_NAME); + } + + @Test + public void eventNotEmittedWithoutDevice() { + // WHEN data source emits an event without device data + mDataListener.onMediaDataLoaded(KEY, mMediaData); + // THEN an event isn't emitted + verify(mListener, never()).onMediaDataLoaded(eq(KEY), any()); + } + + @Test + public void eventNotEmittedWithoutMedia() { + // WHEN device source emits an event without media data + mDeviceListener.onMediaDeviceChanged(KEY, mDeviceData); + // THEN an event isn't emitted + verify(mListener, never()).onMediaDataLoaded(eq(KEY), any()); + } + + @Test + public void emitEventAfterDeviceFirst() { + // GIVEN that a device event has already been received + mDeviceListener.onMediaDeviceChanged(KEY, mDeviceData); + // WHEN media event is received + mDataListener.onMediaDataLoaded(KEY, mMediaData); + // THEN the listener receives a combined event + ArgumentCaptor<MediaData> captor = ArgumentCaptor.forClass(MediaData.class); + verify(mListener).onMediaDataLoaded(eq(KEY), captor.capture()); + assertThat(captor.getValue().getDevice()).isNotNull(); + } + + @Test + public void emitEventAfterMediaFirst() { + // GIVEN that media event has already been received + mDataListener.onMediaDataLoaded(KEY, mMediaData); + // WHEN device event is received + mDeviceListener.onMediaDeviceChanged(KEY, mDeviceData); + // THEN the listener receives a combined event + ArgumentCaptor<MediaData> captor = ArgumentCaptor.forClass(MediaData.class); + verify(mListener).onMediaDataLoaded(eq(KEY), captor.capture()); + assertThat(captor.getValue().getDevice()).isNotNull(); + } + + @Test + public void mediaDataRemoved() { + // WHEN media data is removed without first receiving device or data + mDataListener.onMediaDataRemoved(KEY); + // THEN a removed event isn't emitted + verify(mListener, never()).onMediaDataRemoved(eq(KEY)); + } + + @Test + public void mediaDataRemovedAfterMediaEvent() { + mDataListener.onMediaDataLoaded(KEY, mMediaData); + mDataListener.onMediaDataRemoved(KEY); + verify(mListener).onMediaDataRemoved(eq(KEY)); + } + + @Test + public void mediaDataRemovedAfterDeviceEvent() { + mDeviceListener.onMediaDeviceChanged(KEY, mDeviceData); + mDataListener.onMediaDataRemoved(KEY); + verify(mListener).onMediaDataRemoved(eq(KEY)); + } + + private MediaDataManager.Listener captureDataListener() { + ArgumentCaptor<MediaDataManager.Listener> captor = ArgumentCaptor.forClass( + MediaDataManager.Listener.class); + verify(mDataSource).addListener(captor.capture()); + return captor.getValue(); + } + + private MediaDeviceManager.Listener captureDeviceListener() { + ArgumentCaptor<MediaDeviceManager.Listener> captor = ArgumentCaptor.forClass( + MediaDeviceManager.Listener.class); + verify(mDeviceSource).addListener(captor.capture()); + return captor.getValue(); + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDeviceManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDeviceManagerTest.kt new file mode 100644 index 000000000000..ac6b5f6bca66 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDeviceManagerTest.kt @@ -0,0 +1,195 @@ +/* + * 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.media + +import android.app.Notification +import android.media.MediaMetadata +import android.media.session.MediaSession +import android.media.session.PlaybackState +import android.os.Process +import android.service.notification.StatusBarNotification +import android.testing.AndroidTestingRunner +import android.testing.TestableLooper +import androidx.test.filters.SmallTest + +import com.android.settingslib.media.LocalMediaManager +import com.android.settingslib.media.MediaDevice +import com.android.systemui.SysuiTestCase +import com.android.systemui.util.concurrency.FakeExecutor +import com.android.systemui.util.time.FakeSystemClock + +import com.google.common.truth.Truth.assertThat + +import org.junit.After +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.ArgumentCaptor +import org.mockito.Mock +import org.mockito.Mockito +import org.mockito.Mockito.any +import org.mockito.Mockito.mock +import org.mockito.Mockito.never +import org.mockito.Mockito.verify +import org.mockito.Mockito.`when` as whenever + +private const val KEY = "TEST_KEY" +private const val PACKAGE = "PKG" +private const val SESSION_KEY = "SESSION_KEY" +private const val SESSION_ARTIST = "SESSION_ARTIST" +private const val SESSION_TITLE = "SESSION_TITLE" +private const val DEVICE_NAME = "DEVICE_NAME" + +private fun <T> eq(value: T): T = Mockito.eq(value) ?: value + +@SmallTest +@RunWith(AndroidTestingRunner::class) +@TestableLooper.RunWithLooper +public class MediaDeviceManagerTest : SysuiTestCase() { + + private lateinit var manager: MediaDeviceManager + + @Mock private lateinit var lmmFactory: LocalMediaManagerFactory + @Mock private lateinit var lmm: LocalMediaManager + @Mock private lateinit var featureFlag: MediaFeatureFlag + private lateinit var fakeExecutor: FakeExecutor + + @Mock private lateinit var device: MediaDevice + private lateinit var session: MediaSession + private lateinit var metadataBuilder: MediaMetadata.Builder + private lateinit var playbackBuilder: PlaybackState.Builder + private lateinit var notifBuilder: Notification.Builder + private lateinit var sbn: StatusBarNotification + + @Before + fun setup() { + lmmFactory = mock(LocalMediaManagerFactory::class.java) + lmm = mock(LocalMediaManager::class.java) + device = mock(MediaDevice::class.java) + whenever(device.name).thenReturn(DEVICE_NAME) + whenever(lmmFactory.create(PACKAGE)).thenReturn(lmm) + whenever(lmm.getCurrentConnectedDevice()).thenReturn(device) + featureFlag = mock(MediaFeatureFlag::class.java) + whenever(featureFlag.enabled).thenReturn(true) + + fakeExecutor = FakeExecutor(FakeSystemClock()) + + manager = MediaDeviceManager(context, lmmFactory, featureFlag, fakeExecutor) + + // Create a media sesssion and notification for testing. + metadataBuilder = MediaMetadata.Builder().apply { + putString(MediaMetadata.METADATA_KEY_ARTIST, SESSION_ARTIST) + putString(MediaMetadata.METADATA_KEY_TITLE, SESSION_TITLE) + } + playbackBuilder = PlaybackState.Builder().apply { + setState(PlaybackState.STATE_PAUSED, 6000L, 1f) + setActions(PlaybackState.ACTION_PLAY) + } + session = MediaSession(context, SESSION_KEY).apply { + setMetadata(metadataBuilder.build()) + setPlaybackState(playbackBuilder.build()) + } + session.setActive(true) + notifBuilder = Notification.Builder(context, "NONE").apply { + setContentTitle(SESSION_TITLE) + setContentText(SESSION_ARTIST) + setSmallIcon(android.R.drawable.ic_media_pause) + setStyle(Notification.MediaStyle().setMediaSession(session.getSessionToken())) + } + sbn = StatusBarNotification(PACKAGE, PACKAGE, 0, "TAG", Process.myUid(), 0, 0, + notifBuilder.build(), Process.myUserHandle(), 0) + } + + @After + fun tearDown() { + session.release() + } + + @Test + fun removeUnknown() { + manager.onNotificationRemoved("unknown") + } + + @Test + fun addNotification() { + manager.onNotificationAdded(KEY, sbn) + verify(lmmFactory).create(PACKAGE) + } + + @Test + fun featureDisabled() { + whenever(featureFlag.enabled).thenReturn(false) + manager.onNotificationAdded(KEY, sbn) + verify(lmmFactory, never()).create(PACKAGE) + } + + @Test + fun addAndRemoveNotification() { + manager.onNotificationAdded(KEY, sbn) + manager.onNotificationRemoved(KEY) + verify(lmm).unregisterCallback(any()) + } + + @Test + fun deviceListUpdate() { + val listener = mock(MediaDeviceManager.Listener::class.java) + manager.addListener(listener) + manager.onNotificationAdded(KEY, sbn) + val deviceCallback = captureCallback() + // WHEN the device list changes + deviceCallback.onDeviceListUpdate(mutableListOf(device)) + assertThat(fakeExecutor.runAllReady()).isEqualTo(1) + // THEN the update is dispatched to the listener + val captor = ArgumentCaptor.forClass(MediaDeviceData::class.java) + verify(listener).onMediaDeviceChanged(eq(KEY), captor.capture()) + val data = captor.getValue() + assertThat(data.name).isEqualTo(DEVICE_NAME) + } + + @Test + fun selectedDeviceStateChanged() { + val listener = mock(MediaDeviceManager.Listener::class.java) + manager.addListener(listener) + manager.onNotificationAdded(KEY, sbn) + val deviceCallback = captureCallback() + // WHEN the selected device changes state + deviceCallback.onSelectedDeviceStateChanged(device, 1) + assertThat(fakeExecutor.runAllReady()).isEqualTo(1) + // THEN the update is dispatched to the listener + val captor = ArgumentCaptor.forClass(MediaDeviceData::class.java) + verify(listener).onMediaDeviceChanged(eq(KEY), captor.capture()) + val data = captor.getValue() + assertThat(data.name).isEqualTo(DEVICE_NAME) + } + + @Test + fun listenerReceivesKeyRemoved() { + manager.onNotificationAdded(KEY, sbn) + val listener = mock(MediaDeviceManager.Listener::class.java) + manager.addListener(listener) + // WHEN the notification is removed + manager.onNotificationRemoved(KEY) + // THEN the listener receives key removed event + verify(listener).onKeyRemoved(eq(KEY)) + } + + fun captureCallback(): LocalMediaManager.DeviceCallback { + val captor = ArgumentCaptor.forClass(LocalMediaManager.DeviceCallback::class.java) + verify(lmm).registerCallback(captor.capture()) + return captor.getValue() + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/SeekBarObserverTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/SeekBarObserverTest.kt index 58ee79e39279..75018df023cc 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/SeekBarObserverTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/media/SeekBarObserverTest.kt @@ -22,7 +22,6 @@ import android.view.View import android.widget.SeekBar import android.widget.TextView import androidx.test.filters.SmallTest -import com.android.systemui.R import com.android.systemui.SysuiTestCase import com.google.common.truth.Truth.assertThat import org.junit.Before @@ -38,23 +37,21 @@ import org.mockito.Mockito.`when` as whenever public class SeekBarObserverTest : SysuiTestCase() { private lateinit var observer: SeekBarObserver - @Mock private lateinit var mockView: View + @Mock private lateinit var mockHolder: PlayerViewHolder private lateinit var seekBarView: SeekBar private lateinit var elapsedTimeView: TextView private lateinit var totalTimeView: TextView @Before fun setUp() { - mockView = mock(View::class.java) + mockHolder = mock(PlayerViewHolder::class.java) seekBarView = SeekBar(context) elapsedTimeView = TextView(context) totalTimeView = TextView(context) - whenever<SeekBar>( - mockView.findViewById(R.id.media_progress_bar)).thenReturn(seekBarView) - whenever<TextView>( - mockView.findViewById(R.id.media_elapsed_time)).thenReturn(elapsedTimeView) - whenever<TextView>(mockView.findViewById(R.id.media_total_time)).thenReturn(totalTimeView) - observer = SeekBarObserver(mockView) + whenever(mockHolder.seekBar).thenReturn(seekBarView) + whenever(mockHolder.elapsedTimeView).thenReturn(elapsedTimeView) + whenever(mockHolder.totalTimeView).thenReturn(totalTimeView) + observer = SeekBarObserver(mockHolder) } @Test diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicyTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicyTest.java new file mode 100644 index 000000000000..a14d57556360 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicyTest.java @@ -0,0 +1,168 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.statusbar.phone; + +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.clearInvocations; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.app.AlarmManager; +import android.app.IActivityManager; +import android.content.SharedPreferences; +import android.content.res.Resources; +import android.os.UserManager; +import android.telecom.TelecomManager; +import android.testing.AndroidTestingRunner; +import android.testing.TestableLooper; + +import androidx.test.filters.SmallTest; + +import com.android.systemui.SysuiTestCase; +import com.android.systemui.broadcast.BroadcastDispatcher; +import com.android.systemui.media.MediaDataManager; +import com.android.systemui.screenrecord.RecordingController; +import com.android.systemui.statusbar.CommandQueue; +import com.android.systemui.statusbar.policy.BluetoothController; +import com.android.systemui.statusbar.policy.CastController; +import com.android.systemui.statusbar.policy.DataSaverController; +import com.android.systemui.statusbar.policy.DeviceProvisionedController; +import com.android.systemui.statusbar.policy.HotspotController; +import com.android.systemui.statusbar.policy.KeyguardStateController; +import com.android.systemui.statusbar.policy.LocationController; +import com.android.systemui.statusbar.policy.NextAlarmController; +import com.android.systemui.statusbar.policy.RotationLockController; +import com.android.systemui.statusbar.policy.SensorPrivacyController; +import com.android.systemui.statusbar.policy.UserInfoController; +import com.android.systemui.statusbar.policy.ZenModeController; +import com.android.systemui.util.RingerModeLiveData; +import com.android.systemui.util.RingerModeTracker; +import com.android.systemui.util.time.DateFormatUtil; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; + +import java.util.concurrent.Executor; + +@RunWith(AndroidTestingRunner.class) +@TestableLooper.RunWithLooper +@SmallTest +public class PhoneStatusBarPolicyTest extends SysuiTestCase { + + private static final int DISPLAY_ID = 0; + @Mock + private StatusBarIconController mIconController; + @Mock + private CommandQueue mCommandQueue; + @Mock + private BroadcastDispatcher mBroadcastDispatcher; + @Mock + private Executor mBackgroundExecutor; + @Mock + private CastController mCastController; + @Mock + private HotspotController mHotSpotController; + @Mock + private BluetoothController mBluetoothController; + @Mock + private NextAlarmController mNextAlarmController; + @Mock + private UserInfoController mUserInfoController; + @Mock + private RotationLockController mRotationLockController; + @Mock + private DataSaverController mDataSaverController; + @Mock + private ZenModeController mZenModeController; + @Mock + private DeviceProvisionedController mDeviceProvisionerController; + @Mock + private KeyguardStateController mKeyguardStateController; + @Mock + private LocationController mLocationController; + @Mock + private SensorPrivacyController mSensorPrivacyController; + @Mock + private IActivityManager mIActivityManager; + @Mock + private AlarmManager mAlarmManager; + @Mock + private UserManager mUserManager; + @Mock + private RecordingController mRecordingController; + @Mock + private MediaDataManager mMediaDataManager; + @Mock + private TelecomManager mTelecomManager; + @Mock + private SharedPreferences mSharedPreferences; + @Mock + private DateFormatUtil mDateFormatUtil; + @Mock + private RingerModeTracker mRingerModeTracker; + @Mock + private RingerModeLiveData mRingerModeLiveData; + @Rule + public MockitoRule rule = MockitoJUnit.rule(); + private Resources mResources; + private PhoneStatusBarPolicy mPhoneStatusBarPolicy; + + @Before + public void setup() { + mResources = spy(getContext().getResources()); + mPhoneStatusBarPolicy = new PhoneStatusBarPolicy(mIconController, mCommandQueue, + mBroadcastDispatcher, mBackgroundExecutor, mResources, mCastController, + mHotSpotController, mBluetoothController, mNextAlarmController, mUserInfoController, + mRotationLockController, mDataSaverController, mZenModeController, + mDeviceProvisionerController, mKeyguardStateController, mLocationController, + mSensorPrivacyController, mIActivityManager, mAlarmManager, mUserManager, + mRecordingController, mMediaDataManager, mTelecomManager, DISPLAY_ID, + mSharedPreferences, mDateFormatUtil, mRingerModeTracker); + when(mRingerModeTracker.getRingerMode()).thenReturn(mRingerModeLiveData); + when(mRingerModeTracker.getRingerModeInternal()).thenReturn(mRingerModeLiveData); + clearInvocations(mIconController); + } + + @Test + public void testInit_registerMediaCallback() { + mPhoneStatusBarPolicy.init(); + verify(mMediaDataManager).addListener(eq(mPhoneStatusBarPolicy)); + } + + @Test + public void testOnMediaDataLoaded_updatesIcon_hasMedia() { + String mediaSlot = mResources.getString(com.android.internal.R.string.status_bar_media); + when(mMediaDataManager.hasActiveMedia()).thenReturn(true); + mPhoneStatusBarPolicy.onMediaDataLoaded(null, null); + verify(mMediaDataManager).hasActiveMedia(); + verify(mIconController).setIconVisibility(eq(mediaSlot), eq(true)); + } + + @Test + public void testOnMediaDataRemoved_updatesIcon_noMedia() { + String mediaSlot = mResources.getString(com.android.internal.R.string.status_bar_media); + mPhoneStatusBarPolicy.onMediaDataRemoved(null); + verify(mMediaDataManager).hasActiveMedia(); + verify(mIconController).setIconVisibility(eq(mediaSlot), eq(false)); + } +} diff --git a/services/core/java/com/android/server/biometrics/AuthenticationClient.java b/services/core/java/com/android/server/biometrics/AuthenticationClient.java index 5d334c22f2db..edc8f15a9a03 100644 --- a/services/core/java/com/android/server/biometrics/AuthenticationClient.java +++ b/services/core/java/com/android/server/biometrics/AuthenticationClient.java @@ -84,11 +84,8 @@ public abstract class AuthenticationClient extends ClientMonitor { @Override public void binderDied() { - super.binderDied(); - // When the binder dies, we should stop the client. This probably belongs in - // ClientMonitor's binderDied(), but testing all the cases would be tricky. - // AuthenticationClient is the most user-visible case. - stop(false /* initiatedByClient */); + final boolean clearListener = !isBiometricPrompt(); + binderDiedInternal(clearListener); } @Override diff --git a/services/core/java/com/android/server/biometrics/BiometricService.java b/services/core/java/com/android/server/biometrics/BiometricService.java index 7e28e94a17bb..4ddfe1b6e2d2 100644 --- a/services/core/java/com/android/server/biometrics/BiometricService.java +++ b/services/core/java/com/android/server/biometrics/BiometricService.java @@ -113,6 +113,7 @@ public class BiometricService extends SystemService { private static final int MSG_ON_AUTHENTICATION_TIMED_OUT = 11; private static final int MSG_ON_DEVICE_CREDENTIAL_PRESSED = 12; private static final int MSG_ON_SYSTEM_EVENT = 13; + private static final int MSG_CLIENT_DIED = 14; /** * Authentication either just called and we have not transitioned to the CALLED state, or @@ -151,8 +152,13 @@ public class BiometricService extends SystemService { * Device credential in AuthController is showing */ static final int STATE_SHOWING_DEVICE_CREDENTIAL = 8; + /** + * The client binder died, and sensors were authenticating at the time. Cancel has been + * requested and we're waiting for the HAL(s) to send ERROR_CANCELED. + */ + static final int STATE_CLIENT_DIED_CANCELLING = 9; - final class AuthSession { + final class AuthSession implements IBinder.DeathRecipient { // Map of Authenticator/Cookie pairs. We expect to receive the cookies back from // <Biometric>Services before we can start authenticating. Pairs that have been returned // are moved to mModalitiesMatched. @@ -211,7 +217,14 @@ public class BiometricService extends SystemService { mCallingUserId = callingUserId; mModality = modality; mRequireConfirmation = requireConfirmation; + Slog.d(TAG, "New AuthSession, mSysUiSessionId: " + mSysUiSessionId); + + try { + mClientReceiver.asBinder().linkToDeath(this, 0 /* flags */); + } catch (RemoteException e) { + Slog.w(TAG, "Unable to link to death"); + } } boolean isCrypto() { @@ -231,6 +244,12 @@ public class BiometricService extends SystemService { boolean isAllowDeviceCredential() { return Utils.isCredentialRequested(mBundle); } + + @Override + public void binderDied() { + Slog.e(TAG, "Binder died, sysUiSessionId: " + mSysUiSessionId); + mHandler.obtainMessage(MSG_CLIENT_DIED).sendToTarget(); + } } private final Injector mInjector; @@ -370,6 +389,11 @@ public class BiometricService extends SystemService { break; } + case MSG_CLIENT_DIED: { + handleClientDied(); + break; + } + default: Slog.e(TAG, "Unknown message: " + msg); break; @@ -1391,6 +1415,7 @@ public class BiometricService extends SystemService { } private void handleOnError(int cookie, int modality, int error, int vendorCode) { + Slog.d(TAG, "handleOnError: " + error + " cookie: " + cookie); // Errors can either be from the current auth session or the pending auth session. // The pending auth session may receive errors such as ERROR_LOCKOUT before @@ -1431,6 +1456,9 @@ public class BiometricService extends SystemService { } else if (mCurrentAuthSession.mState == STATE_SHOWING_DEVICE_CREDENTIAL) { Slog.d(TAG, "Biometric canceled, ignoring from state: " + mCurrentAuthSession.mState); + } else if (mCurrentAuthSession.mState == STATE_CLIENT_DIED_CANCELLING) { + mStatusBarService.hideAuthenticationDialog(); + mCurrentAuthSession = null; } else { Slog.e(TAG, "Impossible session error state: " + mCurrentAuthSession.mState); @@ -1622,6 +1650,36 @@ public class BiometricService extends SystemService { } } + private void handleClientDied() { + if (mCurrentAuthSession == null) { + Slog.e(TAG, "Auth session null"); + return; + } + + Slog.e(TAG, "SysUiSessionId: " + mCurrentAuthSession.mSysUiSessionId + + " State: " + mCurrentAuthSession.mState); + + try { + // Check if any sensors are authenticating. If so, need to cancel them. When + // ERROR_CANCELED is received from the HAL, we hide the dialog and cleanup the session. + if (mCurrentAuthSession.mState == STATE_AUTH_STARTED) { + mCurrentAuthSession.mState = STATE_CLIENT_DIED_CANCELLING; + cancelInternal(mCurrentAuthSession.mToken, + mCurrentAuthSession.mOpPackageName, + mCurrentAuthSession.mCallingUid, + mCurrentAuthSession.mCallingPid, + mCurrentAuthSession.mCallingUserId, + false /* fromClient */); + } else { + // If the sensors are not authenticating, set the auth session to null. + mStatusBarService.hideAuthenticationDialog(); + mCurrentAuthSession = null; + } + } catch (RemoteException e) { + Slog.e(TAG, "Remote exception: " + e); + } + } + /** * Invoked when each service has notified that its client is ready to be started. When * all biometrics are ready, this invokes the SystemUI dialog through StatusBar. @@ -1822,11 +1880,11 @@ public class BiometricService extends SystemService { void cancelInternal(IBinder token, String opPackageName, int callingUid, int callingPid, int callingUserId, boolean fromClient) { - if (mCurrentAuthSession == null) { Slog.w(TAG, "Skipping cancelInternal"); return; - } else if (mCurrentAuthSession.mState != STATE_AUTH_STARTED) { + } else if (mCurrentAuthSession.mState != STATE_AUTH_STARTED + && mCurrentAuthSession.mState != STATE_CLIENT_DIED_CANCELLING) { Slog.w(TAG, "Skipping cancelInternal, state: " + mCurrentAuthSession.mState); return; } diff --git a/services/core/java/com/android/server/biometrics/ClientMonitor.java b/services/core/java/com/android/server/biometrics/ClientMonitor.java index 942e0501d88d..b02969524221 100644 --- a/services/core/java/com/android/server/biometrics/ClientMonitor.java +++ b/services/core/java/com/android/server/biometrics/ClientMonitor.java @@ -233,11 +233,17 @@ public abstract class ClientMonitor extends LoggableMonitor implements IBinder.D @Override public void binderDied() { + binderDiedInternal(true /* clearListener */); + } + + void binderDiedInternal(boolean clearListener) { // If the current client dies we should cancel the current operation. Slog.e(getLogTag(), "Binder died, cancelling client"); stop(false /* initiatedByClient */); mToken = null; - mListener = null; + if (clearListener) { + mListener = null; + } } @Override diff --git a/services/core/java/com/android/server/compat/TEST_MAPPING b/services/core/java/com/android/server/compat/TEST_MAPPING index 0c30c790c5dd..bc1c7287d04a 100644 --- a/services/core/java/com/android/server/compat/TEST_MAPPING +++ b/services/core/java/com/android/server/compat/TEST_MAPPING @@ -15,7 +15,7 @@ }, // CTS tests { - "name": "CtsAppCompatHostTestCases#" + "name": "CtsAppCompatHostTestCases" } ] }
\ No newline at end of file diff --git a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java index d7bd794743d4..c65800a17f82 100644 --- a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java +++ b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java @@ -808,14 +808,11 @@ class MediaRouter2ServiceImpl { userRecord.mHandler, manager)); for (RouterRecord routerRecord : userRecord.mRouterRecords) { - // TODO: Do not use notifyPreferredFeaturesChangedToManagers since it updates all - // managers. Instead, Notify only to the manager that is currently being registered. - // TODO: UserRecord <-> routerRecord, why do they reference each other? // How about removing mUserRecord from routerRecord? routerRecord.mUserRecord.mHandler.sendMessage( - obtainMessage(UserHandler::notifyPreferredFeaturesChangedToManagers, - routerRecord.mUserRecord.mHandler, routerRecord)); + obtainMessage(UserHandler::notifyPreferredFeaturesChangedToManager, + routerRecord.mUserRecord.mHandler, routerRecord, manager)); } } @@ -1928,6 +1925,17 @@ class MediaRouter2ServiceImpl { } } + private void notifyPreferredFeaturesChangedToManager(@NonNull RouterRecord routerRecord, + @NonNull IMediaRouter2Manager manager) { + try { + manager.notifyPreferredFeaturesChanged(routerRecord.mPackageName, + routerRecord.mDiscoveryPreference.getPreferredFeatures()); + } catch (RemoteException ex) { + Slog.w(TAG, "Failed to notify preferred features changed." + + " Manager probably died.", ex); + } + } + private void notifyPreferredFeaturesChangedToManagers(@NonNull RouterRecord routerRecord) { MediaRouter2ServiceImpl service = mServiceRef.get(); if (service == null) { diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index d73d872d6acf..f3619f22d231 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -3181,7 +3181,7 @@ public class PackageManagerService extends IPackageManager.Stub } } - final int cachedSystemApps = PackageParser.sCachedPackageReadCount.get(); + final int cachedSystemApps = PackageCacher.sCachedPackageReadCount.get(); // Remove any shared userIDs that have no associated packages mSettings.pruneSharedUsersLPw(); @@ -3315,7 +3315,7 @@ public class PackageManagerService extends IPackageManager.Stub // This must be done last to ensure all stubs are replaced or disabled. installSystemStubPackages(stubSystemApps, scanFlags); - final int cachedNonSystemApps = PackageParser.sCachedPackageReadCount.get() + final int cachedNonSystemApps = PackageCacher.sCachedPackageReadCount.get() - cachedSystemApps; final long dataScanTime = SystemClock.uptimeMillis() - systemScanTime - startTime; diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java index 9de34a92cdf7..a5b1bf98cdb7 100644 --- a/services/core/java/com/android/server/pm/Settings.java +++ b/services/core/java/com/android/server/pm/Settings.java @@ -5595,10 +5595,7 @@ public final class Settings { userId); } else if (packageSetting.sharedUser == null && !isUpgradeToR) { Slog.w(TAG, "Missing permission state for package: " + packageName); - generateFallbackPermissionsStateLpr( - packageSetting.pkg.getRequestedPermissions(), - packageSetting.pkg.getTargetSdkVersion(), - packageSetting.getPermissionsState(), userId); + packageSetting.getPermissionsState().setMissing(true, userId); } } @@ -5616,22 +5613,7 @@ public final class Settings { userId); } else if (!isUpgradeToR) { Slog.w(TAG, "Missing permission state for shared user: " + sharedUserName); - ArraySet<String> requestedPermissions = new ArraySet<>(); - int targetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT; - int sharedUserPackagesSize = sharedUserSetting.packages.size(); - for (int packagesI = 0; packagesI < sharedUserPackagesSize; packagesI++) { - PackageSetting packageSetting = sharedUserSetting.packages.valueAt( - packagesI); - if (packageSetting == null || packageSetting.pkg == null - || !packageSetting.getInstalled(userId)) { - continue; - } - AndroidPackage pkg = packageSetting.pkg; - requestedPermissions.addAll(pkg.getRequestedPermissions()); - targetSdkVersion = Math.min(targetSdkVersion, pkg.getTargetSdkVersion()); - } - generateFallbackPermissionsStateLpr(requestedPermissions, targetSdkVersion, - sharedUserSetting.getPermissionsState(), userId); + sharedUserSetting.getPermissionsState().setMissing(true, userId); } } } @@ -5663,30 +5645,6 @@ public final class Settings { } } - private void generateFallbackPermissionsStateLpr( - @NonNull Collection<String> requestedPermissions, int targetSdkVersion, - @NonNull PermissionsState permissionsState, @UserIdInt int userId) { - for (String permissionName : requestedPermissions) { - BasePermission permission = mPermissions.getPermission(permissionName); - if (Objects.equals(permission.getSourcePackageName(), PLATFORM_PACKAGE_NAME) - && permission.isRuntime() && !permission.isRemoved()) { - if (permission.isHardOrSoftRestricted() || permission.isImmutablyRestricted()) { - permissionsState.updatePermissionFlags(permission, userId, - PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT, - PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT); - } - if (targetSdkVersion < Build.VERSION_CODES.M) { - permissionsState.updatePermissionFlags(permission, userId, - PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED - | PackageManager.FLAG_PERMISSION_REVOKED_COMPAT, - PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED - | PackageManager.FLAG_PERMISSION_REVOKED_COMPAT); - permissionsState.grantRuntimePermission(permission, userId); - } - } - } - } - @GuardedBy("Settings.this.mLock") private void readLegacyStateForUserSyncLPr(int userId) { File permissionsFile = getUserRuntimePermissionsFile(userId); 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 163504cb5011..b0d4d957fc21 100644 --- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java +++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java @@ -155,6 +155,7 @@ import java.io.PrintWriter; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.List; @@ -2478,13 +2479,60 @@ public class PermissionManagerService extends IPermissionManager.Stub { } final PermissionsState permissionsState = ps.getPermissionsState(); - PermissionsState origPermissions = permissionsState; final int[] currentUserIds = UserManagerService.getInstance().getUserIds(); boolean runtimePermissionsRevoked = false; int[] updatedUserIds = EMPTY_INT_ARRAY; + for (int userId : currentUserIds) { + if (permissionsState.isMissing(userId)) { + Collection<String> requestedPermissions; + int targetSdkVersion; + if (!ps.isSharedUser()) { + requestedPermissions = pkg.getRequestedPermissions(); + targetSdkVersion = pkg.getTargetSdkVersion(); + } else { + requestedPermissions = new ArraySet<>(); + targetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT; + List<AndroidPackage> packages = ps.getSharedUser().getPackages(); + int packagesSize = packages.size(); + for (int i = 0; i < packagesSize; i++) { + AndroidPackage sharedUserPackage = packages.get(i); + requestedPermissions.addAll(sharedUserPackage.getRequestedPermissions()); + targetSdkVersion = Math.min(targetSdkVersion, + sharedUserPackage.getTargetSdkVersion()); + } + } + + for (String permissionName : requestedPermissions) { + BasePermission permission = mSettings.getPermission(permissionName); + if (Objects.equals(permission.getSourcePackageName(), PLATFORM_PACKAGE_NAME) + && permission.isRuntime() && !permission.isRemoved()) { + if (permission.isHardOrSoftRestricted() + || permission.isImmutablyRestricted()) { + permissionsState.updatePermissionFlags(permission, userId, + PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT, + PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT); + } + if (targetSdkVersion < Build.VERSION_CODES.M) { + permissionsState.updatePermissionFlags(permission, userId, + PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED + | PackageManager.FLAG_PERMISSION_REVOKED_COMPAT, + PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED + | PackageManager.FLAG_PERMISSION_REVOKED_COMPAT); + permissionsState.grantRuntimePermission(permission, userId); + } + } + } + + permissionsState.setMissing(false, userId); + updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId); + } + } + + PermissionsState origPermissions = permissionsState; + boolean changedInstallPermission = false; if (replace) { diff --git a/services/core/java/com/android/server/pm/permission/PermissionsState.java b/services/core/java/com/android/server/pm/permission/PermissionsState.java index 11e29a02068c..bad59cb1b567 100644 --- a/services/core/java/com/android/server/pm/permission/PermissionsState.java +++ b/services/core/java/com/android/server/pm/permission/PermissionsState.java @@ -16,6 +16,8 @@ package com.android.server.pm.permission; +import android.annotation.Nullable; +import android.annotation.UserIdInt; import android.content.pm.PackageManager; import android.os.UserHandle; import android.util.ArrayMap; @@ -30,6 +32,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.Objects; import java.util.Set; /** @@ -70,6 +73,9 @@ public final class PermissionsState { private int[] mGlobalGids = NO_GIDS; + @Nullable + private SparseBooleanArray mMissing; + private SparseBooleanArray mPermissionReviewRequired; public PermissionsState() { @@ -132,6 +138,23 @@ public final class PermissionsState { other.mGlobalGids.length); } + if (mMissing != null) { + if (other.mMissing == null) { + mMissing = null; + } else { + mMissing.clear(); + } + } + if (other.mMissing != null) { + if (mMissing == null) { + mMissing = new SparseBooleanArray(); + } + final int missingSize = other.mMissing.size(); + for (int i = 0; i < missingSize; i++) { + mMissing.put(other.mMissing.keyAt(i), other.mMissing.valueAt(i)); + } + } + if (mPermissionReviewRequired != null) { if (other.mPermissionReviewRequired == null) { mPermissionReviewRequired = null; @@ -175,6 +198,10 @@ public final class PermissionsState { } } + if (!Objects.equals(mMissing, other.mMissing)) { + return false; + } + if (mPermissionReviewRequired == null) { if (other.mPermissionReviewRequired != null) { return false; @@ -185,6 +212,35 @@ public final class PermissionsState { return Arrays.equals(mGlobalGids, other.mGlobalGids); } + /** + * Check whether the permissions state is missing for a user. This can happen if permission + * state is rolled back and we'll need to generate a reasonable default state to keep the app + * usable. + */ + public boolean isMissing(@UserIdInt int userId) { + return mMissing != null && mMissing.get(userId); + } + + /** + * Set whether the permissions state is missing for a user. This can happen if permission state + * is rolled back and we'll need to generate a reasonable default state to keep the app usable. + */ + public void setMissing(boolean missing, @UserIdInt int userId) { + if (missing) { + if (mMissing == null) { + mMissing = new SparseBooleanArray(); + } + mMissing.put(userId, true); + } else { + if (mMissing != null) { + mMissing.delete(userId); + if (mMissing.size() == 0) { + mMissing = null; + } + } + } + } + public boolean isPermissionReviewRequired(int userId) { return mPermissionReviewRequired != null && mPermissionReviewRequired.get(userId); } @@ -569,6 +625,7 @@ public final class PermissionsState { invalidateCache(); } + mMissing = null; mPermissionReviewRequired = null; } diff --git a/services/core/java/com/android/server/policy/LegacyGlobalActions.java b/services/core/java/com/android/server/policy/LegacyGlobalActions.java index 39f7ac0b5b54..9c3a39440054 100644 --- a/services/core/java/com/android/server/policy/LegacyGlobalActions.java +++ b/services/core/java/com/android/server/policy/LegacyGlobalActions.java @@ -339,7 +339,7 @@ class LegacyGlobalActions implements DialogInterface.OnDismissListener, DialogIn }); dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG); // Don't acquire soft keyboard focus, to avoid destroying state when capturing bugreports - mDialog.getWindow().setFlags(FLAG_ALT_FOCUSABLE_IM, FLAG_ALT_FOCUSABLE_IM); + dialog.getWindow().setFlags(FLAG_ALT_FOCUSABLE_IM, FLAG_ALT_FOCUSABLE_IM); dialog.setOnDismissListener(this); diff --git a/services/core/java/com/android/server/uri/UriGrantsManagerService.java b/services/core/java/com/android/server/uri/UriGrantsManagerService.java index 72cdf4afb007..15b6a8df0151 100644 --- a/services/core/java/com/android/server/uri/UriGrantsManagerService.java +++ b/services/core/java/com/android/server/uri/UriGrantsManagerService.java @@ -114,7 +114,7 @@ public class UriGrantsManagerService extends IUriGrantsManager.Stub { private static final String TAG = "UriGrantsManagerService"; // Maximum number of persisted Uri grants a package is allowed private static final int MAX_PERSISTED_URI_GRANTS = 128; - private static final boolean ENABLE_DYNAMIC_PERMISSIONS = false; + private static final boolean ENABLE_DYNAMIC_PERMISSIONS = true; private final Object mLock = new Object(); private final H mH; diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 85c439ccfe6f..0efb9698f4b0 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -498,8 +498,6 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo */ ActivityRecord mFixedRotationLaunchingApp; - FixedRotationAnimationController mFixedRotationAnimationController; - final FixedRotationTransitionListener mFixedRotationTransitionListener = new FixedRotationTransitionListener(); @@ -1540,11 +1538,6 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo } private void startFixedRotationTransform(WindowToken token, int rotation) { - if (mFixedRotationAnimationController == null) { - mFixedRotationAnimationController = new FixedRotationAnimationController( - this); - } - mFixedRotationAnimationController.hide(rotation); mTmpConfiguration.unset(); final DisplayInfo info = computeScreenConfiguration(mTmpConfiguration, rotation); final WmDisplayCutout cutout = calculateDisplayCutoutForRotation(rotation); @@ -1566,13 +1559,6 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo } } - void finishFixedRotationAnimation() { - if (mFixedRotationAnimationController != null - && mFixedRotationAnimationController.show()) { - mFixedRotationAnimationController = null; - } - } - /** * Update rotation of the display. * diff --git a/services/core/java/com/android/server/wm/DisplayRotation.java b/services/core/java/com/android/server/wm/DisplayRotation.java index c3f906135a00..ebfe70c0c371 100644 --- a/services/core/java/com/android/server/wm/DisplayRotation.java +++ b/services/core/java/com/android/server/wm/DisplayRotation.java @@ -560,7 +560,6 @@ public class DisplayRotation { }, true /* traverseTopToBottom */); mSeamlessRotationCount = 0; mRotatingSeamlessly = false; - mDisplayContent.finishFixedRotationAnimation(); } private void prepareSeamlessRotation() { @@ -647,7 +646,6 @@ public class DisplayRotation { "Performing post-rotate rotation after seamless rotation"); // Finish seamless rotation. mRotatingSeamlessly = false; - mDisplayContent.finishFixedRotationAnimation(); updateRotationAndSendNewConfigIfChanged(); } diff --git a/services/core/java/com/android/server/wm/FixedRotationAnimationController.java b/services/core/java/com/android/server/wm/FixedRotationAnimationController.java deleted file mode 100644 index 7aca63774889..000000000000 --- a/services/core/java/com/android/server/wm/FixedRotationAnimationController.java +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.wm; - -import static com.android.server.wm.AnimationSpecProto.WINDOW; -import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_FIXED_TRANSFORM; -import static com.android.server.wm.WindowAnimationSpecProto.ANIMATION; - -import android.content.res.Configuration; -import android.util.proto.ProtoOutputStream; -import android.view.SurfaceControl; -import android.view.animation.Animation; -import android.view.animation.AnimationUtils; -import android.view.animation.Transformation; - -import com.android.internal.R; - -import java.io.PrintWriter; -import java.util.ArrayList; - -/** - * Controller to fade out and in system ui when applying a fixed rotation transform to a window - * token. - * - * The system bars will be fade out when the fixed rotation transform starts and will be fade in - * once all surfaces have been rotated. - */ -public class FixedRotationAnimationController { - - private final WindowManagerService mWmService; - private boolean mShowRequested = true; - private int mTargetRotation = Configuration.ORIENTATION_UNDEFINED; - private final ArrayList<WindowState> mAnimatedWindowStates = new ArrayList<>(2); - private final Runnable[] mDeferredFinishCallbacks; - - public FixedRotationAnimationController(DisplayContent displayContent) { - mWmService = displayContent.mWmService; - addAnimatedWindow(displayContent.getDisplayPolicy().getStatusBar()); - addAnimatedWindow(displayContent.getDisplayPolicy().getNavigationBar()); - mDeferredFinishCallbacks = new Runnable[mAnimatedWindowStates.size()]; - } - - private void addAnimatedWindow(WindowState windowState) { - if (windowState != null) { - mAnimatedWindowStates.add(windowState); - } - } - - /** - * Show the previously hidden {@link WindowToken} if their surfaces have already been rotated. - * - * @return True if the show animation has been started, in which case the caller no longer needs - * this {@link FixedRotationAnimationController}. - */ - boolean show() { - if (!mShowRequested && readyToShow()) { - mShowRequested = true; - for (int i = mAnimatedWindowStates.size() - 1; i >= 0; i--) { - WindowState windowState = mAnimatedWindowStates.get(i); - fadeWindowToken(true, windowState.getParent(), i); - } - return true; - } - return false; - } - - void hide(int targetRotation) { - mTargetRotation = targetRotation; - if (mShowRequested) { - mShowRequested = false; - for (int i = mAnimatedWindowStates.size() - 1; i >= 0; i--) { - WindowState windowState = mAnimatedWindowStates.get(i); - fadeWindowToken(false /* show */, windowState.getParent(), i); - } - } - } - - void cancel() { - for (int i = mAnimatedWindowStates.size() - 1; i >= 0; i--) { - WindowState windowState = mAnimatedWindowStates.get(i); - mShowRequested = true; - fadeWindowToken(true /* show */, windowState.getParent(), i); - } - } - - private void fadeWindowToken(boolean show, WindowContainer<WindowToken> windowToken, - int index) { - Animation animation = AnimationUtils.loadAnimation(mWmService.mContext, - show ? R.anim.fade_in : R.anim.fade_out); - LocalAnimationAdapter.AnimationSpec windowAnimationSpec = createAnimationSpec(animation); - - FixedRotationAnimationAdapter animationAdapter = new FixedRotationAnimationAdapter( - windowAnimationSpec, windowToken.getSurfaceAnimationRunner(), show, index); - - // We deferred the end of the animation when hiding the token, so we need to end it now that - // it's shown again. - SurfaceAnimator.OnAnimationFinishedCallback finishedCallback = show ? (t, r) -> { - if (mDeferredFinishCallbacks[index] != null) { - mDeferredFinishCallbacks[index].run(); - mDeferredFinishCallbacks[index] = null; - } - } : null; - windowToken.startAnimation(windowToken.getPendingTransaction(), animationAdapter, - mShowRequested, ANIMATION_TYPE_FIXED_TRANSFORM, finishedCallback); - } - - /** - * Check if all the mAnimatedWindowState's surfaces have been rotated to the - * mTargetRotation. - */ - private boolean readyToShow() { - for (int i = mAnimatedWindowStates.size() - 1; i >= 0; i--) { - WindowState windowState = mAnimatedWindowStates.get(i); - if (windowState.getConfiguration().windowConfiguration.getRotation() - != mTargetRotation || windowState.mPendingSeamlessRotate != null) { - return false; - } - } - return true; - } - - - private LocalAnimationAdapter.AnimationSpec createAnimationSpec(Animation animation) { - return new LocalAnimationAdapter.AnimationSpec() { - - Transformation mTransformation = new Transformation(); - - @Override - public boolean getShowWallpaper() { - return true; - } - - @Override - public long getDuration() { - return animation.getDuration(); - } - - @Override - public void apply(SurfaceControl.Transaction t, SurfaceControl leash, - long currentPlayTime) { - mTransformation.clear(); - animation.getTransformation(currentPlayTime, mTransformation); - t.setAlpha(leash, mTransformation.getAlpha()); - } - - @Override - public void dump(PrintWriter pw, String prefix) { - pw.print(prefix); - pw.println(animation); - } - - @Override - public void dumpDebugInner(ProtoOutputStream proto) { - final long token = proto.start(WINDOW); - proto.write(ANIMATION, animation.toString()); - proto.end(token); - } - }; - } - - private class FixedRotationAnimationAdapter extends LocalAnimationAdapter { - private final boolean mShow; - private final int mIndex; - - FixedRotationAnimationAdapter(AnimationSpec windowAnimationSpec, - SurfaceAnimationRunner surfaceAnimationRunner, boolean show, int index) { - super(windowAnimationSpec, surfaceAnimationRunner); - mShow = show; - mIndex = index; - } - - @Override - public boolean shouldDeferAnimationFinish(Runnable endDeferFinishCallback) { - // We defer the end of the hide animation to ensure the tokens stay hidden until - // we show them again. - if (!mShow) { - mDeferredFinishCallbacks[mIndex] = endDeferFinishCallback; - return true; - } - return false; - } - } -} diff --git a/services/core/java/com/android/server/wm/RecentTasks.java b/services/core/java/com/android/server/wm/RecentTasks.java index d8a4ecbbc650..1cd94b40f660 100644 --- a/services/core/java/com/android/server/wm/RecentTasks.java +++ b/services/core/java/com/android/server/wm/RecentTasks.java @@ -1387,9 +1387,7 @@ class RecentTasks { return false; } - /** - * @return whether the given task can be trimmed even if it is outside the visible range. - */ + /** @return whether the given task can be trimmed even if it is outside the visible range. */ protected boolean isTrimmable(Task task) { final ActivityStack stack = task.getStack(); @@ -1404,9 +1402,13 @@ class RecentTasks { return false; } + final ActivityStack rootHomeTask = stack.getDisplayArea().getRootHomeTask(); + // Home stack does not exist. Don't trim the task. + if (rootHomeTask == null) { + return false; + } // Trim tasks that are behind the home task. - final TaskDisplayArea taskDisplayArea = stack.getDisplayArea(); - return task.compareTo(taskDisplayArea.getRootHomeTask()) < 0; + return task.compareTo(rootHomeTask) < 0; } /** Remove the tasks that user may not be able to return. */ diff --git a/services/core/java/com/android/server/wm/RecentsAnimationController.java b/services/core/java/com/android/server/wm/RecentsAnimationController.java index cbc1bdfa0e9e..f1b322ed24ba 100644 --- a/services/core/java/com/android/server/wm/RecentsAnimationController.java +++ b/services/core/java/com/android/server/wm/RecentsAnimationController.java @@ -406,8 +406,9 @@ public class RecentsAnimationController implements DeathRecipient { } // Save the minimized home height - mMinimizedHomeBounds = mDisplayContent.getDefaultTaskDisplayArea().getRootHomeTask() - .getBounds(); + final ActivityStack rootHomeTask = + mDisplayContent.getDefaultTaskDisplayArea().getRootHomeTask(); + mMinimizedHomeBounds = rootHomeTask != null ? rootHomeTask.getBounds() : null; mService.mWindowPlacerLocked.performSurfacePlacement(); diff --git a/services/core/java/com/android/server/wm/RemoteAnimationController.java b/services/core/java/com/android/server/wm/RemoteAnimationController.java index c02e0a11a0c5..c7f78342c829 100644 --- a/services/core/java/com/android/server/wm/RemoteAnimationController.java +++ b/services/core/java/com/android/server/wm/RemoteAnimationController.java @@ -387,9 +387,11 @@ class RemoteAnimationController implements DeathRecipient { int getMode() { final DisplayContent dc = mWindowContainer.getDisplayContent(); final ActivityRecord topActivity = mWindowContainer.getTopMostActivity(); + // Note that opening/closing transitions are per-activity while changing transitions + // are per-task. if (dc.mOpeningApps.contains(topActivity)) { return RemoteAnimationTarget.MODE_OPENING; - } else if (dc.mChangingContainers.contains(topActivity)) { + } else if (dc.mChangingContainers.contains(mWindowContainer)) { return RemoteAnimationTarget.MODE_CHANGING; } else { return RemoteAnimationTarget.MODE_CLOSING; diff --git a/services/core/java/com/android/server/wm/SurfaceAnimator.java b/services/core/java/com/android/server/wm/SurfaceAnimator.java index 0143eb1abe03..42342a60ba16 100644 --- a/services/core/java/com/android/server/wm/SurfaceAnimator.java +++ b/services/core/java/com/android/server/wm/SurfaceAnimator.java @@ -489,12 +489,6 @@ class SurfaceAnimator { static final int ANIMATION_TYPE_INSETS_CONTROL = 1 << 5; /** - * Animation when a fixed rotation transform is applied to a window token. - * @hide - */ - static final int ANIMATION_TYPE_FIXED_TRANSFORM = 1 << 6; - - /** * Bitmask to include all animation types. This is NOT an {@link AnimationType} * @hide */ @@ -511,8 +505,7 @@ class SurfaceAnimator { ANIMATION_TYPE_DIMMER, ANIMATION_TYPE_RECENTS, ANIMATION_TYPE_WINDOW_ANIMATION, - ANIMATION_TYPE_INSETS_CONTROL, - ANIMATION_TYPE_FIXED_TRANSFORM + ANIMATION_TYPE_INSETS_CONTROL }) @Retention(RetentionPolicy.SOURCE) @interface AnimationType {} diff --git a/services/core/java/com/android/server/wm/TaskDisplayArea.java b/services/core/java/com/android/server/wm/TaskDisplayArea.java index 6ce36f1a3eb6..6661c30723d2 100644 --- a/services/core/java/com/android/server/wm/TaskDisplayArea.java +++ b/services/core/java/com/android/server/wm/TaskDisplayArea.java @@ -195,7 +195,7 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> { return mChildren.indexOf(stack); } - ActivityStack getRootHomeTask() { + @Nullable ActivityStack getRootHomeTask() { return mRootHomeTask; } diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java index e2023aeac3dc..7757b3a50941 100644 --- a/services/core/java/com/android/server/wm/WindowContainer.java +++ b/services/core/java/com/android/server/wm/WindowContainer.java @@ -2184,7 +2184,8 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< final int appStackClipMode = getDisplayContent().mAppTransition.getAppStackClipMode(); // Separate position and size for use in animators. - mTmpRect.set(getAnimationBounds(appStackClipMode)); + final Rect screenBounds = getAnimationBounds(appStackClipMode); + mTmpRect.set(screenBounds); getAnimationPosition(mTmpPoint); if (!sHierarchicalAnimations) { // Non-hierarchical animation uses position in global coordinates. @@ -2203,7 +2204,7 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< localBounds.offsetTo(mTmpPoint.x, mTmpPoint.y); final RemoteAnimationController.RemoteAnimationRecord adapters = controller.createRemoteAnimationRecord(this, mTmpPoint, localBounds, - mTmpRect, (isChanging ? mSurfaceFreezer.mFreezeBounds : null)); + screenBounds, (isChanging ? mSurfaceFreezer.mFreezeBounds : null)); resultAdapters = new Pair<>(adapters.mAdapter, adapters.mThumbnailAdapter); } else if (isChanging) { final float durationScale = mWmService.getTransitionAnimationScaleLocked(); diff --git a/services/core/java/com/android/server/wm/WindowProcessController.java b/services/core/java/com/android/server/wm/WindowProcessController.java index fe68cd6110f2..20b109bc06f7 100644 --- a/services/core/java/com/android/server/wm/WindowProcessController.java +++ b/services/core/java/com/android/server/wm/WindowProcessController.java @@ -1315,12 +1315,15 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio * * @param isCached whether or not the process is cached. */ + @HotPath(caller = HotPath.OOM_ADJUSTMENT) public void onProcCachedStateChanged(boolean isCached) { - synchronized (mAtm.mGlobalLock) { - if (!isCached && mPendingConfiguration != null) { - final Configuration config = mPendingConfiguration; - mPendingConfiguration = null; - dispatchConfigurationChange(config); + if (!isCached) { + synchronized (mAtm.mGlobalLockWithoutBoost) { + if (mPendingConfiguration != null) { + final Configuration config = mPendingConfiguration; + mPendingConfiguration = null; + dispatchConfigurationChange(config); + } } } } diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index e925ce5c2dac..3ec6ab41033a 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -1509,7 +1509,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP return mActivityRecord != null ? mActivityRecord.getTask() : null; } - ActivityStack getRootTask() { + @Nullable ActivityStack getRootTask() { final Task task = getTask(); if (task != null) { return (ActivityStack) task.getRootTask(); @@ -2527,7 +2527,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP final Task task = getTask(); if (task != null) { task.getDimBounds(mTmpRect); - } else { + } else if (getRootTask() != null) { getRootTask().getDimBounds(mTmpRect); } } diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java index 8739bad4398b..768f89eff774 100644 --- a/services/core/java/com/android/server/wm/WindowToken.java +++ b/services/core/java/com/android/server/wm/WindowToken.java @@ -642,9 +642,6 @@ class WindowToken extends WindowContainer<WindowState> { final int originalRotation = getWindowConfiguration().getRotation(); onConfigurationChanged(parent.getConfiguration()); onCancelFixedRotationTransform(originalRotation); - if (mDisplayContent.mFixedRotationAnimationController != null) { - mDisplayContent.mFixedRotationAnimationController.cancel(); - } } /** diff --git a/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java b/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java index 285caf34ae67..48ec529c9a45 100644 --- a/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java @@ -115,6 +115,8 @@ public class BiometricServiceTest { public void setUp() { MockitoAnnotations.initMocks(this); + resetReceivers(); + when(mContext.getContentResolver()).thenReturn(mContentResolver); when(mContext.getResources()).thenReturn(mResources); when(mContext.getSystemService(Context.DEVICE_POLICY_SERVICE)) @@ -147,6 +149,74 @@ public class BiometricServiceTest { } @Test + public void testClientBinderDied_whenPaused() throws Exception { + setupAuthForOnly(BiometricAuthenticator.TYPE_FACE, Authenticators.BIOMETRIC_STRONG); + + invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1, + true /* requireConfirmation */, null /* authenticators */); + waitForIdle(); + verify(mReceiver1.asBinder()).linkToDeath(eq(mBiometricService.mCurrentAuthSession), + anyInt()); + + mBiometricService.mInternalReceiver.onError( + getCookieForCurrentSession(mBiometricService.mCurrentAuthSession), + BiometricAuthenticator.TYPE_FACE, + BiometricConstants.BIOMETRIC_ERROR_TIMEOUT, + 0 /* vendorCode */); + waitForIdle(); + + assertEquals(BiometricService.STATE_AUTH_PAUSED, + mBiometricService.mCurrentAuthSession.mState); + + mBiometricService.mCurrentAuthSession.binderDied(); + waitForIdle(); + + assertNull(mBiometricService.mCurrentAuthSession); + verify(mBiometricService.mStatusBarService).hideAuthenticationDialog(); + verify(mReceiver1, never()).onError(anyInt(), anyInt(), anyInt()); + } + + @Test + public void testClientBinderDied_whenAuthenticating() throws Exception { + setupAuthForOnly(BiometricAuthenticator.TYPE_FACE, Authenticators.BIOMETRIC_STRONG); + + invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1, + true /* requireConfirmation */, null /* authenticators */); + waitForIdle(); + verify(mReceiver1.asBinder()).linkToDeath(eq(mBiometricService.mCurrentAuthSession), + anyInt()); + + assertEquals(BiometricService.STATE_AUTH_STARTED, + mBiometricService.mCurrentAuthSession.mState); + mBiometricService.mCurrentAuthSession.binderDied(); + waitForIdle(); + + assertNotNull(mBiometricService.mCurrentAuthSession); + verify(mBiometricService.mStatusBarService, never()).hideAuthenticationDialog(); + assertEquals(BiometricService.STATE_CLIENT_DIED_CANCELLING, + mBiometricService.mCurrentAuthSession.mState); + + verify(mBiometricService.mAuthenticators.get(0).impl).cancelAuthenticationFromService( + any(), + any(), + anyInt(), + anyInt(), + anyInt(), + eq(false) /* fromClient */); + + // Simulate ERROR_CANCELED received from HAL + mBiometricService.mInternalReceiver.onError( + getCookieForCurrentSession(mBiometricService.mCurrentAuthSession), + BiometricAuthenticator.TYPE_FACE, + BiometricConstants.BIOMETRIC_ERROR_CANCELED, + 0 /* vendorCode */); + waitForIdle(); + verify(mBiometricService.mStatusBarService).hideAuthenticationDialog(); + verify(mReceiver1, never()).onError(anyInt(), anyInt(), anyInt()); + assertNull(mBiometricService.mCurrentAuthSession); + } + + @Test public void testAuthenticate_credentialAllowedButNotSetup_returnsNoDeviceCredential() throws Exception { when(mTrustManager.isDeviceSecure(anyInt())).thenReturn(false); @@ -311,7 +381,7 @@ public class BiometricServiceTest { eq(0 /* vendorCode */)); // Enrolled, not disabled in settings, user requires confirmation in settings - resetReceiver(); + resetReceivers(); when(mBiometricService.mSettingObserver.getFaceEnabledForApps(anyInt())).thenReturn(true); when(mBiometricService.mSettingObserver.getFaceAlwaysRequireConfirmation(anyInt())) .thenReturn(true); @@ -332,7 +402,7 @@ public class BiometricServiceTest { anyInt() /* callingUserId */); // Enrolled, not disabled in settings, user doesn't require confirmation in settings - resetReceiver(); + resetReceivers(); when(mBiometricService.mSettingObserver.getFaceAlwaysRequireConfirmation(anyInt())) .thenReturn(false); invokeAuthenticate(mBiometricService.mImpl, mReceiver1, false /* requireConfirmation */, @@ -1198,7 +1268,7 @@ public class BiometricServiceTest { eq(0) /* vendorCode */); // Request for weak auth works - resetReceiver(); + resetReceivers(); authenticators = Authenticators.BIOMETRIC_WEAK; assertEquals(BiometricManager.BIOMETRIC_SUCCESS, invokeCanAuthenticate(mBiometricService, authenticators)); @@ -1217,7 +1287,7 @@ public class BiometricServiceTest { anyInt() /* sysUiSessionId */); // Requesting strong and credential, when credential is setup - resetReceiver(); + resetReceivers(); authenticators = Authenticators.BIOMETRIC_STRONG | Authenticators.DEVICE_CREDENTIAL; when(mTrustManager.isDeviceSecure(anyInt())).thenReturn(true); assertEquals(BiometricManager.BIOMETRIC_SUCCESS, @@ -1244,7 +1314,7 @@ public class BiometricServiceTest { } } - resetReceiver(); + resetReceivers(); authenticators = Authenticators.BIOMETRIC_STRONG; assertEquals(BiometricManager.BIOMETRIC_SUCCESS, invokeCanAuthenticate(mBiometricService, authenticators)); @@ -1449,9 +1519,12 @@ public class BiometricServiceTest { } } - private void resetReceiver() { + private void resetReceivers() { mReceiver1 = mock(IBiometricServiceReceiver.class); mReceiver2 = mock(IBiometricServiceReceiver.class); + + when(mReceiver1.asBinder()).thenReturn(mock(Binder.class)); + when(mReceiver2.asBinder()).thenReturn(mock(Binder.class)); } private void resetStatusBar() { 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 7b23bfb48a1a..ac95a817bec9 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java @@ -57,7 +57,6 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.same; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.times; import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; -import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_FIXED_TRANSFORM; import static com.android.server.wm.WindowContainer.POSITION_TOP; import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_NORMAL; @@ -1060,8 +1059,6 @@ public class DisplayContentTests extends WindowTestsBase { @Test public void testApplyTopFixedRotationTransform() { mWm.mIsFixedRotationTransformEnabled = true; - mDisplayContent.getDisplayPolicy().addWindowLw(mStatusBarWindow, mStatusBarWindow.mAttrs); - mDisplayContent.getDisplayPolicy().addWindowLw(mNavBarWindow, mNavBarWindow.mAttrs); final Configuration config90 = new Configuration(); mDisplayContent.computeScreenConfiguration(config90, ROTATION_90); @@ -1082,12 +1079,6 @@ public class DisplayContentTests extends WindowTestsBase { ROTATION_0 /* oldRotation */, ROTATION_90 /* newRotation */, false /* forceUpdate */)); - assertNotNull(mDisplayContent.mFixedRotationAnimationController); - assertTrue(mStatusBarWindow.getParent().isAnimating(WindowContainer.AnimationFlags.PARENTS, - ANIMATION_TYPE_FIXED_TRANSFORM)); - assertTrue(mNavBarWindow.getParent().isAnimating(WindowContainer.AnimationFlags.PARENTS, - ANIMATION_TYPE_FIXED_TRANSFORM)); - final Rect outFrame = new Rect(); final Rect outInsets = new Rect(); final Rect outStableInsets = new Rect(); @@ -1140,9 +1131,6 @@ public class DisplayContentTests extends WindowTestsBase { assertFalse(app.hasFixedRotationTransform()); assertFalse(app2.hasFixedRotationTransform()); assertEquals(config90.orientation, mDisplayContent.getConfiguration().orientation); - - mDisplayContent.finishFixedRotationAnimation(); - assertNull(mDisplayContent.mFixedRotationAnimationController); } @Test |