summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Android.bp7
-rw-r--r--StubLibraries.bp1
-rw-r--r--apex/blobstore/service/java/com/android/server/blob/BlobStoreConfig.java7
-rw-r--r--cmds/statsd/Android.bp7
-rw-r--r--cmds/statsd/src/external/StatsPullerManager.cpp8
-rw-r--r--cmds/statsd/src/external/StatsPullerManager.h7
-rw-r--r--cmds/statsd/src/metrics/MetricsManager.cpp2
-rw-r--r--cmds/statsd/tests/MetricsManager_test.cpp2
-rw-r--r--cmds/statsd/tests/StatsLogProcessor_test.cpp23
-rw-r--r--cmds/statsd/tests/metrics/metrics_test_helper.h3
-rw-r--r--core/java/android/app/ActivityThread.java78
-rw-r--r--core/java/android/content/pm/PackageParser.java6
-rw-r--r--core/java/android/os/incremental/IncrementalFileStorages.java134
-rw-r--r--core/java/android/os/incremental/IncrementalManager.java92
-rw-r--r--core/java/android/text/style/DynamicDrawableSpan.java2
-rw-r--r--core/java/android/view/InsetsSourceConsumer.java24
-rw-r--r--core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java9
-rw-r--r--core/java/com/android/internal/app/ChooserActivity.java67
-rw-r--r--core/java/com/android/internal/app/ResolverActivity.java58
-rw-r--r--core/java/com/android/internal/app/ResolverMultiProfilePagerAdapter.java6
-rw-r--r--core/java/com/android/internal/widget/ResolverDrawerLayout.java5
-rw-r--r--core/jni/AndroidRuntime.cpp8
-rw-r--r--core/proto/android/app/settings_enums.proto10
-rw-r--r--core/res/res/layout/resolver_empty_states.xml1
-rw-r--r--core/res/res/layout/resolver_list.xml98
-rw-r--r--core/res/res/values/config.xml2
-rw-r--r--core/res/res/values/symbols.xml2
-rwxr-xr-xmedia/java/android/media/AudioManager.java26
-rw-r--r--media/java/android/media/AudioSystem.java169
-rw-r--r--media/java/android/media/MediaMetrics.java111
-rw-r--r--media/java/android/media/soundtrigger_middleware/OWNERS2
-rw-r--r--media/java/android/media/tv/tuner/Tuner.java87
-rwxr-xr-xmedia/java/android/mtp/MtpDatabase.java13
-rw-r--r--media/java/android/mtp/MtpStorage.java2
-rw-r--r--media/jni/android_media_tv_Tuner.cpp32
-rw-r--r--media/jni/android_media_tv_Tuner.h2
-rw-r--r--media/tests/MtpTests/res/raw/test_bad_thumb.jpg0
-rw-r--r--media/tests/MtpTests/src/android/mtp/MtpDatabaseTest.java316
-rw-r--r--packages/CarSystemUI/res/values/config.xml3
-rw-r--r--packages/CarSystemUI/src/com/android/systemui/CarSystemUIBinder.java4
-rw-r--r--packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java2
-rw-r--r--packages/CarSystemUI/src/com/android/systemui/car/volume/CarVolumeDialogComponent.java (renamed from packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeDialogComponent.java)8
-rw-r--r--packages/CarSystemUI/src/com/android/systemui/car/volume/CarVolumeDialogImpl.java (renamed from packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java)69
-rw-r--r--packages/CarSystemUI/src/com/android/systemui/car/volume/CarVolumeItem.java (renamed from packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeItem.java)8
-rw-r--r--packages/CarSystemUI/src/com/android/systemui/car/volume/CarVolumeItemAdapter.java (renamed from packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeItemAdapter.java)4
-rw-r--r--packages/CarSystemUI/src/com/android/systemui/car/volume/VolumeUI.java125
-rw-r--r--packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarNavigationBar.java9
-rw-r--r--packages/CarSystemUI/tests/src/com/android/systemui/navigationbar/car/CarNavigationBarTest.java7
-rw-r--r--packages/SettingsLib/res/values/strings.xml8
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/notification/EnableZenModeDialog.java60
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/utils/PowerUtilTest.java10
-rw-r--r--packages/SystemUI/res/drawable/screenshot_cancel.xml6
-rw-r--r--packages/SystemUI/res/layout/controls_management.xml38
-rw-r--r--packages/SystemUI/res/layout/global_actions_grid_v2.xml2
-rw-r--r--packages/SystemUI/res/layout/global_screenshot.xml1
-rw-r--r--packages/SystemUI/res/values-night/colors.xml9
-rw-r--r--packages/SystemUI/res/values/colors.xml2
-rw-r--r--packages/SystemUI/res/values/dimens.xml2
-rw-r--r--packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java26
-rw-r--r--packages/SystemUI/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayout.java23
-rw-r--r--packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt21
-rw-r--r--packages/SystemUI/src/com/android/systemui/controls/management/ControlsProviderSelectorActivity.kt10
-rw-r--r--packages/SystemUI/src/com/android/systemui/dagger/SystemUIDefaultModule.java13
-rw-r--r--packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/pip/PipAnimationController.java14
-rw-r--r--packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java56
-rw-r--r--packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java45
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/settings/CurrentUserContextTracker.kt7
-rw-r--r--packages/SystemUI/src/com/android/systemui/settings/dagger/SettingsModule.java48
-rw-r--r--packages/SystemUI/src/com/android/systemui/stackdivider/SplitScreenTaskOrganizer.java14
-rw-r--r--packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java5
-rw-r--r--packages/Tethering/res/values-af/strings.xml29
-rw-r--r--packages/Tethering/res/values-am/strings.xml29
-rw-r--r--packages/Tethering/res/values-ar/strings.xml29
-rw-r--r--packages/Tethering/res/values-as/strings.xml29
-rw-r--r--packages/Tethering/res/values-az/strings.xml29
-rw-r--r--packages/Tethering/res/values-b+sr+Latn/strings.xml29
-rw-r--r--packages/Tethering/res/values-be/strings.xml29
-rw-r--r--packages/Tethering/res/values-bg/strings.xml29
-rw-r--r--packages/Tethering/res/values-bn/strings.xml29
-rw-r--r--packages/Tethering/res/values-bs/strings.xml29
-rw-r--r--packages/Tethering/res/values-ca/strings.xml29
-rw-r--r--packages/Tethering/res/values-cs/strings.xml29
-rw-r--r--packages/Tethering/res/values-da/strings.xml29
-rw-r--r--packages/Tethering/res/values-de/strings.xml29
-rw-r--r--packages/Tethering/res/values-el/strings.xml29
-rw-r--r--packages/Tethering/res/values-en-rAU/strings.xml29
-rw-r--r--packages/Tethering/res/values-en-rCA/strings.xml29
-rw-r--r--packages/Tethering/res/values-en-rGB/strings.xml29
-rw-r--r--packages/Tethering/res/values-en-rIN/strings.xml29
-rw-r--r--packages/Tethering/res/values-en-rXC/strings.xml29
-rw-r--r--packages/Tethering/res/values-es-rUS/strings.xml29
-rw-r--r--packages/Tethering/res/values-es/strings.xml29
-rw-r--r--packages/Tethering/res/values-et/strings.xml29
-rw-r--r--packages/Tethering/res/values-eu/strings.xml29
-rw-r--r--packages/Tethering/res/values-fa/strings.xml29
-rw-r--r--packages/Tethering/res/values-fi/strings.xml29
-rw-r--r--packages/Tethering/res/values-fr-rCA/strings.xml29
-rw-r--r--packages/Tethering/res/values-fr/strings.xml29
-rw-r--r--packages/Tethering/res/values-gl/strings.xml29
-rw-r--r--packages/Tethering/res/values-gu/strings.xml29
-rw-r--r--packages/Tethering/res/values-hi/strings.xml29
-rw-r--r--packages/Tethering/res/values-hr/strings.xml29
-rw-r--r--packages/Tethering/res/values-hu/strings.xml29
-rw-r--r--packages/Tethering/res/values-hy/strings.xml29
-rw-r--r--packages/Tethering/res/values-in/strings.xml29
-rw-r--r--packages/Tethering/res/values-is/strings.xml29
-rw-r--r--packages/Tethering/res/values-it/strings.xml29
-rw-r--r--packages/Tethering/res/values-iw/strings.xml29
-rw-r--r--packages/Tethering/res/values-ja/strings.xml29
-rw-r--r--packages/Tethering/res/values-ka/strings.xml29
-rw-r--r--packages/Tethering/res/values-kk/strings.xml29
-rw-r--r--packages/Tethering/res/values-km/strings.xml29
-rw-r--r--packages/Tethering/res/values-kn/strings.xml29
-rw-r--r--packages/Tethering/res/values-ko/strings.xml29
-rw-r--r--packages/Tethering/res/values-ky/strings.xml29
-rw-r--r--packages/Tethering/res/values-lo/strings.xml29
-rw-r--r--packages/Tethering/res/values-lt/strings.xml29
-rw-r--r--packages/Tethering/res/values-lv/strings.xml29
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-af/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-am/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-ar/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-as/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-az/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-b+sr+Latn/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-be/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-bg/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-bn/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-bs/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-ca/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-cs/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-da/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-de/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-el/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-en-rAU/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-en-rCA/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-en-rGB/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-en-rIN/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-en-rXC/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-es-rUS/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-es/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-et/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-eu/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-fa/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-fi/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-fr-rCA/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-fr/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-gl/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-gu/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-hi/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-hr/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-hu/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-hy/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-in/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-is/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-it/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-iw/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-ja/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-ka/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-kk/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-km/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-kn/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-ko/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-ky/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-lo/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-lt/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-lv/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-mk/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-ml/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-mn/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-mr/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-ms/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-my/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-nb/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-ne/strings.xml28
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-nl/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-or/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-pa/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-pl/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-pt-rBR/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-pt-rPT/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-pt/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-ro/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-ru/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-si/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-sk/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-sl/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-sq/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-sr/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-sv/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-sw/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-ta/strings.xml28
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-te/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-th/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-tl/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-tr/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-uk/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-ur/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-uz/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-vi/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-zh-rCN/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-zh-rHK/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-zh-rTW/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004-zu/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc310-mnc004/strings.xml2
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-af/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-am/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-ar/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-as/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-az/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-b+sr+Latn/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-be/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-bg/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-bn/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-bs/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-ca/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-cs/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-da/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-de/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-el/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-en-rAU/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-en-rCA/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-en-rGB/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-en-rIN/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-en-rXC/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-es-rUS/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-es/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-et/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-eu/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-fa/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-fi/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-fr-rCA/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-fr/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-gl/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-gu/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-hi/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-hr/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-hu/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-hy/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-in/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-is/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-it/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-iw/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-ja/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-ka/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-kk/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-km/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-kn/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-ko/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-ky/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-lo/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-lt/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-lv/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-mk/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-ml/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-mn/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-mr/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-ms/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-my/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-nb/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-ne/strings.xml28
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-nl/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-or/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-pa/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-pl/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-pt-rBR/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-pt-rPT/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-pt/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-ro/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-ru/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-si/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-sk/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-sl/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-sq/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-sr/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-sv/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-sw/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-ta/strings.xml28
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-te/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-th/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-tl/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-tr/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-uk/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-ur/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-uz/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-vi/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-zh-rCN/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-zh-rHK/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-zh-rTW/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480-zu/strings.xml24
-rw-r--r--packages/Tethering/res/values-mcc311-mnc480/strings.xml2
-rw-r--r--packages/Tethering/res/values-mcc311-mnc490/strings.xml22
-rw-r--r--packages/Tethering/res/values-mcc312-mnc530/strings.xml22
-rw-r--r--packages/Tethering/res/values-mk/strings.xml29
-rw-r--r--packages/Tethering/res/values-ml/strings.xml29
-rw-r--r--packages/Tethering/res/values-mn/strings.xml29
-rw-r--r--packages/Tethering/res/values-mr/strings.xml29
-rw-r--r--packages/Tethering/res/values-ms/strings.xml29
-rw-r--r--packages/Tethering/res/values-my/strings.xml29
-rw-r--r--packages/Tethering/res/values-nb/strings.xml29
-rw-r--r--packages/Tethering/res/values-ne/strings.xml29
-rw-r--r--packages/Tethering/res/values-nl/strings.xml29
-rw-r--r--packages/Tethering/res/values-or/strings.xml29
-rw-r--r--packages/Tethering/res/values-pa/strings.xml29
-rw-r--r--packages/Tethering/res/values-pl/strings.xml29
-rw-r--r--packages/Tethering/res/values-pt-rBR/strings.xml29
-rw-r--r--packages/Tethering/res/values-pt-rPT/strings.xml29
-rw-r--r--packages/Tethering/res/values-pt/strings.xml29
-rw-r--r--packages/Tethering/res/values-ro/strings.xml29
-rw-r--r--packages/Tethering/res/values-ru/strings.xml29
-rw-r--r--packages/Tethering/res/values-si/strings.xml29
-rw-r--r--packages/Tethering/res/values-sk/strings.xml29
-rw-r--r--packages/Tethering/res/values-sl/strings.xml29
-rw-r--r--packages/Tethering/res/values-sq/strings.xml29
-rw-r--r--packages/Tethering/res/values-sr/strings.xml29
-rw-r--r--packages/Tethering/res/values-sv/strings.xml29
-rw-r--r--packages/Tethering/res/values-sw/strings.xml29
-rw-r--r--packages/Tethering/res/values-ta/strings.xml29
-rw-r--r--packages/Tethering/res/values-te/strings.xml29
-rw-r--r--packages/Tethering/res/values-th/strings.xml29
-rw-r--r--packages/Tethering/res/values-tl/strings.xml29
-rw-r--r--packages/Tethering/res/values-tr/strings.xml29
-rw-r--r--packages/Tethering/res/values-uk/strings.xml29
-rw-r--r--packages/Tethering/res/values-ur/strings.xml29
-rw-r--r--packages/Tethering/res/values-uz/strings.xml29
-rw-r--r--packages/Tethering/res/values-vi/strings.xml29
-rw-r--r--packages/Tethering/res/values-zh-rCN/strings.xml29
-rw-r--r--packages/Tethering/res/values-zh-rHK/strings.xml29
-rw-r--r--packages/Tethering/res/values-zh-rTW/strings.xml29
-rw-r--r--packages/Tethering/res/values-zu/strings.xml29
-rw-r--r--packages/Tethering/res/values/config.xml45
-rw-r--r--packages/Tethering/res/values/overlayable.xml38
-rw-r--r--packages/Tethering/res/values/strings.xml5
-rw-r--r--packages/Tethering/src/com/android/networkstack/tethering/OffloadHardwareInterface.java2
-rw-r--r--packages/Tethering/src/com/android/networkstack/tethering/TetheringNotificationUpdater.java100
-rw-r--r--packages/Tethering/tests/integration/Android.bp1
-rw-r--r--packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringNotificationUpdaterTest.kt207
-rw-r--r--packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_corp.xml39
-rw-r--r--packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_corp_off.xml26
-rw-r--r--packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_screenshot.xml29
-rw-r--r--packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_select.xml32
-rw-r--r--packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_share.xml39
-rw-r--r--packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_corp.xml36
-rw-r--r--packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_corp_off.xml26
-rw-r--r--packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_screenshot.xml29
-rw-r--r--packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_select.xml32
-rw-r--r--packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_share.xml39
-rw-r--r--packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_corp.xml41
-rw-r--r--packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_corp_off.xml26
-rw-r--r--packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_screenshot.xml (renamed from packages/Tethering/res/values-mcc310-mnc120/strings.xml)23
-rw-r--r--packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_select.xml32
-rw-r--r--packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_share.xml39
-rw-r--r--services/core/java/com/android/server/UiModeManagerService.java92
-rw-r--r--services/core/java/com/android/server/am/ActiveServices.java75
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java2
-rw-r--r--services/core/java/com/android/server/am/AppErrors.java4
-rw-r--r--services/core/java/com/android/server/am/OomAdjuster.java7
-rw-r--r--services/core/java/com/android/server/am/ProcessRecord.java76
-rw-r--r--services/core/java/com/android/server/audio/AudioDeviceBroker.java8
-rw-r--r--services/core/java/com/android/server/audio/AudioDeviceInventory.java184
-rwxr-xr-xservices/core/java/com/android/server/audio/AudioService.java225
-rw-r--r--services/core/java/com/android/server/audio/AudioServiceEvents.java102
-rw-r--r--services/core/java/com/android/server/audio/BtHelper.java41
-rwxr-xr-xservices/core/java/com/android/server/audio/MediaFocusControl.java21
-rw-r--r--services/core/java/com/android/server/display/AutomaticBrightnessController.java74
-rw-r--r--services/core/java/com/android/server/display/DisplayPowerController.java3
-rw-r--r--services/core/java/com/android/server/display/HysteresisLevels.java8
-rw-r--r--services/core/java/com/android/server/pm/DataLoaderManagerService.java105
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java19
-rw-r--r--services/core/java/com/android/server/pm/parsing/pkg/AndroidPackageUtils.java12
-rw-r--r--services/core/java/com/android/server/soundtrigger_middleware/OWNERS2
-rw-r--r--services/core/java/com/android/server/wm/AccessibilityController.java87
-rw-r--r--services/core/java/com/android/server/wm/ActivityRecord.java29
-rw-r--r--services/core/java/com/android/server/wm/ActivityStarter.java4
-rw-r--r--services/core/java/com/android/server/wm/ActivityTaskManagerService.java1
-rw-r--r--services/core/java/com/android/server/wm/InsetsPolicy.java19
-rw-r--r--services/core/java/com/android/server/wm/InsetsSourceProvider.java22
-rw-r--r--services/core/java/com/android/server/wm/InsetsStateController.java4
-rw-r--r--services/core/java/com/android/server/wm/Task.java18
-rw-r--r--services/core/java/com/android/server/wm/WallpaperWindowToken.java2
-rw-r--r--services/core/java/com/android/server/wm/WindowContainer.java10
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java23
-rw-r--r--services/core/java/com/android/server/wm/WindowProcessController.java56
-rw-r--r--services/core/java/com/android/server/wm/WindowStateAnimator.java5
-rw-r--r--services/core/jni/com_android_server_tv_TvUinputBridge.cpp2
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java192
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/PersonalAppsSuspensionHelper.java15
-rw-r--r--services/incremental/Android.bp1
-rw-r--r--services/incremental/BinderIncrementalService.cpp13
-rw-r--r--services/incremental/IncrementalService.cpp673
-rw-r--r--services/incremental/IncrementalService.h73
-rw-r--r--services/incremental/IncrementalServiceValidation.cpp77
-rw-r--r--services/incremental/IncrementalServiceValidation.h60
-rw-r--r--services/incremental/ServiceWrappers.cpp57
-rw-r--r--services/incremental/ServiceWrappers.h57
-rw-r--r--services/incremental/path.cpp2
-rw-r--r--services/incremental/test/IncrementalServiceTest.cpp56
-rw-r--r--services/java/com/android/server/SystemServer.java12
-rw-r--r--services/net/Android.bp1
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java8
-rw-r--r--services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java17
-rw-r--r--services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java244
-rw-r--r--services/tests/servicestests/src/com/android/server/display/AutomaticBrightnessControllerTest.java32
-rw-r--r--services/tests/uiservicestests/src/com/android/server/UiModeManagerServiceTest.java4
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java11
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java10
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/SystemServiceTestsBase.java5
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java25
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java19
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java53
-rw-r--r--tests/BlobStoreTestUtils/src/com/android/utils/blob/DummyBlobData.java2
-rw-r--r--tests/BlobStoreTestUtils/src/com/android/utils/blob/Utils.java3
-rw-r--r--wifi/java/android/net/wifi/WifiNetworkSpecifier.java5
417 files changed, 10482 insertions, 2196 deletions
diff --git a/Android.bp b/Android.bp
index bd30de2c6749..8d3b4af82bc8 100644
--- a/Android.bp
+++ b/Android.bp
@@ -708,11 +708,9 @@ filegroup {
name: "framework-services-net-module-wifi-shared-srcs",
srcs: [
"core/java/android/net/DhcpResults.java",
- "core/java/android/net/shared/Inet4AddressUtils.java",
"core/java/android/net/shared/InetAddressUtils.java",
"core/java/android/net/util/IpUtils.java",
"core/java/android/util/LocalLog.java",
- "core/java/com/android/internal/util/Preconditions.java",
],
}
@@ -1175,7 +1173,10 @@ java_library {
"framework-annotations-lib",
"unsupportedappusage",
],
- visibility: ["//frameworks/base/wifi"],
+ visibility: [
+ "//frameworks/base/wifi",
+ "//frameworks/base/services/net",
+ ],
}
filegroup {
diff --git a/StubLibraries.bp b/StubLibraries.bp
index 270c160dc5e9..8ab95242d8a2 100644
--- a/StubLibraries.bp
+++ b/StubLibraries.bp
@@ -145,7 +145,6 @@ droidstubs {
api_tag_name: "SYSTEM",
api_filename: "system-api.txt",
private_api_filename: "system-private.txt",
- private_dex_api_filename: "system-private-dex.txt",
removed_api_filename: "system-removed.txt",
removed_dex_api_filename: "system-removed-dex.txt",
arg_files: [
diff --git a/apex/blobstore/service/java/com/android/server/blob/BlobStoreConfig.java b/apex/blobstore/service/java/com/android/server/blob/BlobStoreConfig.java
index 6af1178b55f1..b4a7cd4de2ae 100644
--- a/apex/blobstore/service/java/com/android/server/blob/BlobStoreConfig.java
+++ b/apex/blobstore/service/java/com/android/server/blob/BlobStoreConfig.java
@@ -131,6 +131,10 @@ class BlobStoreConfig {
LEASE_ACQUISITION_WAIT_DURATION_MS = properties.getLong(key,
DEFAULT_LEASE_ACQUISITION_WAIT_DURATION_MS);
break;
+ case KEY_COMMIT_COOL_OFF_DURATION_MS:
+ COMMIT_COOL_OFF_DURATION_MS = properties.getLong(key,
+ DEFAULT_COMMIT_COOL_OFF_DURATION_MS);
+ break;
default:
Slog.wtf(TAG, "Unknown key in device config properties: " + key);
}
@@ -149,6 +153,9 @@ class BlobStoreConfig {
fout.println(String.format(dumpFormat, KEY_LEASE_ACQUISITION_WAIT_DURATION_MS,
TimeUtils.formatDuration(LEASE_ACQUISITION_WAIT_DURATION_MS),
TimeUtils.formatDuration(DEFAULT_LEASE_ACQUISITION_WAIT_DURATION_MS)));
+ fout.println(String.format(dumpFormat, KEY_COMMIT_COOL_OFF_DURATION_MS,
+ TimeUtils.formatDuration(COMMIT_COOL_OFF_DURATION_MS),
+ TimeUtils.formatDuration(DEFAULT_COMMIT_COOL_OFF_DURATION_MS)));
}
}
diff --git a/cmds/statsd/Android.bp b/cmds/statsd/Android.bp
index 0e49d187a3b5..f30ed17c392f 100644
--- a/cmds/statsd/Android.bp
+++ b/cmds/statsd/Android.bp
@@ -295,7 +295,12 @@ cc_test {
//TODO(b/153588990): Remove when the build system properly separates
//32bit and 64bit architectures.
- compile_multilib: "prefer32",
+ compile_multilib: "both",
+ multilib: {
+ lib64: {
+ suffix: "64",
+ }
+ },
cflags: [
"-Wall",
diff --git a/cmds/statsd/src/external/StatsPullerManager.cpp b/cmds/statsd/src/external/StatsPullerManager.cpp
index ebe961014336..cfd5d14b0d3b 100644
--- a/cmds/statsd/src/external/StatsPullerManager.cpp
+++ b/cmds/statsd/src/external/StatsPullerManager.cpp
@@ -252,9 +252,13 @@ void StatsPullerManager::RegisterPullUidProvider(const ConfigKey& configKey,
mPullUidProviders[configKey] = provider;
}
-void StatsPullerManager::UnregisterPullUidProvider(const ConfigKey& configKey) {
+void StatsPullerManager::UnregisterPullUidProvider(const ConfigKey& configKey,
+ wp<PullUidProvider> provider) {
std::lock_guard<std::mutex> _l(mLock);
- mPullUidProviders.erase(configKey);
+ const auto& it = mPullUidProviders.find(configKey);
+ if (it != mPullUidProviders.end() && it->second == provider) {
+ mPullUidProviders.erase(it);
+ }
}
void StatsPullerManager::OnAlarmFired(int64_t elapsedTimeNs) {
diff --git a/cmds/statsd/src/external/StatsPullerManager.h b/cmds/statsd/src/external/StatsPullerManager.h
index ab0cceeb112e..5e18aaa6ed61 100644
--- a/cmds/statsd/src/external/StatsPullerManager.h
+++ b/cmds/statsd/src/external/StatsPullerManager.h
@@ -78,11 +78,12 @@ public:
wp<PullDataReceiver> receiver);
// Registers a pull uid provider for the config key. When pulling atoms, it will be used to
- // determine which atoms to pull from.
+ // determine which uids to pull from.
virtual void RegisterPullUidProvider(const ConfigKey& configKey, wp<PullUidProvider> provider);
// Unregister a pull uid provider.
- virtual void UnregisterPullUidProvider(const ConfigKey& configKey);
+ virtual void UnregisterPullUidProvider(const ConfigKey& configKey,
+ wp<PullUidProvider> provider);
// Verify if we know how to pull for this matcher
bool PullerForMatcherExists(int tagId) const;
@@ -180,6 +181,8 @@ private:
FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents);
FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents_LateAlarm);
FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents_WithActivation);
+
+ FRIEND_TEST(StatsLogProcessorTest, TestPullUidProviderSetOnConfigUpdate);
};
} // namespace statsd
diff --git a/cmds/statsd/src/metrics/MetricsManager.cpp b/cmds/statsd/src/metrics/MetricsManager.cpp
index bcca1fd9fdc9..e03de0b991cd 100644
--- a/cmds/statsd/src/metrics/MetricsManager.cpp
+++ b/cmds/statsd/src/metrics/MetricsManager.cpp
@@ -189,7 +189,7 @@ MetricsManager::~MetricsManager() {
StateManager::getInstance().unregisterListener(atomId, it);
}
}
- mPullerManager->UnregisterPullUidProvider(mConfigKey);
+ mPullerManager->UnregisterPullUidProvider(mConfigKey, this);
VLOG("~MetricsManager()");
}
diff --git a/cmds/statsd/tests/MetricsManager_test.cpp b/cmds/statsd/tests/MetricsManager_test.cpp
index 1075fe4f9ce1..a44541dddf53 100644
--- a/cmds/statsd/tests/MetricsManager_test.cpp
+++ b/cmds/statsd/tests/MetricsManager_test.cpp
@@ -528,7 +528,7 @@ TEST(MetricsManagerTest, TestLogSources) {
}));
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
EXPECT_CALL(*pullerManager, RegisterPullUidProvider(kConfigKey, _)).Times(1);
- EXPECT_CALL(*pullerManager, UnregisterPullUidProvider(kConfigKey)).Times(1);
+ EXPECT_CALL(*pullerManager, UnregisterPullUidProvider(kConfigKey, _)).Times(1);
sp<AlarmMonitor> anomalyAlarmMonitor;
sp<AlarmMonitor> periodicAlarmMonitor;
diff --git a/cmds/statsd/tests/StatsLogProcessor_test.cpp b/cmds/statsd/tests/StatsLogProcessor_test.cpp
index d29394b1c5a6..b809286da5f4 100644
--- a/cmds/statsd/tests/StatsLogProcessor_test.cpp
+++ b/cmds/statsd/tests/StatsLogProcessor_test.cpp
@@ -301,6 +301,29 @@ TEST(StatsLogProcessorTest, TestOnDumpReportEraseData) {
EXPECT_TRUE(noData);
}
+TEST(StatsLogProcessorTest, TestPullUidProviderSetOnConfigUpdate) {
+ // Setup simple config key corresponding to empty config.
+ sp<UidMap> m = new UidMap();
+ sp<StatsPullerManager> pullerManager = new StatsPullerManager();
+ sp<AlarmMonitor> anomalyAlarmMonitor;
+ sp<AlarmMonitor> subscriberAlarmMonitor;
+ StatsLogProcessor p(
+ m, pullerManager, anomalyAlarmMonitor, subscriberAlarmMonitor, 0,
+ [](const ConfigKey& key) { return true; },
+ [](const int&, const vector<int64_t>&) { return true; });
+ ConfigKey key(3, 4);
+ StatsdConfig config = MakeConfig(false);
+ p.OnConfigUpdated(0, key, config);
+ EXPECT_NE(pullerManager->mPullUidProviders.find(key), pullerManager->mPullUidProviders.end());
+
+ config.add_default_pull_packages("AID_STATSD");
+ p.OnConfigUpdated(5, key, config);
+ EXPECT_NE(pullerManager->mPullUidProviders.find(key), pullerManager->mPullUidProviders.end());
+
+ p.OnConfigRemoved(key);
+ EXPECT_EQ(pullerManager->mPullUidProviders.find(key), pullerManager->mPullUidProviders.end());
+}
+
TEST(StatsLogProcessorTest, TestActiveConfigMetricDiskWriteRead) {
int uid = 1111;
diff --git a/cmds/statsd/tests/metrics/metrics_test_helper.h b/cmds/statsd/tests/metrics/metrics_test_helper.h
index 69f7e3f49792..be410b10d43b 100644
--- a/cmds/statsd/tests/metrics/metrics_test_helper.h
+++ b/cmds/statsd/tests/metrics/metrics_test_helper.h
@@ -44,7 +44,8 @@ public:
vector<std::shared_ptr<LogEvent>>* data, bool useUids));
MOCK_METHOD2(RegisterPullUidProvider,
void(const ConfigKey& configKey, wp<PullUidProvider> provider));
- MOCK_METHOD1(UnregisterPullUidProvider, void(const ConfigKey& configKey));
+ MOCK_METHOD2(UnregisterPullUidProvider,
+ void(const ConfigKey& configKey, wp<PullUidProvider> provider));
};
class MockUidMap : public UidMap {
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 21b56d3e337f..7d6ce41763d7 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -375,7 +375,6 @@ public final class ActivityThread extends ClientTransactionHandler {
String mInstrumentedLibDir = null;
boolean mSystemThread = false;
boolean mSomeActivitiesChanged = false;
- boolean mUpdatingSystemConfig = false;
/* package */ boolean mHiddenApiWarningShown = false;
// These can be accessed by multiple threads; mResourcesManager is the lock.
@@ -587,8 +586,11 @@ public final class ActivityThread extends ClientTransactionHandler {
throw new IllegalStateException(
"Received config update for non-existing activity");
}
+ // Given alwaysReportChange=false because the configuration is from view root, the
+ // activity may not be able to handle the changes. In that case the activity will be
+ // relaunched immediately, then Activity#onConfigurationChanged shouldn't be called.
activity.mMainThread.handleActivityConfigurationChanged(token, overrideConfig,
- newDisplayId);
+ newDisplayId, false /* alwaysReportChange */);
};
}
@@ -2029,12 +2031,7 @@ public final class ActivityThread extends ClientTransactionHandler {
break;
}
case APPLICATION_INFO_CHANGED:
- mUpdatingSystemConfig = true;
- try {
- handleApplicationInfoChanged((ApplicationInfo) msg.obj);
- } finally {
- mUpdatingSystemConfig = false;
- }
+ handleApplicationInfoChanged((ApplicationInfo) msg.obj);
break;
case RUN_ISOLATED_ENTRY_POINT:
handleRunIsolatedEntryPoint((String) ((SomeArgs) msg.obj).arg1,
@@ -2238,7 +2235,9 @@ public final class ActivityThread extends ClientTransactionHandler {
LoadedApk packageInfo = ref != null ? ref.get() : null;
if (ai != null && packageInfo != null) {
if (!isLoadedApkResourceDirsUpToDate(packageInfo, ai)) {
- packageInfo.updateApplicationInfo(ai, null);
+ List<String> oldPaths = new ArrayList<>();
+ LoadedApk.makePaths(this, ai, oldPaths);
+ packageInfo.updateApplicationInfo(ai, oldPaths);
}
if (packageInfo.isSecurityViolation()
@@ -2326,7 +2325,9 @@ public final class ActivityThread extends ClientTransactionHandler {
if (packageInfo != null) {
if (!isLoadedApkResourceDirsUpToDate(packageInfo, aInfo)) {
- packageInfo.updateApplicationInfo(aInfo, null);
+ List<String> oldPaths = new ArrayList<>();
+ LoadedApk.makePaths(this, aInfo, oldPaths);
+ packageInfo.updateApplicationInfo(aInfo, oldPaths);
}
return packageInfo;
@@ -4467,7 +4468,8 @@ public final class ActivityThread extends ClientTransactionHandler {
// simply finishing, and we are not starting another activity.
if (!r.activity.mFinished && willBeVisible && r.activity.mDecor != null && !r.hideForNow) {
if (r.newConfig != null) {
- performConfigurationChangedForActivity(r, r.newConfig);
+ performConfigurationChangedForActivity(r, r.newConfig,
+ false /* alwaysReportChange */);
if (DEBUG_CONFIGURATION) {
Slog.v(TAG, "Resuming activity " + r.activityInfo.name + " with newConfig "
+ r.activity.mCurrentConfig);
@@ -4787,7 +4789,8 @@ public final class ActivityThread extends ClientTransactionHandler {
}
}
if (r.newConfig != null) {
- performConfigurationChangedForActivity(r, r.newConfig);
+ performConfigurationChangedForActivity(r, r.newConfig,
+ false /* alwaysReportChange */);
if (DEBUG_CONFIGURATION) Slog.v(TAG, "Updating activity vis "
+ r.activityInfo.name + " with new config "
+ r.activity.mCurrentConfig);
@@ -5447,11 +5450,12 @@ public final class ActivityThread extends ClientTransactionHandler {
* @param r ActivityClientRecord representing the Activity.
* @param newBaseConfig The new configuration to use. This may be augmented with
* {@link ActivityClientRecord#overrideConfig}.
+ * @param alwaysReportChange If the configuration is changed, always report to activity.
*/
private void performConfigurationChangedForActivity(ActivityClientRecord r,
- Configuration newBaseConfig) {
- performConfigurationChangedForActivity(r, newBaseConfig,
- r.activity.getDisplayId(), false /* movedToDifferentDisplay */);
+ Configuration newBaseConfig, boolean alwaysReportChange) {
+ performConfigurationChangedForActivity(r, newBaseConfig, r.activity.getDisplayId(),
+ false /* movedToDifferentDisplay */, alwaysReportChange);
}
/**
@@ -5464,16 +5468,19 @@ public final class ActivityThread extends ClientTransactionHandler {
* {@link ActivityClientRecord#overrideConfig}.
* @param displayId The id of the display where the Activity currently resides.
* @param movedToDifferentDisplay Indicates if the activity was moved to different display.
+ * @param alwaysReportChange If the configuration is changed, always report to activity.
* @return {@link Configuration} instance sent to client, null if not sent.
*/
private Configuration performConfigurationChangedForActivity(ActivityClientRecord r,
- Configuration newBaseConfig, int displayId, boolean movedToDifferentDisplay) {
+ Configuration newBaseConfig, int displayId, boolean movedToDifferentDisplay,
+ boolean alwaysReportChange) {
r.tmpConfig.setTo(newBaseConfig);
if (r.overrideConfig != null) {
r.tmpConfig.updateFrom(r.overrideConfig);
}
final Configuration reportedConfig = performActivityConfigurationChanged(r.activity,
- r.tmpConfig, r.overrideConfig, displayId, movedToDifferentDisplay);
+ r.tmpConfig, r.overrideConfig, displayId, movedToDifferentDisplay,
+ alwaysReportChange);
freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(r.tmpConfig));
return reportedConfig;
}
@@ -5529,11 +5536,12 @@ public final class ActivityThread extends ClientTransactionHandler {
* ActivityManager.
* @param displayId Id of the display where activity currently resides.
* @param movedToDifferentDisplay Indicates if the activity was moved to different display.
+ * @param alwaysReportChange If the configuration is changed, always report to activity.
* @return Configuration sent to client, null if no changes and not moved to different display.
*/
private Configuration performActivityConfigurationChanged(Activity activity,
Configuration newConfig, Configuration amOverrideConfig, int displayId,
- boolean movedToDifferentDisplay) {
+ boolean movedToDifferentDisplay, boolean alwaysReportChange) {
if (activity == null) {
throw new IllegalArgumentException("No activity provided.");
}
@@ -5556,7 +5564,7 @@ public final class ActivityThread extends ClientTransactionHandler {
// Always send the task-level config changes. For system-level configuration, if
// this activity doesn't handle any of the config changes, then don't bother
// calling onConfigurationChanged as we're going to destroy it.
- if (!mUpdatingSystemConfig
+ if (alwaysReportChange
|| (~activity.mActivityInfo.getRealConfigChanged() & diff) == 0
|| !REPORT_TO_ACTIVITY) {
shouldChangeConfig = true;
@@ -5638,12 +5646,7 @@ public final class ActivityThread extends ClientTransactionHandler {
public void handleConfigurationChanged(Configuration config) {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "configChanged");
mCurDefaultDisplayDpi = config.densityDpi;
- mUpdatingSystemConfig = true;
- try {
- handleConfigurationChanged(config, null /* compat */);
- } finally {
- mUpdatingSystemConfig = false;
- }
+ handleConfigurationChanged(config, null /* compat */);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
@@ -5725,7 +5728,7 @@ public final class ActivityThread extends ClientTransactionHandler {
// config and avoid onConfigurationChanged if it hasn't changed.
Activity a = (Activity) cb;
performConfigurationChangedForActivity(mActivities.get(a.getActivityToken()),
- config);
+ config, false /* alwaysReportChange */);
} else if (!equivalent) {
performConfigurationChanged(cb, config);
} else {
@@ -5832,16 +5835,28 @@ public final class ActivityThread extends ClientTransactionHandler {
}
}
+ @Override
+ public void handleActivityConfigurationChanged(IBinder activityToken,
+ Configuration overrideConfig, int displayId) {
+ handleActivityConfigurationChanged(activityToken, overrideConfig, displayId,
+ // This is the only place that uses alwaysReportChange=true. The entry point should
+ // be from ActivityConfigurationChangeItem or MoveToDisplayItem, so the server side
+ // has confirmed the activity should handle the configuration instead of relaunch.
+ // If Activity#onConfigurationChanged is called unexpectedly, then we can know it is
+ // something wrong from server side.
+ true /* alwaysReportChange */);
+ }
+
/**
* Handle new activity configuration and/or move to a different display.
* @param activityToken Target activity token.
* @param overrideConfig Activity override config.
* @param displayId Id of the display where activity was moved to, -1 if there was no move and
* value didn't change.
+ * @param alwaysReportChange If the configuration is changed, always report to activity.
*/
- @Override
- public void handleActivityConfigurationChanged(IBinder activityToken,
- Configuration overrideConfig, int displayId) {
+ void handleActivityConfigurationChanged(IBinder activityToken, Configuration overrideConfig,
+ int displayId, boolean alwaysReportChange) {
ActivityClientRecord r = mActivities.get(activityToken);
// Check input params.
if (r == null || r.activity == null) {
@@ -5880,14 +5895,15 @@ public final class ActivityThread extends ClientTransactionHandler {
+ ", config=" + overrideConfig);
final Configuration reportedConfig = performConfigurationChangedForActivity(r,
- mCompatConfiguration, displayId, true /* movedToDifferentDisplay */);
+ mCompatConfiguration, displayId, true /* movedToDifferentDisplay */,
+ alwaysReportChange);
if (viewRoot != null) {
viewRoot.onMovedToDisplay(displayId, reportedConfig);
}
} else {
if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle activity config changed: "
+ r.activityInfo.name + ", config=" + overrideConfig);
- performConfigurationChangedForActivity(r, mCompatConfiguration);
+ performConfigurationChangedForActivity(r, mCompatConfiguration, alwaysReportChange);
}
// Notify the ViewRootImpl instance about configuration changes. It may have initiated this
// update to make sure that resources are updated before updating itself.
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 85bafd9d37e2..8a57f826ad2e 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -6873,9 +6873,9 @@ public class PackageParser {
/** @hide */
public boolean canHaveOatDir() {
- // The following app types CANNOT have oat directory
- // - non-updated system apps
- return !isSystem() || isUpdatedSystemApp();
+ // Nobody should be calling this method ever, but we can't rely on this.
+ // Thus no logic here and a reasonable return value.
+ return true;
}
public boolean isMatch(int flags) {
diff --git a/core/java/android/os/incremental/IncrementalFileStorages.java b/core/java/android/os/incremental/IncrementalFileStorages.java
index 251995a14090..321dc9e2246e 100644
--- a/core/java/android/os/incremental/IncrementalFileStorages.java
+++ b/core/java/android/os/incremental/IncrementalFileStorages.java
@@ -38,16 +38,10 @@ import android.content.pm.DataLoaderParams;
import android.content.pm.IDataLoaderStatusListener;
import android.content.pm.InstallationFileParcel;
import android.text.TextUtils;
-import android.util.Slog;
import java.io.File;
import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
import java.util.List;
-import java.util.Objects;
-import java.util.Random;
/**
* This class manages storage instances used during a package installation session.
@@ -56,13 +50,9 @@ import java.util.Random;
public final class IncrementalFileStorages {
private static final String TAG = "IncrementalFileStorages";
- private static final String TMP_DIR_ROOT = "/data/incremental/tmp";
- private static final Random TMP_DIR_RANDOM = new Random();
-
+ private @NonNull final IncrementalManager mIncrementalManager;
+ private @NonNull final File mStageDir;
private @Nullable IncrementalStorage mDefaultStorage;
- private @Nullable String mDefaultDir;
- private @NonNull IncrementalManager mIncrementalManager;
- private @NonNull File mStageDir;
/**
* Set up files and directories used in an installation session. Only used by Incremental.
@@ -85,72 +75,63 @@ public final class IncrementalFileStorages {
throw new IOException("Failed to obtain incrementalManager.");
}
- IncrementalFileStorages result = null;
- try {
- result = new IncrementalFileStorages(stageDir, incrementalManager, dataLoaderParams,
- dataLoaderStatusListener);
-
- if (!addedFiles.isEmpty()) {
- result.mDefaultStorage.bind(stageDir.getAbsolutePath());
- }
-
- for (InstallationFileParcel file : addedFiles) {
- if (file.location == LOCATION_DATA_APP) {
- try {
- result.addApkFile(file);
- } catch (IOException e) {
- // TODO(b/146080380): add incremental-specific error code
- throw new IOException(
- "Failed to add file to IncFS: " + file.name + ", reason: ", e);
- }
- } else {
- throw new IOException("Unknown file location: " + file.location);
+ final IncrementalFileStorages result =
+ new IncrementalFileStorages(stageDir, incrementalManager, dataLoaderParams,
+ dataLoaderStatusListener);
+ for (InstallationFileParcel file : addedFiles) {
+ if (file.location == LOCATION_DATA_APP) {
+ try {
+ result.addApkFile(file);
+ } catch (IOException e) {
+ // TODO(b/146080380): add incremental-specific error code
+ throw new IOException(
+ "Failed to add file to IncFS: " + file.name + ", reason: ", e);
}
+ } else {
+ throw new IOException("Unknown file location: " + file.location);
}
+ }
- // TODO(b/146080380): remove 5 secs wait in startLoading
- if (!result.mDefaultStorage.startLoading()) {
- // TODO(b/146080380): add incremental-specific error code
- throw new IOException("Failed to start loading data for Incremental installation.");
- }
-
- return result;
- } catch (IOException e) {
- Slog.e(TAG, "Failed to initialize Incremental file storages. Cleaning up...", e);
- if (result != null) {
- result.cleanUp();
- }
- throw e;
+ if (!result.mDefaultStorage.startLoading()) {
+ // TODO(b/146080380): add incremental-specific error code
+ throw new IOException("Failed to start loading data for Incremental installation.");
}
+
+ return result;
}
private IncrementalFileStorages(@NonNull File stageDir,
@NonNull IncrementalManager incrementalManager,
@NonNull DataLoaderParams dataLoaderParams,
@Nullable IDataLoaderStatusListener dataLoaderStatusListener) throws IOException {
- mStageDir = stageDir;
- mIncrementalManager = incrementalManager;
- if (dataLoaderParams.getComponentName().getPackageName().equals("local")) {
- final String incrementalPath = dataLoaderParams.getArguments();
- mDefaultDir = incrementalPath;
- if (TextUtils.isEmpty(mDefaultDir)) {
- throw new IOException("Failed to create storage: incrementalPath is empty");
- }
- mDefaultStorage = mIncrementalManager.openStorage(incrementalPath);
- } else {
- mDefaultDir = getTempDir();
- if (mDefaultDir == null) {
- throw new IOException("Failed to create storage: tempDir is empty");
+ try {
+ mStageDir = stageDir;
+ mIncrementalManager = incrementalManager;
+ if (dataLoaderParams.getComponentName().getPackageName().equals("local")) {
+ final String incrementalPath = dataLoaderParams.getArguments();
+ if (TextUtils.isEmpty(incrementalPath)) {
+ throw new IOException("Failed to create storage: incrementalPath is empty");
+ }
+ mDefaultStorage = mIncrementalManager.openStorage(incrementalPath);
+ if (mDefaultStorage == null) {
+ throw new IOException(
+ "Couldn't open incremental storage at " + incrementalPath);
+ }
+ mDefaultStorage.bind(stageDir.getAbsolutePath());
+ } else {
+ mDefaultStorage = mIncrementalManager.createStorage(stageDir.getAbsolutePath(),
+ dataLoaderParams,
+ dataLoaderStatusListener,
+ IncrementalManager.CREATE_MODE_CREATE
+ | IncrementalManager.CREATE_MODE_TEMPORARY_BIND, false);
+ if (mDefaultStorage == null) {
+ throw new IOException(
+ "Couldn't create incremental storage at " + stageDir);
+ }
}
- mDefaultStorage = mIncrementalManager.createStorage(mDefaultDir,
- dataLoaderParams,
- dataLoaderStatusListener,
- IncrementalManager.CREATE_MODE_CREATE
- | IncrementalManager.CREATE_MODE_TEMPORARY_BIND, false);
- }
-
- if (mDefaultStorage == null) {
- throw new IOException("Failed to create storage");
+ } catch (IOException e) {
+ cleanUp();
+ throw e;
}
}
@@ -167,27 +148,14 @@ public final class IncrementalFileStorages {
* TODO(b/136132412): make sure unnecessary binds are removed but useful storages are kept
*/
public void cleanUp() {
- Objects.requireNonNull(mDefaultStorage);
+ if (mDefaultStorage == null) {
+ return;
+ }
try {
- mDefaultStorage.unBind(mDefaultDir);
mDefaultStorage.unBind(mStageDir.getAbsolutePath());
} catch (IOException ignored) {
}
-
- mDefaultDir = null;
mDefaultStorage = null;
}
-
- private static String getTempDir() {
- final Path tmpDir = Paths.get(TMP_DIR_ROOT,
- String.valueOf(TMP_DIR_RANDOM.nextInt(Integer.MAX_VALUE - 1)));
- try {
- Files.createDirectories(tmpDir);
- } catch (Exception ex) {
- Slog.e(TAG, "Failed to create dir", ex);
- return null;
- }
- return tmpDir.toAbsolutePath().toString();
- }
}
diff --git a/core/java/android/os/incremental/IncrementalManager.java b/core/java/android/os/incremental/IncrementalManager.java
index 35518db32829..916edfae679f 100644
--- a/core/java/android/os/incremental/IncrementalManager.java
+++ b/core/java/android/os/incremental/IncrementalManager.java
@@ -32,8 +32,12 @@ import java.io.File;
import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.nio.file.FileVisitResult;
+import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.attribute.BasicFileAttributes;
/**
* Provides operations to open or create an IncrementalStorage, using IIncrementalService
@@ -176,25 +180,6 @@ public final class IncrementalManager {
}
/**
- * Iterates through path parents to find the base dir of an Incremental Storage.
- *
- * @param file Target file to search storage for.
- * @return Absolute path which is a bind-mount point of Incremental File System.
- */
- @Nullable
- private Path getStoragePathForFile(File file) {
- File currentPath = new File(file.getParent());
- while (currentPath.getParent() != null) {
- IncrementalStorage storage = openStorage(currentPath.getAbsolutePath());
- if (storage != null) {
- return currentPath.toPath();
- }
- currentPath = new File(currentPath.getParent());
- }
- return null;
- }
-
- /**
* Set up an app's code path. The expected outcome of this method is:
* 1) The actual apk directory under /data/incremental is bind-mounted to the parent directory
* of {@code afterCodeFile}.
@@ -212,29 +197,27 @@ public final class IncrementalManager {
*/
public void renameCodePath(File beforeCodeFile, File afterCodeFile)
throws IllegalArgumentException, IOException {
- final String beforeCodePath = beforeCodeFile.getAbsolutePath();
- final String afterCodePathParent = afterCodeFile.getParentFile().getAbsolutePath();
- if (!isIncrementalPath(beforeCodePath)) {
- throw new IllegalArgumentException("Not an Incremental path: " + beforeCodePath);
- }
- final String afterCodePathName = afterCodeFile.getName();
- final Path apkStoragePath = Paths.get(beforeCodePath);
- if (apkStoragePath == null || apkStoragePath.toAbsolutePath() == null) {
- throw new IOException("Invalid source storage path for: " + beforeCodePath);
- }
- final IncrementalStorage apkStorage =
- openStorage(apkStoragePath.toAbsolutePath().toString());
+ final File beforeCodeAbsolute = beforeCodeFile.getAbsoluteFile();
+ final IncrementalStorage apkStorage = openStorage(beforeCodeAbsolute.toString());
if (apkStorage == null) {
- throw new IOException("Failed to retrieve storage from Incremental Service.");
+ throw new IllegalArgumentException("Not an Incremental path: " + beforeCodeAbsolute);
}
- final IncrementalStorage linkedApkStorage = createStorage(afterCodePathParent, apkStorage,
- IncrementalManager.CREATE_MODE_CREATE
- | IncrementalManager.CREATE_MODE_PERMANENT_BIND);
+ final String targetStorageDir = afterCodeFile.getAbsoluteFile().getParent();
+ final IncrementalStorage linkedApkStorage =
+ createStorage(targetStorageDir, apkStorage,
+ IncrementalManager.CREATE_MODE_CREATE
+ | IncrementalManager.CREATE_MODE_PERMANENT_BIND);
if (linkedApkStorage == null) {
- throw new IOException("Failed to create linked storage at dir: " + afterCodePathParent);
+ throw new IOException("Failed to create linked storage at dir: " + targetStorageDir);
+ }
+ try {
+ final String afterCodePathName = afterCodeFile.getName();
+ linkFiles(apkStorage, beforeCodeAbsolute, "", linkedApkStorage, afterCodePathName);
+ apkStorage.unBind(beforeCodeAbsolute.toString());
+ } catch (Exception e) {
+ linkedApkStorage.unBind(targetStorageDir);
+ throw e;
}
- linkFiles(apkStorage, beforeCodeFile, "", linkedApkStorage, afterCodePathName);
- apkStorage.unBind(beforeCodePath);
}
/**
@@ -252,22 +235,27 @@ public final class IncrementalManager {
private void linkFiles(IncrementalStorage sourceStorage, File sourceAbsolutePath,
String sourceRelativePath, IncrementalStorage targetStorage,
String targetRelativePath) throws IOException {
- targetStorage.makeDirectory(targetRelativePath);
- final File[] entryList = sourceAbsolutePath.listFiles();
- for (int i = 0; i < entryList.length; i++) {
- final File entry = entryList[i];
- final String entryName = entryList[i].getName();
- final String sourceEntryRelativePath =
- sourceRelativePath.isEmpty() ? entryName : sourceRelativePath + "/" + entryName;
- final String targetEntryRelativePath = targetRelativePath + "/" + entryName;
- if (entry.isFile()) {
+ final Path sourceBase = sourceAbsolutePath.toPath().resolve(sourceRelativePath);
+ final Path targetRelative = Paths.get(targetRelativePath);
+ Files.walkFileTree(sourceAbsolutePath.toPath(), new SimpleFileVisitor<Path>() {
+ @Override
+ public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
+ throws IOException {
+ final Path relativeDir = sourceBase.relativize(dir);
+ targetStorage.makeDirectory(targetRelative.resolve(relativeDir).toString());
+ return FileVisitResult.CONTINUE;
+ }
+
+ @Override
+ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
+ throws IOException {
+ final Path relativeFile = sourceBase.relativize(file);
sourceStorage.makeLink(
- sourceEntryRelativePath, targetStorage, targetEntryRelativePath);
- } else if (entry.isDirectory()) {
- linkFiles(sourceStorage, entry, sourceEntryRelativePath, targetStorage,
- targetEntryRelativePath);
+ file.toAbsolutePath().toString(), targetStorage,
+ targetRelative.resolve(relativeFile).toString());
+ return FileVisitResult.CONTINUE;
}
- }
+ });
}
/**
diff --git a/core/java/android/text/style/DynamicDrawableSpan.java b/core/java/android/text/style/DynamicDrawableSpan.java
index f37e4238a1c6..d6d99f846e16 100644
--- a/core/java/android/text/style/DynamicDrawableSpan.java
+++ b/core/java/android/text/style/DynamicDrawableSpan.java
@@ -166,7 +166,7 @@ public abstract class DynamicDrawableSpan extends ReplacementSpan {
if (mVerticalAlignment == ALIGN_BASELINE) {
transY -= paint.getFontMetricsInt().descent;
} else if (mVerticalAlignment == ALIGN_CENTER) {
- transY = (bottom - top) / 2 - b.getBounds().height() / 2;
+ transY = top + (bottom - top) / 2 - b.getBounds().height() / 2;
}
canvas.translate(x, transY);
diff --git a/core/java/android/view/InsetsSourceConsumer.java b/core/java/android/view/InsetsSourceConsumer.java
index a72383913420..2dcfd899adf4 100644
--- a/core/java/android/view/InsetsSourceConsumer.java
+++ b/core/java/android/view/InsetsSourceConsumer.java
@@ -69,6 +69,13 @@ public class InsetsSourceConsumer {
private Rect mPendingFrame;
private Rect mPendingVisibleFrame;
+ /**
+ * Indicates if we have the pending animation. When we have the control, we need to play the
+ * animation if the requested visibility is different from the current state. But if we haven't
+ * had a leash yet, we will set this flag, and play the animation once we get the leash.
+ */
+ private boolean mIsAnimationPending;
+
public InsetsSourceConsumer(@InternalInsetsType int type, InsetsState state,
Supplier<Transaction> transactionSupplier, InsetsController controller) {
mType = type;
@@ -107,13 +114,21 @@ public class InsetsSourceConsumer {
} else {
// We are gaining control, and need to run an animation since previous state
// didn't match
- if (isRequestedVisibleAwaitingControl() != mState.getSource(mType).isVisible()) {
- if (isRequestedVisibleAwaitingControl()) {
+ final boolean requestedVisible = isRequestedVisibleAwaitingControl();
+ final boolean needAnimation = requestedVisible != mState.getSource(mType).isVisible();
+ if (control.getLeash() != null && (needAnimation || mIsAnimationPending)) {
+ if (requestedVisible) {
showTypes[0] |= toPublicType(getType());
} else {
hideTypes[0] |= toPublicType(getType());
}
+ mIsAnimationPending = false;
} else {
+ if (needAnimation) {
+ // We need animation but we haven't had a leash yet. Set this flag that when we
+ // get the leash we can play the deferred animation.
+ mIsAnimationPending = true;
+ }
// We are gaining control, but don't need to run an animation.
// However make sure that the leash visibility is still up to date.
if (applyLocalVisibilityOverride()) {
@@ -274,7 +289,10 @@ public class InsetsSourceConsumer {
* the moment.
*/
protected void setRequestedVisible(boolean requestedVisible) {
- mRequestedVisible = requestedVisible;
+ if (mRequestedVisible != requestedVisible) {
+ mRequestedVisible = requestedVisible;
+ mIsAnimationPending = false;
+ }
if (applyLocalVisibilityOverride()) {
mController.notifyVisibilityChanged();
}
diff --git a/core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java b/core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java
index b1e356d258ee..bcb32fb60f47 100644
--- a/core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java
+++ b/core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java
@@ -437,6 +437,9 @@ public abstract class AbstractMultiProfilePagerAdapter extends PagerAdapter {
resetViewVisibilitiesForWorkProfileEmptyState(emptyStateView);
emptyStateView.setVisibility(View.VISIBLE);
+ View container = emptyStateView.findViewById(R.id.resolver_empty_state_container);
+ setupContainerPadding(container);
+
TextView title = emptyStateView.findViewById(R.id.resolver_empty_state_title);
title.setText(titleRes);
@@ -463,6 +466,12 @@ public abstract class AbstractMultiProfilePagerAdapter extends PagerAdapter {
activeListAdapter.markTabLoaded();
}
+ /**
+ * Sets up the padding of the view containing the empty state screens.
+ * <p>This method is meant to be overridden so that subclasses can customize the padding.
+ */
+ protected void setupContainerPadding(View container) {}
+
private void showConsumerUserNoAppsAvailableEmptyState(ResolverListAdapter activeListAdapter) {
ProfileDescriptor descriptor = getItem(
userHandleToPageIndex(activeListAdapter.getUserHandle()));
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index 970bab9bc53b..b671fa74bf9a 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -2721,11 +2721,12 @@ public class ChooserActivity extends ResolverActivity implements
}
private void setupScrollListener() {
- if (mResolverDrawerLayout == null || shouldShowTabs()) {
+ if (mResolverDrawerLayout == null) {
return;
}
- final View chooserHeader = mResolverDrawerLayout.findViewById(R.id.chooser_header);
- final float defaultElevation = chooserHeader.getElevation();
+ int elevatedViewResId = shouldShowTabs() ? R.id.resolver_tab_divider : R.id.chooser_header;
+ final View elevatedView = mResolverDrawerLayout.findViewById(elevatedViewResId);
+ final float defaultElevation = elevatedView.getElevation();
final float chooserHeaderScrollElevation =
getResources().getDimensionPixelSize(R.dimen.chooser_header_scroll_elevation);
@@ -2738,12 +2739,12 @@ public class ChooserActivity extends ResolverActivity implements
if (view.getChildCount() > 0) {
View child = view.getLayoutManager().findViewByPosition(0);
if (child == null || child.getTop() < 0) {
- chooserHeader.setElevation(chooserHeaderScrollElevation);
+ elevatedView.setElevation(chooserHeaderScrollElevation);
return;
}
}
- chooserHeader.setElevation(defaultElevation);
+ elevatedView.setElevation(defaultElevation);
}
});
}
@@ -2885,6 +2886,13 @@ public class ChooserActivity extends ResolverActivity implements
return METRICS_CATEGORY_CHOOSER;
}
+ @Override
+ protected void onProfileTabSelected() {
+ ChooserGridAdapter currentRootAdapter =
+ mChooserMultiProfilePagerAdapter.getCurrentRootAdapter();
+ currentRootAdapter.updateDirectShareExpansion();
+ }
+
/**
* Adapter for all types of items and targets in ShareSheet.
* Note that ranked sections like Direct Share - while appearing grid-like - are handled on the
@@ -3357,15 +3365,7 @@ public class ChooserActivity extends ResolverActivity implements
}
public void handleScroll(View v, int y, int oldy) {
- // Only expand direct share area if there is a minimum number of shortcuts,
- // which will help reduce the amount of visible shuffling due to older-style
- // direct share targets.
- int orientation = getResources().getConfiguration().orientation;
- boolean canExpandDirectShare =
- mChooserListAdapter.getNumShortcutResults() > getMaxTargetsPerRow()
- && orientation == Configuration.ORIENTATION_PORTRAIT
- && !isInMultiWindowMode();
-
+ boolean canExpandDirectShare = canExpandDirectShare();
if (mDirectShareViewHolder != null && canExpandDirectShare) {
mDirectShareViewHolder.handleScroll(
mChooserMultiProfilePagerAdapter.getActiveAdapterView(), y, oldy,
@@ -3373,6 +3373,18 @@ public class ChooserActivity extends ResolverActivity implements
}
}
+ /**
+ * Only expand direct share area if there is a minimum number of shortcuts,
+ * which will help reduce the amount of visible shuffling due to older-style
+ * direct share targets.
+ */
+ private boolean canExpandDirectShare() {
+ int orientation = getResources().getConfiguration().orientation;
+ return mChooserListAdapter.getNumShortcutResults() > getMaxTargetsPerRow()
+ && orientation == Configuration.ORIENTATION_PORTRAIT
+ && !isInMultiWindowMode();
+ }
+
public ChooserListAdapter getListAdapter() {
return mChooserListAdapter;
}
@@ -3380,6 +3392,19 @@ public class ChooserActivity extends ResolverActivity implements
boolean shouldCellSpan(int position) {
return getItemViewType(position) == VIEW_TYPE_NORMAL;
}
+
+ void updateDirectShareExpansion() {
+ if (mDirectShareViewHolder == null || !canExpandDirectShare()) {
+ return;
+ }
+ RecyclerView activeAdapterView =
+ mChooserMultiProfilePagerAdapter.getActiveAdapterView();
+ if (mResolverDrawerLayout.isCollapsed()) {
+ mDirectShareViewHolder.collapse(activeAdapterView);
+ } else {
+ mDirectShareViewHolder.expand(activeAdapterView);
+ }
+ }
}
/**
@@ -3577,6 +3602,20 @@ public class ChooserActivity extends ResolverActivity implements
newHeight = Math.max(newHeight, mDirectShareMinHeight);
yDiff = newHeight - prevHeight;
+ updateDirectShareRowHeight(view, yDiff, newHeight);
+ }
+
+ void expand(RecyclerView view) {
+ updateDirectShareRowHeight(view, mDirectShareMaxHeight - mDirectShareCurrHeight,
+ mDirectShareMaxHeight);
+ }
+
+ void collapse(RecyclerView view) {
+ updateDirectShareRowHeight(view, mDirectShareMinHeight - mDirectShareCurrHeight,
+ mDirectShareMinHeight);
+ }
+
+ private void updateDirectShareRowHeight(RecyclerView view, int yDiff, int newHeight) {
if (view == null || view.getChildCount() == 0 || yDiff == 0) {
return;
}
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index 1bc982cdb42b..00faa3b3d21e 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -146,6 +146,7 @@ public class ResolverActivity extends Activity implements
private static final String TAG = "ResolverActivity";
private static final boolean DEBUG = false;
+ private static final String LAST_SHOWN_TAB_KEY = "last_shown_tab_key";
private boolean mRegistered;
@@ -844,9 +845,19 @@ public class ResolverActivity extends Activity implements
}
@Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ ViewPager viewPager = findViewById(R.id.profile_pager);
+ outState.putInt(LAST_SHOWN_TAB_KEY, viewPager.getCurrentItem());
+ }
+
+ @Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
resetButtonBar();
+ ViewPager viewPager = findViewById(R.id.profile_pager);
+ viewPager.setCurrentItem(savedInstanceState.getInt(LAST_SHOWN_TAB_KEY));
+ mMultiProfilePagerAdapter.clearInactiveProfileCache();
}
private boolean isHttpSchemeAndViewAction(Intent intent) {
@@ -1585,6 +1596,7 @@ public class ResolverActivity extends Activity implements
TabHost tabHost = findViewById(R.id.profile_tabhost);
tabHost.setup();
ViewPager viewPager = findViewById(R.id.profile_pager);
+ viewPager.setSaveEnabled(false);
TabHost.TabSpec tabSpec = tabHost.newTabSpec(TAB_TAG_PERSONAL)
.setContent(R.id.profile_pager)
.setIndicator(getString(R.string.resolver_personal_tab));
@@ -1610,6 +1622,7 @@ public class ResolverActivity extends Activity implements
}
setupViewVisibilities();
maybeLogProfileChange();
+ onProfileTabSelected();
DevicePolicyEventLogger
.createEvent(DevicePolicyEnums.RESOLVER_SWITCH_TABS)
.setInt(viewPager.getCurrentItem())
@@ -1628,6 +1641,12 @@ public class ResolverActivity extends Activity implements
findViewById(R.id.resolver_tab_divider).setVisibility(View.VISIBLE);
}
+ /**
+ * Callback called when user changes the profile tab.
+ * <p>This method is intended to be overridden by subclasses.
+ */
+ protected void onProfileTabSelected() { }
+
private void resetCheckedItem() {
if (!isIntentPicker()) {
return;
@@ -1745,22 +1764,33 @@ public class ResolverActivity extends Activity implements
return;
}
final ViewGroup buttonLayout = findViewById(R.id.button_bar);
- if (buttonLayout != null) {
- buttonLayout.setVisibility(View.VISIBLE);
-
- if (!useLayoutWithDefault()) {
- int inset = mSystemWindowInsets != null ? mSystemWindowInsets.bottom : 0;
- buttonLayout.setPadding(buttonLayout.getPaddingLeft(), buttonLayout.getPaddingTop(),
- buttonLayout.getPaddingRight(), getResources().getDimensionPixelSize(
- R.dimen.resolver_button_bar_spacing) + inset);
- }
- mOnceButton = (Button) buttonLayout.findViewById(R.id.button_once);
- mAlwaysButton = (Button) buttonLayout.findViewById(R.id.button_always);
-
- resetAlwaysOrOnceButtonBar();
- } else {
+ if (buttonLayout == null) {
Log.e(TAG, "Layout unexpectedly does not have a button bar");
+ return;
+ }
+ ResolverListAdapter activeListAdapter =
+ mMultiProfilePagerAdapter.getActiveListAdapter();
+ View buttonBarDivider = findViewById(R.id.resolver_button_bar_divider);
+ if (activeListAdapter.isTabLoaded()
+ && mMultiProfilePagerAdapter.shouldShowEmptyStateScreen(activeListAdapter)) {
+ buttonLayout.setVisibility(View.INVISIBLE);
+ buttonBarDivider.setVisibility(View.INVISIBLE);
+ return;
}
+
+ buttonBarDivider.setVisibility(View.VISIBLE);
+ buttonLayout.setVisibility(View.VISIBLE);
+
+ if (!useLayoutWithDefault()) {
+ int inset = mSystemWindowInsets != null ? mSystemWindowInsets.bottom : 0;
+ buttonLayout.setPadding(buttonLayout.getPaddingLeft(), buttonLayout.getPaddingTop(),
+ buttonLayout.getPaddingRight(), getResources().getDimensionPixelSize(
+ R.dimen.resolver_button_bar_spacing) + inset);
+ }
+ mOnceButton = (Button) buttonLayout.findViewById(R.id.button_once);
+ mAlwaysButton = (Button) buttonLayout.findViewById(R.id.button_always);
+
+ resetAlwaysOrOnceButtonBar();
}
private void resetAlwaysOrOnceButtonBar() {
diff --git a/core/java/com/android/internal/app/ResolverMultiProfilePagerAdapter.java b/core/java/com/android/internal/app/ResolverMultiProfilePagerAdapter.java
index ad31d8b2e49a..885d1bbc5b77 100644
--- a/core/java/com/android/internal/app/ResolverMultiProfilePagerAdapter.java
+++ b/core/java/com/android/internal/app/ResolverMultiProfilePagerAdapter.java
@@ -213,6 +213,12 @@ public class ResolverMultiProfilePagerAdapter extends AbstractMultiProfilePagerA
/* subtitleRes */ 0);
}
+ @Override
+ protected void setupContainerPadding(View container) {
+ container.setPadding(container.getPaddingLeft(), container.getPaddingTop(),
+ container.getPaddingRight(), /* bottom */ 0);
+ }
+
class ResolverProfileDescriptor extends ProfileDescriptor {
private ResolverListAdapter resolverListAdapter;
final ListView listView;
diff --git a/core/java/com/android/internal/widget/ResolverDrawerLayout.java b/core/java/com/android/internal/widget/ResolverDrawerLayout.java
index 31527e8dbe5d..fb2ecf3a478f 100644
--- a/core/java/com/android/internal/widget/ResolverDrawerLayout.java
+++ b/core/java/com/android/internal/widget/ResolverDrawerLayout.java
@@ -1084,6 +1084,7 @@ public class ResolverDrawerLayout extends ViewGroup {
protected Parcelable onSaveInstanceState() {
final SavedState ss = new SavedState(super.onSaveInstanceState());
ss.open = mCollapsibleHeight > 0 && mCollapseOffset == 0;
+ ss.mCollapsibleHeightReserved = mCollapsibleHeightReserved;
return ss;
}
@@ -1092,6 +1093,7 @@ public class ResolverDrawerLayout extends ViewGroup {
final SavedState ss = (SavedState) state;
super.onRestoreInstanceState(ss.getSuperState());
mOpenOnLayout = ss.open;
+ mCollapsibleHeightReserved = ss.mCollapsibleHeightReserved;
}
public static class LayoutParams extends MarginLayoutParams {
@@ -1142,6 +1144,7 @@ public class ResolverDrawerLayout extends ViewGroup {
static class SavedState extends BaseSavedState {
boolean open;
+ private int mCollapsibleHeightReserved;
SavedState(Parcelable superState) {
super(superState);
@@ -1150,12 +1153,14 @@ public class ResolverDrawerLayout extends ViewGroup {
private SavedState(Parcel in) {
super(in);
open = in.readInt() != 0;
+ mCollapsibleHeightReserved = in.readInt();
}
@Override
public void writeToParcel(Parcel out, int flags) {
super.writeToParcel(out, flags);
out.writeInt(open ? 1 : 0);
+ out.writeInt(mCollapsibleHeightReserved);
}
public static final Parcelable.Creator<SavedState> CREATOR =
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index b51d4f509f38..4cb2e975a58b 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -301,6 +301,8 @@ AndroidRuntime::~AndroidRuntime()
}
void AndroidRuntime::setArgv0(const char* argv0, bool setProcName) {
+ // Set the kernel's task name, for as much of the name as we can fit.
+ // The kernel's TASK_COMM_LEN minus one for the terminating NUL == 15.
if (setProcName) {
int len = strlen(argv0);
if (len < 15) {
@@ -309,8 +311,14 @@ void AndroidRuntime::setArgv0(const char* argv0, bool setProcName) {
pthread_setname_np(pthread_self(), argv0 + len - 15);
}
}
+
+ // Directly change the memory pointed to by argv[0].
memset(mArgBlockStart, 0, mArgBlockLength);
strlcpy(mArgBlockStart, argv0, mArgBlockLength);
+
+ // Let bionic know that we just did that, because __progname points
+ // into argv[0] (https://issuetracker.google.com/152893281).
+ setprogname(mArgBlockStart);
}
status_t AndroidRuntime::callMain(const String8& className, jclass clazz,
diff --git a/core/proto/android/app/settings_enums.proto b/core/proto/android/app/settings_enums.proto
index 3e007e4704a4..997829eacf96 100644
--- a/core/proto/android/app/settings_enums.proto
+++ b/core/proto/android/app/settings_enums.proto
@@ -2523,16 +2523,10 @@ enum PageId {
// OS: R
PANEL_ADD_WIFI_NETWORKS = 1809;
- // OPEN: Settings > Accessibility > Enable accessibility service > Show tutorial dialog
+ // OPEN: Settings > Accessibility > Enable the feature or shortcut > Show tutorial dialog
// CATEGORY: SETTINGS
// OS: R
- DIALOG_TOGGLE_SCREEN_ACCESSIBILITY_BUTTON = 1810;
-
- // OPEN: Settings > Accessibility > Enable accessibility service > Show tutorial dialog in
- // gesture mode
- // CATEGORY: SETTINGS
- // OS: R
- DIALOG_TOGGLE_SCREEN_GESTURE_NAVIGATION = 1811;
+ DIALOG_ACCESSIBILITY_TUTORIAL = 1810;
// OPEN: Settings > Accessibility > Edit shortcut dialog
// CATEGORY: SETTINGS
diff --git a/core/res/res/layout/resolver_empty_states.xml b/core/res/res/layout/resolver_empty_states.xml
index 25615d2dc304..fe11769e8613 100644
--- a/core/res/res/layout/resolver_empty_states.xml
+++ b/core/res/res/layout/resolver_empty_states.xml
@@ -24,6 +24,7 @@
android:paddingStart="24dp"
android:paddingEnd="24dp">
<RelativeLayout
+ android:id="@+id/resolver_empty_state_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="48dp"
diff --git a/core/res/res/layout/resolver_list.xml b/core/res/res/layout/resolver_list.xml
index b754e0cfc022..76ecefc67c22 100644
--- a/core/res/res/layout/resolver_list.xml
+++ b/core/res/res/layout/resolver_list.xml
@@ -112,59 +112,61 @@
</FrameLayout>
</LinearLayout>
</TabHost>
-
- <View
- android:layout_alwaysShow="true"
- android:layout_width="match_parent"
- android:layout_height="1dp"
- android:background="?attr/colorBackgroundFloating"
- android:foreground="?attr/dividerVertical" />
-
<LinearLayout
- android:id="@+id/button_bar"
- android:visibility="gone"
- style="?attr/buttonBarStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_ignoreOffset="true"
android:layout_alwaysShow="true"
- android:layout_hasNestedScrollIndicator="true"
- android:gravity="end|center_vertical"
- android:orientation="horizontal"
- android:layoutDirection="locale"
- android:measureWithLargestChild="true"
- android:background="?attr/colorBackgroundFloating"
- android:paddingTop="@dimen/resolver_button_bar_spacing"
- android:paddingBottom="@dimen/resolver_button_bar_spacing"
- android:paddingStart="@dimen/resolver_edge_margin"
- android:paddingEnd="@dimen/resolver_small_margin"
- android:elevation="@dimen/resolver_elevation">
-
- <Button
- android:id="@+id/button_once"
- android:layout_width="wrap_content"
- android:layout_gravity="start"
- android:maxLines="2"
- style="?attr/buttonBarButtonStyle"
- android:fontFamily="@android:string/config_headlineFontFamilyMedium"
+ android:orientation="vertical"
+ android:background="?attr/colorBackgroundFloating">
+ <View
+ android:id="@+id/resolver_button_bar_divider"
+ android:layout_width="match_parent"
+ android:layout_height="1dp"
+ android:background="?attr/colorBackgroundFloating"
+ android:foreground="?attr/dividerVertical" />
+ <LinearLayout
+ android:id="@+id/button_bar"
+ android:visibility="gone"
+ style="?attr/buttonBarStyle"
+ android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:textAllCaps="false"
- android:enabled="false"
- android:text="@string/activity_resolver_use_once"
- android:onClick="onButtonClick" />
+ android:layout_ignoreOffset="true"
+ android:layout_hasNestedScrollIndicator="true"
+ android:gravity="end|center_vertical"
+ android:orientation="horizontal"
+ android:layoutDirection="locale"
+ android:measureWithLargestChild="true"
+ android:paddingTop="@dimen/resolver_button_bar_spacing"
+ android:paddingBottom="@dimen/resolver_button_bar_spacing"
+ android:paddingStart="@dimen/resolver_edge_margin"
+ android:paddingEnd="@dimen/resolver_small_margin"
+ android:elevation="@dimen/resolver_elevation">
- <Button
- android:id="@+id/button_always"
- android:layout_width="wrap_content"
- android:layout_gravity="end"
- android:maxLines="2"
- style="?attr/buttonBarButtonStyle"
- android:fontFamily="@android:string/config_headlineFontFamilyMedium"
- android:textAllCaps="false"
- android:layout_height="wrap_content"
- android:enabled="false"
- android:text="@string/activity_resolver_use_always"
- android:onClick="onButtonClick" />
- </LinearLayout>
+ <Button
+ android:id="@+id/button_once"
+ android:layout_width="wrap_content"
+ android:layout_gravity="start"
+ android:maxLines="2"
+ style="?attr/buttonBarButtonStyle"
+ android:fontFamily="@android:string/config_headlineFontFamilyMedium"
+ android:layout_height="wrap_content"
+ android:textAllCaps="false"
+ android:enabled="false"
+ android:text="@string/activity_resolver_use_once"
+ android:onClick="onButtonClick" />
+ <Button
+ android:id="@+id/button_always"
+ android:layout_width="wrap_content"
+ android:layout_gravity="end"
+ android:maxLines="2"
+ style="?attr/buttonBarButtonStyle"
+ android:fontFamily="@android:string/config_headlineFontFamilyMedium"
+ android:textAllCaps="false"
+ android:layout_height="wrap_content"
+ android:enabled="false"
+ android:text="@string/activity_resolver_use_always"
+ android:onClick="onButtonClick" />
+ </LinearLayout>
+ </LinearLayout>
</com.android.internal.widget.ResolverDrawerLayout>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 8f16e530dfe0..6fac46e834f2 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -1908,7 +1908,7 @@
<!-- The name of the package that will hold the call screening role by default. -->
<string name="config_defaultCallScreening" translatable="false"></string>
<!-- The name of the package that will hold the system gallery role. -->
- <string name="config_systemGallery" translatable="false">com.android.gallery</string>
+ <string name="config_systemGallery" translatable="false">com.android.gallery3d</string>
<!-- The name of the package that will be allowed to change its components' label/icon. -->
<string name="config_overrideComponentUiPackage" translatable="false"></string>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index ebc3612ca1e6..4efd7ff3207e 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -3921,6 +3921,8 @@
<java-symbol type="id" name="resolver_empty_state_button" />
<java-symbol type="id" name="resolver_empty_state_progress" />
<java-symbol type="id" name="resolver_tab_divider" />
+ <java-symbol type="id" name="resolver_button_bar_divider" />
+ <java-symbol type="id" name="resolver_empty_state_container" />
<java-symbol type="string" name="resolver_cant_share_with_work_apps" />
<java-symbol type="string" name="resolver_cant_share_with_work_apps_explanation" />
<java-symbol type="string" name="resolver_cant_share_with_personal_apps" />
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 3e1f72da8731..8ea68833e20d 100755
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -2713,6 +2713,32 @@ public class AudioManager {
}
/**
+ * @hide
+ */
+ public static String audioFocusToString(int focus) {
+ switch (focus) {
+ case AUDIOFOCUS_NONE:
+ return "AUDIOFOCUS_NONE";
+ case AUDIOFOCUS_GAIN:
+ return "AUDIOFOCUS_GAIN";
+ case AUDIOFOCUS_GAIN_TRANSIENT:
+ return "AUDIOFOCUS_GAIN_TRANSIENT";
+ case AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK:
+ return "AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK";
+ case AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE:
+ return "AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE";
+ case AUDIOFOCUS_LOSS:
+ return "AUDIOFOCUS_LOSS";
+ case AUDIOFOCUS_LOSS_TRANSIENT:
+ return "AUDIOFOCUS_LOSS_TRANSIENT";
+ case AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK: // Note CAN_DUCK not MAY_DUCK.
+ return "AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK";
+ default:
+ return "AUDIO_FOCUS_UNKNOWN(" + focus + ")";
+ }
+ }
+
+ /**
* Used to indicate no audio focus has been gained or lost, or requested.
*/
public static final int AUDIOFOCUS_NONE = 0;
diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java
index c11762bcdb40..373f6e126924 100644
--- a/media/java/android/media/AudioSystem.java
+++ b/media/java/android/media/AudioSystem.java
@@ -214,6 +214,175 @@ public class AudioSystem
}
}
+ /**
+ * @hide
+ * Convert a native audio format integer constant to a string.
+ */
+ public static String audioFormatToString(int audioFormat) {
+ switch (audioFormat) {
+ case /* AUDIO_FORMAT_INVALID */ 0xFFFFFFFF:
+ return "AUDIO_FORMAT_INVALID";
+ case /* AUDIO_FORMAT_DEFAULT */ 0:
+ return "AUDIO_FORMAT_DEFAULT";
+ case /* AUDIO_FORMAT_MP3 */ 0x01000000:
+ return "AUDIO_FORMAT_MP3";
+ case /* AUDIO_FORMAT_AMR_NB */ 0x02000000:
+ return "AUDIO_FORMAT_AMR_NB";
+ case /* AUDIO_FORMAT_AMR_WB */ 0x03000000:
+ return "AUDIO_FORMAT_AMR_WB";
+ case /* AUDIO_FORMAT_AAC */ 0x04000000:
+ return "AUDIO_FORMAT_AAC";
+ case /* AUDIO_FORMAT_HE_AAC_V1 */ 0x05000000:
+ return "AUDIO_FORMAT_HE_AAC_V1";
+ case /* AUDIO_FORMAT_HE_AAC_V2 */ 0x06000000:
+ return "AUDIO_FORMAT_HE_AAC_V2";
+ case /* AUDIO_FORMAT_VORBIS */ 0x07000000:
+ return "AUDIO_FORMAT_VORBIS";
+ case /* AUDIO_FORMAT_OPUS */ 0x08000000:
+ return "AUDIO_FORMAT_OPUS";
+ case /* AUDIO_FORMAT_AC3 */ 0x09000000:
+ return "AUDIO_FORMAT_AC3";
+ case /* AUDIO_FORMAT_E_AC3 */ 0x0A000000:
+ return "AUDIO_FORMAT_E_AC3";
+ case /* AUDIO_FORMAT_DTS */ 0x0B000000:
+ return "AUDIO_FORMAT_DTS";
+ case /* AUDIO_FORMAT_DTS_HD */ 0x0C000000:
+ return "AUDIO_FORMAT_DTS_HD";
+ case /* AUDIO_FORMAT_IEC61937 */ 0x0D000000:
+ return "AUDIO_FORMAT_IEC61937";
+ case /* AUDIO_FORMAT_DOLBY_TRUEHD */ 0x0E000000:
+ return "AUDIO_FORMAT_DOLBY_TRUEHD";
+ case /* AUDIO_FORMAT_EVRC */ 0x10000000:
+ return "AUDIO_FORMAT_EVRC";
+ case /* AUDIO_FORMAT_EVRCB */ 0x11000000:
+ return "AUDIO_FORMAT_EVRCB";
+ case /* AUDIO_FORMAT_EVRCWB */ 0x12000000:
+ return "AUDIO_FORMAT_EVRCWB";
+ case /* AUDIO_FORMAT_EVRCNW */ 0x13000000:
+ return "AUDIO_FORMAT_EVRCNW";
+ case /* AUDIO_FORMAT_AAC_ADIF */ 0x14000000:
+ return "AUDIO_FORMAT_AAC_ADIF";
+ case /* AUDIO_FORMAT_WMA */ 0x15000000:
+ return "AUDIO_FORMAT_WMA";
+ case /* AUDIO_FORMAT_WMA_PRO */ 0x16000000:
+ return "AUDIO_FORMAT_WMA_PRO";
+ case /* AUDIO_FORMAT_AMR_WB_PLUS */ 0x17000000:
+ return "AUDIO_FORMAT_AMR_WB_PLUS";
+ case /* AUDIO_FORMAT_MP2 */ 0x18000000:
+ return "AUDIO_FORMAT_MP2";
+ case /* AUDIO_FORMAT_QCELP */ 0x19000000:
+ return "AUDIO_FORMAT_QCELP";
+ case /* AUDIO_FORMAT_DSD */ 0x1A000000:
+ return "AUDIO_FORMAT_DSD";
+ case /* AUDIO_FORMAT_FLAC */ 0x1B000000:
+ return "AUDIO_FORMAT_FLAC";
+ case /* AUDIO_FORMAT_ALAC */ 0x1C000000:
+ return "AUDIO_FORMAT_ALAC";
+ case /* AUDIO_FORMAT_APE */ 0x1D000000:
+ return "AUDIO_FORMAT_APE";
+ case /* AUDIO_FORMAT_AAC_ADTS */ 0x1E000000:
+ return "AUDIO_FORMAT_AAC_ADTS";
+ case /* AUDIO_FORMAT_SBC */ 0x1F000000:
+ return "AUDIO_FORMAT_SBC";
+ case /* AUDIO_FORMAT_APTX */ 0x20000000:
+ return "AUDIO_FORMAT_APTX";
+ case /* AUDIO_FORMAT_APTX_HD */ 0x21000000:
+ return "AUDIO_FORMAT_APTX_HD";
+ case /* AUDIO_FORMAT_AC4 */ 0x22000000:
+ return "AUDIO_FORMAT_AC4";
+ case /* AUDIO_FORMAT_LDAC */ 0x23000000:
+ return "AUDIO_FORMAT_LDAC";
+ case /* AUDIO_FORMAT_MAT */ 0x24000000:
+ return "AUDIO_FORMAT_MAT";
+ case /* AUDIO_FORMAT_AAC_LATM */ 0x25000000:
+ return "AUDIO_FORMAT_AAC_LATM";
+ case /* AUDIO_FORMAT_CELT */ 0x26000000:
+ return "AUDIO_FORMAT_CELT";
+ case /* AUDIO_FORMAT_APTX_ADAPTIVE */ 0x27000000:
+ return "AUDIO_FORMAT_APTX_ADAPTIVE";
+ case /* AUDIO_FORMAT_LHDC */ 0x28000000:
+ return "AUDIO_FORMAT_LHDC";
+ case /* AUDIO_FORMAT_LHDC_LL */ 0x29000000:
+ return "AUDIO_FORMAT_LHDC_LL";
+ case /* AUDIO_FORMAT_APTX_TWSP */ 0x2A000000:
+ return "AUDIO_FORMAT_APTX_TWSP";
+
+ /* Aliases */
+ case /* AUDIO_FORMAT_PCM_16_BIT */ 0x1:
+ return "AUDIO_FORMAT_PCM_16_BIT"; // (PCM | PCM_SUB_16_BIT)
+ case /* AUDIO_FORMAT_PCM_8_BIT */ 0x2:
+ return "AUDIO_FORMAT_PCM_8_BIT"; // (PCM | PCM_SUB_8_BIT)
+ case /* AUDIO_FORMAT_PCM_32_BIT */ 0x3:
+ return "AUDIO_FORMAT_PCM_32_BIT"; // (PCM | PCM_SUB_32_BIT)
+ case /* AUDIO_FORMAT_PCM_8_24_BIT */ 0x4:
+ return "AUDIO_FORMAT_PCM_8_24_BIT"; // (PCM | PCM_SUB_8_24_BIT)
+ case /* AUDIO_FORMAT_PCM_FLOAT */ 0x5:
+ return "AUDIO_FORMAT_PCM_FLOAT"; // (PCM | PCM_SUB_FLOAT)
+ case /* AUDIO_FORMAT_PCM_24_BIT_PACKED */ 0x6:
+ return "AUDIO_FORMAT_PCM_24_BIT_PACKED"; // (PCM | PCM_SUB_24_BIT_PACKED)
+ case /* AUDIO_FORMAT_AAC_MAIN */ 0x4000001:
+ return "AUDIO_FORMAT_AAC_MAIN"; // (AAC | AAC_SUB_MAIN)
+ case /* AUDIO_FORMAT_AAC_LC */ 0x4000002:
+ return "AUDIO_FORMAT_AAC_LC"; // (AAC | AAC_SUB_LC)
+ case /* AUDIO_FORMAT_AAC_SSR */ 0x4000004:
+ return "AUDIO_FORMAT_AAC_SSR"; // (AAC | AAC_SUB_SSR)
+ case /* AUDIO_FORMAT_AAC_LTP */ 0x4000008:
+ return "AUDIO_FORMAT_AAC_LTP"; // (AAC | AAC_SUB_LTP)
+ case /* AUDIO_FORMAT_AAC_HE_V1 */ 0x4000010:
+ return "AUDIO_FORMAT_AAC_HE_V1"; // (AAC | AAC_SUB_HE_V1)
+ case /* AUDIO_FORMAT_AAC_SCALABLE */ 0x4000020:
+ return "AUDIO_FORMAT_AAC_SCALABLE"; // (AAC | AAC_SUB_SCALABLE)
+ case /* AUDIO_FORMAT_AAC_ERLC */ 0x4000040:
+ return "AUDIO_FORMAT_AAC_ERLC"; // (AAC | AAC_SUB_ERLC)
+ case /* AUDIO_FORMAT_AAC_LD */ 0x4000080:
+ return "AUDIO_FORMAT_AAC_LD"; // (AAC | AAC_SUB_LD)
+ case /* AUDIO_FORMAT_AAC_HE_V2 */ 0x4000100:
+ return "AUDIO_FORMAT_AAC_HE_V2"; // (AAC | AAC_SUB_HE_V2)
+ case /* AUDIO_FORMAT_AAC_ELD */ 0x4000200:
+ return "AUDIO_FORMAT_AAC_ELD"; // (AAC | AAC_SUB_ELD)
+ case /* AUDIO_FORMAT_AAC_XHE */ 0x4000300:
+ return "AUDIO_FORMAT_AAC_XHE"; // (AAC | AAC_SUB_XHE)
+ case /* AUDIO_FORMAT_AAC_ADTS_MAIN */ 0x1e000001:
+ return "AUDIO_FORMAT_AAC_ADTS_MAIN"; // (AAC_ADTS | AAC_SUB_MAIN)
+ case /* AUDIO_FORMAT_AAC_ADTS_LC */ 0x1e000002:
+ return "AUDIO_FORMAT_AAC_ADTS_LC"; // (AAC_ADTS | AAC_SUB_LC)
+ case /* AUDIO_FORMAT_AAC_ADTS_SSR */ 0x1e000004:
+ return "AUDIO_FORMAT_AAC_ADTS_SSR"; // (AAC_ADTS | AAC_SUB_SSR)
+ case /* AUDIO_FORMAT_AAC_ADTS_LTP */ 0x1e000008:
+ return "AUDIO_FORMAT_AAC_ADTS_LTP"; // (AAC_ADTS | AAC_SUB_LTP)
+ case /* AUDIO_FORMAT_AAC_ADTS_HE_V1 */ 0x1e000010:
+ return "AUDIO_FORMAT_AAC_ADTS_HE_V1"; // (AAC_ADTS | AAC_SUB_HE_V1)
+ case /* AUDIO_FORMAT_AAC_ADTS_SCALABLE */ 0x1e000020:
+ return "AUDIO_FORMAT_AAC_ADTS_SCALABLE"; // (AAC_ADTS | AAC_SUB_SCALABLE)
+ case /* AUDIO_FORMAT_AAC_ADTS_ERLC */ 0x1e000040:
+ return "AUDIO_FORMAT_AAC_ADTS_ERLC"; // (AAC_ADTS | AAC_SUB_ERLC)
+ case /* AUDIO_FORMAT_AAC_ADTS_LD */ 0x1e000080:
+ return "AUDIO_FORMAT_AAC_ADTS_LD"; // (AAC_ADTS | AAC_SUB_LD)
+ case /* AUDIO_FORMAT_AAC_ADTS_HE_V2 */ 0x1e000100:
+ return "AUDIO_FORMAT_AAC_ADTS_HE_V2"; // (AAC_ADTS | AAC_SUB_HE_V2)
+ case /* AUDIO_FORMAT_AAC_ADTS_ELD */ 0x1e000200:
+ return "AUDIO_FORMAT_AAC_ADTS_ELD"; // (AAC_ADTS | AAC_SUB_ELD)
+ case /* AUDIO_FORMAT_AAC_ADTS_XHE */ 0x1e000300:
+ return "AUDIO_FORMAT_AAC_ADTS_XHE"; // (AAC_ADTS | AAC_SUB_XHE)
+ case /* AUDIO_FORMAT_AAC_LATM_LC */ 0x25000002:
+ return "AUDIO_FORMAT_AAC_LATM_LC"; // (AAC_LATM | AAC_SUB_LC)
+ case /* AUDIO_FORMAT_AAC_LATM_HE_V1 */ 0x25000010:
+ return "AUDIO_FORMAT_AAC_LATM_HE_V1"; // (AAC_LATM | AAC_SUB_HE_V1)
+ case /* AUDIO_FORMAT_AAC_LATM_HE_V2 */ 0x25000100:
+ return "AUDIO_FORMAT_AAC_LATM_HE_V2"; // (AAC_LATM | AAC_SUB_HE_V2)
+ case /* AUDIO_FORMAT_E_AC3_JOC */ 0xA000001:
+ return "AUDIO_FORMAT_E_AC3_JOC"; // (E_AC3 | E_AC3_SUB_JOC)
+ case /* AUDIO_FORMAT_MAT_1_0 */ 0x24000001:
+ return "AUDIO_FORMAT_MAT_1_0"; // (MAT | MAT_SUB_1_0)
+ case /* AUDIO_FORMAT_MAT_2_0 */ 0x24000002:
+ return "AUDIO_FORMAT_MAT_2_0"; // (MAT | MAT_SUB_2_0)
+ case /* AUDIO_FORMAT_MAT_2_1 */ 0x24000003:
+ return "AUDIO_FORMAT_MAT_2_1"; // (MAT | MAT_SUB_2_1)
+ default:
+ return "AUDIO_FORMAT_(" + audioFormat + ")";
+ }
+ }
+
/* Routing bits for the former setRouting/getRouting API */
/** @hide @deprecated */
@Deprecated public static final int ROUTE_EARPIECE = (1 << 0);
diff --git a/media/java/android/media/MediaMetrics.java b/media/java/android/media/MediaMetrics.java
index 540955f3b393..f6f482dd0cd3 100644
--- a/media/java/android/media/MediaMetrics.java
+++ b/media/java/android/media/MediaMetrics.java
@@ -38,6 +38,117 @@ import java.util.Objects;
public class MediaMetrics {
public static final String TAG = "MediaMetrics";
+ public static final String SEPARATOR = ".";
+
+ /**
+ * A list of established MediaMetrics names that can be used for Items.
+ */
+ public static class Name {
+ public static final String AUDIO = "audio";
+ public static final String AUDIO_BLUETOOTH = AUDIO + SEPARATOR + "bluetooth";
+ public static final String AUDIO_DEVICE = AUDIO + SEPARATOR + "device";
+ public static final String AUDIO_FOCUS = AUDIO + SEPARATOR + "focus";
+ public static final String AUDIO_FORCE_USE = AUDIO + SEPARATOR + "forceUse";
+ public static final String AUDIO_MIC = AUDIO + SEPARATOR + "mic";
+ public static final String AUDIO_SERVICE = AUDIO + SEPARATOR + "service";
+ public static final String AUDIO_VOLUME = AUDIO + SEPARATOR + "volume";
+ public static final String AUDIO_VOLUME_EVENT = AUDIO_VOLUME + SEPARATOR + "event";
+ }
+
+ /**
+ * A list of established string values.
+ */
+ public static class Value {
+ public static final String CONNECT = "connect";
+ public static final String CONNECTED = "connected";
+ public static final String DISCONNECT = "disconnect";
+ public static final String DISCONNECTED = "disconnected";
+ public static final String DOWN = "down";
+ public static final String MUTE = "mute";
+ public static final String NO = "no";
+ public static final String OFF = "off";
+ public static final String ON = "on";
+ public static final String UNMUTE = "unmute";
+ public static final String UP = "up";
+ public static final String YES = "yes";
+ }
+
+ /**
+ * A list of standard property keys for consistent use and type.
+ */
+ public static class Property {
+ // A use for Bluetooth or USB device addresses
+ public static final Key<String> ADDRESS = createKey("address", String.class);
+ // A string representing the Audio Attributes
+ public static final Key<String> ATTRIBUTES = createKey("attributes", String.class);
+
+ // The calling package responsible for the state change
+ public static final Key<String> CALLING_PACKAGE =
+ createKey("callingPackage", String.class);
+
+ // The client name
+ public static final Key<String> CLIENT_NAME = createKey("clientName", String.class);
+
+ // The device type
+ public static final Key<Integer> DELAY_MS = createKey("delayMs", Integer.class);
+
+ // The device type
+ public static final Key<String> DEVICE = createKey("device", String.class);
+
+ // For volume changes, up or down
+ public static final Key<String> DIRECTION = createKey("direction", String.class);
+
+ // A reason for early return or error
+ public static final Key<String> EARLY_RETURN =
+ createKey("earlyReturn", String.class);
+ // ENCODING_ ... string to match AudioFormat encoding
+ public static final Key<String> ENCODING = createKey("encoding", String.class);
+
+ public static final Key<String> EVENT = createKey("event#", String.class);
+
+ // event generated is external (yes, no)
+ public static final Key<String> EXTERNAL = createKey("external", String.class);
+
+ public static final Key<Integer> FLAGS = createKey("flags", Integer.class);
+ public static final Key<String> FOCUS_CHANGE_HINT =
+ createKey("focusChangeHint", String.class);
+ public static final Key<String> FORCE_USE_DUE_TO =
+ createKey("forceUseDueTo", String.class);
+ public static final Key<String> FORCE_USE_MODE =
+ createKey("forceUseMode", String.class);
+ public static final Key<Double> GAIN_DB =
+ createKey("gainDb", Double.class);
+ public static final Key<String> GROUP =
+ createKey("group", String.class);
+ // For volume
+ public static final Key<Integer> INDEX = createKey("index", Integer.class);
+ public static final Key<Integer> MAX_INDEX = createKey("maxIndex", Integer.class);
+ public static final Key<Integer> MIN_INDEX = createKey("minIndex", Integer.class);
+ public static final Key<String> MODE =
+ createKey("mode", String.class); // audio_mode
+ public static final Key<String> MUTE =
+ createKey("mute", String.class); // microphone, on or off.
+
+ // Bluetooth or Usb device name
+ public static final Key<String> NAME =
+ createKey("name", String.class);
+
+ // Number of observers
+ public static final Key<Integer> OBSERVERS =
+ createKey("observers", Integer.class);
+
+ public static final Key<String> REQUEST =
+ createKey("request", String.class);
+
+ // For Bluetooth
+ public static final Key<String> SCO_AUDIO_MODE =
+ createKey("scoAudioMode", String.class);
+ public static final Key<Integer> SDK = createKey("sdk", Integer.class);
+ public static final Key<String> STATE = createKey("state", String.class);
+ public static final Key<Integer> STATUS = createKey("status", Integer.class);
+ public static final Key<String> STREAM_TYPE = createKey("streamType", String.class);
+ }
+
/**
* The TYPE constants below should match those in native MediaMetricsItem.h
*/
diff --git a/media/java/android/media/soundtrigger_middleware/OWNERS b/media/java/android/media/soundtrigger_middleware/OWNERS
new file mode 100644
index 000000000000..e5d037003ac4
--- /dev/null
+++ b/media/java/android/media/soundtrigger_middleware/OWNERS
@@ -0,0 +1,2 @@
+ytai@google.com
+elaurent@google.com
diff --git a/media/java/android/media/tv/tuner/Tuner.java b/media/java/android/media/tv/tuner/Tuner.java
index d331126e4194..50af60a0ad92 100644
--- a/media/java/android/media/tv/tuner/Tuner.java
+++ b/media/java/android/media/tv/tuner/Tuner.java
@@ -353,13 +353,16 @@ public class Tuner implements AutoCloseable {
@Override
public void close() {
if (mFrontendHandle != null) {
- nativeCloseFrontendByHandle(mFrontendHandle);
+ int res = nativeCloseFrontend(mFrontendHandle);
+ if (res != Tuner.RESULT_SUCCESS) {
+ TunerUtils.throwExceptionForResult(res, "failed to close frontend");
+ }
mTunerResourceManager.releaseFrontend(mFrontendHandle, mClientId);
mFrontendHandle = null;
mFrontend = null;
}
if (mLnb != null) {
- releaseLnb();
+ mLnb.close();
}
if (!mDescramblers.isEmpty()) {
for (Map.Entry<Integer, Descrambler> d : mDescramblers.entrySet()) {
@@ -374,6 +377,14 @@ public class Tuner implements AutoCloseable {
}
mFilters.clear();
}
+ if (mDemuxHandle != null) {
+ int res = nativeCloseDemux(mDemuxHandle);
+ if (res != Tuner.RESULT_SUCCESS) {
+ TunerUtils.throwExceptionForResult(res, "failed to close demux");
+ }
+ mTunerResourceManager.releaseDemux(mDemuxHandle, mClientId);
+ mFrontendHandle = null;
+ }
TunerUtils.throwExceptionForResult(nativeClose(), "failed to close tuner");
}
@@ -425,6 +436,8 @@ public class Tuner implements AutoCloseable {
private static native DemuxCapabilities nativeGetDemuxCapabilities();
+ private native int nativeCloseDemux(int handle);
+ private native int nativeCloseFrontend(int handle);
private native int nativeClose();
@@ -545,10 +558,11 @@ public class Tuner implements AutoCloseable {
@Result
public int tune(@NonNull FrontendSettings settings) {
mFrontendType = settings.getType();
- checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_FRONTEND);
-
- mFrontendInfo = null;
- return nativeTune(settings.getType(), settings);
+ if (checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_FRONTEND)) {
+ mFrontendInfo = null;
+ return nativeTune(settings.getType(), settings);
+ }
+ return RESULT_UNAVAILABLE;
}
/**
@@ -584,11 +598,13 @@ public class Tuner implements AutoCloseable {
+ "started.");
}
mFrontendType = settings.getType();
- checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_FRONTEND);
- mScanCallback = scanCallback;
- mScanCallbackExecutor = executor;
- mFrontendInfo = null;
- return nativeScan(settings.getType(), settings, scanType);
+ if (checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_FRONTEND)) {
+ mScanCallback = scanCallback;
+ mScanCallbackExecutor = executor;
+ mFrontendInfo = null;
+ return nativeScan(settings.getType(), settings, scanType);
+ }
+ return RESULT_UNAVAILABLE;
}
/**
@@ -671,7 +687,9 @@ public class Tuner implements AutoCloseable {
* @return the id of hardware A/V sync.
*/
public int getAvSyncHwId(@NonNull Filter filter) {
- checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_DEMUX);
+ if (!checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_DEMUX)) {
+ return INVALID_AV_SYNC_ID;
+ }
Integer id = nativeGetAvSyncHwId(filter);
return id == null ? INVALID_AV_SYNC_ID : id;
}
@@ -686,7 +704,9 @@ public class Tuner implements AutoCloseable {
* @return the current timestamp of hardware A/V sync.
*/
public long getAvSyncTime(int avSyncHwId) {
- checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_DEMUX);
+ if (!checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_DEMUX)) {
+ return INVALID_TIMESTAMP;
+ }
Long time = nativeGetAvSyncTime(avSyncHwId);
return time == null ? INVALID_TIMESTAMP : time;
}
@@ -702,8 +722,10 @@ public class Tuner implements AutoCloseable {
*/
@Result
public int connectCiCam(int ciCamId) {
- checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_DEMUX);
- return nativeConnectCiCam(ciCamId);
+ if (checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_DEMUX)) {
+ return nativeConnectCiCam(ciCamId);
+ }
+ return RESULT_UNAVAILABLE;
}
/**
@@ -715,8 +737,10 @@ public class Tuner implements AutoCloseable {
*/
@Result
public int disconnectCiCam() {
- checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_DEMUX);
- return nativeDisconnectCiCam();
+ if (checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_DEMUX)) {
+ return nativeDisconnectCiCam();
+ }
+ return RESULT_UNAVAILABLE;
}
/**
@@ -726,7 +750,9 @@ public class Tuner implements AutoCloseable {
*/
@Nullable
public FrontendInfo getFrontendInfo() {
- checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_FRONTEND);
+ if (!checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_FRONTEND)) {
+ return null;
+ }
if (mFrontend == null) {
throw new IllegalStateException("frontend is not initialized");
}
@@ -861,7 +887,9 @@ public class Tuner implements AutoCloseable {
public Filter openFilter(@Type int mainType, @Subtype int subType,
@BytesLong long bufferSize, @CallbackExecutor @Nullable Executor executor,
@Nullable FilterCallback cb) {
- checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_DEMUX);
+ if (!checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_DEMUX)) {
+ return null;
+ }
Filter filter = nativeOpenFilter(
mainType, TunerUtils.getFilterSubtype(mainType, subType), bufferSize);
if (filter != null) {
@@ -891,12 +919,15 @@ public class Tuner implements AutoCloseable {
Objects.requireNonNull(executor, "executor must not be null");
Objects.requireNonNull(cb, "LnbCallback must not be null");
if (mLnb != null) {
+ mLnb.setCallback(executor, cb, this);
return mLnb;
}
if (checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_LNB) && mLnb != null) {
mLnb.setCallback(executor, cb, this);
+ setLnb(mLnb);
+ return mLnb;
}
- return mLnb;
+ return null;
}
/**
@@ -922,6 +953,7 @@ public class Tuner implements AutoCloseable {
}
mLnb = newLnb;
mLnb.setCallback(executor, cb, this);
+ setLnb(mLnb);
}
return mLnb;
}
@@ -944,7 +976,9 @@ public class Tuner implements AutoCloseable {
*/
@Nullable
public TimeFilter openTimeFilter() {
- checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_DEMUX);
+ if (!checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_DEMUX)) {
+ return null;
+ }
return nativeOpenTimeFilter();
}
@@ -956,6 +990,9 @@ public class Tuner implements AutoCloseable {
@RequiresPermission(android.Manifest.permission.ACCESS_TV_DESCRAMBLER)
@Nullable
public Descrambler openDescrambler() {
+ if (!checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_DEMUX)) {
+ return null;
+ }
return requestDescrambler();
}
@@ -976,7 +1013,9 @@ public class Tuner implements AutoCloseable {
@NonNull OnRecordStatusChangedListener l) {
Objects.requireNonNull(executor, "executor must not be null");
Objects.requireNonNull(l, "OnRecordStatusChangedListener must not be null");
- checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_DEMUX);
+ if (!checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_DEMUX)) {
+ return null;
+ }
DvrRecorder dvr = nativeOpenDvrRecorder(bufferSize);
dvr.setListener(executor, l);
return dvr;
@@ -999,7 +1038,9 @@ public class Tuner implements AutoCloseable {
@NonNull OnPlaybackStatusChangedListener l) {
Objects.requireNonNull(executor, "executor must not be null");
Objects.requireNonNull(l, "OnPlaybackStatusChangedListener must not be null");
- checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_DEMUX);
+ if (!checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_DEMUX)) {
+ return null;
+ }
DvrPlayback dvr = nativeOpenDvrPlayback(bufferSize);
dvr.setListener(executor, l);
return dvr;
diff --git a/media/java/android/mtp/MtpDatabase.java b/media/java/android/mtp/MtpDatabase.java
index e6962a14a2d0..aba74e518a22 100755
--- a/media/java/android/mtp/MtpDatabase.java
+++ b/media/java/android/mtp/MtpDatabase.java
@@ -46,6 +46,7 @@ import android.view.Display;
import android.view.WindowManager;
import com.android.internal.annotations.VisibleForNative;
+import com.android.internal.annotations.VisibleForTesting;
import dalvik.system.CloseGuard;
@@ -408,7 +409,8 @@ public class MtpDatabase implements AutoCloseable {
}
@VisibleForNative
- private int beginSendObject(String path, int format, int parent, int storageId) {
+ @VisibleForTesting
+ public int beginSendObject(String path, int format, int parent, int storageId) {
MtpStorageManager.MtpObject parentObj =
parent == 0 ? mManager.getStorageRoot(storageId) : mManager.getObject(parent);
if (parentObj == null) {
@@ -452,7 +454,8 @@ public class MtpDatabase implements AutoCloseable {
}
@VisibleForNative
- private int getNumObjects(int storageID, int format, int parent) {
+ @VisibleForTesting
+ public int getNumObjects(int storageID, int format, int parent) {
List<MtpStorageManager.MtpObject> objs = mManager.getObjects(parent,
format, storageID);
if (objs == null) {
@@ -830,7 +833,8 @@ public class MtpDatabase implements AutoCloseable {
}
@VisibleForNative
- private boolean getThumbnailInfo(int handle, long[] outLongs) {
+ @VisibleForTesting
+ public boolean getThumbnailInfo(int handle, long[] outLongs) {
MtpStorageManager.MtpObject obj = mManager.getObject(handle);
if (obj == null) {
return false;
@@ -866,7 +870,8 @@ public class MtpDatabase implements AutoCloseable {
}
@VisibleForNative
- private byte[] getThumbnailData(int handle) {
+ @VisibleForTesting
+ public byte[] getThumbnailData(int handle) {
MtpStorageManager.MtpObject obj = mManager.getObject(handle);
if (obj == null) {
return null;
diff --git a/media/java/android/mtp/MtpStorage.java b/media/java/android/mtp/MtpStorage.java
index ba752633718c..88c32a3ea72b 100644
--- a/media/java/android/mtp/MtpStorage.java
+++ b/media/java/android/mtp/MtpStorage.java
@@ -36,7 +36,7 @@ public class MtpStorage {
public MtpStorage(StorageVolume volume, int storageId) {
mStorageId = storageId;
- mPath = volume.getInternalPath();
+ mPath = volume.getPath();
mDescription = volume.getDescription(null);
mRemovable = volume.isRemovable();
mMaxFileSize = volume.getMaxFileSize();
diff --git a/media/jni/android_media_tv_Tuner.cpp b/media/jni/android_media_tv_Tuner.cpp
index 614fe73a76de..ab311c0e245a 100644
--- a/media/jni/android_media_tv_Tuner.cpp
+++ b/media/jni/android_media_tv_Tuner.cpp
@@ -1130,7 +1130,7 @@ jintArray JTuner::getLnbIds() {
lnbIds = ids;
res = r;
});
- if (res != Result::SUCCESS || mLnbIds.size() == 0) {
+ if (res != Result::SUCCESS || lnbIds.size() == 0) {
ALOGW("Lnb isn't available");
return NULL;
}
@@ -1797,6 +1797,22 @@ jobject JTuner::getFrontendStatus(jintArray types) {
return statusObj;
}
+jint JTuner::closeFrontend() {
+ Result r = Result::SUCCESS;
+ if (mFe != NULL) {
+ r = mFe->close();
+ }
+ return (jint) r;
+}
+
+jint JTuner::closeDemux() {
+ Result r = Result::SUCCESS;
+ if (mDemux != NULL) {
+ r = mDemux->close();
+ }
+ return (jint) r;
+}
+
} // namespace android
////////////////////////////////////////////////////////////////////////////////
@@ -3199,6 +3215,16 @@ static jint android_media_tv_Tuner_close_tuner(JNIEnv* env, jobject thiz) {
return (jint) tuner->close();
}
+static jint android_media_tv_Tuner_close_demux(JNIEnv* env, jobject thiz, jint /* handle */) {
+ sp<JTuner> tuner = getTuner(env, thiz);
+ return tuner->closeDemux();
+}
+
+static jint android_media_tv_Tuner_close_frontend(JNIEnv* env, jobject thiz, jint /* handle */) {
+ sp<JTuner> tuner = getTuner(env, thiz);
+ return tuner->closeFrontend();
+}
+
static jint android_media_tv_Tuner_attach_filter(JNIEnv *env, jobject dvr, jobject filter) {
sp<Dvr> dvrSp = getDvr(env, dvr);
if (dvrSp == NULL) {
@@ -3526,7 +3552,9 @@ static const JNINativeMethod gTunerMethods[] = {
{ "nativeGetDemuxCapabilities", "()Landroid/media/tv/tuner/DemuxCapabilities;",
(void *)android_media_tv_Tuner_get_demux_caps },
{ "nativeOpenDemuxByhandle", "(I)I", (void *)android_media_tv_Tuner_open_demux },
- {"nativeClose", "()I", (void *)android_media_tv_Tuner_close_tuner },
+ { "nativeClose", "()I", (void *)android_media_tv_Tuner_close_tuner },
+ { "nativeCloseFrontend", "(I)I", (void *)android_media_tv_Tuner_close_frontend },
+ { "nativeCloseDemux", "(I)I", (void *)android_media_tv_Tuner_close_demux },
};
static const JNINativeMethod gFilterMethods[] = {
diff --git a/media/jni/android_media_tv_Tuner.h b/media/jni/android_media_tv_Tuner.h
index 750b146dbd59..3da78acb2f90 100644
--- a/media/jni/android_media_tv_Tuner.h
+++ b/media/jni/android_media_tv_Tuner.h
@@ -191,6 +191,8 @@ struct JTuner : public RefBase {
jobject getFrontendStatus(jintArray types);
Result openDemux();
jint close();
+ jint closeFrontend();
+ jint closeDemux();
protected:
virtual ~JTuner();
diff --git a/media/tests/MtpTests/res/raw/test_bad_thumb.jpg b/media/tests/MtpTests/res/raw/test_bad_thumb.jpg
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/media/tests/MtpTests/res/raw/test_bad_thumb.jpg
diff --git a/media/tests/MtpTests/src/android/mtp/MtpDatabaseTest.java b/media/tests/MtpTests/src/android/mtp/MtpDatabaseTest.java
new file mode 100644
index 000000000000..e2e8ff4946e0
--- /dev/null
+++ b/media/tests/MtpTests/src/android/mtp/MtpDatabaseTest.java
@@ -0,0 +1,316 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.mtp;
+
+import android.annotation.NonNull;
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.os.Build;
+import android.os.FileUtils;
+import android.os.UserHandle;
+import android.os.storage.StorageManager;
+import android.os.storage.StorageVolume;
+import android.util.Log;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.internal.util.Preconditions;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Assume;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/**
+ * Tests for MtpDatabase functionality.
+ */
+@RunWith(AndroidJUnit4.class)
+public class MtpDatabaseTest {
+ private static final String TAG = MtpDatabaseTest.class.getSimpleName();
+
+ private final Context mContext = InstrumentationRegistry.getContext();
+
+ private static final File mBaseDir = InstrumentationRegistry.getContext().getExternalCacheDir();
+ private static final String MAIN_STORAGE_DIR = mBaseDir.getPath() + "/" + TAG + "/";
+ private static final String TEST_DIRNAME = "/TestIs";
+
+ private static final int MAIN_STORAGE_ID = 0x10001;
+ private static final int SCND_STORAGE_ID = 0x20001;
+ private static final String MAIN_STORAGE_ID_STR = Integer.toHexString(MAIN_STORAGE_ID);
+ private static final String SCND_STORAGE_ID_STR = Integer.toHexString(SCND_STORAGE_ID);
+
+ private static final File mMainStorageDir = new File(MAIN_STORAGE_DIR);
+
+ private static ServerHolder mServerHolder;
+ private MtpDatabase mMtpDatabase;
+
+ private static void logMethodName() {
+ Log.d(TAG, Thread.currentThread().getStackTrace()[3].getMethodName());
+ }
+
+ private static File createNewDir(File parent, String name) {
+ File ret = new File(parent, name);
+ if (!ret.mkdir())
+ throw new AssertionError(
+ "Failed to create file: name=" + name + ", " + parent.getPath());
+ return ret;
+ }
+
+ private static void writeNewFile(File newFile) {
+ try {
+ new FileOutputStream(newFile).write(new byte[] {0, 0, 0});
+ } catch (IOException e) {
+ Assert.fail();
+ }
+ }
+
+ private static void writeNewFileFromByte(File newFile, byte[] byteData) {
+ try {
+ new FileOutputStream(newFile).write(byteData);
+ } catch (IOException e) {
+ Assert.fail();
+ }
+ }
+
+ private static class ServerHolder {
+ @NonNull final MtpServer server;
+ @NonNull final MtpDatabase database;
+
+ ServerHolder(@NonNull MtpServer server, @NonNull MtpDatabase database) {
+ Preconditions.checkNotNull(server);
+ Preconditions.checkNotNull(database);
+ this.server = server;
+ this.database = database;
+ }
+
+ void close() {
+ this.database.setServer(null);
+ }
+ }
+
+ private class OnServerTerminated implements Runnable {
+ @Override
+ public void run() {
+ if (mServerHolder == null) {
+ Log.e(TAG, "mServerHolder is unexpectedly null.");
+ return;
+ }
+ mServerHolder.close();
+ mServerHolder = null;
+ }
+ }
+
+ @Before
+ public void setUp() {
+ FileUtils.deleteContentsAndDir(mMainStorageDir);
+ Assert.assertTrue(mMainStorageDir.mkdir());
+
+ StorageVolume mainStorage = new StorageVolume(MAIN_STORAGE_ID_STR,
+ mMainStorageDir, mMainStorageDir, "Primary Storage",
+ true, false, true, false, -1, UserHandle.CURRENT, "", "");
+
+ final StorageVolume primary = mainStorage;
+
+ mMtpDatabase = new MtpDatabase(mContext, null);
+
+ final MtpServer server =
+ new MtpServer(mMtpDatabase, null, false,
+ new OnServerTerminated(), Build.MANUFACTURER,
+ Build.MODEL, "1.0");
+ mMtpDatabase.setServer(server);
+ mServerHolder = new ServerHolder(server, mMtpDatabase);
+
+ mMtpDatabase.addStorage(mainStorage);
+ }
+
+ @After
+ public void tearDown() {
+ FileUtils.deleteContentsAndDir(mMainStorageDir);
+ }
+
+ private File stageFile(int resId, File file) throws IOException {
+ try (InputStream source = mContext.getResources().openRawResource(resId);
+ OutputStream target = new FileOutputStream(file)) {
+ android.os.FileUtils.copy(source, target);
+ }
+ return file;
+ }
+
+ /**
+ * Refer to BitmapUtilTests, but keep here,
+ * so as to be aware of the behavior or interface change there
+ */
+ private void assertBitmapSize(int expectedWidth, int expectedHeight, Bitmap bitmap) {
+ Assert.assertTrue(
+ "Abnormal bitmap.width: " + bitmap.getWidth(), bitmap.getWidth() >= expectedWidth);
+ Assert.assertTrue(
+ "Abnormal bitmap.height: " + bitmap.getHeight(),
+ bitmap.getHeight() >= expectedHeight);
+ }
+
+ private byte[] createJpegRawData(int sourceWidth, int sourceHeight) throws IOException {
+ return createRawData(Bitmap.CompressFormat.JPEG, sourceWidth, sourceHeight);
+ }
+
+ private byte[] createPngRawData(int sourceWidth, int sourceHeight) throws IOException {
+ return createRawData(Bitmap.CompressFormat.PNG, sourceWidth, sourceHeight);
+ }
+
+ private byte[] createRawData(Bitmap.CompressFormat format, int sourceWidth, int sourceHeight)
+ throws IOException {
+ // Create a temp bitmap as our source
+ Bitmap b = Bitmap.createBitmap(sourceWidth, sourceHeight, Bitmap.Config.ARGB_8888);
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ b.compress(format, 50, outputStream);
+ final byte[] data = outputStream.toByteArray();
+ outputStream.close();
+ return data;
+ }
+
+ /**
+ * Decodes the bitmap with the given sample size
+ */
+ public static Bitmap decodeBitmapFromBytes(byte[] bytes, int sampleSize) {
+ final BitmapFactory.Options options;
+ if (sampleSize <= 1) {
+ options = null;
+ } else {
+ options = new BitmapFactory.Options();
+ options.inSampleSize = sampleSize;
+ }
+ return BitmapFactory.decodeByteArray(bytes, 0, bytes.length, options);
+ }
+
+ private void testThumbnail(int fileHandle, File imgFile, boolean isGoodThumb)
+ throws IOException {
+ boolean isValidThumb;
+ byte[] byteArray;
+ long[] outLongs = new long[3];
+
+ isValidThumb = mMtpDatabase.getThumbnailInfo(fileHandle, outLongs);
+ Assert.assertTrue(isValidThumb);
+
+ byteArray = mMtpDatabase.getThumbnailData(fileHandle);
+
+ if (isGoodThumb) {
+ Assert.assertNotNull("Fail to generate thumbnail:" + imgFile.getPath(), byteArray);
+
+ Bitmap testBitmap = decodeBitmapFromBytes(byteArray, 4);
+ assertBitmapSize(32, 16, testBitmap);
+ } else Assert.assertNull("Bad image should return null:" + imgFile.getPath(), byteArray);
+ }
+
+ @Test
+ @SmallTest
+ public void testMtpDatabaseThumbnail() throws IOException {
+ int baseHandle;
+ int handleJpgBadThumb, handleJpgNoThumb, handleJpgBad;
+ int handlePng1, handlePngBad;
+ final String baseTestDirStr = mMainStorageDir.getPath() + TEST_DIRNAME;
+
+ logMethodName();
+
+ Log.d(TAG, "testMtpDatabaseThumbnail: Generate and insert tested files.");
+
+ baseHandle = mMtpDatabase.beginSendObject(baseTestDirStr,
+ MtpConstants.FORMAT_ASSOCIATION, 0, MAIN_STORAGE_ID);
+
+ File baseDir = new File(baseTestDirStr);
+ baseDir.mkdirs();
+
+ final File jpgfileBadThumb = new File(baseDir, "jpgfileBadThumb.jpg");
+ final File jpgFileNoThumb = new File(baseDir, "jpgFileNoThumb.jpg");
+ final File jpgfileBad = new File(baseDir, "jpgfileBad.jpg");
+ final File pngFile1 = new File(baseDir, "pngFile1.png");
+ final File pngFileBad = new File(baseDir, "pngFileBad.png");
+
+ handleJpgBadThumb = mMtpDatabase.beginSendObject(jpgfileBadThumb.getPath(),
+ MtpConstants.FORMAT_EXIF_JPEG, baseHandle, MAIN_STORAGE_ID);
+ stageFile(R.raw.test_bad_thumb, jpgfileBadThumb);
+
+ handleJpgNoThumb = mMtpDatabase.beginSendObject(jpgFileNoThumb.getPath(),
+ MtpConstants.FORMAT_EXIF_JPEG, baseHandle, MAIN_STORAGE_ID);
+ writeNewFileFromByte(jpgFileNoThumb, createJpegRawData(128, 64));
+
+ handleJpgBad = mMtpDatabase.beginSendObject(jpgfileBad.getPath(),
+ MtpConstants.FORMAT_EXIF_JPEG, baseHandle, MAIN_STORAGE_ID);
+ writeNewFile(jpgfileBad);
+
+ handlePng1 = mMtpDatabase.beginSendObject(pngFile1.getPath(),
+ MtpConstants.FORMAT_PNG, baseHandle, MAIN_STORAGE_ID);
+ writeNewFileFromByte(pngFile1, createPngRawData(128, 64));
+
+ handlePngBad = mMtpDatabase.beginSendObject(pngFileBad.getPath(),
+ MtpConstants.FORMAT_PNG, baseHandle, MAIN_STORAGE_ID);
+ writeNewFile(pngFileBad);
+
+ Log.d(TAG, "testMtpDatabaseThumbnail: Test bad JPG");
+
+ testThumbnail(handleJpgBadThumb, jpgfileBadThumb, false);
+
+ testThumbnail(handleJpgNoThumb, jpgFileNoThumb, false);
+
+ testThumbnail(handleJpgBad, jpgfileBad, false);
+
+ Log.d(TAG, "testMtpDatabaseThumbnail: Test PNG");
+
+ testThumbnail(handlePng1, pngFile1, true);
+
+ Log.d(TAG, "testMtpDatabaseThumbnail: Test bad PNG");
+
+ testThumbnail(handlePngBad, pngFileBad, false);
+ }
+
+ @Test
+ @SmallTest
+ public void testMtpDatabaseExtStorage() throws IOException {
+ int numObj;
+ StorageVolume[] mVolumes;
+
+ logMethodName();
+
+ mVolumes = StorageManager.getVolumeList(UserHandle.myUserId(), 0);
+ // Currently it may need manual setup for 2nd storage on virtual device testing.
+ // Thus only run test when 2nd storage exists.
+ Assume.assumeTrue(
+ "Skip when 2nd storage not available, volume numbers = " + mVolumes.length,
+ mVolumes.length >= 2);
+
+ for (int ii = 0; ii < mVolumes.length; ii++) {
+ StorageVolume volume = mVolumes[ii];
+ // Skip Actual Main storage (Internal Storage),
+ // since we use manipulated path as testing Main storage
+ if (ii > 0)
+ mMtpDatabase.addStorage(volume);
+ }
+
+ numObj = mMtpDatabase.getNumObjects(SCND_STORAGE_ID, 0, 0xFFFFFFFF);
+ Assert.assertTrue(
+ "Fail to get objects in 2nd storage, object numbers = " + numObj, numObj >= 0);
+ }
+}
diff --git a/packages/CarSystemUI/res/values/config.xml b/packages/CarSystemUI/res/values/config.xml
index aeff35d88e23..52d13c3f5b4a 100644
--- a/packages/CarSystemUI/res/values/config.xml
+++ b/packages/CarSystemUI/res/values/config.xml
@@ -87,7 +87,7 @@
<item>com.android.systemui.util.NotificationChannels</item>
<item>com.android.systemui.keyguard.KeyguardViewMediator</item>
<!-- <item>com.android.systemui.recents.Recents</item>-->
- <item>com.android.systemui.volume.VolumeUI</item>
+<!-- <item>com.android.systemui.volume.VolumeUI</item>-->
<!-- <item>com.android.systemui.stackdivider.Divider</item>-->
<!-- <item>com.android.systemui.statusbar.phone.StatusBar</item>-->
<item>com.android.systemui.usb.StorageNotification</item>
@@ -110,5 +110,6 @@
<item>com.android.systemui.toast.ToastUI</item>
<item>com.android.systemui.car.voicerecognition.ConnectedDeviceVoiceRecognitionNotifier</item>
<item>com.android.systemui.window.SystemUIOverlayWindowManager</item>
+ <item>com.android.systemui.car.volume.VolumeUI</item>
</string-array>
</resources>
diff --git a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIBinder.java b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIBinder.java
index a69c92f0bd05..91e222c325a3 100644
--- a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIBinder.java
+++ b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIBinder.java
@@ -20,6 +20,7 @@ import com.android.systemui.biometrics.AuthController;
import com.android.systemui.bubbles.dagger.BubbleModule;
import com.android.systemui.car.notification.CarNotificationModule;
import com.android.systemui.car.voicerecognition.ConnectedDeviceVoiceRecognitionNotifier;
+import com.android.systemui.car.volume.VolumeUI;
import com.android.systemui.globalactions.GlobalActionsComponent;
import com.android.systemui.keyguard.KeyguardViewMediator;
import com.android.systemui.keyguard.dagger.KeyguardModule;
@@ -39,7 +40,6 @@ import com.android.systemui.statusbar.tv.TvStatusBar;
import com.android.systemui.theme.ThemeOverlayController;
import com.android.systemui.toast.ToastUI;
import com.android.systemui.util.leak.GarbageMonitor;
-import com.android.systemui.volume.VolumeUI;
import com.android.systemui.window.OverlayWindowModule;
import com.android.systemui.window.SystemUIOverlayWindowManager;
@@ -65,7 +65,7 @@ public abstract class CarSystemUIBinder {
@ClassKey(Divider.class)
public abstract SystemUI bindDivider(Divider sysui);
- /** */
+ /** Inject Car Navigation Bar. */
@Binds
@IntoMap
@ClassKey(CarNavigationBar.class)
diff --git a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java
index 4ea48ba24fa9..13a555692f22 100644
--- a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java
+++ b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java
@@ -25,6 +25,7 @@ import com.android.keyguard.KeyguardViewController;
import com.android.systemui.car.CarDeviceProvisionedController;
import com.android.systemui.car.CarDeviceProvisionedControllerImpl;
import com.android.systemui.car.keyguard.CarKeyguardViewController;
+import com.android.systemui.car.volume.CarVolumeDialogComponent;
import com.android.systemui.dagger.SystemUIRootComponent;
import com.android.systemui.dock.DockManager;
import com.android.systemui.dock.DockManagerImpl;
@@ -55,7 +56,6 @@ import com.android.systemui.statusbar.policy.BatteryControllerImpl;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
import com.android.systemui.statusbar.policy.HeadsUpManager;
-import com.android.systemui.volume.CarVolumeDialogComponent;
import com.android.systemui.volume.VolumeDialogComponent;
import javax.inject.Named;
diff --git a/packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeDialogComponent.java b/packages/CarSystemUI/src/com/android/systemui/car/volume/CarVolumeDialogComponent.java
index 5a3443674cf4..a22d1abc9c61 100644
--- a/packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeDialogComponent.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/volume/CarVolumeDialogComponent.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,13 +14,16 @@
* limitations under the License.
*/
-package com.android.systemui.volume;
+package com.android.systemui.car.volume;
import android.content.Context;
import com.android.systemui.car.CarServiceProvider;
import com.android.systemui.keyguard.KeyguardViewMediator;
import com.android.systemui.plugins.VolumeDialog;
+import com.android.systemui.volume.Events;
+import com.android.systemui.volume.VolumeDialogComponent;
+import com.android.systemui.volume.VolumeDialogControllerImpl;
import javax.inject.Inject;
import javax.inject.Singleton;
@@ -45,6 +48,7 @@ public class CarVolumeDialogComponent extends VolumeDialogComponent {
@Override
protected VolumeDialog createDefault() {
mCarVolumeDialog = new CarVolumeDialogImpl(mContext);
+ mCarVolumeDialog.show(Events.SHOW_REASON_VOLUME_CHANGED);
return mCarVolumeDialog;
}
}
diff --git a/packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java b/packages/CarSystemUI/src/com/android/systemui/car/volume/CarVolumeDialogImpl.java
index 873d7d7975e0..12818840af9a 100644
--- a/packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/volume/CarVolumeDialogImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.volume;
+package com.android.systemui.car.volume;
import android.animation.Animator;
import android.animation.AnimatorInflater;
@@ -61,6 +61,9 @@ import androidx.recyclerview.widget.RecyclerView;
import com.android.systemui.R;
import com.android.systemui.car.CarServiceProvider;
import com.android.systemui.plugins.VolumeDialog;
+import com.android.systemui.volume.Events;
+import com.android.systemui.volume.SystemUIInterpolators;
+import com.android.systemui.volume.VolumeDialogImpl;
import org.xmlpull.v1.XmlPullParserException;
@@ -75,7 +78,8 @@ import java.util.List;
*/
public class CarVolumeDialogImpl implements VolumeDialog {
- private static final String TAG = Util.logTag(CarVolumeDialogImpl.class);
+ private static final String TAG = "CarVolumeDialog";
+ private static final boolean DEBUG = false;
private static final String XML_TAG_VOLUME_ITEMS = "carVolumeItems";
private static final String XML_TAG_VOLUME_ITEM = "item";
@@ -134,9 +138,9 @@ public class CarVolumeDialogImpl implements VolumeDialog {
// this
// callback. Updating the seekbar at the same time could block the continuous
// seeking.
- if (value != volumeItem.progress && isShowing) {
- volumeItem.carVolumeItem.setProgress(value);
- volumeItem.progress = value;
+ if (value != volumeItem.mProgress && isShowing) {
+ volumeItem.mCarVolumeItem.setProgress(value);
+ volumeItem.mProgress = value;
}
if ((flags & AudioManager.FLAG_SHOW_UI) != 0) {
mPreviouslyDisplayingGroupId = mCurrentlyDisplayingGroupId;
@@ -234,6 +238,20 @@ public class CarVolumeDialogImpl implements VolumeDialog {
cleanupAudioManager();
}
+ /**
+ * Reveals volume dialog.
+ */
+ public void show(int reason) {
+ mHandler.obtainMessage(H.SHOW, reason).sendToTarget();
+ }
+
+ /**
+ * Hides volume dialog.
+ */
+ public void dismiss(int reason) {
+ mHandler.obtainMessage(H.DISMISS, reason).sendToTarget();
+ }
+
private void initDialog() {
loadAudioUsageItems();
mCarVolumeLineItems.clear();
@@ -293,7 +311,7 @@ public class CarVolumeDialogImpl implements VolumeDialog {
private void showH(int reason) {
- if (D.BUG) {
+ if (DEBUG) {
Log.d(TAG, "showH r=" + Events.DISMISS_REASONS[reason]);
}
@@ -323,7 +341,7 @@ public class CarVolumeDialogImpl implements VolumeDialog {
private void clearAllAndSetupDefaultCarVolumeLineItem(int groupId) {
mCarVolumeLineItems.clear();
VolumeItem volumeItem = mAvailableVolumeItems.get(groupId);
- volumeItem.defaultItem = true;
+ volumeItem.mDefaultItem = true;
addCarVolumeListItem(volumeItem, /* volumeGroupId = */ groupId,
R.drawable.car_ic_keyboard_arrow_down, new ExpandIconListener());
}
@@ -334,7 +352,7 @@ public class CarVolumeDialogImpl implements VolumeDialog {
mHandler.sendMessageDelayed(mHandler
.obtainMessage(H.DISMISS, Events.DISMISS_REASON_TIMEOUT), timeout);
- if (D.BUG) {
+ if (DEBUG) {
Log.d(TAG, "rescheduleTimeout " + timeout + " " + Debug.getCaller());
}
}
@@ -348,7 +366,7 @@ public class CarVolumeDialogImpl implements VolumeDialog {
}
private void dismissH(int reason) {
- if (D.BUG) {
+ if (DEBUG) {
Log.d(TAG, "dismissH r=" + Events.DISMISS_REASONS[reason]);
}
@@ -365,7 +383,7 @@ public class CarVolumeDialogImpl implements VolumeDialog {
.setDuration(LISTVIEW_ANIMATION_DURATION_IN_MILLIS)
.setInterpolator(new SystemUIInterpolators.LogAccelerateInterpolator())
.withEndAction(() -> mHandler.postDelayed(() -> {
- if (D.BUG) {
+ if (DEBUG) {
Log.d(TAG, "mDialog.dismiss()");
}
mDialog.dismiss();
@@ -410,8 +428,8 @@ public class CarVolumeDialogImpl implements VolumeDialog {
/* defValue= */ -1);
if (usage >= 0) {
VolumeItem volumeItem = new VolumeItem();
- volumeItem.rank = rank;
- volumeItem.icon = item.getResourceId(
+ volumeItem.mRank = rank;
+ volumeItem.mIcon = item.getResourceId(
R.styleable.carVolumeItems_item_icon, /* defValue= */ 0);
mVolumeItems.put(usage, volumeItem);
rank++;
@@ -429,8 +447,8 @@ public class CarVolumeDialogImpl implements VolumeDialog {
VolumeItem result = null;
for (int usage : usages) {
VolumeItem volumeItem = mVolumeItems.get(usage);
- if (volumeItem.rank < rank) {
- rank = volumeItem.rank;
+ if (volumeItem.mRank < rank) {
+ rank = volumeItem.mRank;
result = volumeItem;
}
}
@@ -449,7 +467,7 @@ public class CarVolumeDialogImpl implements VolumeDialog {
carVolumeItem.setGroupId(volumeGroupId);
int color = mContext.getColor(R.color.car_volume_dialog_tint);
- Drawable primaryIcon = mContext.getDrawable(volumeItem.icon);
+ Drawable primaryIcon = mContext.getDrawable(volumeItem.mIcon);
primaryIcon.mutate().setTint(color);
carVolumeItem.setPrimaryIcon(primaryIcon);
if (supplementalIcon != null) {
@@ -462,8 +480,8 @@ public class CarVolumeDialogImpl implements VolumeDialog {
/* showSupplementalIconDivider= */ false);
}
- volumeItem.carVolumeItem = carVolumeItem;
- volumeItem.progress = seekbarProgressValue;
+ volumeItem.mCarVolumeItem = carVolumeItem;
+ volumeItem.mProgress = seekbarProgressValue;
return carVolumeItem;
}
@@ -490,13 +508,12 @@ public class CarVolumeDialogImpl implements VolumeDialog {
* Wrapper class which contains information of each volume group.
*/
private static class VolumeItem {
-
- private int rank;
- private boolean defaultItem = false;
+ private int mRank;
+ private boolean mDefaultItem = false;
@DrawableRes
- private int icon;
- private CarVolumeItem carVolumeItem;
- private int progress;
+ private int mIcon;
+ private CarVolumeItem mCarVolumeItem;
+ private int mProgress;
}
private final class H extends Handler {
@@ -624,9 +641,9 @@ public class CarVolumeDialogImpl implements VolumeDialog {
Log.w(TAG, "Ignoring volume change event because the car isn't connected");
return;
}
- mAvailableVolumeItems.get(mVolumeGroupId).progress = progress;
+ mAvailableVolumeItems.get(mVolumeGroupId).mProgress = progress;
mAvailableVolumeItems.get(
- mVolumeGroupId).carVolumeItem.setProgress(progress);
+ mVolumeGroupId).mCarVolumeItem.setProgress(progress);
mCarAudioManager.setGroupVolume(mVolumeGroupId, progress, 0);
}
diff --git a/packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeItem.java b/packages/CarSystemUI/src/com/android/systemui/car/volume/CarVolumeItem.java
index b83740f4259d..1e7e5348b7fa 100644
--- a/packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeItem.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/volume/CarVolumeItem.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.volume;
+package com.android.systemui.car.volume;
import android.graphics.drawable.Drawable;
import android.view.View;
@@ -38,12 +38,12 @@ public class CarVolumeItem {
private int mMax;
private int mProgress;
private SeekBar.OnSeekBarChangeListener mOnSeekBarChangeListener;
-
+
/**
* Called when {@link CarVolumeItem} is bound to its ViewHolder.
*/
void bind(CarVolumeItemViewHolder viewHolder) {
- viewHolder.bind(/* carVolumeItem= */ this);
+ viewHolder.bind(/* carVolumeItem= */ this);
}
/** Sets progress of seekbar. */
diff --git a/packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeItemAdapter.java b/packages/CarSystemUI/src/com/android/systemui/car/volume/CarVolumeItemAdapter.java
index 5c1f8170afc4..7f336b5250a7 100644
--- a/packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeItemAdapter.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/volume/CarVolumeItemAdapter.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.volume;
+package com.android.systemui.car.volume;
import android.content.Context;
import android.view.LayoutInflater;
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/volume/VolumeUI.java b/packages/CarSystemUI/src/com/android/systemui/car/volume/VolumeUI.java
new file mode 100644
index 000000000000..2bdb85ff9acc
--- /dev/null
+++ b/packages/CarSystemUI/src/com/android/systemui/car/volume/VolumeUI.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.car.volume;
+
+import android.car.Car;
+import android.car.media.CarAudioManager;
+import android.content.Context;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.os.Handler;
+import android.util.Log;
+
+import com.android.systemui.R;
+import com.android.systemui.SystemUI;
+import com.android.systemui.car.CarServiceProvider;
+import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.volume.VolumeDialogComponent;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import dagger.Lazy;
+
+/** The entry point for controlling the volume ui in cars. */
+@Singleton
+public class VolumeUI extends SystemUI {
+
+ private static final String TAG = "VolumeUI";
+ private final Resources mResources;
+ private final Handler mMainHandler;
+ private final CarServiceProvider mCarServiceProvider;
+ private final Lazy<VolumeDialogComponent> mVolumeDialogComponentLazy;
+
+ private final CarAudioManager.CarVolumeCallback mVolumeChangeCallback =
+ new CarAudioManager.CarVolumeCallback() {
+ @Override
+ public void onGroupVolumeChanged(int zoneId, int groupId, int flags) {
+ if (mVolumeDialogComponent == null) {
+ mMainHandler.post(() -> {
+ mVolumeDialogComponent = mVolumeDialogComponentLazy.get();
+ mVolumeDialogComponent.register();
+ });
+ mCarAudioManager.unregisterCarVolumeCallback(mVolumeChangeCallback);
+ }
+ }
+
+ @Override
+ public void onMasterMuteChanged(int zoneId, int flags) {
+ // ignored
+ }
+ };
+
+ private boolean mEnabled;
+ private CarAudioManager mCarAudioManager;
+ private VolumeDialogComponent mVolumeDialogComponent;
+
+ @Inject
+ public VolumeUI(
+ Context context,
+ @Main Resources resources,
+ @Main Handler mainHandler,
+ CarServiceProvider carServiceProvider,
+ Lazy<VolumeDialogComponent> volumeDialogComponentLazy
+ ) {
+ super(context);
+ mResources = resources;
+ mMainHandler = mainHandler;
+ mCarServiceProvider = carServiceProvider;
+ mVolumeDialogComponentLazy = volumeDialogComponentLazy;
+ }
+
+ @Override
+ public void start() {
+ boolean enableVolumeUi = mResources.getBoolean(R.bool.enable_volume_ui);
+ mEnabled = enableVolumeUi;
+ if (!mEnabled) return;
+
+ mCarServiceProvider.addListener(car -> {
+ if (mCarAudioManager != null) {
+ return;
+ }
+
+ mCarAudioManager = (CarAudioManager) car.getCarManager(Car.AUDIO_SERVICE);
+ Log.d(TAG, "Registering mVolumeChangeCallback.");
+ // This volume call back is never unregistered because CarStatusBar is
+ // never destroyed.
+ mCarAudioManager.registerCarVolumeCallback(mVolumeChangeCallback);
+ });
+ }
+
+ @Override
+ protected void onConfigurationChanged(Configuration newConfig) {
+ super.onConfigurationChanged(newConfig);
+ if (!mEnabled) return;
+ if (mVolumeDialogComponent != null) {
+ mVolumeDialogComponent.onConfigurationChanged(newConfig);
+ }
+ }
+
+ @Override
+ public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ pw.print("mEnabled="); pw.println(mEnabled);
+ if (!mEnabled) return;
+ if (mVolumeDialogComponent != null) {
+ mVolumeDialogComponent.dump(fd, pw, args);
+ }
+ }
+}
diff --git a/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarNavigationBar.java b/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarNavigationBar.java
index 2c2aec21ea4f..4e315c69a973 100644
--- a/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarNavigationBar.java
+++ b/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarNavigationBar.java
@@ -51,7 +51,6 @@ import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.statusbar.AutoHideUiElement;
import com.android.systemui.statusbar.CommandQueue;
-import com.android.systemui.statusbar.NavigationBarController;
import com.android.systemui.statusbar.phone.AutoHideController;
import com.android.systemui.statusbar.phone.BarTransitions;
import com.android.systemui.statusbar.phone.PhoneStatusBarPolicy;
@@ -78,7 +77,6 @@ public class CarNavigationBar extends SystemUI implements CommandQueue.Callbacks
private final ButtonSelectionStateListener mButtonSelectionStateListener;
private final Handler mMainHandler;
private final Lazy<KeyguardStateController> mKeyguardStateControllerLazy;
- private final Lazy<NavigationBarController> mNavigationBarControllerLazy;
private final ButtonSelectionStateController mButtonSelectionStateController;
private final PhoneStatusBarPolicy mIconPolicy;
private final StatusBarIconController mIconController;
@@ -124,7 +122,6 @@ public class CarNavigationBar extends SystemUI implements CommandQueue.Callbacks
ButtonSelectionStateListener buttonSelectionStateListener,
@Main Handler mainHandler,
Lazy<KeyguardStateController> keyguardStateControllerLazy,
- Lazy<NavigationBarController> navigationBarControllerLazy,
ButtonSelectionStateController buttonSelectionStateController,
PhoneStatusBarPolicy iconPolicy,
StatusBarIconController iconController
@@ -139,7 +136,6 @@ public class CarNavigationBar extends SystemUI implements CommandQueue.Callbacks
mButtonSelectionStateListener = buttonSelectionStateListener;
mMainHandler = mainHandler;
mKeyguardStateControllerLazy = keyguardStateControllerLazy;
- mNavigationBarControllerLazy = navigationBarControllerLazy;
mButtonSelectionStateController = buttonSelectionStateController;
mIconPolicy = iconPolicy;
mIconController = iconController;
@@ -315,11 +311,6 @@ public class CarNavigationBar extends SystemUI implements CommandQueue.Callbacks
result.mImeWindowVis, result.mImeBackDisposition,
result.mShowImeSwitcher);
}
-
- // There has been a car customized nav bar on the default display, so just create nav bars
- // on external displays.
- mNavigationBarControllerLazy.get().createNavigationBars(/* includeDefaultDisplay= */ false,
- result);
}
private void buildNavBarWindows() {
diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/navigationbar/car/CarNavigationBarTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/navigationbar/car/CarNavigationBarTest.java
index 6da34d4dddc0..f789d3832e76 100644
--- a/packages/CarSystemUI/tests/src/com/android/systemui/navigationbar/car/CarNavigationBarTest.java
+++ b/packages/CarSystemUI/tests/src/com/android/systemui/navigationbar/car/CarNavigationBarTest.java
@@ -37,7 +37,6 @@ import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.car.CarDeviceProvisionedController;
import com.android.systemui.statusbar.CommandQueue;
-import com.android.systemui.statusbar.NavigationBarController;
import com.android.systemui.statusbar.phone.AutoHideController;
import com.android.systemui.statusbar.phone.PhoneStatusBarPolicy;
import com.android.systemui.statusbar.phone.StatusBarIconController;
@@ -72,8 +71,6 @@ public class CarNavigationBarTest extends SysuiTestCase {
@Mock
private KeyguardStateController mKeyguardStateController;
@Mock
- private NavigationBarController mNavigationBarController;
- @Mock
private ButtonSelectionStateController mButtonSelectionStateController;
@Mock
private PhoneStatusBarPolicy mIconPolicy;
@@ -88,8 +85,8 @@ public class CarNavigationBarTest extends SysuiTestCase {
mCarNavigationBar = new CarNavigationBar(mContext, mTestableResources.getResources(),
mCarNavigationBarController, mWindowManager, mDeviceProvisionedController,
new CommandQueue(mContext), mAutoHideController, mButtonSelectionStateListener,
- mHandler, () -> mKeyguardStateController, () -> mNavigationBarController,
- mButtonSelectionStateController, mIconPolicy, mIconController);
+ mHandler, () -> mKeyguardStateController, mButtonSelectionStateController,
+ mIconPolicy, mIconController);
}
@Test
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index 1007d8379b8e..7baaf494771b 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -1080,14 +1080,14 @@
<string name="power_suggestion_battery_run_out">Battery may run out by <xliff:g id="time" example="12 PM">%1$s</xliff:g></string>
<!-- [CHAR_LIMIT=60] label for estimated remaining duration of battery when under a certain amount -->
- <string name="power_remaining_less_than_duration_only">Less than <xliff:g id="threshold">%1$s</xliff:g> remaining</string>
+ <string name="power_remaining_less_than_duration_only">Less than <xliff:g id="threshold">%1$s</xliff:g> left</string>
<!-- [CHAR_LIMIT=60] label for estimated remaining duration of battery when under a certain amount with the percentage -->
- <string name="power_remaining_less_than_duration">Less than <xliff:g id="threshold">%1$s</xliff:g> remaining (<xliff:g id="level">%2$s</xliff:g>)</string>
+ <string name="power_remaining_less_than_duration">Less than <xliff:g id="threshold">%1$s</xliff:g> left (<xliff:g id="level">%2$s</xliff:g>)</string>
<!-- Used to let users know that they have more than some amount of battery life remaining with percentage. ex: 75% - more than 1 day remaining [CHAR LIMIT = 80] -->
- <string name="power_remaining_more_than_subtext">More than <xliff:g id="time_remaining">%1$s</xliff:g> remaining (<xliff:g id="level">%2$s</xliff:g>)</string>
+ <string name="power_remaining_more_than_subtext">More than <xliff:g id="time_remaining">%1$s</xliff:g> left (<xliff:g id="level">%2$s</xliff:g>)</string>
<!-- Used to let users know that they have more than some amount of battery life remaining. ex: more than 1 day remaining [CHAR LIMIT = 40] -->
- <string name="power_remaining_only_more_than_subtext">More than <xliff:g id="time_remaining">%1$s</xliff:g> remaining</string>
+ <string name="power_remaining_only_more_than_subtext">More than <xliff:g id="time_remaining">%1$s</xliff:g> left</string>
<!-- [CHAR_LIMIT=50] Short label for imminent shutdown warning of device -->
<string name="power_remaining_duration_only_shutdown_imminent" product="default">Phone may shut down soon</string>
diff --git a/packages/SettingsLib/src/com/android/settingslib/notification/EnableZenModeDialog.java b/packages/SettingsLib/src/com/android/settingslib/notification/EnableZenModeDialog.java
index deccde593315..a210e90a3cfc 100644
--- a/packages/SettingsLib/src/com/android/settingslib/notification/EnableZenModeDialog.java
+++ b/packages/SettingsLib/src/com/android/settingslib/notification/EnableZenModeDialog.java
@@ -358,49 +358,45 @@ public class EnableZenModeDialog {
}
});
- // minus button
- final ImageView button1 = (ImageView) row.findViewById(android.R.id.button1);
- button1.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- onClickTimeButton(row, tag, false /*down*/, rowId);
- tag.lines.setAccessibilityLiveRegion(View.ACCESSIBILITY_LIVE_REGION_POLITE);
- }
- });
-
- // plus button
- final ImageView button2 = (ImageView) row.findViewById(android.R.id.button2);
- button2.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- onClickTimeButton(row, tag, true /*up*/, rowId);
- tag.lines.setAccessibilityLiveRegion(View.ACCESSIBILITY_LIVE_REGION_POLITE);
- }
- });
-
final long time = ZenModeConfig.tryParseCountdownConditionId(conditionId);
+ final ImageView minusButton = (ImageView) row.findViewById(android.R.id.button1);
+ final ImageView plusButton = (ImageView) row.findViewById(android.R.id.button2);
if (rowId == COUNTDOWN_CONDITION_INDEX && time > 0) {
- button1.setVisibility(View.VISIBLE);
- button2.setVisibility(View.VISIBLE);
+ minusButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ onClickTimeButton(row, tag, false /*down*/, rowId);
+ tag.lines.setAccessibilityLiveRegion(View.ACCESSIBILITY_LIVE_REGION_POLITE);
+ }
+ });
+
+ plusButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ onClickTimeButton(row, tag, true /*up*/, rowId);
+ tag.lines.setAccessibilityLiveRegion(View.ACCESSIBILITY_LIVE_REGION_POLITE);
+ }
+ });
if (mBucketIndex > -1) {
- button1.setEnabled(mBucketIndex > 0);
- button2.setEnabled(mBucketIndex < MINUTE_BUCKETS.length - 1);
+ minusButton.setEnabled(mBucketIndex > 0);
+ plusButton.setEnabled(mBucketIndex < MINUTE_BUCKETS.length - 1);
} else {
final long span = time - System.currentTimeMillis();
- button1.setEnabled(span > MIN_BUCKET_MINUTES * MINUTES_MS);
+ minusButton.setEnabled(span > MIN_BUCKET_MINUTES * MINUTES_MS);
final Condition maxCondition = ZenModeConfig.toTimeCondition(mContext,
MAX_BUCKET_MINUTES, ActivityManager.getCurrentUser());
- button2.setEnabled(!Objects.equals(condition.summary, maxCondition.summary));
+ plusButton.setEnabled(!Objects.equals(condition.summary, maxCondition.summary));
}
- button1.setAlpha(button1.isEnabled() ? 1f : .5f);
- button2.setAlpha(button2.isEnabled() ? 1f : .5f);
+ minusButton.setAlpha(minusButton.isEnabled() ? 1f : .5f);
+ plusButton.setAlpha(plusButton.isEnabled() ? 1f : .5f);
} else {
- if (button1 != null) {
- ((ViewGroup) row).removeView(button1);
+ if (minusButton != null) {
+ ((ViewGroup) row).removeView(minusButton);
}
- if (button2 != null) {
- ((ViewGroup) row).removeView(button2);
+
+ if (plusButton != null) {
+ ((ViewGroup) row).removeView(plusButton);
}
}
}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/utils/PowerUtilTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/utils/PowerUtilTest.java
index 342d127abd03..4b779ac4a7f5 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/utils/PowerUtilTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/utils/PowerUtilTest.java
@@ -137,9 +137,9 @@ public class PowerUtilTest {
true /* basedOnUsage */);
// shortened string should not have percentage
- assertThat(info).isEqualTo("Less than 15 min remaining");
+ assertThat(info).isEqualTo("Less than 15 min left");
// Add percentage to string when provided
- assertThat(info2).isEqualTo("Less than 15 min remaining (10%)");
+ assertThat(info2).isEqualTo("Less than 15 min left (10%)");
}
@Test
@@ -171,9 +171,9 @@ public class PowerUtilTest {
true /* basedOnUsage */);
// shortened string should not have percentage
- assertThat(info).isEqualTo("More than 2 days remaining");
+ assertThat(info).isEqualTo("More than 2 days left");
// Add percentage to string when provided
- assertThat(info2).isEqualTo("More than 2 days remaining (10%)");
+ assertThat(info2).isEqualTo("More than 2 days left (10%)");
}
@Test
@@ -181,7 +181,7 @@ public class PowerUtilTest {
String info = PowerUtil.getBatteryTipStringFormatted(mContext,
THREE_DAYS_MILLIS);
- assertThat(info).isEqualTo("More than 3 days remaining");
+ assertThat(info).isEqualTo("More than 3 days left");
}
@Test
diff --git a/packages/SystemUI/res/drawable/screenshot_cancel.xml b/packages/SystemUI/res/drawable/screenshot_cancel.xml
index be3c5983bb2e..f0dfd21a830d 100644
--- a/packages/SystemUI/res/drawable/screenshot_cancel.xml
+++ b/packages/SystemUI/res/drawable/screenshot_cancel.xml
@@ -20,9 +20,9 @@
android:viewportWidth="48.0"
android:viewportHeight="48.0">
<path
- android:pathData="M24,24m-16,0a16,16 0,1 1,32 0a16,16 0,1 1,-32 0"
- android:fillColor="@android:color/white"/>
+ android:fillColor="@color/global_screenshot_dismiss_background"
+ android:pathData="M24,24m-16,0a16,16 0,1 1,32 0a16,16 0,1 1,-32 0"/>
<path
- android:fillColor="@color/GM2_grey_500"
+ android:fillColor="@color/global_screenshot_dismiss_foreground"
android:pathData="M31,18.41L29.59,17 24,22.59 18.41,17 17,18.41 22.59,24 17,29.59 18.41,31 24,25.41 29.59,31 31,29.59 25.41,24z"/>
</vector> \ No newline at end of file
diff --git a/packages/SystemUI/res/layout/controls_management.xml b/packages/SystemUI/res/layout/controls_management.xml
index 6da96d10c253..835e54e9e433 100644
--- a/packages/SystemUI/res/layout/controls_management.xml
+++ b/packages/SystemUI/res/layout/controls_management.xml
@@ -26,41 +26,15 @@
android:paddingStart="@dimen/controls_management_side_padding"
android:paddingEnd="@dimen/controls_management_side_padding" >
- <LinearLayout
- android:orientation="horizontal"
+
+ <TextView
+ android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:focusable="false"
- android:clickable="false"
- android:gravity="center_vertical">
-
- <FrameLayout
- android:id="@+id/icon_frame"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:gravity="start|center_vertical"
- android:minWidth="56dp"
- android:visibility="gone"
- android:paddingTop="@dimen/controls_app_icon_frame_top_padding"
- android:paddingBottom="@dimen/controls_app_icon_frame_bottom_padding"
- android:paddingEnd="@dimen/controls_app_icon_frame_side_padding"
- android:paddingStart="@dimen/controls_app_icon_frame_side_padding" >
-
- <ImageView
- android:id="@android:id/icon"
- android:layout_width="@dimen/controls_app_icon_size"
- android:layout_height="@dimen/controls_app_icon_size" />
- </FrameLayout>
-
- <TextView
- android:id="@+id/title"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:textAppearance="?android:attr/textAppearanceLarge"
- android:textSize="@dimen/controls_title_size"
- android:textAlignment="center" />
+ android:textAppearance="?android:attr/textAppearanceLarge"
+ android:textSize="@dimen/controls_title_size"
+ android:textAlignment="center" />
- </LinearLayout>
<TextView
diff --git a/packages/SystemUI/res/layout/global_actions_grid_v2.xml b/packages/SystemUI/res/layout/global_actions_grid_v2.xml
index 1c4ec64e9620..66f57fd6f37c 100644
--- a/packages/SystemUI/res/layout/global_actions_grid_v2.xml
+++ b/packages/SystemUI/res/layout/global_actions_grid_v2.xml
@@ -14,7 +14,6 @@
android:theme="@style/qs_theme"
android:clipChildren="false"
android:clipToPadding="false"
- android:layout_marginTop="@dimen/global_actions_top_margin"
android:layout_marginStart="@dimen/global_actions_side_margin"
>
<LinearLayout
@@ -51,6 +50,7 @@
android:paddingBottom="@dimen/global_actions_grid_container_shadow_offset"
android:layout_marginBottom="@dimen/global_actions_grid_container_negative_shadow_offset"
android:orientation="vertical"
+ android:scrollbars="none"
>
<LinearLayout
android:id="@+id/global_actions_grid_root"
diff --git a/packages/SystemUI/res/layout/global_screenshot.xml b/packages/SystemUI/res/layout/global_screenshot.xml
index d506e7e8e700..db109fe8a541 100644
--- a/packages/SystemUI/res/layout/global_screenshot.xml
+++ b/packages/SystemUI/res/layout/global_screenshot.xml
@@ -68,6 +68,7 @@
android:visibility="gone"
android:contentDescription="@string/screenshot_dismiss_ui_description">
<ImageView
+ android:id="@+id/global_screenshot_dismiss_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="@dimen/screenshot_dismiss_button_margin"
diff --git a/packages/SystemUI/res/values-night/colors.xml b/packages/SystemUI/res/values-night/colors.xml
index 93aa2701ad07..2d5101104237 100644
--- a/packages/SystemUI/res/values-night/colors.xml
+++ b/packages/SystemUI/res/values-night/colors.xml
@@ -72,9 +72,14 @@
<color name="global_actions_alert_text">@color/GM2_red_300</color>
<!-- Global screenshot actions -->
- <color name="global_screenshot_button_background">@color/GM2_grey_900</color>
+ <color name="global_screenshot_button_background">@color/GM2_grey_800</color>
<color name="global_screenshot_button_ripple">#42FFFFFF</color>
- <color name="global_screenshot_button_text">@color/GM2_blue_300</color>
+ <color name="global_screenshot_button_text">#FFFFFF</color>
+ <color name="global_screenshot_button_border">@color/GM2_grey_600</color>
+ <color name="global_screenshot_button_icon">@color/GM2_blue_300</color>
+ <color name="global_screenshot_dismiss_background">@color/GM2_grey_800</color>
+ <color name="global_screenshot_dismiss_foreground">#FFFFFF</color>
+
<!-- Biometric dialog colors -->
<color name="biometric_dialog_gray">#ff888888</color>
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index 4482cdac3327..8b6b5f67d5a7 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -198,6 +198,8 @@
<color name="global_screenshot_button_border">@color/GM2_grey_300</color>
<color name="global_screenshot_button_ripple">#1f000000</color>
<color name="global_screenshot_button_icon">@color/GM2_blue_500</color>
+ <color name="global_screenshot_dismiss_background">#FFFFFF</color>
+ <color name="global_screenshot_dismiss_foreground">@color/GM2_grey_500</color>
<!-- GM2 colors -->
<color name="GM2_grey_50">#F8F9FA</color>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 179f8b8ea9f4..39aa771bc797 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -993,8 +993,6 @@
<dimen name="cell_overlay_padding">18dp</dimen>
<!-- Global actions power menu -->
- <dimen name="global_actions_top_margin">12dp</dimen>
-
<dimen name="global_actions_panel_width">120dp</dimen>
<dimen name="global_actions_padding">12dp</dimen>
<dimen name="global_actions_translate">9dp</dimen>
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java b/packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java
index 0002e862bb41..35406c71a080 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java
@@ -128,17 +128,31 @@ public class ExpandedAnimationController
*/
private boolean mBubbleDraggedOutEnough = false;
+ /** End action to run when the lead bubble's expansion animation completes. */
+ @Nullable private Runnable mLeadBubbleEndAction;
+
/**
- * Animates expanding the bubbles into a row along the top of the screen.
+ * Animates expanding the bubbles into a row along the top of the screen, optionally running an
+ * end action when the entire animation completes, and an end action when the lead bubble's
+ * animation ends.
*/
- public void expandFromStack(@Nullable Runnable after) {
+ public void expandFromStack(
+ @Nullable Runnable after, @Nullable Runnable leadBubbleEndAction) {
mAnimatingCollapse = false;
mAnimatingExpand = true;
mAfterExpand = after;
+ mLeadBubbleEndAction = leadBubbleEndAction;
startOrUpdatePathAnimation(true /* expanding */);
}
+ /**
+ * Animates expanding the bubbles into a row along the top of the screen.
+ */
+ public void expandFromStack(@Nullable Runnable after) {
+ expandFromStack(after, null /* leadBubbleEndAction */);
+ }
+
/** Animate collapsing the bubbles back to their stacked position. */
public void collapseBackToStack(PointF collapsePoint, Runnable after) {
mAnimatingExpand = false;
@@ -237,11 +251,17 @@ public class ExpandedAnimationController
? (index * 10)
: ((mLayout.getChildCount() - index) * 10);
+ final boolean isLeadBubble =
+ (firstBubbleLeads && index == 0)
+ || (!firstBubbleLeads && index == mLayout.getChildCount() - 1);
+
animation
.followAnimatedTargetAlongPath(
path,
EXPAND_COLLAPSE_TARGET_ANIM_DURATION /* targetAnimDuration */,
- Interpolators.LINEAR /* targetAnimInterpolator */)
+ Interpolators.LINEAR /* targetAnimInterpolator */,
+ isLeadBubble ? mLeadBubbleEndAction : null /* endAction */,
+ () -> mLeadBubbleEndAction = null /* endAction */)
.withStartDelay(startDelay)
.withStiffness(EXPAND_COLLAPSE_ANIM_STIFFNESS);
}).startAll(after);
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayout.java b/packages/SystemUI/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayout.java
index b1bbafc1ed8f..a7d1be1a766a 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayout.java
@@ -758,21 +758,34 @@ public class PhysicsAnimationLayout extends FrameLayout {
* or {@link #position}, ultimately animating the view's position to the final point on the
* given path.
*
- * Any provided end listeners will be called when the physics-based animations kicked off by
- * the moving target have completed - not when the target animation completes.
+ * @param pathAnimEndActions End actions to run after the animator that moves the target
+ * along the path ends. The views following the target may still
+ * be moving.
*/
public PhysicsPropertyAnimator followAnimatedTargetAlongPath(
Path path,
int targetAnimDuration,
TimeInterpolator targetAnimInterpolator,
- Runnable... endActions) {
+ Runnable... pathAnimEndActions) {
mPathAnimator = ObjectAnimator.ofFloat(
this, mCurrentPointOnPathXProperty, mCurrentPointOnPathYProperty, path);
+
+ if (pathAnimEndActions != null) {
+ mPathAnimator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ for (Runnable action : pathAnimEndActions) {
+ if (action != null) {
+ action.run();
+ }
+ }
+ }
+ });
+ }
+
mPathAnimator.setDuration(targetAnimDuration);
mPathAnimator.setInterpolator(targetAnimInterpolator);
- mPositionEndActions = endActions;
-
// Remove translation related values since we're going to ignore them and follow the
// path instead.
clearTranslationValues();
diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt
index 183bd7bb2b7a..9a2ccb52132b 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt
@@ -20,7 +20,6 @@ import android.app.ActivityOptions
import android.content.ComponentName
import android.content.Intent
import android.content.res.Configuration
-import android.graphics.drawable.Drawable
import android.os.Bundle
import android.text.TextUtils
import android.view.Gravity
@@ -29,7 +28,6 @@ import android.view.ViewGroup
import android.view.ViewStub
import android.widget.Button
import android.widget.FrameLayout
-import android.widget.ImageView
import android.widget.TextView
import androidx.viewpager2.widget.ViewPager2
import com.android.systemui.Prefs
@@ -76,11 +74,10 @@ class ControlsFavoritingActivity @Inject constructor(
private lateinit var structurePager: ViewPager2
private lateinit var statusText: TextView
private lateinit var titleView: TextView
- private lateinit var iconView: ImageView
- private lateinit var iconFrame: View
private lateinit var pageIndicator: ManagementPageIndicator
private var mTooltipManager: TooltipManager? = null
private lateinit var doneButton: View
+ private lateinit var otherAppsButton: View
private var listOfStructures = emptyList<StructureContainer>()
private lateinit var comparator: Comparator<StructureContainer>
@@ -99,17 +96,10 @@ class ControlsFavoritingActivity @Inject constructor(
}
private val listingCallback = object : ControlsListingController.ControlsListingCallback {
- private var icon: Drawable? = null
override fun onServicesUpdated(serviceInfos: List<ControlsServiceInfo>) {
- val newIcon = serviceInfos.firstOrNull { it.componentName == component }?.loadIcon()
- if (icon == newIcon) return
- icon = newIcon
- executor.execute {
- if (icon != null) {
- iconView.setImageDrawable(icon)
- }
- iconFrame.visibility = if (icon != null) View.VISIBLE else View.GONE
+ if (serviceInfos.size > 1) {
+ otherAppsButton.visibility = View.VISIBLE
}
}
}
@@ -271,8 +261,6 @@ class ControlsFavoritingActivity @Inject constructor(
}
requireViewById<TextView>(R.id.subtitle).text =
resources.getText(R.string.controls_favorite_subtitle)
- iconView = requireViewById(com.android.internal.R.id.icon)
- iconFrame = requireViewById(R.id.icon_frame)
structurePager = requireViewById<ViewPager2>(R.id.structure_pager)
structurePager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
override fun onPageSelected(position: Int) {
@@ -284,8 +272,7 @@ class ControlsFavoritingActivity @Inject constructor(
}
private fun bindButtons() {
- requireViewById<Button>(R.id.other_apps).apply {
- visibility = View.VISIBLE
+ otherAppsButton = requireViewById<Button>(R.id.other_apps).apply {
setOnClickListener {
val i = Intent()
i.setComponent(
diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsProviderSelectorActivity.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsProviderSelectorActivity.kt
index 80cb96803f24..00448544d691 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsProviderSelectorActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsProviderSelectorActivity.kt
@@ -21,6 +21,7 @@ import android.content.ComponentName
import android.content.Intent
import android.os.Bundle
import android.view.LayoutInflater
+import android.view.View
import android.view.ViewGroup
import android.view.ViewStub
import android.widget.Button
@@ -90,9 +91,14 @@ class ControlsProviderSelectorActivity @Inject constructor(
text = resources.getText(R.string.controls_providers_title)
}
- requireViewById<Button>(R.id.done).setOnClickListener {
- this@ControlsProviderSelectorActivity.finishAffinity()
+ requireViewById<Button>(R.id.other_apps).apply {
+ visibility = View.VISIBLE
+ setText(com.android.internal.R.string.cancel)
+ setOnClickListener {
+ this@ControlsProviderSelectorActivity.finishAffinity()
+ }
}
+ requireViewById<View>(R.id.done).visibility = View.GONE
}
override fun onStart() {
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIDefaultModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIDefaultModule.java
index 88f96a8b19fe..8c572fe8f842 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIDefaultModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIDefaultModule.java
@@ -24,7 +24,6 @@ import android.content.Context;
import androidx.annotation.Nullable;
import com.android.keyguard.KeyguardViewController;
-import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.dock.DockManager;
import com.android.systemui.dock.DockManagerImpl;
import com.android.systemui.plugins.qs.QSFactory;
@@ -34,7 +33,6 @@ import com.android.systemui.power.EnhancedEstimatesImpl;
import com.android.systemui.qs.tileimpl.QSFactoryImpl;
import com.android.systemui.recents.Recents;
import com.android.systemui.recents.RecentsImplementation;
-import com.android.systemui.settings.CurrentUserContextTracker;
import com.android.systemui.stackdivider.DividerModule;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
@@ -138,15 +136,4 @@ public abstract class SystemUIDefaultModule {
@Binds
abstract KeyguardViewController bindKeyguardViewController(
StatusBarKeyguardViewManager statusBarKeyguardViewManager);
-
- @Singleton
- @Provides
- static CurrentUserContextTracker provideCurrentUserContextTracker(
- Context context,
- BroadcastDispatcher broadcastDispatcher) {
- CurrentUserContextTracker tracker =
- new CurrentUserContextTracker(context, broadcastDispatcher);
- tracker.initialize();
- return tracker;
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
index 2e9ce1200c85..90cd13fd1330 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
@@ -29,6 +29,7 @@ import com.android.systemui.log.dagger.LogModule;
import com.android.systemui.model.SysUiState;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.recents.Recents;
+import com.android.systemui.settings.dagger.SettingsModule;
import com.android.systemui.stackdivider.Divider;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinder;
@@ -61,6 +62,7 @@ import dagger.Provides;
ConcurrencyModule.class,
LogModule.class,
PeopleHubModule.class,
+ SettingsModule.class
},
subcomponents = {StatusBarComponent.class,
NotificationRowComponent.class,
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
index 233d24b17d44..8dcf52827145 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
@@ -632,8 +632,10 @@ public class MediaControlPanel {
public void onError() {
Log.d(TAG, "Cannot resume with " + componentName);
mServiceComponent = null;
- clearControls();
- // remove
+ if (!hasMediaSession()) {
+ // If it's not active and we can't resume, remove
+ removePlayer();
+ }
}
},
componentName);
diff --git a/packages/SystemUI/src/com/android/systemui/pip/PipAnimationController.java b/packages/SystemUI/src/com/android/systemui/pip/PipAnimationController.java
index dba43430b490..f322489b8dc2 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/PipAnimationController.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/PipAnimationController.java
@@ -53,16 +53,23 @@ public class PipAnimationController {
public static final int TRANSITION_DIRECTION_SAME = 1;
public static final int TRANSITION_DIRECTION_TO_PIP = 2;
public static final int TRANSITION_DIRECTION_TO_FULLSCREEN = 3;
+ public static final int TRANSITION_DIRECTION_TO_SPLIT_SCREEN = 4;
@IntDef(prefix = { "TRANSITION_DIRECTION_" }, value = {
TRANSITION_DIRECTION_NONE,
TRANSITION_DIRECTION_SAME,
TRANSITION_DIRECTION_TO_PIP,
- TRANSITION_DIRECTION_TO_FULLSCREEN
+ TRANSITION_DIRECTION_TO_FULLSCREEN,
+ TRANSITION_DIRECTION_TO_SPLIT_SCREEN
})
@Retention(RetentionPolicy.SOURCE)
public @interface TransitionDirection {}
+ public static boolean isOutPipDirection(@TransitionDirection int direction) {
+ return direction == TRANSITION_DIRECTION_TO_FULLSCREEN
+ || direction == TRANSITION_DIRECTION_TO_SPLIT_SCREEN;
+ }
+
private final Interpolator mFastOutSlowInInterpolator;
private final PipSurfaceTransactionHelper mSurfaceTransactionHelper;
@@ -253,14 +260,13 @@ public class PipAnimationController {
}
boolean shouldApplyCornerRadius() {
- return mTransitionDirection != TRANSITION_DIRECTION_TO_FULLSCREEN;
+ return !isOutPipDirection(mTransitionDirection);
}
boolean inScaleTransition() {
if (mAnimationType != ANIM_TYPE_BOUNDS) return false;
final int direction = getTransitionDirection();
- return direction != TRANSITION_DIRECTION_TO_FULLSCREEN
- && direction != TRANSITION_DIRECTION_TO_PIP;
+ return !isOutPipDirection(direction) && direction != TRANSITION_DIRECTION_TO_PIP;
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java b/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java
index 0125153542c1..9eae3ca232ff 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java
@@ -16,7 +16,6 @@
package com.android.systemui.pip;
-import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static com.android.systemui.pip.PipAnimationController.ANIM_TYPE_ALPHA;
@@ -25,6 +24,8 @@ import static com.android.systemui.pip.PipAnimationController.TRANSITION_DIRECTI
import static com.android.systemui.pip.PipAnimationController.TRANSITION_DIRECTION_SAME;
import static com.android.systemui.pip.PipAnimationController.TRANSITION_DIRECTION_TO_FULLSCREEN;
import static com.android.systemui.pip.PipAnimationController.TRANSITION_DIRECTION_TO_PIP;
+import static com.android.systemui.pip.PipAnimationController.TRANSITION_DIRECTION_TO_SPLIT_SCREEN;
+import static com.android.systemui.pip.PipAnimationController.isOutPipDirection;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -48,6 +49,7 @@ import android.window.WindowOrganizer;
import com.android.internal.os.SomeArgs;
import com.android.systemui.R;
import com.android.systemui.pip.phone.PipUpdateThread;
+import com.android.systemui.stackdivider.Divider;
import java.util.ArrayList;
import java.util.HashMap;
@@ -85,6 +87,7 @@ public class PipTaskOrganizer extends TaskOrganizer {
private final int mEnterExitAnimationDuration;
private final PipSurfaceTransactionHelper mSurfaceTransactionHelper;
private final Map<IBinder, Rect> mBoundsToRestore = new HashMap<>();
+ private final Divider mSplitDivider;
// These callbacks are called on the update thread
private final PipAnimationController.PipAnimationCallback mPipAnimationCallback =
@@ -189,7 +192,8 @@ public class PipTaskOrganizer extends TaskOrganizer {
mSurfaceControlTransactionFactory;
public PipTaskOrganizer(Context context, @NonNull PipBoundsHandler boundsHandler,
- @NonNull PipSurfaceTransactionHelper surfaceTransactionHelper) {
+ @NonNull PipSurfaceTransactionHelper surfaceTransactionHelper,
+ @Nullable Divider divider) {
mMainHandler = new Handler(Looper.getMainLooper());
mUpdateHandler = new Handler(PipUpdateThread.get().getLooper(), mUpdateCallbacks);
mPipBoundsHandler = boundsHandler;
@@ -198,6 +202,7 @@ public class PipTaskOrganizer extends TaskOrganizer {
mSurfaceTransactionHelper = surfaceTransactionHelper;
mPipAnimationController = new PipAnimationController(context, surfaceTransactionHelper);
mSurfaceControlTransactionFactory = SurfaceControl.Transaction::new;
+ mSplitDivider = divider;
}
public Handler getUpdateHandler() {
@@ -226,20 +231,21 @@ public class PipTaskOrganizer extends TaskOrganizer {
/**
* Dismiss PiP, this is done in two phases using {@link WindowContainerTransaction}
- * - setActivityWindowingMode to fullscreen at beginning of the transaction. without changing
- * the windowing mode of the Task itself. This makes sure the activity render it's fullscreen
+ * - setActivityWindowingMode to undefined at beginning of the transaction. without changing
+ * the windowing mode of the Task itself. This makes sure the activity render it's final
* configuration while the Task is still in PiP.
- * - setWindowingMode to fullscreen at the end of transition
+ * - setWindowingMode to undefined at the end of transition
* @param animationDurationMs duration in millisecond for the exiting PiP transition
*/
public void dismissPip(int animationDurationMs) {
final WindowContainerTransaction wct = new WindowContainerTransaction();
- wct.setActivityWindowingMode(mToken, WINDOWING_MODE_FULLSCREEN);
+ wct.setActivityWindowingMode(mToken, WINDOWING_MODE_UNDEFINED);
WindowOrganizer.applyTransaction(wct);
final Rect destinationBounds = mBoundsToRestore.remove(mToken.asBinder());
+ final int direction = syncWithSplitScreenBounds(destinationBounds)
+ ? TRANSITION_DIRECTION_TO_SPLIT_SCREEN : TRANSITION_DIRECTION_TO_FULLSCREEN;
scheduleAnimateResizePip(mLastReportedBounds, destinationBounds,
- TRANSITION_DIRECTION_TO_FULLSCREEN, animationDurationMs,
- null /* updateBoundsCallback */);
+ direction, animationDurationMs, null /* updateBoundsCallback */);
mInPip = false;
}
@@ -282,6 +288,9 @@ public class PipTaskOrganizer extends TaskOrganizer {
*/
@Override
public void onTaskVanished(ActivityManager.RunningTaskInfo info) {
+ if (!mInPip) {
+ return;
+ }
final WindowContainerToken token = info.token;
Objects.requireNonNull(token, "Requires valid WindowContainerToken");
if (token.asBinder() != mToken.asBinder()) {
@@ -519,14 +528,13 @@ public class PipTaskOrganizer extends TaskOrganizer {
mLastReportedBounds.set(destinationBounds);
final WindowContainerTransaction wct = new WindowContainerTransaction();
final Rect taskBounds;
- if (direction == TRANSITION_DIRECTION_TO_FULLSCREEN) {
+ if (isOutPipDirection(direction)) {
// If we are animating to fullscreen, then we need to reset the override bounds
- // on the task to ensure that the task "matches" the parent's bounds, this applies
- // also to the final windowing mode, which should be reset to undefined rather than
- // fullscreen.
- taskBounds = null;
- wct.setWindowingMode(mToken, WINDOWING_MODE_UNDEFINED)
- .setActivityWindowingMode(mToken, WINDOWING_MODE_UNDEFINED);
+ // on the task to ensure that the task "matches" the parent's bounds.
+ taskBounds = (direction == TRANSITION_DIRECTION_TO_FULLSCREEN)
+ ? null : destinationBounds;
+ // As for the final windowing mode, simply reset it to undefined.
+ wct.setWindowingMode(mToken, WINDOWING_MODE_UNDEFINED);
} else {
taskBounds = destinationBounds;
}
@@ -578,6 +586,24 @@ public class PipTaskOrganizer extends TaskOrganizer {
}
/**
+ * Sync with {@link #mSplitDivider} on destination bounds if PiP is going to split screen.
+ *
+ * @param destinationBoundsOut contain the updated destination bounds if applicable
+ * @return {@code true} if destinationBounds is altered for split screen
+ */
+ private boolean syncWithSplitScreenBounds(Rect destinationBoundsOut) {
+ if (mSplitDivider == null || !mSplitDivider.inSplitMode()) {
+ // bail early if system is not in split screen mode
+ return false;
+ }
+ // PiP window will go to split-secondary mode instead of fullscreen, populates the
+ // split screen bounds here.
+ destinationBoundsOut.set(
+ mSplitDivider.getView().getNonMinimizedSplitScreenSecondaryBounds());
+ return true;
+ }
+
+ /**
* Callback interface for PiP transitions (both from and to PiP mode)
*/
public interface PipTransitionCallback {
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
index ba9a30fb554f..78975735ef0f 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
@@ -19,7 +19,7 @@ package com.android.systemui.pip.phone;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
-import static com.android.systemui.pip.PipAnimationController.TRANSITION_DIRECTION_TO_FULLSCREEN;
+import static com.android.systemui.pip.PipAnimationController.isOutPipDirection;
import android.annotation.Nullable;
import android.app.ActivityManager;
@@ -53,6 +53,7 @@ import com.android.systemui.shared.system.InputConsumerController;
import com.android.systemui.shared.system.PinnedStackListenerForwarder.PinnedStackListener;
import com.android.systemui.shared.system.TaskStackChangeListener;
import com.android.systemui.shared.system.WindowManagerWrapper;
+import com.android.systemui.stackdivider.Divider;
import com.android.systemui.util.DeviceConfigProxy;
import com.android.systemui.util.FloatingContentCoordinator;
import com.android.systemui.wm.DisplayChangeController;
@@ -199,7 +200,8 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio
DeviceConfigProxy deviceConfig,
PipBoundsHandler pipBoundsHandler,
PipSnapAlgorithm pipSnapAlgorithm,
- PipSurfaceTransactionHelper surfaceTransactionHelper) {
+ PipSurfaceTransactionHelper surfaceTransactionHelper,
+ Divider divider) {
mContext = context;
mActivityManager = ActivityManager.getService();
@@ -214,7 +216,7 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio
final IActivityTaskManager activityTaskManager = ActivityTaskManager.getService();
mPipBoundsHandler = pipBoundsHandler;
mPipTaskOrganizer = new PipTaskOrganizer(context, pipBoundsHandler,
- surfaceTransactionHelper);
+ surfaceTransactionHelper, divider);
mPipTaskOrganizer.registerPipTransitionCallback(this);
mInputConsumerController = InputConsumerController.getPipInputConsumer();
mMediaController = new PipMediaController(context, mActivityManager, broadcastDispatcher);
@@ -312,7 +314,7 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio
@Override
public void onPipTransitionStarted(ComponentName activity, int direction) {
- if (direction == TRANSITION_DIRECTION_TO_FULLSCREEN) {
+ if (isOutPipDirection(direction)) {
// On phones, the expansion animation that happens on pip tap before restoring
// to fullscreen makes it so that the bounds received here are the expanded
// bounds. We want to restore to the unexpanded bounds when re-entering pip,
diff --git a/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java
index 3a2d786cebe4..6c5312d57b2a 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java
@@ -57,6 +57,7 @@ import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.PinnedStackListenerForwarder.PinnedStackListener;
import com.android.systemui.shared.system.TaskStackChangeListener;
import com.android.systemui.shared.system.WindowManagerWrapper;
+import com.android.systemui.stackdivider.Divider;
import java.util.ArrayList;
import java.util.List;
@@ -232,7 +233,8 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio
@Inject
public PipManager(Context context, BroadcastDispatcher broadcastDispatcher,
PipBoundsHandler pipBoundsHandler,
- PipSurfaceTransactionHelper surfaceTransactionHelper) {
+ PipSurfaceTransactionHelper surfaceTransactionHelper,
+ Divider divider) {
if (mInitialized) {
return;
}
@@ -249,7 +251,7 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio
mResizeAnimationDuration = context.getResources()
.getInteger(R.integer.config_pipResizeAnimationDuration);
mPipTaskOrganizer = new PipTaskOrganizer(mContext, mPipBoundsHandler,
- surfaceTransactionHelper);
+ surfaceTransactionHelper, divider);
mPipTaskOrganizer.registerPipTransitionCallback(this);
mActivityTaskManager = ActivityTaskManager.getService();
ActivityManagerWrapper.getInstance().registerTaskStackListener(mTaskStackListener);
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
index 1efe663ca6ce..70454d4d63df 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
@@ -36,6 +36,7 @@ import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
+import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Insets;
@@ -184,9 +185,11 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset
private final LinearLayout mActionsView;
private final ImageView mBackgroundProtection;
private final FrameLayout mDismissButton;
+ private final ImageView mDismissImage;
private Bitmap mScreenBitmap;
private Animator mScreenshotAnimation;
+ private boolean mInDarkMode = false;
private float mScreenshotOffsetXPx;
private float mScreenshotOffsetYPx;
@@ -250,6 +253,7 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset
mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_EXPLICIT_DISMISSAL);
clearScreenshot("dismiss_button");
});
+ mDismissImage = mDismissButton.findViewById(R.id.global_screenshot_dismiss_image);
mScreenshotFlash = mScreenshotLayout.findViewById(R.id.global_screenshot_flash);
mScreenshotSelectorView = mScreenshotLayout.findViewById(R.id.global_screenshot_selector);
@@ -356,6 +360,8 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset
mScreenBitmap.setHasAlpha(false);
mScreenBitmap.prepareToDraw();
+ updateDarkTheme();
+
mWindowManager.addView(mScreenshotLayout, mWindowLayoutParams);
mScreenshotLayout.getViewTreeObserver().addOnComputeInternalInsetsListener(this);
@@ -434,7 +440,7 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset
* Clears current screenshot
*/
private void clearScreenshot(String reason) {
- Log.e(TAG, "clearing screenshot: " + reason);
+ Log.v(TAG, "clearing screenshot: " + reason);
if (mScreenshotLayout.isAttachedToWindow()) {
mWindowManager.removeView(mScreenshotLayout);
}
@@ -454,6 +460,41 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset
}
/**
+ * Update assets (called when the dark theme status changes). We only need to update the dismiss
+ * button and the actions container background, since the buttons are re-inflated on demand.
+ */
+ private void reloadAssets() {
+ mDismissImage.setImageDrawable(mContext.getDrawable(R.drawable.screenshot_cancel));
+ mActionsContainer.setBackground(
+ mContext.getDrawable(R.drawable.action_chip_container_background));
+
+ }
+
+ /**
+ * Checks the current dark theme status and updates if it has changed.
+ */
+ private void updateDarkTheme() {
+ int currentNightMode = mContext.getResources().getConfiguration().uiMode
+ & Configuration.UI_MODE_NIGHT_MASK;
+ switch (currentNightMode) {
+ case Configuration.UI_MODE_NIGHT_NO:
+ // Night mode is not active, we're using the light theme
+ if (mInDarkMode) {
+ mInDarkMode = false;
+ reloadAssets();
+ }
+ break;
+ case Configuration.UI_MODE_NIGHT_YES:
+ // Night mode is active, we're using dark theme
+ if (!mInDarkMode) {
+ mInDarkMode = true;
+ reloadAssets();
+ }
+ break;
+ }
+ }
+
+ /**
* Starts the animation after taking the screenshot
*/
private void startAnimation(final Consumer<Uri> finisher, int w, int h,
@@ -660,7 +701,7 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset
R.layout.global_screenshot_action_chip, mActionsView, false);
Toast scrollNotImplemented = Toast.makeText(
mContext, "Not implemented", Toast.LENGTH_SHORT);
- scrollChip.setText("Extend"); // TODO : add resource and translate
+ scrollChip.setText("Extend"); // TODO: add resource and translate
scrollChip.setIcon(
Icon.createWithResource(mContext, R.drawable.ic_arrow_downward), true);
scrollChip.setOnClickListener(v -> {
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java b/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java
index a6e083b04ea3..f68cb745e4c8 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java
@@ -132,7 +132,7 @@ public class TakeScreenshotService extends Service {
@Override
public boolean onUnbind(Intent intent) {
if (mScreenshot != null) mScreenshot.stopScreenshot();
- // TODO (mkephart) remove once notifications flow is fully deprecated
+ // TODO remove once notifications flow is fully deprecated
if (mScreenshotLegacy != null) mScreenshotLegacy.stopScreenshot();
return true;
}
diff --git a/packages/SystemUI/src/com/android/systemui/settings/CurrentUserContextTracker.kt b/packages/SystemUI/src/com/android/systemui/settings/CurrentUserContextTracker.kt
index 4de978c77128..825a7f3dbadb 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/CurrentUserContextTracker.kt
+++ b/packages/SystemUI/src/com/android/systemui/settings/CurrentUserContextTracker.kt
@@ -22,14 +22,13 @@ import androidx.annotation.VisibleForTesting
import com.android.systemui.broadcast.BroadcastDispatcher
import com.android.systemui.util.Assert
import java.lang.IllegalStateException
-import javax.inject.Inject
-import javax.inject.Singleton
/**
* Tracks a reference to the context for the current user
+ *
+ * Constructor is injected at SettingsModule
*/
-@Singleton
-class CurrentUserContextTracker @Inject constructor(
+class CurrentUserContextTracker internal constructor(
private val sysuiContext: Context,
broadcastDispatcher: BroadcastDispatcher
) {
diff --git a/packages/SystemUI/src/com/android/systemui/settings/dagger/SettingsModule.java b/packages/SystemUI/src/com/android/systemui/settings/dagger/SettingsModule.java
new file mode 100644
index 000000000000..2c5c3ceb6e66
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/settings/dagger/SettingsModule.java
@@ -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.
+ */
+
+package com.android.systemui.settings.dagger;
+
+import android.content.Context;
+
+import com.android.systemui.broadcast.BroadcastDispatcher;
+import com.android.systemui.settings.CurrentUserContextTracker;
+
+import javax.inject.Singleton;
+
+import dagger.Module;
+import dagger.Provides;
+
+/**
+ * Dagger Module for classes found within the com.android.systemui.settings package.
+ */
+@Module
+public interface SettingsModule {
+
+ /**
+ * Provides and initializes a CurrentUserContextTracker
+ */
+ @Singleton
+ @Provides
+ static CurrentUserContextTracker provideCurrentUserContextTracker(
+ Context context,
+ BroadcastDispatcher broadcastDispatcher) {
+ CurrentUserContextTracker tracker =
+ new CurrentUserContextTracker(context, broadcastDispatcher);
+ tracker.initialize();
+ return tracker;
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/SplitScreenTaskOrganizer.java b/packages/SystemUI/src/com/android/systemui/stackdivider/SplitScreenTaskOrganizer.java
index a4b1310687aa..f5d6cb6fd4b0 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/SplitScreenTaskOrganizer.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/SplitScreenTaskOrganizer.java
@@ -33,10 +33,8 @@ import android.view.SurfaceControl;
import android.view.SurfaceSession;
import android.window.TaskOrganizer;
-import java.util.ArrayList;
-
class SplitScreenTaskOrganizer extends TaskOrganizer {
- private static final String TAG = "SplitScreenTaskOrganizer";
+ private static final String TAG = "SplitScreenTaskOrg";
private static final boolean DEBUG = Divider.DEBUG;
RunningTaskInfo mPrimary;
@@ -45,7 +43,6 @@ class SplitScreenTaskOrganizer extends TaskOrganizer {
SurfaceControl mSecondarySurface;
SurfaceControl mPrimaryDim;
SurfaceControl mSecondaryDim;
- ArrayList<SurfaceControl> mHomeAndRecentsSurfaces = new ArrayList<>();
Rect mHomeBounds = new Rect();
final Divider mDivider;
private boolean mSplitScreenSupported = false;
@@ -110,6 +107,15 @@ class SplitScreenTaskOrganizer extends TaskOrganizer {
* presentations based on the contents of the split regions.
*/
private void handleTaskInfoChanged(RunningTaskInfo info) {
+ if (!mSplitScreenSupported) {
+ // This shouldn't happen; but apparently there is a chance that SysUI crashes without
+ // system server receiving binder-death (or maybe it receives binder-death too late?).
+ // In this situation, when sys-ui restarts, the split root-tasks will still exist so
+ // there is a small window of time during init() where WM might send messages here
+ // before init() fails. So, avoid a cycle of crashes by returning early.
+ Log.e(TAG, "Got handleTaskInfoChanged when not initialized: " + info);
+ return;
+ }
final boolean secondaryWasHomeOrRecents = mSecondary.topActivityType == ACTIVITY_TYPE_HOME
|| mSecondary.topActivityType == ACTIVITY_TYPE_RECENTS;
final boolean primaryWasEmpty = mPrimary.topActivityType == ACTIVITY_TYPE_UNDEFINED;
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java b/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java
index 5aa7946bcb7f..3027bd225216 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java
@@ -174,12 +174,8 @@ public class WindowManagerProxy {
if (rootTasks.isEmpty()) {
return false;
}
- tiles.mHomeAndRecentsSurfaces.clear();
for (int i = rootTasks.size() - 1; i >= 0; --i) {
final ActivityManager.RunningTaskInfo rootTask = rootTasks.get(i);
- if (isHomeOrRecentTask(rootTask)) {
- tiles.mHomeAndRecentsSurfaces.add(rootTask.token.getLeash());
- }
// Only move resizeable task to split secondary. WM will just ignore this anyways...
if (!rootTask.isResizable()) continue;
// Only move fullscreen tasks to split secondary.
@@ -211,7 +207,6 @@ public class WindowManagerProxy {
// Set launch root first so that any task created after getChildContainers and
// before reparent (pretty unlikely) are put into fullscreen.
TaskOrganizer.setLaunchRoot(Display.DEFAULT_DISPLAY, null);
- tiles.mHomeAndRecentsSurfaces.clear();
// TODO(task-org): Once task-org is more complete, consider using Appeared/Vanished
// plus specific APIs to clean this up.
List<ActivityManager.RunningTaskInfo> primaryChildren =
diff --git a/packages/Tethering/res/values-af/strings.xml b/packages/Tethering/res/values-af/strings.xml
index 1258805378ea..056168b12e89 100644
--- a/packages/Tethering/res/values-af/strings.xml
+++ b/packages/Tethering/res/values-af/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"Verbinding of Wi-Fi-warmkol aktief"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"Tik om op te stel."</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"Verbinding is gedeaktiveer"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"Kontak jou administrateur vir besonderhede"</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"Verbinding of warmkol is aktief"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"Tik om op te stel."</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"Verbinding is gedeaktiveer"</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"Kontak jou administrateur vir besonderhede"</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Warmkol- en verbindingstatus"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-am/strings.xml b/packages/Tethering/res/values-am/strings.xml
index 9c36192257c0..ac468dd14414 100644
--- a/packages/Tethering/res/values-am/strings.xml
+++ b/packages/Tethering/res/values-am/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"መሰካት ወይም ገባሪ ድረስ ነጥብ"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"ለማዋቀር መታ ያድርጉ።"</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"እንደ ሞደም መሰካት ተሰናክሏል"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"ለዝርዝሮች የእርስዎን አስተዳዳሪ ያነጋግሩ"</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"እንደ ሞደም መሰካት ወይም መገናኛ ነጥብ ገባሪ"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"ለማዋቀር መታ ያድርጉ።"</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"እንደ ሞደም መሰካት ተሰናክሏል"</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"ለዝርዝሮች የእርስዎን አስተዳዳሪ ያነጋግሩ"</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"መገናኛ ነጥብ እና እንደ ሞደም የመሰካት ሁኔታ"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-ar/strings.xml b/packages/Tethering/res/values-ar/strings.xml
index 9f84ce4090c6..7d5bad34da04 100644
--- a/packages/Tethering/res/values-ar/strings.xml
+++ b/packages/Tethering/res/values-ar/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"النطاق أو نقطة الاتصال نشطة"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"انقر للإعداد."</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"تم إيقاف التوصيل"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"اتصل بالمشرف للحصول على التفاصيل"</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"النطاق نشط أو نقطة الاتصال نشطة"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"انقر للإعداد."</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"التوصيل متوقف."</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"تواصَل مع المشرف للحصول على التفاصيل."</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"حالة نقطة الاتصال والتوصيل"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-as/strings.xml b/packages/Tethering/res/values-as/strings.xml
index 8855822e7c8b..091350455ba0 100644
--- a/packages/Tethering/res/values-as/strings.xml
+++ b/packages/Tethering/res/values-as/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"টেডাৰিং বা হটস্প\'ট সক্ৰিয় অৱস্থাত আছে"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"ছেট আপ কৰিবলৈ টিপক।"</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"টেডাৰিং অক্ষম কৰি থোৱা হৈছে"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"সবিশেষ জানিবলৈ আপোনাৰ প্ৰশাসকৰ সৈতে যোগাযোগ কৰক"</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"টে\'ডাৰিং অথবা হ\'টস্প\'ট সক্ৰিয় অৱস্থাত আছে"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"ছেট আপ কৰিবলৈ টিপক।"</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"টে\'ডাৰিঙৰ সুবিধাটো অক্ষম কৰি থোৱা হৈছে"</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"সবিশেষ জানিবলৈ আপোনাৰ প্ৰশাসকৰ সৈতে যোগাযোগ কৰক"</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"হ’টস্প\'ট আৰু টে\'ডাৰিঙৰ স্থিতি"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-az/strings.xml b/packages/Tethering/res/values-az/strings.xml
index eba50eb636c1..dce70da178f1 100644
--- a/packages/Tethering/res/values-az/strings.xml
+++ b/packages/Tethering/res/values-az/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"Tezerinq və ya hotspot aktivdir"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"Quraşdırmaq üçün tıklayın."</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"Birləşmə deaktivdir"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"Məlumat üçün adminlə əlaqə saxlayın"</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"Birləşmə və ya hotspot aktivdir"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"Ayarlamaq üçün toxunun."</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"Birləşmə deaktivdir"</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"Detallar üçün adminlə əlaqə saxlayın"</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Hotspot &amp; birləşmə statusu"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-b+sr+Latn/strings.xml b/packages/Tethering/res/values-b+sr+Latn/strings.xml
index 5b0e488ba5e6..b0774ec9a840 100644
--- a/packages/Tethering/res/values-b+sr+Latn/strings.xml
+++ b/packages/Tethering/res/values-b+sr+Latn/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"Aktivno povezivanje sa internetom preko mobilnog uređaja ili hotspot"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"Dodirnite da biste podesili."</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"Privezivanje je onemogućeno"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"Potražite detalje od administratora"</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"Privezivanje ili hotspot je aktivan"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"Dodirnite da biste podesili."</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"Privezivanje je onemogućeno"</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"Potražite detalje od administratora"</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Status hotspota i privezivanja"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-be/strings.xml b/packages/Tethering/res/values-be/strings.xml
index 5966c7155ecd..a8acebe2e992 100644
--- a/packages/Tethering/res/values-be/strings.xml
+++ b/packages/Tethering/res/values-be/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"USB-мадэм або хот-спот Wi-Fi актыўныя"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"Дакраніцеся, каб наладзіць."</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"Рэжым мадэма адключаны"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"Звярніцеся да адміністратара па падрабязную інфармацыю"</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"Мадэм або хот-спот актыўныя"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"Дакраніцеся, каб наладзіць."</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"Рэжым мадэма выключаны"</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"Звярніцеся да адміністратара па падрабязную інфармацыю"</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Стан \"Хот-спот і мадэм\""</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-bg/strings.xml b/packages/Tethering/res/values-bg/strings.xml
index ed58d7311aca..94fb2d8f176a 100644
--- a/packages/Tethering/res/values-bg/strings.xml
+++ b/packages/Tethering/res/values-bg/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"Има активна споделена връзка или безжична точка за достъп"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"Докоснете, за да настроите."</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"Функцията за тетъринг е деактивирана"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"Свържете се с администратора си за подробности"</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"Има активна споделена връзка или точка за достъп"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"Докоснете, за да настроите."</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"Функцията за тетъринг е деактивирана"</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"Свържете се с администратора си за подробности"</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Състояние на функцията за точка за достъп и тетъринг"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-bn/strings.xml b/packages/Tethering/res/values-bn/strings.xml
index 8d9880aa9aca..aea02b9ddff8 100644
--- a/packages/Tethering/res/values-bn/strings.xml
+++ b/packages/Tethering/res/values-bn/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"টিথারিং বা হটস্পট সক্রিয় আছে"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"সেট-আপ করার জন্য আলতো চাপুন৷"</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"টিথারিং অক্ষম করা আছে"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"বিশদ বিবরণের জন্য প্রশাসকের সাথে যোগাযোগ করুন"</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"টিথারিং বা হটস্পট চালু আছে"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"সেট-আপ করতে ট্যাপ করুন।"</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"টিথারিং বন্ধ করা আছে"</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"বিশদে জানতে অ্যাডমিনের সাথে যোগাযোগ করুন"</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"হটস্পট ও টিথারিং স্ট্যাটাস"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-bs/strings.xml b/packages/Tethering/res/values-bs/strings.xml
index 2361b9dd382c..de232724c5d9 100644
--- a/packages/Tethering/res/values-bs/strings.xml
+++ b/packages/Tethering/res/values-bs/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"Uređaj dijeli vezu ili djeluje kao pristupna tačka"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"Dodirnite za postavke"</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"Povezivanje putem mobitela je onemogućeno"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"Kontaktirajte svog administratora za dodatne detalje"</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"Aktivno je povezivanje putem mobitela ili pristupna tačka"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"Dodirnite da postavite."</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"Povezivanje putem mobitela je onemogućeno"</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"Kontaktirajte svog administratora za detalje"</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Status pristupne tačke i povezivanja putem mobitela"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-ca/strings.xml b/packages/Tethering/res/values-ca/strings.xml
index 6752b519e218..88b795c1f8b2 100644
--- a/packages/Tethering/res/values-ca/strings.xml
+++ b/packages/Tethering/res/values-ca/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"Compartició de xarxa o punt d\'accés Wi-Fi activat"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"Toca per configurar."</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"La compartició de xarxa està desactivada"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"Contacta amb el teu administrador per obtenir més informació"</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"Compartició de xarxa o punt d\'accés Wi‑Fi actius"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"Toca per configurar."</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"La compartició de xarxa està desactivada"</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"Contacta amb el teu administrador per obtenir més informació"</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Estat del punt d\'accés Wi‑Fi i de la compartició de xarxa"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-cs/strings.xml b/packages/Tethering/res/values-cs/strings.xml
index 5fdd53adf15c..8c1b83bf3ee3 100644
--- a/packages/Tethering/res/values-cs/strings.xml
+++ b/packages/Tethering/res/values-cs/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"Sdílené připojení nebo hotspot je aktivní."</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"Klepnutím zahájíte nastavení."</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering je zakázán"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"O podrobnosti požádejte administrátora"</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"Tethering nebo hotspot je aktivní"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"Klepnutím zahájíte nastavení."</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering je zakázán"</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"O podrobnosti požádejte administrátora"</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Stav hotspotu a tetheringu"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-da/strings.xml b/packages/Tethering/res/values-da/strings.xml
index 2775dfa551cb..f413e7054819 100644
--- a/packages/Tethering/res/values-da/strings.xml
+++ b/packages/Tethering/res/values-da/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"Netdeling eller hotspot er aktivt"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"Tryk for at konfigurere"</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"Netdeling er deaktiveret"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"Kontakt din administrator for at få oplysninger"</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"Netdeling eller hotspot er aktivt"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"Tryk for at konfigurere."</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"Netdeling er deaktiveret"</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"Kontakt din administrator for at få oplysninger"</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Status for hotspot og netdeling"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-de/strings.xml b/packages/Tethering/res/values-de/strings.xml
index 9046cd5e1144..f057d7824e81 100644
--- a/packages/Tethering/res/values-de/strings.xml
+++ b/packages/Tethering/res/values-de/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering oder Hotspot aktiv"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"Zum Einrichten tippen."</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering ist deaktiviert"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"Bitte wende dich für weitere Informationen an den Administrator"</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"Tethering oder Hotspot aktiv"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"Zum Einrichten tippen."</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering ist deaktiviert"</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"Bitte wende dich für weitere Informationen an den Administrator"</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Hotspot- und Tethering-Status"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-el/strings.xml b/packages/Tethering/res/values-el/strings.xml
index 3b9f53733b8a..b3c986bdafd6 100644
--- a/packages/Tethering/res/values-el/strings.xml
+++ b/packages/Tethering/res/values-el/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"Πρόσδεση ή σύνδεση σημείου πρόσβασης ενεργή"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"Πατήστε για ρύθμιση."</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"Η σύνδεση είναι απενεργοποιημένη"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"Επικοινωνήστε με τον διαχειριστή σας για λεπτομέρειες"</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"Πρόσδεση ή σύνδεση σημείου πρόσβασης ενεργή"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"Πατήστε για ρύθμιση."</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"Η σύνδεση είναι απενεργοποιημένη"</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"Επικοινωνήστε με τον διαχειριστή σας για λεπτομέρειες"</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Κατάσταση σημείου πρόσβασης Wi-Fi και σύνδεσης"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-en-rAU/strings.xml b/packages/Tethering/res/values-en-rAU/strings.xml
index 56b88a5fb3e1..769e01208afc 100644
--- a/packages/Tethering/res/values-en-rAU/strings.xml
+++ b/packages/Tethering/res/values-en-rAU/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering or hotspot active"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"Tap to set up."</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering is disabled"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"Contact your admin for details"</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"Tethering or hotspot active"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"Tap to set up."</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering is disabled"</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"Contact your admin for details"</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Hotspot and tethering status"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-en-rCA/strings.xml b/packages/Tethering/res/values-en-rCA/strings.xml
index 56b88a5fb3e1..769e01208afc 100644
--- a/packages/Tethering/res/values-en-rCA/strings.xml
+++ b/packages/Tethering/res/values-en-rCA/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering or hotspot active"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"Tap to set up."</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering is disabled"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"Contact your admin for details"</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"Tethering or hotspot active"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"Tap to set up."</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering is disabled"</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"Contact your admin for details"</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Hotspot and tethering status"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-en-rGB/strings.xml b/packages/Tethering/res/values-en-rGB/strings.xml
index 56b88a5fb3e1..769e01208afc 100644
--- a/packages/Tethering/res/values-en-rGB/strings.xml
+++ b/packages/Tethering/res/values-en-rGB/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering or hotspot active"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"Tap to set up."</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering is disabled"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"Contact your admin for details"</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"Tethering or hotspot active"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"Tap to set up."</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering is disabled"</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"Contact your admin for details"</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Hotspot and tethering status"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-en-rIN/strings.xml b/packages/Tethering/res/values-en-rIN/strings.xml
index 56b88a5fb3e1..769e01208afc 100644
--- a/packages/Tethering/res/values-en-rIN/strings.xml
+++ b/packages/Tethering/res/values-en-rIN/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering or hotspot active"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"Tap to set up."</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering is disabled"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"Contact your admin for details"</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"Tethering or hotspot active"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"Tap to set up."</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering is disabled"</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"Contact your admin for details"</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Hotspot and tethering status"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-en-rXC/strings.xml b/packages/Tethering/res/values-en-rXC/strings.xml
index 7f47fc89d2af..f1674bed4eb7 100644
--- a/packages/Tethering/res/values-en-rXC/strings.xml
+++ b/packages/Tethering/res/values-en-rXC/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‏‏‎‏‎‏‎‏‏‎‏‎‎‏‏‎‏‏‎‏‏‏‎‏‏‏‏‏‏‏‎‏‎‎‎‎‏‎‎‏‏‎‎‎‏‏‎‏‎‏‏‏‎‏‎‎‏‎Tethering or hotspot active‎‏‎‎‏‎"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‏‎‏‎‏‎‏‎‏‎‎‎‏‏‏‎‏‏‏‏‏‎‎‎‎‏‏‏‏‎‎‎‎‏‏‏‏‎‎‎‏‏‏‎‏‏‏‏‎‎‏‎‏‎‎‎‏‎Tap to set up.‎‏‎‎‏‎"</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‎‎‏‏‏‎‏‎‏‎‎‏‏‎‎‏‎‏‎‎‎‏‏‏‏‎‏‏‏‏‏‏‎‏‏‏‏‎‏‎‎‎‏‏‏‎‎‎‏‎‎‏‎‏‎‏‏‎Tethering is disabled‎‏‎‎‏‎"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‎‎‏‏‎‏‏‏‎‎‏‎‏‏‎‏‏‎‏‎‏‎‏‎‎‏‏‎‎‎‎‎‎‎‏‎‎‏‎‏‏‏‎‏‎‎‎‏‏‎‎‎‎‏‏‏‏‎Contact your admin for details‎‏‎‎‏‎"</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‎‏‎‎‏‎‏‏‏‏‏‎‏‏‏‏‎‏‏‎‎‎‏‎‎‎‎‎‏‏‎‏‏‏‏‎‎‎‎‏‏‏‎‎‏‎‎‏‎‏‏‎‏‏‎‎‎‎‎Tethering or hotspot active‎‏‎‎‏‎"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‎‎‏‏‏‎‎‏‏‎‎‎‏‏‏‎‎‎‎‎‎‎‏‏‏‎‎‏‏‏‏‎‏‏‏‏‏‎‏‏‏‏‎‎‏‎‏‏‎‏‎‎‎‏‏‎‎‎‎Tap to set up.‎‏‎‎‏‎"</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‏‏‎‏‏‎‎‏‎‎‎‏‎‏‎‎‏‎‎‏‎‎‎‏‎‎‎‎‏‏‏‎‏‎‎‎‏‏‏‎‎‎‏‎‏‎‎‎‏‏‎‎‏‏‏‏‏‎Tethering is disabled‎‏‎‎‏‎"</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‏‎‎‏‏‏‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‏‎‏‏‏‏‏‎‎‏‏‎‎‏‎‎‏‎‏‎‎‏‏‏‎‏‎‏‎‏‎‎‏‎‎‎Contact your admin for details‎‏‎‎‏‎"</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‎‏‏‏‏‎‏‏‎‏‎‎‎‎‏‏‎‎‏‎‎‏‏‎‎‎‎‏‏‎‏‏‎‏‏‎‎‎‏‏‏‏‏‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎Hotspot &amp; tethering status‎‏‎‎‏‎"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-es-rUS/strings.xml b/packages/Tethering/res/values-es-rUS/strings.xml
index e4618b8cec96..63689f43997c 100644
--- a/packages/Tethering/res/values-es-rUS/strings.xml
+++ b/packages/Tethering/res/values-es-rUS/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"Anclaje a red o zona activa conectados"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"Presiona para configurar."</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"Se inhabilitó la conexión mediante dispositivo portátil"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"Para obtener más información, comunícate con el administrador"</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"Conexión a red o hotspot conectados"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"Presiona para configurar esta opción."</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"Se inhabilitó la conexión mediante dispositivo portátil"</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"Para obtener más información, comunícate con el administrador"</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Estado del hotspot y la conexión mediante dispositivo portátil"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-es/strings.xml b/packages/Tethering/res/values-es/strings.xml
index 8dc1575ce8ea..9a34ed5e388a 100644
--- a/packages/Tethering/res/values-es/strings.xml
+++ b/packages/Tethering/res/values-es/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"Compartir conexión/Zona Wi-Fi activada"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"Toca para configurar."</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"La conexión compartida está inhabilitada"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"Ponte en contacto con el administrador para obtener más información"</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"Conexión compartida o punto de acceso activos"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"Toca para configurar."</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"La conexión compartida está inhabilitada"</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"Solicita más información a tu administrador"</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Estado del punto de acceso y de la conexión compartida"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-et/strings.xml b/packages/Tethering/res/values-et/strings.xml
index 872c8a74cc59..0970341ab0cd 100644
--- a/packages/Tethering/res/values-et/strings.xml
+++ b/packages/Tethering/res/values-et/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"Jagamine või kuumkoht on aktiivne"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"Puudutage seadistamiseks."</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"Jagamine on keelatud"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"Lisateabe saamiseks võtke ühendust oma administraatoriga"</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"Jagamine või kuumkoht on aktiivne"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"Puudutage seadistamiseks."</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"Jagamine on keelatud"</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"Lisateabe saamiseks võtke ühendust oma administraatoriga"</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Kuumkoha ja jagamise olek"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-eu/strings.xml b/packages/Tethering/res/values-eu/strings.xml
index 6c4605e616c1..632019e2ef1b 100644
--- a/packages/Tethering/res/values-eu/strings.xml
+++ b/packages/Tethering/res/values-eu/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"Konexioa partekatzea edo sare publikoa aktibo"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"Sakatu konfiguratzeko."</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"Desgaituta dago konexioa partekatzeko aukera"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"Xehetasunak lortzeko, jarri administratzailearekin harremanetan"</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"Konexioa partekatzea edo wifi-gunea aktibo dago"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"Sakatu konfiguratzeko."</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"Desgaituta dago konexioa partekatzeko aukera"</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"Xehetasunak lortzeko, jarri administratzailearekin harremanetan"</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Wifi-gunearen eta konexioa partekatzeko eginbidearen egoera"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-fa/strings.xml b/packages/Tethering/res/values-fa/strings.xml
index bc2ee23609c3..2e21c85fa179 100644
--- a/packages/Tethering/res/values-fa/strings.xml
+++ b/packages/Tethering/res/values-fa/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"اشتراک‌گذاری اینترنت یا نقطه اتصال فعال"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"برای راه‌اندازی ضربه بزنید."</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"اشتراک‌گذاری اینترنت غیرفعال است"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"برای جزئیات، با سرپرستتان تماس بگیرید"</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"اشتراک‌گذاری اینترنت یا نقطه اتصال فعال"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"برای راه‌اندازی ضربه بزنید."</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"اشتراک‌گذاری اینترنت غیرفعال است"</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"برای جزئیات، با سرپرستتان تماس بگیرید"</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"وضعیت نقطه اتصال و اشتراک‌گذاری اینترنت"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-fi/strings.xml b/packages/Tethering/res/values-fi/strings.xml
index ff0fca6502df..413db3f0f8c9 100644
--- a/packages/Tethering/res/values-fi/strings.xml
+++ b/packages/Tethering/res/values-fi/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"Internetin jakaminen tai yhteyspiste käytössä"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"Määritä napauttamalla."</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"Yhteyden jakaminen poistettu käytöstä"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"Kysy lisätietoja järjestelmänvalvojalta."</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"Yhteyden jakaminen tai hotspot käytössä"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"Ota käyttöön napauttamalla."</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"Yhteyden jakaminen on poistettu käytöstä"</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"Pyydä lisätietoja järjestelmänvalvojalta"</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Hotspotin ja yhteyden jakamisen tila"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-fr-rCA/strings.xml b/packages/Tethering/res/values-fr-rCA/strings.xml
index 1f5df0ee0cb0..eb2e4ba54000 100644
--- a/packages/Tethering/res/values-fr-rCA/strings.xml
+++ b/packages/Tethering/res/values-fr-rCA/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"Partage de connexion ou point d\'accès sans fil activé"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"Touchez pour configurer."</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"Le partage de connexion est désactivé"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"Communiquez avec votre administrateur pour obtenir plus de détails"</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"Partage de connexion ou point d\'accès sans fil activé"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"Touchez pour configurer."</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"Le partage de connexion est désactivé"</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"Communiquez avec votre administrateur pour obtenir plus de détails"</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Point d\'accès et partage de connexion"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-fr/strings.xml b/packages/Tethering/res/values-fr/strings.xml
index daf7c9d830d5..22259c52ab9e 100644
--- a/packages/Tethering/res/values-fr/strings.xml
+++ b/packages/Tethering/res/values-fr/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"Partage de connexion ou point d\'accès sans fil activé"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"Appuyez ici pour configurer."</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"Le partage de connexion est désactivé"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"Pour en savoir plus, contactez votre administrateur"</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"Partage de connexion ou point d\'accès activé"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"Appuyez pour effectuer la configuration."</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"Le partage de connexion est désactivé"</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"Pour en savoir plus, contactez votre administrateur"</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"État du point d\'accès et du partage de connexion"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-gl/strings.xml b/packages/Tethering/res/values-gl/strings.xml
index 0d16a1de094f..ded82fcd54ad 100644
--- a/packages/Tethering/res/values-gl/strings.xml
+++ b/packages/Tethering/res/values-gl/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"Conexión compartida ou zona wifi activada"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"Tocar para configurar."</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"A conexión compartida está desactivada"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"Contacta co administrador para obter información"</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"Conexión compartida ou zona wifi activada"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"Toca para configurar."</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"A conexión compartida está desactivada"</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"Contacta co administrador para obter información"</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Estado da zona wifi e da conexión compartida"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-gu/strings.xml b/packages/Tethering/res/values-gu/strings.xml
index 9d6b02f85fc9..7cbbc2de3d91 100644
--- a/packages/Tethering/res/values-gu/strings.xml
+++ b/packages/Tethering/res/values-gu/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"ટિથરિંગ અથવા હૉટસ્પૉટ સક્રિય"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"સેટ કરવા માટે ટૅપ કરો."</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"ટિથરિંગ અક્ષમ કરેલ છે"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"વિગતો માટે તમારા વ્યવસ્થાપકનો સંપર્ક કરો"</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"ઇન્ટરનેટ શેર કરવાની સુવિધા અથવા હૉટસ્પૉટ સક્રિય છે"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"સેટઅપ કરવા માટે ટૅપ કરો."</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"ઇન્ટરનેટ શેર કરવાની સુવિધા બંધ કરી છે"</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"વિગતો માટે તમારા વ્યવસ્થાપકનો સંપર્ક કરો"</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"હૉટસ્પૉટ અને ઇન્ટરનેટ શેર કરવાની સુવિધાનું સ્ટેટસ"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-hi/strings.xml b/packages/Tethering/res/values-hi/strings.xml
index 9c29d9a8f9a1..08af81b826b3 100644
--- a/packages/Tethering/res/values-hi/strings.xml
+++ b/packages/Tethering/res/values-hi/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"टेदरिंग या हॉटस्‍पॉट सक्रिय"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"सेट करने के लिए टैप करें."</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"टेदरिंग अक्षम है"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"जानकारी के लिए अपने एडमिन से संपर्क करें"</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"टेदरिंग या हॉटस्पॉट चालू है"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"सेट अप करने के लिए टैप करें."</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"टेदरिंग बंद है"</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"जानकारी के लिए अपने एडमिन से संपर्क करें"</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"हॉटस्पॉट और टेदरिंग की स्थिति"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-hr/strings.xml b/packages/Tethering/res/values-hr/strings.xml
index d0d25bb755aa..827c135f205d 100644
--- a/packages/Tethering/res/values-hr/strings.xml
+++ b/packages/Tethering/res/values-hr/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"Ograničenje ili aktivan hotspot"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"Dodirnite da biste postavili."</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"Modemsko je povezivanje onemogućeno"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"Obratite se administratoru da biste saznali pojedinosti"</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"Modemsko povezivanje ili žarišna točka aktivni"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"Dodirnite da biste postavili."</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"Modemsko je povezivanje onemogućeno"</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"Obratite se administratoru da biste saznali pojedinosti"</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Status žarišne točke i modemskog povezivanja"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-hu/strings.xml b/packages/Tethering/res/values-hu/strings.xml
index 31296599231e..eb68d6babf8f 100644
--- a/packages/Tethering/res/values-hu/strings.xml
+++ b/packages/Tethering/res/values-hu/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"Megosztás vagy aktív hotspot"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"Koppintson a beállításhoz."</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"Az internetmegosztás le van tiltva"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"A részletekért forduljon rendszergazdájához"</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"Megosztás vagy aktív hotspot"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"Koppintson a beállításhoz."</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"Az internetmegosztás le van tiltva"</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"A részletekért forduljon rendszergazdájához"</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Hotspot és internetmegosztás állapota"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-hy/strings.xml b/packages/Tethering/res/values-hy/strings.xml
index 8ba6435fd58e..912941e53835 100644
--- a/packages/Tethering/res/values-hy/strings.xml
+++ b/packages/Tethering/res/values-hy/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"Մոդեմի ռեժիմը միացված է"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"Հպեք՝ կարգավորելու համար:"</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"Մոդեմի ռեժիմն անջատված է"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"Մանրամասների համար դիմեք ձեր ադմինիստրատորին"</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"Մոդեմի ռեժիմը միացված է"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"Հպեք՝ կարգավորելու համար։"</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"Մոդեմի ռեժիմն անջատված է"</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"Մանրամասների համար դիմեք ձեր ադմինիստրատորին"</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Թեժ կետի և մոդեմի ռեժիմի կարգավիճակը"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-in/strings.xml b/packages/Tethering/res/values-in/strings.xml
index 1e093ab237e8..a4e175a439e9 100644
--- a/packages/Tethering/res/values-in/strings.xml
+++ b/packages/Tethering/res/values-in/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering (Penambatan) atau hotspot aktif"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"Ketuk untuk menyiapkan."</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering dinonaktifkan"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"Hubungi admin untuk mengetahui detailnya"</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"Tethering atau hotspot aktif"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"Ketuk untuk menyiapkan."</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering dinonaktifkan"</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"Hubungi admin untuk mengetahui detailnya"</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Status hotspot &amp; tethering"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-is/strings.xml b/packages/Tethering/res/values-is/strings.xml
index f5769d5344ae..e9f6670bcd09 100644
--- a/packages/Tethering/res/values-is/strings.xml
+++ b/packages/Tethering/res/values-is/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"Kveikt á tjóðrun eða aðgangsstað"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"Ýttu til að setja upp."</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"Slökkt er á tjóðrun"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"Hafðu samband við kerfisstjórann til að fá upplýsingar"</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"Kveikt á tjóðrun eða aðgangsstað"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"Ýttu til að setja upp."</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"Slökkt er á tjóðrun"</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"Hafðu samband við kerfisstjórann til að fá upplýsingar"</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Staða heits reits og tjóðrunar"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-it/strings.xml b/packages/Tethering/res/values-it/strings.xml
index e0b3724325fc..ffb9196f5ee3 100644
--- a/packages/Tethering/res/values-it/strings.xml
+++ b/packages/Tethering/res/values-it/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering oppure hotspot attivo"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"Tocca per impostare."</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering disattivato"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"Contatta il tuo amministratore per avere informazioni dettagliate"</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"Hotspot o tethering attivo"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"Tocca per impostare."</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering disattivato"</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"Contatta il tuo amministratore per avere informazioni dettagliate"</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Stato hotspot e tethering"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-iw/strings.xml b/packages/Tethering/res/values-iw/strings.xml
index c002c44b2361..7adcb47350c1 100644
--- a/packages/Tethering/res/values-iw/strings.xml
+++ b/packages/Tethering/res/values-iw/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"שיתוף אינטרנט פעיל"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"הקש כדי להגדיר."</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"שיתוף האינטרנט בין ניידים מושבת"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"לפרטים, יש לפנות למנהל המערכת"</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"נקודה לשיתוף אינטרנט או שיתוף אינטרנט בין מכשירים: בסטטוס פעיל"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"יש להקיש כדי להגדיר."</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"שיתוף האינטרנט בין מכשירים מושבת"</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"לפרטים, יש לפנות למנהל המערכת"</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"סטטוס של נקודה לשיתוף אינטרנט ושיתוף אינטרנט בין מכשירים"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-ja/strings.xml b/packages/Tethering/res/values-ja/strings.xml
index 314bde00df02..f68a73010b36 100644
--- a/packages/Tethering/res/values-ja/strings.xml
+++ b/packages/Tethering/res/values-ja/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"テザリングまたはアクセスポイントが有効です"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"タップしてセットアップします。"</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"テザリングは無効に設定されています"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"詳しくは、管理者にお問い合わせください"</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"テザリングまたはアクセス ポイントが有効です"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"タップしてセットアップします。"</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"テザリングは無効に設定されています"</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"詳しくは、管理者にお問い合わせください"</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"アクセス ポイントとテザリングのステータス"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-ka/strings.xml b/packages/Tethering/res/values-ka/strings.xml
index 7bbd81d3435a..7c22e82bd370 100644
--- a/packages/Tethering/res/values-ka/strings.xml
+++ b/packages/Tethering/res/values-ka/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"ტეტერინგი ან უსადენო ქსელი აქტიურია"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"შეეხეთ დასაყენებლად."</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"ტეტერინგი გათიშულია"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"დამატებითი ინფორმაციისთვის დაუკავშირდით თქვენს ადმინისტრატორს"</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"ტეტერინგი ან უსადენო ქსელი აქტიურია"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"შეეხეთ დასაყენებლად."</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"ტეტერინგი გათიშულია"</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"დამატებითი ინფორმაციისთვის დაუკავშირდით თქვენს ადმინისტრატორს"</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"უსადენო ქსელის და ტეტერინგის სტატუსი"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-kk/strings.xml b/packages/Tethering/res/values-kk/strings.xml
index 7fd87a159657..0857d06de243 100644
--- a/packages/Tethering/res/values-kk/strings.xml
+++ b/packages/Tethering/res/values-kk/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"Тетеринг немесе хотспот қосулы"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"Реттеу үшін түртіңіз."</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"Тетеринг өшірілді"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"Мәліметтерді әкімшіден алыңыз"</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"Тетеринг немесе хотспот қосулы"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"Реттеу үшін түртіңіз."</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"Тетеринг өшірілді."</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"Мәліметтерді әкімшіден алыңыз."</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Хотспот және тетеринг күйі"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-km/strings.xml b/packages/Tethering/res/values-km/strings.xml
index 2f852246790c..536e3d1703b1 100644
--- a/packages/Tethering/res/values-km/strings.xml
+++ b/packages/Tethering/res/values-km/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"ភ្ជាប់ ឬ​ហតស្ពត​សកម្ម"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"ប៉ះដើម្បីកំណត់"</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"ការភ្ជាប់​ត្រូវបានបិទ"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"ទាក់ទងអ្នកគ្រប់គ្រង​របស់អ្នកសម្រាប់​ព័ត៌មានលម្អិត"</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"ការភ្ជាប់ ឬហតស្ប៉ត​កំពុងដំណើរការ"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"ចុច​ដើម្បី​រៀបចំ។"</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"ការភ្ជាប់​ត្រូវបានបិទ"</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"ទាក់ទងអ្នកគ្រប់គ្រង​របស់អ្នក ដើម្បីទទួលបានព័ត៌មានលម្អិត"</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"ស្ថានភាពនៃការភ្ជាប់ និងហតស្ប៉ត"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-kn/strings.xml b/packages/Tethering/res/values-kn/strings.xml
index f11a83ea40ee..32f54926f4bf 100644
--- a/packages/Tethering/res/values-kn/strings.xml
+++ b/packages/Tethering/res/values-kn/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"ಟೆಥರಿಂಗ್ ಅಥವಾ ಹಾಟ್‌ಸ್ಪಾಟ್ ಸಕ್ರಿಯವಾಗಿದೆ"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"ಹೊಂದಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"ಟೆಥರಿಂಗ್ ಅನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"ವಿವರಗಳಿಗಾಗಿ ನಿಮ್ಮ ನಿರ್ವಾಹಕರನ್ನು ಸಂಪರ್ಕಿಸಿ"</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"ಟೆಥರಿಂಗ್ ಅಥವಾ ಹಾಟ್‌ಸ್ಪಾಟ್ ಸಕ್ರಿಯವಾಗಿದೆ"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"ಸೆಟಪ್ ಮಾಡಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"ಟೆಥರಿಂಗ್ ಅನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"ವಿವರಗಳಿಗಾಗಿ ನಿಮ್ಮ ನಿರ್ವಾಹಕರನ್ನು ಸಂಪರ್ಕಿಸಿ"</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"ಹಾಟ್‌ಸ್ಪಾಟ್ ಮತ್ತು ಟೆಥರಿಂಗ್‌ ಸ್ಥಿತಿ"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-ko/strings.xml b/packages/Tethering/res/values-ko/strings.xml
index 57f24f5b1ae2..156b24786db5 100644
--- a/packages/Tethering/res/values-ko/strings.xml
+++ b/packages/Tethering/res/values-ko/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"테더링 또는 핫스팟 사용"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"설정하려면 탭하세요."</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"테더링이 사용 중지됨"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"자세한 정보는 관리자에게 문의하세요."</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"테더링 또는 핫스팟 사용"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"설정하려면 탭하세요."</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"테더링이 사용 중지됨"</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"자세한 정보는 관리자에게 문의하세요."</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"핫스팟 및 테더링 상태"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-ky/strings.xml b/packages/Tethering/res/values-ky/strings.xml
index 79854859d41e..18ee5fd35718 100644
--- a/packages/Tethering/res/values-ky/strings.xml
+++ b/packages/Tethering/res/values-ky/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"Жалгаштыруу же хотспот жандырылган"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"Жөндөө үчүн таптап коюңуз."</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"Жалгаштыруу функциясы өчүрүлгөн"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"Кеңири маалымат үчүн администраторуңузга кайрылыңыз"</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"Модем режими күйүп турат"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"Жөндөө үчүн таптап коюңуз."</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"Телефонду модем катары колдонууга болбойт"</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"Кеңири маалымат үчүн администраторуңузга кайрылыңыз"</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Байланыш түйүнүнүн жана модем режиминин статусу"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-lo/strings.xml b/packages/Tethering/res/values-lo/strings.xml
index 78f1585f60f7..b12767018c3a 100644
--- a/packages/Tethering/res/values-lo/strings.xml
+++ b/packages/Tethering/res/values-lo/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"ເປີດ​ການ​ປ່ອຍ​ສັນຍານ ຫຼື​ຮັອດສະປອດ​ແລ້ວ"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"ແຕະເພື່ອຕັ້ງຄ່າ."</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"ການປ່ອຍສັນຍານຖືກປິດໄວ້"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"ຕິດຕໍ່ຜູ້ເບິ່ງແຍງລະບົບສຳລັບລາຍລະອຽດ"</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"ເປີດການປ່ອຍສັນຍານ ຫຼື ຮັອດສະປອດແລ້ວ"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"ແຕະເພື່ອຕັ້ງຄ່າ."</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"ການປ່ອຍສັນຍານຖືກປິດໄວ້"</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"ຕິດຕໍ່ຜູ້ເບິ່ງແຍງລະບົບສຳລັບລາຍລະອຽດ"</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"ສະຖານະຮັອດສະປອດ ແລະ ການປ່ອຍສັນຍານ"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-lt/strings.xml b/packages/Tethering/res/values-lt/strings.xml
index ebff8ac9d1f1..8427baf39f31 100644
--- a/packages/Tethering/res/values-lt/strings.xml
+++ b/packages/Tethering/res/values-lt/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"Susietas ar aktyvus"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"Palieskite, kad nustatytumėte."</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"Įrenginio kaip modemo naudojimas išjungtas"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"Jei reikia išsamios informacijos, susisiekite su administratoriumi"</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"Įrenginys naudojamas kaip modemas arba įjungtas viešosios interneto prieigos taškas"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"Palieskite, kad nustatytumėte."</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"Įrenginio kaip modemo naudojimas išjungtas"</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"Jei reikia išsamios informacijos, susisiekite su administratoriumi"</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Viešosios interneto prieigos taško ir įrenginio kaip modemo naudojimo būsena"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-lv/strings.xml b/packages/Tethering/res/values-lv/strings.xml
index 54d0048b526a..aa2d6990e04f 100644
--- a/packages/Tethering/res/values-lv/strings.xml
+++ b/packages/Tethering/res/values-lv/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"Piesaiste vai tīklājs ir aktīvs."</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"Pieskarieties, lai iestatītu."</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"Piesaiste ir atspējota"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"Lai iegūtu detalizētu informāciju, sazinieties ar savu administratoru."</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"Piesaiste vai tīklājs ir aktīvs."</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"Pieskarieties, lai to iestatītu."</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"Piesaiste ir atspējota"</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"Lai iegūtu detalizētu informāciju, sazinieties ar savu administratoru."</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Tīklāja un piesaistes statuss"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-af/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-af/strings.xml
new file mode 100644
index 000000000000..19d659c6ce36
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-af/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"Verbinding het nie internet nie"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"Toestelle kan nie koppel nie"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Skakel verbinding af"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Warmkol of verbinding is aan"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Bykomende heffings kan geld terwyl jy swerf"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-am/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-am/strings.xml
new file mode 100644
index 000000000000..8995430b4f09
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-am/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"ማስተሳሰር ምንም በይነመረብ የለውም"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"መሣሪያዎችን ማገናኘት አይቻልም"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"ማስተሳሰርን አጥፋ"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"መገናኛ ነጥብ ወይም ማስተሳሰር በርቷል"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"በሚያንዣብብበት ጊዜ ተጨማሪ ክፍያዎች ተፈጻሚ ሊሆኑ ይችላሉ"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-ar/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-ar/strings.xml
new file mode 100644
index 000000000000..54f3b5389ae9
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-ar/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"ما مِن اتصال بالإنترنت خلال التوصيل"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"تعذّر اتصال الأجهزة"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"إيقاف التوصيل"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"نقطة الاتصال أو التوصيل مفعّلان"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"قد يتم تطبيق رسوم إضافية أثناء التجوال."</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-as/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-as/strings.xml
new file mode 100644
index 000000000000..e215141c9eb6
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-as/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"টে\'ডাৰিঙৰ ইণ্টাৰনেট নাই"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"ডিভাইচসমূহ সংযোগ কৰিব নোৱাৰি"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"টে\'ডাৰিং অফ কৰক"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"হটস্পট অথবা টে\'ডাৰিং অন আছে"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"ৰ\'মিঙত থাকিলে অতিৰিক্ত মাচুল প্ৰযোজ্য হ’ব পাৰে"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-az/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-az/strings.xml
new file mode 100644
index 000000000000..1fd8e4c963a7
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-az/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"Modemin internetə girişi yoxdur"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"Cihazları qoşmaq mümkün deyil"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Modemi deaktiv edin"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Hotspot və ya modem aktivdir"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Rouminq zamanı əlavə ödənişlər tətbiq edilə bilər"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-b+sr+Latn/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-b+sr+Latn/strings.xml
new file mode 100644
index 000000000000..1abe4f3aa3c7
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-b+sr+Latn/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"Privezivanje nema pristup internetu"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"Povezivanje uređaja nije uspelo"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Isključi privezivanje"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Uključen je hotspot ili privezivanje"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Možda važe dodatni troškovi u romingu"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-be/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-be/strings.xml
new file mode 100644
index 000000000000..38dbd1e3914f
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-be/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"Рэжым мадэма выкарыстоўваецца без доступу да інтэрнэту"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"Не ўдалося падключыць прылады"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Выключыць рэжым мадэма"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Хот-спот або рэжым мадэма ўключаны"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Пры выкарыстанні роўмінгу можа спаганяцца дадатковая плата"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-bg/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-bg/strings.xml
new file mode 100644
index 000000000000..04b44db5c1a4
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-bg/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"Тетърингът няма връзка с интернет"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"Устройствата не могат да установят връзка"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Изключване на тетъринга"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Точката за достъп или тетърингът са включени"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Възможно е да ви бъдат начислени допълнителни такси при роуминг"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-bn/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-bn/strings.xml
new file mode 100644
index 000000000000..579d1be1c1ea
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-bn/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"টিথারিং করার জন্য কোনও ইন্টারনেট কানেকশন নেই"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"ডিভাইস কানেক্ট করতে পারছে না"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"টিথারিং বন্ধ করুন"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"হটস্পট বা টিথারিং চালু আছে"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"রোমিংয়ের সময় অতিরিক্ত চার্জ করা হতে পারে"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-bs/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-bs/strings.xml
new file mode 100644
index 000000000000..9ce3efe6c39d
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-bs/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"Povezivanje putem mobitela nema internet"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"Uređaji se ne mogu povezati"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Isključi povezivanje putem mobitela"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Pristupna tačka ili povezivanje putem mobitela je uključeno"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Mogu nastati dodatni troškovi u romingu"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-ca/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-ca/strings.xml
new file mode 100644
index 000000000000..46d4c35b9b83
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-ca/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"La compartició de xarxa no té accés a Internet"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"No es poden connectar els dispositius"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Desactiva la compartició de xarxa"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"S\'ha activat el punt d\'accés Wi‑Fi o la compartició de xarxa"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"És possible que s\'apliquin costos addicionals en itinerància"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-cs/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-cs/strings.xml
new file mode 100644
index 000000000000..cc13860b3da1
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-cs/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"Tethering nemá připojení k internetu"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"Zařízení se nemůžou připojit"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Vypnout tethering"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Je zapnutý hotspot nebo tethering"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Při roamingu mohou být účtovány dodatečné poplatky"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-da/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-da/strings.xml
new file mode 100644
index 000000000000..92c3ae11567d
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-da/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"Netdeling har ingen internetforbindelse"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"Enheder kan ikke oprette forbindelse"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Deaktiver netdeling"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Hotspot eller netdeling er aktiveret"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Der opkræves muligvis yderligere gebyrer ved roaming"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-de/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-de/strings.xml
new file mode 100644
index 000000000000..967eb4db2e77
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-de/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"Tethering hat keinen Internetzugriff"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"Geräte können sich nicht verbinden"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Tethering deaktivieren"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Hotspot oder Tethering ist aktiviert"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Für das Roaming können zusätzliche Gebühren anfallen"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-el/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-el/strings.xml
new file mode 100644
index 000000000000..5fb497451f6d
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-el/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"Η σύνδεση δεν έχει πρόσβαση στο διαδίκτυο"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"Δεν είναι δυνατή η σύνδεση των συσκευών"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Απενεργοποιήστε τη σύνδεση"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Ενεργό σημείο πρόσβασης Wi-Fi ή ενεργή σύνδεση"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Ενδέχεται να ισχύουν επιπλέον χρεώσεις κατά την περιαγωγή."</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-en-rAU/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-en-rAU/strings.xml
new file mode 100644
index 000000000000..45647f93f246
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-en-rAU/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"Tethering has no Internet"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"Devices can’t connect"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Turn off tethering"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Hotspot or tethering is on"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Additional charges may apply while roaming"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-en-rCA/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-en-rCA/strings.xml
new file mode 100644
index 000000000000..45647f93f246
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-en-rCA/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"Tethering has no Internet"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"Devices can’t connect"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Turn off tethering"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Hotspot or tethering is on"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Additional charges may apply while roaming"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-en-rGB/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-en-rGB/strings.xml
new file mode 100644
index 000000000000..45647f93f246
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-en-rGB/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"Tethering has no Internet"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"Devices can’t connect"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Turn off tethering"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Hotspot or tethering is on"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Additional charges may apply while roaming"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-en-rIN/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-en-rIN/strings.xml
new file mode 100644
index 000000000000..45647f93f246
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-en-rIN/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"Tethering has no Internet"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"Devices can’t connect"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Turn off tethering"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Hotspot or tethering is on"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Additional charges may apply while roaming"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-en-rXC/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-en-rXC/strings.xml
new file mode 100644
index 000000000000..7877074afc66
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-en-rXC/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‎‏‏‏‎‎‏‏‏‎‎‏‎‎‏‏‎‏‎‎‎‏‎‏‎‏‏‏‏‏‎‎‏‏‎‎‎‎‏‎‏‏‏‏‎‏‎‏‎‎‎‏‏‏‎‏‎‎‎Tethering has no internet‎‏‎‎‏‎"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‏‎‏‎‏‎‏‏‏‎‏‎‎‎‎‎‏‏‏‏‏‏‏‎‏‎‎‎‏‏‎‎‎‎‎‏‏‏‎‎‏‏‎‏‏‎‎‏‎‏‎‎‎‎‏‏‏‎Devices can’t connect‎‏‎‎‏‎"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‎‎‏‎‎‏‏‏‎‏‏‏‎‏‎‎‏‎‏‎‏‎‎‏‏‏‎‎‎‏‏‎‎‏‏‎‏‎‏‏‏‏‎‎‎‏‎‏‏‎‎‎‏‎‏‎‎‎‎Turn off tethering‎‏‎‎‏‎"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‏‏‏‎‏‏‎‏‎‏‎‏‎‏‏‎‎‎‎‏‎‎‎‏‏‎‎‎‎‎‎‎‎‏‎‎‏‏‏‏‏‏‏‏‏‎‎‎‏‏‎‏‎‎‏‏‏‎Hotspot or tethering is on‎‏‎‎‏‎"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‏‎‏‎‏‎‎‎‏‏‏‏‏‏‏‎‏‏‎‏‏‏‏‎‎‏‏‏‏‏‎‏‏‎‎‎‎‏‏‎‎‎‏‏‏‏‏‎‏‎‏‎‏‏‏‏‎‎Additional charges may apply while roaming‎‏‎‎‏‎"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-es-rUS/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-es-rUS/strings.xml
new file mode 100644
index 000000000000..08edd81a6b04
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-es-rUS/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"La conexión mediante dispositivo móvil no tiene Internet"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"No se pueden conectar los dispositivos"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Desactivar conexión mediante dispositivo móvil"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Se activó el hotspot o la conexión mediante dispositivo móvil"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Es posible que se apliquen cargos adicionales por roaming"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-es/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-es/strings.xml
new file mode 100644
index 000000000000..79f51d00e2e8
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-es/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"La conexión no se puede compartir, porque no hay acceso a Internet"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"Los dispositivos no se pueden conectar"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Desactivar conexión compartida"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Punto de acceso o conexión compartida activados"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Puede que se apliquen cargos adicionales en itinerancia"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-et/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-et/strings.xml
new file mode 100644
index 000000000000..2da5f8a6d62a
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-et/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"Jagamisel puudub internetiühendus"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"Seadmed ei saa ühendust luua"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Lülita jagamine välja"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Kuumkoht või jagamine on sisse lülitatud"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Rändluse kasutamisega võivad kaasneda lisatasud"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-eu/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-eu/strings.xml
new file mode 100644
index 000000000000..2073f2806c18
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-eu/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"Konexioa partekatzeko aukerak ez du Interneteko konexiorik"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"Ezin dira konektatu gailuak"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Desaktibatu konexioa partekatzeko aukera"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Wifi-gunea edo konexioa partekatzeko aukera aktibatuta dago"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Baliteke kostu gehigarriak ordaindu behar izatea ibiltaritzan"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-fa/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-fa/strings.xml
new file mode 100644
index 000000000000..e21b2a0852c7
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-fa/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"«اشتراک‌گذاری اینترنت» به اینترنت دسترسی ندارد"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"دستگاه‌ها متصل نمی‌شوند"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"خاموش کردن «اشتراک‌گذاری اینترنت»"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"«نقطه اتصال» یا «اشتراک‌گذاری اینترنت» روشن است"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"ممکن است درحین فراگردی تغییرات دیگر اعمال شود"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-fi/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-fi/strings.xml
new file mode 100644
index 000000000000..88b0b13eb4b5
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-fi/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"Ei jaettavaa internetyhteyttä"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"Laitteet eivät voi muodostaa yhteyttä"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Laita yhteyden jakaminen pois päältä"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Hotspot tai yhteyden jakaminen on päällä"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Roaming voi aiheuttaa lisämaksuja"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-fr-rCA/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-fr-rCA/strings.xml
new file mode 100644
index 000000000000..3b781bc8db31
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-fr-rCA/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"Le partage de connexion n\'est pas connecté à Internet"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"Impossible de connecter les appareils"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Désactiver le partage de connexion"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Le point d\'accès ou le partage de connexion est activé"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"En itinérance, des frais supplémentaires peuvent s\'appliquer"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-fr/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-fr/strings.xml
new file mode 100644
index 000000000000..51d7203c3652
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-fr/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"Aucune connexion à Internet n\'est disponible pour le partage de connexion"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"Impossible de connecter les appareils"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Désactiver le partage de connexion"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Le point d\'accès ou le partage de connexion est activé"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"En itinérance, des frais supplémentaires peuvent s\'appliquer"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-gl/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-gl/strings.xml
new file mode 100644
index 000000000000..008ccb475d66
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-gl/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"A conexión compartida non ten Internet"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"Non se puideron conectar os dispositivos"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Desactivar conexión compartida"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Está activada a zona wifi ou a conexión compartida"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Pódense aplicar cargos adicionais en itinerancia"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-gu/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-gu/strings.xml
new file mode 100644
index 000000000000..f2e3b4df782f
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-gu/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"ઇન્ટરનેટ શેર કરવાની સુવિધામાં ઇન્ટરનેટ નથી"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"ડિવાઇસ કનેક્ટ કરી શકાતા નથી"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"ઇન્ટરનેટ શેર કરવાની સુવિધા બંધ કરો"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"હૉટસ્પૉટ અથવા ઇન્ટરનેટ શેર કરવાની સુવિધા ચાલુ છે"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"રોમિંગમાં વધારાના શુલ્ક લાગી શકે છે"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-hi/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-hi/strings.xml
new file mode 100644
index 000000000000..b11839d760c8
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-hi/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"टेदरिंग से इंटरनेट नहीं चल रहा"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"डिवाइस कनेक्ट नहीं हो पा रहे"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"टेदरिंग बंद करें"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"हॉटस्पॉट या टेदरिंग चालू है"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"रोमिंग के दौरान अतिरिक्त शुल्क लग सकता है"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-hr/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-hr/strings.xml
new file mode 100644
index 000000000000..0a5aca25b1a9
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-hr/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"Modemsko povezivanje nema internet"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"Uređaji se ne mogu povezati"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Isključivanje modemskog povezivanja"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Uključena je žarišna točka ili modemsko povezivanje"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"U roamingu su mogući dodatni troškovi"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-hu/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-hu/strings.xml
new file mode 100644
index 000000000000..21c689a44ef8
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-hu/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"Nincs internetkapcsolat az internet megosztásához"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"Az eszközök nem tudnak csatlakozni"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Internetmegosztás kikapcsolása"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"A hotspot vagy az internetmegosztás be van kapcsolva"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Roaming során további díjak léphetnek fel"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-hy/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-hy/strings.xml
new file mode 100644
index 000000000000..689d92870e50
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-hy/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"Մոդեմի ռեժիմի կապը բացակայում է"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"Չհաջողվեց միացնել սարքը"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Անջատել մոդեմի ռեժիմը"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Թեժ կետը կամ մոդեմի ռեժիմը միացված է"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Ռոումինգում կարող են լրացուցիչ վճարներ գանձվել"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-in/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-in/strings.xml
new file mode 100644
index 000000000000..a5f4d19abfe9
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-in/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"Tidak ada koneksi internet di tethering"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"Perangkat tidak dapat terhubung"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Nonaktifkan tethering"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Hotspot atau tethering aktif"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Biaya tambahan mungkin berlaku saat roaming"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-is/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-is/strings.xml
new file mode 100644
index 000000000000..fc7e8aaf4e42
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-is/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"Tjóðrun er ekki með internettengingu"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"Tæki geta ekki tengst"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Slökkva á tjóðrun"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Kveikt er á heitum reit eða tjóðrun"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Viðbótargjöld kunna að eiga við í reiki"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-it/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-it/strings.xml
new file mode 100644
index 000000000000..6456dd1b806a
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-it/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"Nessuna connessione a Internet per il tethering"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"Impossibile connettere i dispositivi"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Disattiva il tethering"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Hotspot o tethering attivi"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Potrebbero essere applicati costi aggiuntivi durante il roaming"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-iw/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-iw/strings.xml
new file mode 100644
index 000000000000..46b24bd3c508
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-iw/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"אי אפשר להפעיל את תכונת שיתוף האינטרנט בין מכשירים כי אין חיבור לאינטרנט"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"למכשירים אין אפשרות להתחבר"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"השבתה של שיתוף האינטרנט בין מכשירים"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"תכונת הנקודה לשיתוף אינטרנט או תכונת שיתוף האינטרנט בין מכשירים פועלת"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"ייתכנו חיובים נוספים בעת נדידה"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-ja/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-ja/strings.xml
new file mode 100644
index 000000000000..e6eb277b90dd
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-ja/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"テザリングがインターネットに接続されていません"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"デバイスを接続できません"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"テザリングを OFF にする"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"アクセス ポイントまたはテザリングが ON です"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"ローミング時に追加料金が発生することがあります"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-ka/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-ka/strings.xml
new file mode 100644
index 000000000000..aeddd7101da0
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-ka/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"ტეტერინგს არ აქვს ინტერნეტზე წვდომა"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"მოწყობილობები ვერ ახერხებენ დაკავშირებას"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"ტეტერინგის გამორთვა"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"ჩართულია უსადენო ქსელი ან ტეტერინგი"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"როუმინგის გამოყენებისას შეიძლება ჩამოგეჭრათ დამატებითი საფასური"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-kk/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-kk/strings.xml
new file mode 100644
index 000000000000..255f0a276f95
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-kk/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"Тетеринг режимі интернет байланысынсыз пайдаланылуда"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"Құрылғыларды байланыстыру мүмкін емес"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Тетерингіні өшіру"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Хотспот немесе тетеринг қосулы"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Роуминг кезінде қосымша ақы алынуы мүмкін."</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-km/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-km/strings.xml
new file mode 100644
index 000000000000..2bceb1cf7788
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-km/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"ការភ្ជាប់​មិនមានអ៊ីនធឺណិត​ទេ"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"មិនអាច​ភ្ជាប់ឧបករណ៍​បានទេ"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"បិទការភ្ជាប់"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"ហតស្ប៉ត ឬការភ្ជាប់​ត្រូវបានបើក"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"អាចមាន​ការគិតថ្លៃ​បន្ថែម នៅពេល​រ៉ូមីង"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-kn/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-kn/strings.xml
new file mode 100644
index 000000000000..ed769305a679
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-kn/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"ಟೆಥರಿಂಗ್‌ ಯಾವುದೇ ಇಂಟರ್ನೆಟ್ ಕನೆಕ್ಷನ್ ಹೊಂದಿಲ್ಲ"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"ಸಾಧನಗಳನ್ನು ಕನೆಕ್ಟ್ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"ಟೆಥರಿಂಗ್‌ ಆಫ್ ಮಾಡಿ"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"ಹಾಟ್‌ಸ್ಪಾಟ್ ಅಥವಾ ಟೆಥರಿಂಗ್‌ ಆನ್ ಆಗಿದೆ"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"ರೋಮಿಂಗ್‌ನಲ್ಲಿರುವಾಗ ಹೆಚ್ಚುವರಿ ಶುಲ್ಕಗಳು ಅನ್ವಯವಾಗಬಹುದು"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-ko/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-ko/strings.xml
new file mode 100644
index 000000000000..6e504941eb8b
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-ko/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"테더링으로 인터넷을 사용할 수 없음"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"기기에서 연결할 수 없음"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"테더링 사용 중지"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"핫스팟 또는 테더링 켜짐"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"로밍 중에는 추가 요금이 발생할 수 있습니다."</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-ky/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-ky/strings.xml
new file mode 100644
index 000000000000..d68128b9a554
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-ky/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"Модем режими Интернети жок колдонулууда"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"Түзмөктөр туташпай жатат"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Модем режимин өчүрүү"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Байланыш түйүнү же модем режими күйүк"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Роумингде кошумча акы алынышы мүмкүн"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-lo/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-lo/strings.xml
new file mode 100644
index 000000000000..03e134a0fc79
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-lo/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"ການປ່ອຍສັນຍານບໍ່ມີອິນເຕີເນັດ"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"ອຸປະກອນບໍ່ສາມາດເຊື່ອມຕໍ່ໄດ້"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"ປິດການປ່ອຍສັນຍານ"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"ເປີດໃຊ້ຮັອດສະປອດ ຫຼື ການປ່ອຍສັນຍານຢູ່"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"ອາດມີຄ່າໃຊ້ຈ່າຍເພີ່ມເຕີມໃນລະຫວ່າງການໂຣມມິງ"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-lt/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-lt/strings.xml
new file mode 100644
index 000000000000..652cedc6e6ae
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-lt/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"Nėra įrenginio kaip modemo naudojimo interneto ryšio"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"Nepavyko susieti įrenginių"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Išjungti įrenginio kaip modemo naudojimą"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Įjungtas viešosios interneto prieigos taškas arba įrenginio kaip modemo naudojimas"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Veikiant tarptinkliniam ryšiui gali būti taikomi papildomi mokesčiai"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-lv/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-lv/strings.xml
new file mode 100644
index 000000000000..221972298c18
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-lv/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"Piesaistei nav interneta savienojuma"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"Nevar savienot ierīces"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Izslēgt piesaisti"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Ir ieslēgts tīklājs vai piesaiste"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Viesabonēšanas laikā var tikt piemērota papildu samaksa"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-mk/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-mk/strings.xml
new file mode 100644
index 000000000000..227f9e346651
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-mk/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"Нема интернет преку мобилен"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"Уредите не може да се поврзат"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Исклучи интернет преку мобилен"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Точката на пристап или интернетот преку мобилен е вклучен"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"При роаминг може да се наплатат дополнителни трошоци"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-ml/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-ml/strings.xml
new file mode 100644
index 000000000000..ec4388512645
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-ml/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"ടെതറിംഗിന് ഇന്റർനെറ്റ് ഇല്ല"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"ഉപകരണങ്ങൾ കണക്റ്റ് ചെയ്യാനാവില്ല"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"ടെതറിംഗ് ഓഫാക്കുക"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"ഹോട്ട്‌സ്‌പോട്ട് അല്ലെങ്കിൽ ടെതറിംഗ് ഓണാണ്"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"റോമിംഗ് ചെയ്യുമ്പോൾ അധിക നിരക്കുകൾ ബാധകമായേക്കാം"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-mn/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-mn/strings.xml
new file mode 100644
index 000000000000..e263573799ed
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-mn/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"Модемд интернэт алга байна"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"Төхөөрөмжүүд холбогдох боломжгүй байна"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Модем болгохыг унтраах"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Сүлжээний цэг эсвэл модем болгох асаалттай байна"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Роумингийн үеэр нэмэлт төлбөр нэхэмжилж болзошгүй"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-mr/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-mr/strings.xml
new file mode 100644
index 000000000000..adf845d078bf
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-mr/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"टेदरिंगला इंटरनेट नाही"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"डिव्हाइस कनेक्ट होऊ शकत नाहीत"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"टेदरिंग बंद करा"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"हॉटस्पॉट किंवा टेदरिंग सुरू आहे"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"रोमिंगदरम्यान अतिरिक्त शुल्क लागू होऊ शकतात"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-ms/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-ms/strings.xml
new file mode 100644
index 000000000000..f65c451e4c21
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-ms/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"Penambatan tiada Internet"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"Peranti tidak dapat disambungkan"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Matikan penambatan"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Tempat liputan atau penambatan dihidupkan"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Caj tambahan mungkin digunakan semasa perayauan"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-my/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-my/strings.xml
new file mode 100644
index 000000000000..4118e775cd84
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-my/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"မိုဘိုင်းဖုန်းသုံး ချိတ်ဆက်မျှဝေခြင်းတွင် အင်တာနက် မရှိပါ"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"စက်များ ချိတ်ဆက်၍ မရပါ"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"မိုဘိုင်းဖုန်းသုံး ချိတ်ဆက်မျှဝေခြင်း ပိတ်ရန်"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"ဟော့စပေါ့ (သို့) မိုဘိုင်းဖုန်းသုံး ချိတ်ဆက်မျှဝေခြင်း ဖွင့်ထားသည်"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"ပြင်ပကွန်ရက်နှင့် ချိတ်ဆက်သည့်အခါ နောက်ထပ်ကျသင့်မှုများ ရှိနိုင်သည်"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-nb/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-nb/strings.xml
new file mode 100644
index 000000000000..36853583ce82
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-nb/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"Internettdeling har ikke internettilgang"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"Enhetene kan ikke koble til"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Slå av internettdeling"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Wi-Fi-sone eller internettdeling er på"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Ytterligere kostnader kan påløpe under roaming"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-ne/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-ne/strings.xml
new file mode 100644
index 000000000000..2a7330098faf
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-ne/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- no translation found for no_upstream_notification_title (5030042590486713460) -->
+ <skip />
+ <!-- no translation found for no_upstream_notification_message (3843613362272973447) -->
+ <skip />
+ <!-- no translation found for no_upstream_notification_disable_button (6385491461813507624) -->
+ <skip />
+ <!-- no translation found for upstream_roaming_notification_title (3015912166812283303) -->
+ <skip />
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"रोमिङ सेवा प्रयोग गर्दा अतिरिक्त शुल्क लाग्न सक्छ"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-nl/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-nl/strings.xml
new file mode 100644
index 000000000000..1d888942f49b
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-nl/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"Tethering heeft geen internet"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"Apparaten kunnen niet worden verbonden"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Tethering uitschakelen"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Hotspot of tethering is ingeschakeld"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Er kunnen extra kosten voor roaming in rekening worden gebracht."</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-or/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-or/strings.xml
new file mode 100644
index 000000000000..8038815fe804
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-or/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"ଟିଥରିଂ ପାଇଁ କୌଣସି ଇଣ୍ଟର୍ନେଟ୍ ସଂଯୋଗ ନାହିଁ"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"ଡିଭାଇସଗୁଡ଼ିକ ସଂଯୋଗ କରାଯାଇପାରିବ ନାହିଁ"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"ଟିଥରିଂ ବନ୍ଦ କରନ୍ତୁ"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"ହଟସ୍ପଟ୍ କିମ୍ବା ଟିଥରିଂ ଚାଲୁ ଅଛି"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"ରୋମିଂରେ ଥିବା ସମୟରେ ଅତିରିକ୍ତ ଶୁଳ୍କ ଲାଗୁ ହୋଇପାରେ"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-pa/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-pa/strings.xml
new file mode 100644
index 000000000000..819833eab07f
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-pa/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"ਟੈਦਰਿੰਗ ਕੋਲ ਇੰਟਰਨੈੱਟ ਪਹੁੰਚ ਨਹੀਂ ਹੈ"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"ਡੀਵਾਈਸ ਕਨੈਕਟ ਨਹੀਂ ਕੀਤੇ ਜਾ ਸਕਦੇ"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"ਟੈਦਰਿੰਗ ਬੰਦ ਕਰੋ"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"ਹੌਟਸਪੌਟ ਜਾਂ ਟੈਦਰਿੰਗ ਚਾਲੂ ਹੈ"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"ਰੋਮਿੰਗ ਦੌਰਾਨ ਵਧੀਕ ਖਰਚੇ ਲਾਗੂ ਹੋ ਸਕਦੇ ਹਨ"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-pl/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-pl/strings.xml
new file mode 100644
index 000000000000..65e4380e3916
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-pl/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"Tethering nie ma internetu"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"Urządzenia nie mogą się połączyć"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Wyłącz tethering"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Hotspot lub tethering jest włączony"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Podczas korzystania z roamingu mogą zostać naliczone dodatkowe opłaty"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-pt-rBR/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-pt-rBR/strings.xml
new file mode 100644
index 000000000000..d8866170c191
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-pt-rBR/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"O tethering não tem Internet"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"Não é possível conectar os dispositivos"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Desativar o tethering"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Ponto de acesso ou tethering ativado"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Pode haver cobranças extras durante o roaming"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-pt-rPT/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-pt-rPT/strings.xml
new file mode 100644
index 000000000000..bfd45ca0a3e1
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-pt-rPT/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"A ligação (à Internet) via telemóvel não tem Internet"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"Não é possível ligar os dispositivos"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Desativar ligação (à Internet) via telemóvel"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"A zona Wi-Fi ou a ligação (à Internet) via telemóvel está ativada"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Podem aplicar-se custos adicionais em roaming."</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-pt/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-pt/strings.xml
new file mode 100644
index 000000000000..d8866170c191
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-pt/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"O tethering não tem Internet"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"Não é possível conectar os dispositivos"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Desativar o tethering"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Ponto de acesso ou tethering ativado"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Pode haver cobranças extras durante o roaming"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-ro/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-ro/strings.xml
new file mode 100644
index 000000000000..8d87a9e516ad
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-ro/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"Procesul de tethering nu are internet"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"Dispozitivele nu se pot conecta"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Dezactivați procesul de tethering"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"S-a activat hotspotul sau tethering"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Se pot aplica taxe suplimentare pentru roaming"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-ru/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-ru/strings.xml
new file mode 100644
index 000000000000..dbdb9ebe4931
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-ru/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"Режим модема используется без доступа к Интернету"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"Невозможно подключить устройства."</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Отключить режим модема"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Включены точка доступа или режим модема"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"За использование услуг связи в роуминге может взиматься дополнительная плата."</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-si/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-si/strings.xml
new file mode 100644
index 000000000000..d8301e41c2b2
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-si/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"ටෙදරින් හට අන්තර්ජාලය නැත"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"උපාංගවලට සම්බන්ධ විය නොහැකිය"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"ටෙදරින් ක්‍රියාවිරහිත කරන්න"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"හොට්ස්පොට් හෝ ටෙදරින් ක්‍රියාත්මකයි"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"රෝමිං අතරතුර අමතර ගාස්තු අදාළ විය හැකිය"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-sk/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-sk/strings.xml
new file mode 100644
index 000000000000..bef71363f450
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-sk/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"Tethering nemá internetové pripojenie"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"Zariadenia sa nemôžu pripojiť"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Vypnúť tethering"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Je zapnutý hotspot alebo tethering"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Počas roamingu vám môžu byť účtované ďalšie poplatky"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-sl/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-sl/strings.xml
new file mode 100644
index 000000000000..3202c62e8a3a
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-sl/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"Internetna povezava prek mobilnega telefona ni vzpostavljena"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"Napravi se ne moreta povezati"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Izklopi internetno povezavo prek mobilnega telefona"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Dostopna točka ali internetna povezava prek mobilnega telefona je vklopljena"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Med gostovanjem lahko nastanejo dodatni stroški"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-sq/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-sq/strings.xml
new file mode 100644
index 000000000000..37f6ad286880
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-sq/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"Ndarja e internetit nuk ka internet"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"Pajisjet nuk mund të lidhen"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Çaktivizo ndarjen e internetit"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Zona e qasjes për internet ose ndarja e internetit është aktive"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Mund të zbatohen tarifime shtesë kur je në roaming"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-sr/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-sr/strings.xml
new file mode 100644
index 000000000000..5566d03ed13a
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-sr/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"Привезивање нема приступ интернету"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"Повезивање уређаја није успело"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Искључи привезивање"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Укључен је хотспот или привезивање"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Можда важе додатни трошкови у ромингу"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-sv/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-sv/strings.xml
new file mode 100644
index 000000000000..9765acd0cf46
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-sv/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"Det finns ingen internetanslutning för internetdelningen"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"Enheterna kan inte anslutas"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Inaktivera internetdelning"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Surfzon eller internetdelning har aktiverats"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Ytterligare avgifter kan tillkomma vid roaming"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-sw/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-sw/strings.xml
new file mode 100644
index 000000000000..cf850c9cd222
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-sw/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"Kipengele cha kusambaza mtandao hakina intaneti"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"Imeshindwa kuunganisha vifaa"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Zima kipengele cha kusambaza mtandao"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Umewasha kipengele cha kusambaza mtandao au mtandao pepe"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Huenda ukatozwa gharama za ziada ukitumia mitandao ya ng\'ambo"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-ta/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-ta/strings.xml
new file mode 100644
index 000000000000..ea04821e33bd
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-ta/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- no translation found for no_upstream_notification_title (5030042590486713460) -->
+ <skip />
+ <!-- no translation found for no_upstream_notification_message (3843613362272973447) -->
+ <skip />
+ <!-- no translation found for no_upstream_notification_disable_button (6385491461813507624) -->
+ <skip />
+ <!-- no translation found for upstream_roaming_notification_title (3015912166812283303) -->
+ <skip />
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"ரோமிங்கின்போது கூடுதல் கட்டணங்கள் விதிக்கப்படக்கூடும்"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-te/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-te/strings.xml
new file mode 100644
index 000000000000..937d34d52027
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-te/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"టెథరింగ్ చేయడానికి ఇంటర్నెట్ కనెక్షన్ లేదు"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"పరికరాలు కనెక్ట్ అవ్వడం లేదు"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"టెథరింగ్‌ను ఆఫ్ చేయండి"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"హాట్‌స్పాట్ లేదా టెథరింగ్ ఆన్‌లో ఉంది"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"రోమింగ్‌లో ఉన్నప్పుడు అదనపు ఛార్జీలు వర్తించవచ్చు"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-th/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-th/strings.xml
new file mode 100644
index 000000000000..f781fae5252e
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-th/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"การเชื่อมต่ออินเทอร์เน็ตผ่านมือถือไม่มีอินเทอร์เน็ต"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"อุปกรณ์เชื่อมต่อไม่ได้"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"ปิดการเชื่อมต่ออินเทอร์เน็ตผ่านมือถือ"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"ฮอตสปอตหรือการเชื่อมต่ออินเทอร์เน็ตผ่านมือถือเปิดอยู่"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"อาจมีค่าใช้จ่ายเพิ่มเติมขณะโรมมิ่ง"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-tl/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-tl/strings.xml
new file mode 100644
index 000000000000..8d5d46537334
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-tl/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"Walang internet ang pag-tether"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"Hindi makakonekta ang mga device"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"I-off ang pag-tether"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Naka-on ang Hotspot o pag-tether"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Posibleng magkaroon ng mga karagdagang singil habang nagro-roam"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-tr/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-tr/strings.xml
new file mode 100644
index 000000000000..80cab33ac05e
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-tr/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"Tethering\'in internet bağlantısı yok"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"Cihazlar bağlanamıyor"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Tethering\'i kapat"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Hotspot veya tethering açık"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Dolaşım sırasında ek ücretler uygulanabilir"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-uk/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-uk/strings.xml
new file mode 100644
index 000000000000..c05932a5ae7f
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-uk/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"Телефон, який використовується як модем, не підключений до Інтернету"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"Не вдається підключити пристрої"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Вимкнути використання телефона як модема"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Увімкнено точку доступу або використання телефона як модема"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"У роумінгу може стягуватися додаткова плата"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-ur/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-ur/strings.xml
new file mode 100644
index 000000000000..d820eee8ba3c
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-ur/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"ٹیدرنگ میں انٹرنیٹ نہیں ہے"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"آلات منسلک نہیں ہو سکتے"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"ٹیدرنگ آف کریں"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"ہاٹ اسپاٹ یا ٹیدرنگ آن ہے"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"رومنگ کے دوران اضافی چارجز لاگو ہو سکتے ہیں"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-uz/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-uz/strings.xml
new file mode 100644
index 000000000000..726148aaee5a
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-uz/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"Modem internetga ulanmagan"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"Qurilmalar ulanmadi"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Modem rejimini faolsizlantirish"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Hotspot yoki modem rejimi yoniq"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Rouming vaqtida qoʻshimcha haq olinishi mumkin"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-vi/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-vi/strings.xml
new file mode 100644
index 000000000000..b7cb0456b673
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-vi/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"Không có Internet để chia sẻ kết Internet"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"Các thiết bị không thể kết nối"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Tắt tính năng chia sẻ Internet"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"Điểm phát sóng hoặc tính năng chia sẻ Internet đang bật"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Bạn có thể mất thêm phí dữ liệu khi chuyển vùng"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-zh-rCN/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-zh-rCN/strings.xml
new file mode 100644
index 000000000000..af91afff9a4c
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-zh-rCN/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"共享网络未连接到互联网"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"设备无法连接"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"关闭网络共享"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"热点或网络共享已开启"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"漫游时可能会产生额外的费用"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-zh-rHK/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-zh-rHK/strings.xml
new file mode 100644
index 000000000000..28e6b80c01a9
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-zh-rHK/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"無法透過網絡共享連線至互聯網"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"裝置無法連接"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"關閉網絡共享"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"熱點或網絡共享已開啟"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"漫遊時可能需要支付額外費用"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-zh-rTW/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-zh-rTW/strings.xml
new file mode 100644
index 000000000000..05b90692ea7b
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-zh-rTW/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"無法透過數據連線連上網際網路"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"裝置無法連線"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"關閉數據連線"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"無線基地台或數據連線已開啟"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"使用漫遊服務可能須支付額外費用"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004-zu/strings.xml b/packages/Tethering/res/values-mcc310-mnc004-zu/strings.xml
new file mode 100644
index 000000000000..11eb66621971
--- /dev/null
+++ b/packages/Tethering/res/values-mcc310-mnc004-zu/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="5030042590486713460">"Ukusebenzisa ifoni njengemodemu akunayo i-inthanethi"</string>
+ <string name="no_upstream_notification_message" msgid="3843613362272973447">"Amadivayisi awakwazi ukuxhumeka"</string>
+ <string name="no_upstream_notification_disable_button" msgid="6385491461813507624">"Vala ukusebenzisa ifoni njengemodemu"</string>
+ <string name="upstream_roaming_notification_title" msgid="3015912166812283303">"I-hotspot noma ukusebenzisa ifoni njengemodemu kuvuliwe"</string>
+ <string name="upstream_roaming_notification_message" msgid="6724434706748439902">"Kungaba nezinkokhelo ezengeziwe uma uzula"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc310-mnc004/strings.xml b/packages/Tethering/res/values-mcc310-mnc004/strings.xml
index 9dadd49cf8a4..ce9ff6080717 100644
--- a/packages/Tethering/res/values-mcc310-mnc004/strings.xml
+++ b/packages/Tethering/res/values-mcc310-mnc004/strings.xml
@@ -25,6 +25,4 @@
<string name="upstream_roaming_notification_title">Hotspot or tethering is on</string>
<!-- String for cellular roaming notification message [CHAR LIMIT=500] -->
<string name="upstream_roaming_notification_message">Additional charges may apply while roaming</string>
- <!-- String for cellular roaming notification continue button [CHAR LIMIT=200] -->
- <string name="upstream_roaming_notification_continue_button">Continue</string>
</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-af/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-af/strings.xml
new file mode 100644
index 000000000000..9bfa5317a9e4
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-af/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"Verbinding het nie internet nie"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"Toestelle kan nie koppel nie"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Skakel verbinding af"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Warmkol of verbinding is aan"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Bykomende heffings kan geld terwyl jy swerf"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-am/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-am/strings.xml
new file mode 100644
index 000000000000..5949dfa776d7
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-am/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"ማስተሳሰር ምንም በይነመረብ የለውም"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"መሣሪያዎችን ማገናኘት አይቻልም"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"ማስተሳሰርን አጥፋ"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"መገናኛ ነጥብ ወይም ማስተሳሰር በርቷል"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"በሚያንዣብብበት ጊዜ ተጨማሪ ክፍያዎች ተፈጻሚ ሊሆኑ ይችላሉ"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-ar/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-ar/strings.xml
new file mode 100644
index 000000000000..8467f9b1f5cf
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-ar/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"ما مِن اتصال بالإنترنت خلال التوصيل"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"تعذّر اتصال الأجهزة"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"إيقاف التوصيل"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"نقطة الاتصال أو التوصيل مفعّلان"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"قد يتم تطبيق رسوم إضافية أثناء التجوال."</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-as/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-as/strings.xml
new file mode 100644
index 000000000000..9776bd89da48
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-as/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"টে\'ডাৰিঙৰ ইণ্টাৰনেট নাই"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"ডিভাইচসমূহ সংযোগ কৰিব নোৱাৰি"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"টে\'ডাৰিং অফ কৰক"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"হটস্পট অথবা টে\'ডাৰিং অন আছে"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"ৰ\'মিঙত থাকিলে অতিৰিক্ত মাচুল প্ৰযোজ্য হ’ব পাৰে"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-az/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-az/strings.xml
new file mode 100644
index 000000000000..e6d3eaf9f07c
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-az/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"Modemin internetə girişi yoxdur"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"Cihazları qoşmaq mümkün deyil"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Modemi deaktiv edin"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Hotspot və ya modem aktivdir"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Rouminq zamanı əlavə ödənişlər tətbiq edilə bilər"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-b+sr+Latn/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-b+sr+Latn/strings.xml
new file mode 100644
index 000000000000..4c8a1df8eece
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-b+sr+Latn/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"Privezivanje nema pristup internetu"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"Povezivanje uređaja nije uspelo"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Isključi privezivanje"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Uključen je hotspot ili privezivanje"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Možda važe dodatni troškovi u romingu"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-be/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-be/strings.xml
new file mode 100644
index 000000000000..edfa41e1ffd3
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-be/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"Рэжым мадэма выкарыстоўваецца без доступу да інтэрнэту"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"Не ўдалося падключыць прылады"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Выключыць рэжым мадэма"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Хот-спот або рэжым мадэма ўключаны"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Пры выкарыстанні роўмінгу можа спаганяцца дадатковая плата"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-bg/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-bg/strings.xml
new file mode 100644
index 000000000000..f56398196f51
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-bg/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"Тетърингът няма връзка с интернет"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"Устройствата не могат да установят връзка"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Изключване на тетъринга"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Точката за достъп или тетърингът са включени"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Възможно е да ви бъдат начислени допълнителни такси при роуминг"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-bn/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-bn/strings.xml
new file mode 100644
index 000000000000..d8ecd2e988f9
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-bn/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"টিথারিং করার জন্য কোনও ইন্টারনেট কানেকশন নেই"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"ডিভাইস কানেক্ট করতে পারছে না"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"টিথারিং বন্ধ করুন"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"হটস্পট বা টিথারিং চালু আছে"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"রোমিংয়ের সময় অতিরিক্ত চার্জ করা হতে পারে"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-bs/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-bs/strings.xml
new file mode 100644
index 000000000000..b85fd5e28577
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-bs/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"Povezivanje putem mobitela nema internet"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"Uređaji se ne mogu povezati"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Isključi povezivanje putem mobitela"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Pristupna tačka ili povezivanje putem mobitela je uključeno"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Mogu nastati dodatni troškovi u romingu"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-ca/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-ca/strings.xml
new file mode 100644
index 000000000000..a3572151be6b
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-ca/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"La compartició de xarxa no té accés a Internet"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"No es poden connectar els dispositius"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Desactiva la compartició de xarxa"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"S\'ha activat el punt d\'accés Wi‑Fi o la compartició de xarxa"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"És possible que s\'apliquin costos addicionals en itinerància"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-cs/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-cs/strings.xml
new file mode 100644
index 000000000000..91196be9e557
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-cs/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"Tethering nemá připojení k internetu"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"Zařízení se nemůžou připojit"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Vypnout tethering"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Je zapnutý hotspot nebo tethering"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Při roamingu mohou být účtovány dodatečné poplatky"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-da/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-da/strings.xml
new file mode 100644
index 000000000000..196890011d50
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-da/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"Netdeling har ingen internetforbindelse"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"Enheder kan ikke oprette forbindelse"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Deaktiver netdeling"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Hotspot eller netdeling er aktiveret"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Der opkræves muligvis yderligere gebyrer ved roaming"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-de/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-de/strings.xml
new file mode 100644
index 000000000000..eb3f8c52c0c5
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-de/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"Tethering hat keinen Internetzugriff"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"Geräte können sich nicht verbinden"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Tethering deaktivieren"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Hotspot oder Tethering ist aktiviert"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Für das Roaming können zusätzliche Gebühren anfallen"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-el/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-el/strings.xml
new file mode 100644
index 000000000000..56c3d81b634e
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-el/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"Η σύνδεση δεν έχει πρόσβαση στο διαδίκτυο"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"Δεν είναι δυνατή η σύνδεση των συσκευών"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Απενεργοποιήστε τη σύνδεση"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Ενεργό σημείο πρόσβασης Wi-Fi ή ενεργή σύνδεση"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Ενδέχεται να ισχύουν επιπλέον χρεώσεις κατά την περιαγωγή."</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-en-rAU/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-en-rAU/strings.xml
new file mode 100644
index 000000000000..dd1a1971cdd8
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-en-rAU/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"Tethering has no Internet"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"Devices can’t connect"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Turn off tethering"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Hotspot or tethering is on"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Additional charges may apply while roaming"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-en-rCA/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-en-rCA/strings.xml
new file mode 100644
index 000000000000..dd1a1971cdd8
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-en-rCA/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"Tethering has no Internet"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"Devices can’t connect"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Turn off tethering"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Hotspot or tethering is on"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Additional charges may apply while roaming"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-en-rGB/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-en-rGB/strings.xml
new file mode 100644
index 000000000000..dd1a1971cdd8
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-en-rGB/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"Tethering has no Internet"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"Devices can’t connect"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Turn off tethering"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Hotspot or tethering is on"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Additional charges may apply while roaming"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-en-rIN/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-en-rIN/strings.xml
new file mode 100644
index 000000000000..dd1a1971cdd8
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-en-rIN/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"Tethering has no Internet"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"Devices can’t connect"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Turn off tethering"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Hotspot or tethering is on"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Additional charges may apply while roaming"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-en-rXC/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-en-rXC/strings.xml
new file mode 100644
index 000000000000..d3347aae207d
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-en-rXC/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‎‎‎‎‎‏‎‎‏‏‏‏‎‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‎‏‎‏‏‎‏‏‏‎‎‏‎‏‎‎‎‏‎‎‎Tethering has no internet‎‏‎‎‏‎"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‎‎‏‎‏‎‎‏‎‎‏‏‏‎‏‏‎‏‎‏‎‏‎‎‎‏‎‎‎‎‎‏‏‏‏‎‏‎‎‎‎‏‎‏‏‎‏‏‎‏‎‎‏‏‏‏‏‎Devices can’t connect‎‏‎‎‏‎"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‏‏‎‎‏‏‎‎‏‏‏‎‏‎‏‎‎‎‏‏‏‎‎‏‏‏‏‎‎‏‏‏‏‏‏‎‎‎‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‎‎‎Turn off tethering‎‏‎‎‏‎"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‏‏‎‏‏‏‎‎‏‎‎‏‎‏‎‏‏‏‎‏‎‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‎‏‎‎‏‏‏‏‎‏‎‎‎‏‎‎‎‎‏‏‎Hotspot or tethering is on‎‏‎‎‏‎"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‏‎‏‏‏‎‏‎‏‎‏‎‎‎‏‎‏‎‏‏‎‏‎‎‎‏‏‏‏‎‎‏‏‏‏‎‎‎‏‎‎‎‎‏‏‎‏‎‏‎‎‏‏‎‎‏‏‎Additional charges may apply while roaming‎‏‎‎‏‎"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-es-rUS/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-es-rUS/strings.xml
new file mode 100644
index 000000000000..2f0504f07de7
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-es-rUS/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"La conexión mediante dispositivo móvil no tiene Internet"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"No se pueden conectar los dispositivos"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Desactivar conexión mediante dispositivo móvil"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Se activó el hotspot o la conexión mediante dispositivo móvil"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Es posible que se apliquen cargos adicionales por roaming"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-es/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-es/strings.xml
new file mode 100644
index 000000000000..2d8f88242502
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-es/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"La conexión no se puede compartir, porque no hay acceso a Internet"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"Los dispositivos no se pueden conectar"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Desactivar conexión compartida"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Punto de acceso o conexión compartida activados"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Puede que se apliquen cargos adicionales en itinerancia"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-et/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-et/strings.xml
new file mode 100644
index 000000000000..8493c470710d
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-et/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"Jagamisel puudub internetiühendus"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"Seadmed ei saa ühendust luua"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Lülita jagamine välja"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Kuumkoht või jagamine on sisse lülitatud"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Rändluse kasutamisega võivad kaasneda lisatasud"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-eu/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-eu/strings.xml
new file mode 100644
index 000000000000..33bccab3e88c
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-eu/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"Konexioa partekatzeko aukerak ez du Interneteko konexiorik"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"Ezin dira konektatu gailuak"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Desaktibatu konexioa partekatzeko aukera"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Wifi-gunea edo konexioa partekatzeko aukera aktibatuta dago"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Baliteke kostu gehigarriak ordaindu behar izatea ibiltaritzan"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-fa/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-fa/strings.xml
new file mode 100644
index 000000000000..cf8a0cc27705
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-fa/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"«اشتراک‌گذاری اینترنت» به اینترنت دسترسی ندارد"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"دستگاه‌ها متصل نمی‌شوند"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"خاموش کردن «اشتراک‌گذاری اینترنت»"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"«نقطه اتصال» یا «اشتراک‌گذاری اینترنت» روشن است"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"ممکن است درحین فراگردی تغییرات دیگر اعمال شود"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-fi/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-fi/strings.xml
new file mode 100644
index 000000000000..6a3ab806db98
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-fi/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"Ei jaettavaa internetyhteyttä"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"Laitteet eivät voi muodostaa yhteyttä"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Laita yhteyden jakaminen pois päältä"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Hotspot tai yhteyden jakaminen on päällä"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Roaming voi aiheuttaa lisämaksuja"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-fr-rCA/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-fr-rCA/strings.xml
new file mode 100644
index 000000000000..ffb9bf60472e
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-fr-rCA/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"Le partage de connexion n\'est pas connecté à Internet"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"Impossible de connecter les appareils"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Désactiver le partage de connexion"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Le point d\'accès ou le partage de connexion est activé"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"En itinérance, des frais supplémentaires peuvent s\'appliquer"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-fr/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-fr/strings.xml
new file mode 100644
index 000000000000..768bce3f0ab1
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-fr/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"Aucune connexion à Internet n\'est disponible pour le partage de connexion"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"Impossible de connecter les appareils"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Désactiver le partage de connexion"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Le point d\'accès ou le partage de connexion est activé"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"En itinérance, des frais supplémentaires peuvent s\'appliquer"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-gl/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-gl/strings.xml
new file mode 100644
index 000000000000..0c4195a7caf3
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-gl/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"A conexión compartida non ten Internet"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"Non se puideron conectar os dispositivos"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Desactivar conexión compartida"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Está activada a zona wifi ou a conexión compartida"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Pódense aplicar cargos adicionais en itinerancia"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-gu/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-gu/strings.xml
new file mode 100644
index 000000000000..e9d33a7db259
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-gu/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"ઇન્ટરનેટ શેર કરવાની સુવિધામાં ઇન્ટરનેટ નથી"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"ડિવાઇસ કનેક્ટ કરી શકાતા નથી"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"ઇન્ટરનેટ શેર કરવાની સુવિધા બંધ કરો"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"હૉટસ્પૉટ અથવા ઇન્ટરનેટ શેર કરવાની સુવિધા ચાલુ છે"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"રોમિંગમાં વધારાના શુલ્ક લાગી શકે છે"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-hi/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-hi/strings.xml
new file mode 100644
index 000000000000..aa418ac5d3bb
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-hi/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"टेदरिंग से इंटरनेट नहीं चल रहा"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"डिवाइस कनेक्ट नहीं हो पा रहे"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"टेदरिंग बंद करें"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"हॉटस्पॉट या टेदरिंग चालू है"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"रोमिंग के दौरान अतिरिक्त शुल्क लग सकता है"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-hr/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-hr/strings.xml
new file mode 100644
index 000000000000..51c524afbc53
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-hr/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"Modemsko povezivanje nema internet"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"Uređaji se ne mogu povezati"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Isključivanje modemskog povezivanja"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Uključena je žarišna točka ili modemsko povezivanje"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"U roamingu su mogući dodatni troškovi"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-hu/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-hu/strings.xml
new file mode 100644
index 000000000000..164e45edd142
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-hu/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"Nincs internetkapcsolat az internet megosztásához"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"Az eszközök nem tudnak csatlakozni"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Internetmegosztás kikapcsolása"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"A hotspot vagy az internetmegosztás be van kapcsolva"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Roaming során további díjak léphetnek fel"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-hy/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-hy/strings.xml
new file mode 100644
index 000000000000..e76c0a4c80d5
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-hy/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"Մոդեմի ռեժիմի կապը բացակայում է"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"Չհաջողվեց միացնել սարքը"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Անջատել մոդեմի ռեժիմը"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Թեժ կետը կամ մոդեմի ռեժիմը միացված է"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Ռոումինգում կարող են լրացուցիչ վճարներ գանձվել"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-in/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-in/strings.xml
new file mode 100644
index 000000000000..2b817f8abd17
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-in/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"Tidak ada koneksi internet di tethering"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"Perangkat tidak dapat terhubung"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Nonaktifkan tethering"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Hotspot atau tethering aktif"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Biaya tambahan mungkin berlaku saat roaming"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-is/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-is/strings.xml
new file mode 100644
index 000000000000..a338d9c7cab8
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-is/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"Tjóðrun er ekki með internettengingu"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"Tæki geta ekki tengst"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Slökkva á tjóðrun"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Kveikt er á heitum reit eða tjóðrun"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Viðbótargjöld kunna að eiga við í reiki"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-it/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-it/strings.xml
new file mode 100644
index 000000000000..77769c2ac56c
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-it/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"Nessuna connessione a Internet per il tethering"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"Impossibile connettere i dispositivi"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Disattiva il tethering"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Hotspot o tethering attivi"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Potrebbero essere applicati costi aggiuntivi durante il roaming"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-iw/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-iw/strings.xml
new file mode 100644
index 000000000000..5267b5126435
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-iw/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"אי אפשר להפעיל את תכונת שיתוף האינטרנט בין מכשירים כי אין חיבור לאינטרנט"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"למכשירים אין אפשרות להתחבר"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"השבתה של שיתוף האינטרנט בין מכשירים"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"תכונת הנקודה לשיתוף אינטרנט או תכונת שיתוף האינטרנט בין מכשירים פועלת"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"ייתכנו חיובים נוספים בעת נדידה"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-ja/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-ja/strings.xml
new file mode 100644
index 000000000000..66a9a6dd35c2
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-ja/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"テザリングがインターネットに接続されていません"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"デバイスを接続できません"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"テザリングを OFF にする"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"アクセス ポイントまたはテザリングが ON です"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"ローミング時に追加料金が発生することがあります"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-ka/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-ka/strings.xml
new file mode 100644
index 000000000000..d8ad8808498f
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-ka/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"ტეტერინგს არ აქვს ინტერნეტზე წვდომა"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"მოწყობილობები ვერ ახერხებენ დაკავშირებას"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"ტეტერინგის გამორთვა"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"ჩართულია უსადენო ქსელი ან ტეტერინგი"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"როუმინგის გამოყენებისას შეიძლება ჩამოგეჭრათ დამატებითი საფასური"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-kk/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-kk/strings.xml
new file mode 100644
index 000000000000..1ddd6b419b57
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-kk/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"Тетеринг режимі интернет байланысынсыз пайдаланылуда"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"Құрылғыларды байланыстыру мүмкін емес"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Тетерингіні өшіру"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Хотспот немесе тетеринг қосулы"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Роуминг кезінде қосымша ақы алынуы мүмкін."</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-km/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-km/strings.xml
new file mode 100644
index 000000000000..cf5a1379ccc7
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-km/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"ការភ្ជាប់​មិនមានអ៊ីនធឺណិត​ទេ"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"មិនអាច​ភ្ជាប់ឧបករណ៍​បានទេ"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"បិទការភ្ជាប់"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"ហតស្ប៉ត ឬការភ្ជាប់​ត្រូវបានបើក"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"អាចមាន​ការគិតថ្លៃ​បន្ថែម នៅពេល​រ៉ូមីង"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-kn/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-kn/strings.xml
new file mode 100644
index 000000000000..68ae68bc1998
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-kn/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"ಟೆಥರಿಂಗ್‌ ಯಾವುದೇ ಇಂಟರ್ನೆಟ್ ಕನೆಕ್ಷನ್ ಹೊಂದಿಲ್ಲ"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"ಸಾಧನಗಳನ್ನು ಕನೆಕ್ಟ್ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"ಟೆಥರಿಂಗ್‌ ಆಫ್ ಮಾಡಿ"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"ಹಾಟ್‌ಸ್ಪಾಟ್ ಅಥವಾ ಟೆಥರಿಂಗ್‌ ಆನ್ ಆಗಿದೆ"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"ರೋಮಿಂಗ್‌ನಲ್ಲಿರುವಾಗ ಹೆಚ್ಚುವರಿ ಶುಲ್ಕಗಳು ಅನ್ವಯವಾಗಬಹುದು"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-ko/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-ko/strings.xml
new file mode 100644
index 000000000000..17185ba2d063
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-ko/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"테더링으로 인터넷을 사용할 수 없음"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"기기에서 연결할 수 없음"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"테더링 사용 중지"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"핫스팟 또는 테더링 켜짐"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"로밍 중에는 추가 요금이 발생할 수 있습니다."</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-ky/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-ky/strings.xml
new file mode 100644
index 000000000000..6a9fb9810cc6
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-ky/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"Модем режими Интернети жок колдонулууда"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"Түзмөктөр туташпай жатат"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Модем режимин өчүрүү"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Байланыш түйүнү же модем режими күйүк"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Роумингде кошумча акы алынышы мүмкүн"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-lo/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-lo/strings.xml
new file mode 100644
index 000000000000..bcc4b5762678
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-lo/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"ການປ່ອຍສັນຍານບໍ່ມີອິນເຕີເນັດ"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"ອຸປະກອນບໍ່ສາມາດເຊື່ອມຕໍ່ໄດ້"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"ປິດການປ່ອຍສັນຍານ"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"ເປີດໃຊ້ຮັອດສະປອດ ຫຼື ການປ່ອຍສັນຍານຢູ່"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"ອາດມີຄ່າໃຊ້ຈ່າຍເພີ່ມເຕີມໃນລະຫວ່າງການໂຣມມິງ"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-lt/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-lt/strings.xml
new file mode 100644
index 000000000000..011c2c11fb88
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-lt/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"Nėra įrenginio kaip modemo naudojimo interneto ryšio"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"Nepavyko susieti įrenginių"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Išjungti įrenginio kaip modemo naudojimą"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Įjungtas viešosios interneto prieigos taškas arba įrenginio kaip modemo naudojimas"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Veikiant tarptinkliniam ryšiui gali būti taikomi papildomi mokesčiai"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-lv/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-lv/strings.xml
new file mode 100644
index 000000000000..5cb2f3b7aac8
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-lv/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"Piesaistei nav interneta savienojuma"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"Nevar savienot ierīces"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Izslēgt piesaisti"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Ir ieslēgts tīklājs vai piesaiste"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Viesabonēšanas laikā var tikt piemērota papildu samaksa"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-mk/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-mk/strings.xml
new file mode 100644
index 000000000000..4cbfd887c57e
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-mk/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"Нема интернет преку мобилен"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"Уредите не може да се поврзат"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Исклучи интернет преку мобилен"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Точката на пристап или интернетот преку мобилен е вклучен"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"При роаминг може да се наплатат дополнителни трошоци"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-ml/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-ml/strings.xml
new file mode 100644
index 000000000000..9cf4eaf34a97
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-ml/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"ടെതറിംഗിന് ഇന്റർനെറ്റ് ഇല്ല"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"ഉപകരണങ്ങൾ കണക്റ്റ് ചെയ്യാനാവില്ല"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"ടെതറിംഗ് ഓഫാക്കുക"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"ഹോട്ട്‌സ്‌പോട്ട് അല്ലെങ്കിൽ ടെതറിംഗ് ഓണാണ്"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"റോമിംഗ് ചെയ്യുമ്പോൾ അധിക നിരക്കുകൾ ബാധകമായേക്കാം"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-mn/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-mn/strings.xml
new file mode 100644
index 000000000000..47c82c14d9d6
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-mn/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"Модемд интернэт алга байна"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"Төхөөрөмжүүд холбогдох боломжгүй байна"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Модем болгохыг унтраах"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Сүлжээний цэг эсвэл модем болгох асаалттай байна"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Роумингийн үеэр нэмэлт төлбөр нэхэмжилж болзошгүй"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-mr/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-mr/strings.xml
new file mode 100644
index 000000000000..ad9e809ab27d
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-mr/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"टेदरिंगला इंटरनेट नाही"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"डिव्हाइस कनेक्ट होऊ शकत नाहीत"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"टेदरिंग बंद करा"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"हॉटस्पॉट किंवा टेदरिंग सुरू आहे"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"रोमिंगदरम्यान अतिरिक्त शुल्क लागू होऊ शकतात"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-ms/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-ms/strings.xml
new file mode 100644
index 000000000000..e708cb8717b3
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-ms/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"Penambatan tiada Internet"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"Peranti tidak dapat disambungkan"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Matikan penambatan"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Tempat liputan atau penambatan dihidupkan"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Caj tambahan mungkin digunakan semasa perayauan"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-my/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-my/strings.xml
new file mode 100644
index 000000000000..ba5462250b05
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-my/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"မိုဘိုင်းဖုန်းသုံး ချိတ်ဆက်မျှဝေခြင်းတွင် အင်တာနက် မရှိပါ"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"စက်များ ချိတ်ဆက်၍ မရပါ"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"မိုဘိုင်းဖုန်းသုံး ချိတ်ဆက်မျှဝေခြင်း ပိတ်ရန်"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"ဟော့စပေါ့ (သို့) မိုဘိုင်းဖုန်းသုံး ချိတ်ဆက်မျှဝေခြင်း ဖွင့်ထားသည်"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"ပြင်ပကွန်ရက်နှင့် ချိတ်ဆက်သည့်အခါ နောက်ထပ်ကျသင့်မှုများ ရှိနိုင်သည်"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-nb/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-nb/strings.xml
new file mode 100644
index 000000000000..57db484a2543
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-nb/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"Internettdeling har ikke internettilgang"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"Enhetene kan ikke koble til"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Slå av internettdeling"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Wi-Fi-sone eller internettdeling er på"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Ytterligere kostnader kan påløpe under roaming"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-ne/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-ne/strings.xml
new file mode 100644
index 000000000000..617c50dd0ce8
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-ne/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- no translation found for no_upstream_notification_title (611650570559011140) -->
+ <skip />
+ <!-- no translation found for no_upstream_notification_message (6508394877641864863) -->
+ <skip />
+ <!-- no translation found for no_upstream_notification_disable_button (7609346639290990508) -->
+ <skip />
+ <!-- no translation found for upstream_roaming_notification_title (6032901176124830787) -->
+ <skip />
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"रोमिङ सेवा प्रयोग गर्दा अतिरिक्त शुल्क लाग्न सक्छ"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-nl/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-nl/strings.xml
new file mode 100644
index 000000000000..b08133f4e592
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-nl/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"Tethering heeft geen internet"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"Apparaten kunnen niet worden verbonden"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Tethering uitschakelen"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Hotspot of tethering is ingeschakeld"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Er kunnen extra kosten voor roaming in rekening worden gebracht."</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-or/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-or/strings.xml
new file mode 100644
index 000000000000..1ad4ca354ad5
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-or/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"ଟିଥରିଂ ପାଇଁ କୌଣସି ଇଣ୍ଟର୍ନେଟ୍ ସଂଯୋଗ ନାହିଁ"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"ଡିଭାଇସଗୁଡ଼ିକ ସଂଯୋଗ କରାଯାଇପାରିବ ନାହିଁ"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"ଟିଥରିଂ ବନ୍ଦ କରନ୍ତୁ"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"ହଟସ୍ପଟ୍ କିମ୍ବା ଟିଥରିଂ ଚାଲୁ ଅଛି"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"ରୋମିଂରେ ଥିବା ସମୟରେ ଅତିରିକ୍ତ ଶୁଳ୍କ ଲାଗୁ ହୋଇପାରେ"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-pa/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-pa/strings.xml
new file mode 100644
index 000000000000..88def563d85a
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-pa/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"ਟੈਦਰਿੰਗ ਕੋਲ ਇੰਟਰਨੈੱਟ ਪਹੁੰਚ ਨਹੀਂ ਹੈ"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"ਡੀਵਾਈਸ ਕਨੈਕਟ ਨਹੀਂ ਕੀਤੇ ਜਾ ਸਕਦੇ"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"ਟੈਦਰਿੰਗ ਬੰਦ ਕਰੋ"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"ਹੌਟਸਪੌਟ ਜਾਂ ਟੈਦਰਿੰਗ ਚਾਲੂ ਹੈ"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"ਰੋਮਿੰਗ ਦੌਰਾਨ ਵਧੀਕ ਖਰਚੇ ਲਾਗੂ ਹੋ ਸਕਦੇ ਹਨ"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-pl/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-pl/strings.xml
new file mode 100644
index 000000000000..f9890abdc26b
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-pl/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"Tethering nie ma internetu"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"Urządzenia nie mogą się połączyć"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Wyłącz tethering"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Hotspot lub tethering jest włączony"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Podczas korzystania z roamingu mogą zostać naliczone dodatkowe opłaty"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-pt-rBR/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-pt-rBR/strings.xml
new file mode 100644
index 000000000000..ce3b88479f09
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-pt-rBR/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"O tethering não tem Internet"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"Não é possível conectar os dispositivos"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Desativar o tethering"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Ponto de acesso ou tethering ativado"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Pode haver cobranças extras durante o roaming"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-pt-rPT/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-pt-rPT/strings.xml
new file mode 100644
index 000000000000..7e883ea57682
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-pt-rPT/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"A ligação (à Internet) via telemóvel não tem Internet"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"Não é possível ligar os dispositivos"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Desativar ligação (à Internet) via telemóvel"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"A zona Wi-Fi ou a ligação (à Internet) via telemóvel está ativada"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Podem aplicar-se custos adicionais em roaming."</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-pt/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-pt/strings.xml
new file mode 100644
index 000000000000..ce3b88479f09
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-pt/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"O tethering não tem Internet"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"Não é possível conectar os dispositivos"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Desativar o tethering"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Ponto de acesso ou tethering ativado"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Pode haver cobranças extras durante o roaming"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-ro/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-ro/strings.xml
new file mode 100644
index 000000000000..1009417316ed
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-ro/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"Procesul de tethering nu are internet"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"Dispozitivele nu se pot conecta"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Dezactivați procesul de tethering"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"S-a activat hotspotul sau tethering"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Se pot aplica taxe suplimentare pentru roaming"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-ru/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-ru/strings.xml
new file mode 100644
index 000000000000..88683bed95b8
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-ru/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"Режим модема используется без доступа к Интернету"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"Невозможно подключить устройства."</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Отключить режим модема"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Включены точка доступа или режим модема"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"За использование услуг связи в роуминге может взиматься дополнительная плата."</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-si/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-si/strings.xml
new file mode 100644
index 000000000000..176bcdb797c6
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-si/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"ටෙදරින් හට අන්තර්ජාලය නැත"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"උපාංගවලට සම්බන්ධ විය නොහැකිය"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"ටෙදරින් ක්‍රියාවිරහිත කරන්න"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"හොට්ස්පොට් හෝ ටෙදරින් ක්‍රියාත්මකයි"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"රෝමිං අතරතුර අමතර ගාස්තු අදාළ විය හැකිය"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-sk/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-sk/strings.xml
new file mode 100644
index 000000000000..b9e2127fa879
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-sk/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"Tethering nemá internetové pripojenie"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"Zariadenia sa nemôžu pripojiť"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Vypnúť tethering"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Je zapnutý hotspot alebo tethering"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Počas roamingu vám môžu byť účtované ďalšie poplatky"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-sl/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-sl/strings.xml
new file mode 100644
index 000000000000..e8140e686a0c
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-sl/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"Internetna povezava prek mobilnega telefona ni vzpostavljena"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"Napravi se ne moreta povezati"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Izklopi internetno povezavo prek mobilnega telefona"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Dostopna točka ali internetna povezava prek mobilnega telefona je vklopljena"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Med gostovanjem lahko nastanejo dodatni stroški"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-sq/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-sq/strings.xml
new file mode 100644
index 000000000000..61e698d6e8ab
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-sq/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"Ndarja e internetit nuk ka internet"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"Pajisjet nuk mund të lidhen"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Çaktivizo ndarjen e internetit"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Zona e qasjes për internet ose ndarja e internetit është aktive"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Mund të zbatohen tarifime shtesë kur je në roaming"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-sr/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-sr/strings.xml
new file mode 100644
index 000000000000..b4c411c35475
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-sr/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"Привезивање нема приступ интернету"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"Повезивање уређаја није успело"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Искључи привезивање"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Укључен је хотспот или привезивање"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Можда важе додатни трошкови у ромингу"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-sv/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-sv/strings.xml
new file mode 100644
index 000000000000..4f543e47b998
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-sv/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"Det finns ingen internetanslutning för internetdelningen"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"Enheterna kan inte anslutas"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Inaktivera internetdelning"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Surfzon eller internetdelning har aktiverats"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Ytterligare avgifter kan tillkomma vid roaming"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-sw/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-sw/strings.xml
new file mode 100644
index 000000000000..ac347ab485e0
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-sw/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"Kipengele cha kusambaza mtandao hakina intaneti"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"Imeshindwa kuunganisha vifaa"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Zima kipengele cha kusambaza mtandao"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Umewasha kipengele cha kusambaza mtandao au mtandao pepe"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Huenda ukatozwa gharama za ziada ukitumia mitandao ya ng\'ambo"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-ta/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-ta/strings.xml
new file mode 100644
index 000000000000..0e437593ee87
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-ta/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- no translation found for no_upstream_notification_title (611650570559011140) -->
+ <skip />
+ <!-- no translation found for no_upstream_notification_message (6508394877641864863) -->
+ <skip />
+ <!-- no translation found for no_upstream_notification_disable_button (7609346639290990508) -->
+ <skip />
+ <!-- no translation found for upstream_roaming_notification_title (6032901176124830787) -->
+ <skip />
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"ரோமிங்கின்போது கூடுதல் கட்டணங்கள் விதிக்கப்படக்கூடும்"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-te/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-te/strings.xml
new file mode 100644
index 000000000000..9360297dd807
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-te/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"టెథరింగ్ చేయడానికి ఇంటర్నెట్ కనెక్షన్ లేదు"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"పరికరాలు కనెక్ట్ అవ్వడం లేదు"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"టెథరింగ్‌ను ఆఫ్ చేయండి"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"హాట్‌స్పాట్ లేదా టెథరింగ్ ఆన్‌లో ఉంది"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"రోమింగ్‌లో ఉన్నప్పుడు అదనపు ఛార్జీలు వర్తించవచ్చు"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-th/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-th/strings.xml
new file mode 100644
index 000000000000..9c4d7e08f2b6
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-th/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"การเชื่อมต่ออินเทอร์เน็ตผ่านมือถือไม่มีอินเทอร์เน็ต"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"อุปกรณ์เชื่อมต่อไม่ได้"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"ปิดการเชื่อมต่ออินเทอร์เน็ตผ่านมือถือ"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"ฮอตสปอตหรือการเชื่อมต่ออินเทอร์เน็ตผ่านมือถือเปิดอยู่"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"อาจมีค่าใช้จ่ายเพิ่มเติมขณะโรมมิ่ง"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-tl/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-tl/strings.xml
new file mode 100644
index 000000000000..a7c78a593267
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-tl/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"Walang internet ang pag-tether"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"Hindi makakonekta ang mga device"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"I-off ang pag-tether"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Naka-on ang Hotspot o pag-tether"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Posibleng magkaroon ng mga karagdagang singil habang nagro-roam"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-tr/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-tr/strings.xml
new file mode 100644
index 000000000000..93da2c3f7981
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-tr/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"Tethering\'in internet bağlantısı yok"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"Cihazlar bağlanamıyor"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Tethering\'i kapat"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Hotspot veya tethering açık"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Dolaşım sırasında ek ücretler uygulanabilir"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-uk/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-uk/strings.xml
new file mode 100644
index 000000000000..ee0dcd2c4b6a
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-uk/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"Телефон, який використовується як модем, не підключений до Інтернету"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"Не вдається підключити пристрої"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Вимкнути використання телефона як модема"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Увімкнено точку доступу або використання телефона як модема"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"У роумінгу може стягуватися додаткова плата"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-ur/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-ur/strings.xml
new file mode 100644
index 000000000000..41cd28eef9bd
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-ur/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"ٹیدرنگ میں انٹرنیٹ نہیں ہے"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"آلات منسلک نہیں ہو سکتے"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"ٹیدرنگ آف کریں"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"ہاٹ اسپاٹ یا ٹیدرنگ آن ہے"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"رومنگ کے دوران اضافی چارجز لاگو ہو سکتے ہیں"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-uz/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-uz/strings.xml
new file mode 100644
index 000000000000..c847bc943bd4
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-uz/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"Modem internetga ulanmagan"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"Qurilmalar ulanmadi"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Modem rejimini faolsizlantirish"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Hotspot yoki modem rejimi yoniq"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Rouming vaqtida qoʻshimcha haq olinishi mumkin"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-vi/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-vi/strings.xml
new file mode 100644
index 000000000000..a74326f09ec5
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-vi/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"Không có Internet để chia sẻ kết Internet"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"Các thiết bị không thể kết nối"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Tắt tính năng chia sẻ Internet"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"Điểm phát sóng hoặc tính năng chia sẻ Internet đang bật"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Bạn có thể mất thêm phí dữ liệu khi chuyển vùng"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-zh-rCN/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-zh-rCN/strings.xml
new file mode 100644
index 000000000000..d7370036e351
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-zh-rCN/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"共享网络未连接到互联网"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"设备无法连接"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"关闭网络共享"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"热点或网络共享已开启"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"漫游时可能会产生额外的费用"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-zh-rHK/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-zh-rHK/strings.xml
new file mode 100644
index 000000000000..f378a9dc2cfb
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-zh-rHK/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"無法透過網絡共享連線至互聯網"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"裝置無法連接"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"關閉網絡共享"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"熱點或網絡共享已開啟"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"漫遊時可能需要支付額外費用"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-zh-rTW/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-zh-rTW/strings.xml
new file mode 100644
index 000000000000..ea01b943fbe8
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-zh-rTW/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"無法透過數據連線連上網際網路"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"裝置無法連線"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"關閉數據連線"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"無線基地台或數據連線已開啟"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"使用漫遊服務可能須支付額外費用"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480-zu/strings.xml b/packages/Tethering/res/values-mcc311-mnc480-zu/strings.xml
new file mode 100644
index 000000000000..32f6df56f154
--- /dev/null
+++ b/packages/Tethering/res/values-mcc311-mnc480-zu/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="no_upstream_notification_title" msgid="611650570559011140">"Ukusebenzisa ifoni njengemodemu akunayo i-inthanethi"</string>
+ <string name="no_upstream_notification_message" msgid="6508394877641864863">"Amadivayisi awakwazi ukuxhumeka"</string>
+ <string name="no_upstream_notification_disable_button" msgid="7609346639290990508">"Vala ukusebenzisa ifoni njengemodemu"</string>
+ <string name="upstream_roaming_notification_title" msgid="6032901176124830787">"I-hotspot noma ukusebenzisa ifoni njengemodemu kuvuliwe"</string>
+ <string name="upstream_roaming_notification_message" msgid="7599056263326217523">"Kungaba nezinkokhelo ezengeziwe uma uzula"</string>
+</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc480/strings.xml b/packages/Tethering/res/values-mcc311-mnc480/strings.xml
index 9dadd49cf8a4..ce9ff6080717 100644
--- a/packages/Tethering/res/values-mcc311-mnc480/strings.xml
+++ b/packages/Tethering/res/values-mcc311-mnc480/strings.xml
@@ -25,6 +25,4 @@
<string name="upstream_roaming_notification_title">Hotspot or tethering is on</string>
<!-- String for cellular roaming notification message [CHAR LIMIT=500] -->
<string name="upstream_roaming_notification_message">Additional charges may apply while roaming</string>
- <!-- String for cellular roaming notification continue button [CHAR LIMIT=200] -->
- <string name="upstream_roaming_notification_continue_button">Continue</string>
</resources>
diff --git a/packages/Tethering/res/values-mcc311-mnc490/strings.xml b/packages/Tethering/res/values-mcc311-mnc490/strings.xml
deleted file mode 100644
index 618df90c7105..000000000000
--- a/packages/Tethering/res/values-mcc311-mnc490/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2020 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- String for tethered notification title with client number info. -->
- <plurals name="tethered_notification_title_with_client_number">
- <item quantity="one"><xliff:g>%1$d</xliff:g> device connected.</item>
- <item quantity="other"><xliff:g>%1$d</xliff:g> devices connected.</item>
- </plurals>
-</resources> \ No newline at end of file
diff --git a/packages/Tethering/res/values-mcc312-mnc530/strings.xml b/packages/Tethering/res/values-mcc312-mnc530/strings.xml
deleted file mode 100644
index 618df90c7105..000000000000
--- a/packages/Tethering/res/values-mcc312-mnc530/strings.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2020 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- String for tethered notification title with client number info. -->
- <plurals name="tethered_notification_title_with_client_number">
- <item quantity="one"><xliff:g>%1$d</xliff:g> device connected.</item>
- <item quantity="other"><xliff:g>%1$d</xliff:g> devices connected.</item>
- </plurals>
-</resources> \ No newline at end of file
diff --git a/packages/Tethering/res/values-mk/strings.xml b/packages/Tethering/res/values-mk/strings.xml
index 0fab8aa4761f..9ad9b9a58935 100644
--- a/packages/Tethering/res/values-mk/strings.xml
+++ b/packages/Tethering/res/values-mk/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"Поврзувањето или точката на пристап се активни"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"Допрете за поставување."</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"Врзувањето е оневозможено"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"Контактирајте со администраторот за детали"</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"Активно е врзување или точка на пристап"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"Допрете за поставување."</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"Врзувањето е оневозможено"</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"Контактирајте со администраторот за детали"</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Статус на точката на пристап и врзувањето"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-ml/strings.xml b/packages/Tethering/res/values-ml/strings.xml
index fd7e556e3899..9db79ce220a4 100644
--- a/packages/Tethering/res/values-ml/strings.xml
+++ b/packages/Tethering/res/values-ml/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"ടെതറിംഗ് അല്ലെങ്കിൽ ഹോട്ട്സ്‌പോട്ട് സജീവമാണ്"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"സജ്ജമാക്കാൻ ടാപ്പുചെയ്യുക."</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"ടെതറിംഗ് പ്രവർത്തനരഹിതമാക്കിയിരിക്കുന്നു"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"വിശദവിവരങ്ങൾക്ക് നിങ്ങളുടെ അഡ്മിനെ ബന്ധപ്പെടുക"</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"ടെതറിംഗ് അല്ലെങ്കിൽ ഹോട്ട്സ്‌പോട്ട് സജീവമാണ്"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"സജ്ജീകരിക്കാൻ ടാപ്പ് ചെയ്യുക."</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"ടെതറിംഗ് പ്രവർത്തനരഹിതമാക്കിയിരിക്കുന്നു"</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"വിശദാംശങ്ങൾക്ക് നിങ്ങളുടെ അഡ്മിനെ ബന്ധപ്പെടുക"</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"ഹോട്ട്‌സ്പോട്ടിന്റെയും ടെതറിംഗിന്റെയും നില"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-mn/strings.xml b/packages/Tethering/res/values-mn/strings.xml
index 4596577c5d95..42d1edbaceb9 100644
--- a/packages/Tethering/res/values-mn/strings.xml
+++ b/packages/Tethering/res/values-mn/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"Модем болгох эсвэл идэвхтэй цэг болгох"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"Тохируулахын тулд товшино уу."</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"Модем болгох боломжгүй байна"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"Дэлгэрэнгүй мэдээлэл авахын тулд админтайгаа холбогдоно уу"</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"Модем болгох эсвэл сүлжээний цэг идэвхтэй байна"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"Тохируулахын тулд товшино уу."</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"Модем болгохыг идэвхгүй болгосон"</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"Дэлгэрэнгүй мэдээлэл авахын тулд админтайгаа холбогдоно уу"</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Сүлжээний цэг болон модем болгох төлөв"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-mr/strings.xml b/packages/Tethering/res/values-mr/strings.xml
index 85c9ade4feee..13995b6b8aa5 100644
--- a/packages/Tethering/res/values-mr/strings.xml
+++ b/packages/Tethering/res/values-mr/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"टेदरिंग किंवा हॉटस्पॉट सक्रिय"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"सेट करण्यासाठी टॅप करा."</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"टेदरिंग बंद आहे"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"तपशीलांसाठी तुमच्या प्रशासकाशी संपर्क साधा"</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"टेदरिंग किंवा हॉटस्पॉट अ‍ॅक्टिव्ह आहे"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"सेट करण्यासाठी टॅप करा."</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"टेदरिंग बंद केले आहे"</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"तपशीलांसाठी तुमच्या ॲडमिनशी संपर्क साधा"</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"हॉटस्पॉट आणि टेदरिंगची स्थिती"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-ms/strings.xml b/packages/Tethering/res/values-ms/strings.xml
index ec6bdbda08e7..d6a67f37b1de 100644
--- a/packages/Tethering/res/values-ms/strings.xml
+++ b/packages/Tethering/res/values-ms/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"Penambatan atau titik panas aktif"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"Ketik untuk membuat persediaan."</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"Penambatan dilumpuhkan"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"Hubungi pentadbir anda untuk maklumat lanjut"</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"Penambatan atau tempat liputan aktif"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"Ketik untuk membuat persediaan."</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"Penambatan dilumpuhkan"</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"Hubungi pentadbir anda untuk mendapatkan maklumat lanjut"</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Status tempat liputan &amp; penambatan"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-my/strings.xml b/packages/Tethering/res/values-my/strings.xml
index 83978b67d433..49f6b88a7514 100644
--- a/packages/Tethering/res/values-my/strings.xml
+++ b/packages/Tethering/res/values-my/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"တဆင့်ပြန်လည်လွှင့်ခြင်း သို့မဟုတ် ဟော့စပေါ့ ဖွင့်ထားသည်"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"စနစ်ထည့်သွင်းရန် တို့ပါ။"</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"မိုဘိုင်းဖုန်းကို မိုဒမ်အဖြစ်သုံးခြင်းအား ပိတ်ထားသည်"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"အသေးစိတ်အချက်အလက်များအတွက် သင့်စီမံခန့်ခွဲသူကို ဆက်သွယ်ပါ"</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"မိုဘိုင်းဖုန်းသုံး ချိတ်ဆက်မျှဝေခြင်း သို့မဟုတ် ဟော့စပေါ့ ဖွင့်ထားသည်"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"စနစ်ထည့်သွင်းရန် တို့ပါ။"</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"မိုဘိုင်းဖုန်းသုံး ချိတ်ဆက်မျှဝေခြင်းကို ပိတ်ထားသည်"</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"အသေးစိတ်အတွက် သင့်စီမံခန့်ခွဲသူကို ဆက်သွယ်ပါ"</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"ဟော့စပေါ့နှင့် မိုဘိုင်းဖုန်းသုံး ချိတ်ဆက်မျှဝေခြင်း အခြေအနေ"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-nb/strings.xml b/packages/Tethering/res/values-nb/strings.xml
index 9abf32dd7bf1..9594e0a70a69 100644
--- a/packages/Tethering/res/values-nb/strings.xml
+++ b/packages/Tethering/res/values-nb/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"Internettdeling eller trådløs sone er aktiv"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"Trykk for å konfigurere."</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"Internettdeling er slått av"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"Ta kontakt med administratoren din for å få mer informasjon"</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"Internettdeling eller Wi-Fi-sone er aktiv"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"Trykk for å konfigurere."</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"Internettdeling er slått av"</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"Ta kontakt med administratoren din for å få mer informasjon"</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Status for Wi-Fi-sone og internettdeling"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-ne/strings.xml b/packages/Tethering/res/values-ne/strings.xml
index c8869298a546..72ae3a80a928 100644
--- a/packages/Tethering/res/values-ne/strings.xml
+++ b/packages/Tethering/res/values-ne/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"टेथर गर्ने वा हटस्पट सक्रिय"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"सेटअप गर्न ट्याप गर्नुहोस्।"</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"टेदरिङलाई असक्षम पारिएको छ"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"विवरणहरूका लागि आफ्ना प्रशासकलाई सम्पर्क गर्नुहोस्"</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"टेदरिङ वा हटस्पट सक्रिय छ"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"सेटअप गर्न ट्याप गर्नुहोस्।"</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"टेदरिङ सुविधा असक्षम पारिएको छ"</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"विवरणहरूका लागि आफ्ना प्रशासकलाई सम्पर्क गर्नुहोस्"</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"हटस्पट तथा टेदरिङको स्थिति"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-nl/strings.xml b/packages/Tethering/res/values-nl/strings.xml
index 0ec4bff62154..18b2bbfc7670 100644
--- a/packages/Tethering/res/values-nl/strings.xml
+++ b/packages/Tethering/res/values-nl/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering of hotspot actief"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"Tik om in te stellen."</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering is uitgeschakeld"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"Neem contact op met je beheerder voor meer informatie"</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"Tethering of hotspot actief"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"Tik om in te stellen."</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering is uitgeschakeld"</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"Neem contact op met je beheerder voor meer informatie"</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Status van hotspot en tethering"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-or/strings.xml b/packages/Tethering/res/values-or/strings.xml
index 457685795a16..a15a6db42af6 100644
--- a/packages/Tethering/res/values-or/strings.xml
+++ b/packages/Tethering/res/values-or/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"ଟିଥରିଙ୍ଗ କିମ୍ୱା ହଟସ୍ପଟ୍‌ ସକ୍ରିୟ ଅଛି"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"ସେଟଅପ୍‍ କରିବାକୁ ଟାପ୍‍ କରନ୍ତୁ।"</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"ଟିଥରିଙ୍ଗ ଅକ୍ଷମ କରାଯାଇଛି"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"ବିବରଣୀ ପାଇଁ ନିଜ ଆଡମିନ୍‌ଙ୍କ ସହ ଯୋଗାଯୋଗ କରନ୍ତୁ"</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"ଟିଥେରିଂ କିମ୍ୱା ହଟସ୍ପଟ୍ ସକ୍ରିୟ ଅଛି"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"ସେଟ୍ ଅପ୍ କରିବାକୁ ଟାପ୍ କରନ୍ତୁ।"</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"ଟିଥେରିଂ ଅକ୍ଷମ କରାଯାଇଛି"</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"ବିବରଣୀଗୁଡ଼ିକ ପାଇଁ ଆପଣଙ୍କ ଆଡମିନଙ୍କ ସହ ଯୋଗାଯୋଗ କରନ୍ତୁ"</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"ହଟସ୍ପଟ୍ ଓ ଟିଥେରିଂ ସ୍ଥିତି"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-pa/strings.xml b/packages/Tethering/res/values-pa/strings.xml
index deddf2ea27f7..a8235e423e47 100644
--- a/packages/Tethering/res/values-pa/strings.xml
+++ b/packages/Tethering/res/values-pa/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"ਟੈਦਰਿੰਗ ਜਾਂ ਹੌਟਸਪੌਟ ਕਿਰਿਆਸ਼ੀਲ"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"ਸਥਾਪਤ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ।"</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"ਟੈਦਰਿੰਗ ਨੂੰ ਅਯੋਗ ਬਣਾਇਆ ਗਿਆ ਹੈ"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"ਵੇਰਵਿਆਂ ਲਈ ਆਪਣੇ ਪ੍ਰਸ਼ਾਸਕ ਨੂੰ ਸੰਪਰਕ ਕਰੋ"</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"ਟੈਦਰਿੰਗ ਜਾਂ ਹੌਟਸਪੌਟ ਕਿਰਿਆਸ਼ੀਲ"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"ਸੈੱਟਅੱਪ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ।"</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"ਟੈਦਰਿੰਗ ਨੂੰ ਬੰਦ ਕੀਤਾ ਗਿਆ ਹੈ"</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"ਵੇਰਵਿਆਂ ਲਈ ਆਪਣੇ ਪ੍ਰਸ਼ਾਸਕ ਨਾਲ ਸੰਪਰਕ ਕਰੋ"</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"ਹੌਟਸਪੌਟ ਅਤੇ ਟੈਦਰਿੰਗ ਦੀ ਸਥਿਤੀ"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-pl/strings.xml b/packages/Tethering/res/values-pl/strings.xml
index 48d8468935a1..ccb017d43fa8 100644
--- a/packages/Tethering/res/values-pl/strings.xml
+++ b/packages/Tethering/res/values-pl/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"Aktywny tethering lub punkt dostępu"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"Kliknij, by skonfigurować."</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering został wyłączony"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"Aby uzyskać szczegółowe informacje, skontaktuj się z administratorem"</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"Aktywny tethering lub punkt dostępu"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"Kliknij, by skonfigurować"</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering został wyłączony"</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"Aby uzyskać szczegółowe informacje, skontaktuj się z administratorem"</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Hotspot i tethering – stan"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-pt-rBR/strings.xml b/packages/Tethering/res/values-pt-rBR/strings.xml
index 32c22b8713b5..a0a4745f9394 100644
--- a/packages/Tethering/res/values-pt-rBR/strings.xml
+++ b/packages/Tethering/res/values-pt-rBR/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"Ponto de acesso ou tethering ativo"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"Toque para configurar."</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering desativado"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"Fale com seu administrador para saber detalhes"</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"Ponto de acesso ou tethering ativo"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"Toque para configurar."</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering desativado"</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"Fale com seu administrador para saber detalhes"</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Status de ponto de acesso e tethering"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-pt-rPT/strings.xml b/packages/Tethering/res/values-pt-rPT/strings.xml
index 641e22f44f25..e3f03fcc6934 100644
--- a/packages/Tethering/res/values-pt-rPT/strings.xml
+++ b/packages/Tethering/res/values-pt-rPT/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"Ligação ponto a ponto ou hotspot activos"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"Toque para configurar."</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"A ligação (à Internet) via telemóvel está desativada."</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"Contacte o gestor para obter detalhes."</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"Ligação (à Internet) via telemóvel ou zona Wi-Fi ativas"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"Toque para configurar."</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"A ligação (à Internet) via telemóvel está desativada."</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"Contacte o administrador para obter detalhes."</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Estado da zona Wi-Fi e da ligação (à Internet) via telemóvel"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-pt/strings.xml b/packages/Tethering/res/values-pt/strings.xml
index 32c22b8713b5..a0a4745f9394 100644
--- a/packages/Tethering/res/values-pt/strings.xml
+++ b/packages/Tethering/res/values-pt/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"Ponto de acesso ou tethering ativo"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"Toque para configurar."</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering desativado"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"Fale com seu administrador para saber detalhes"</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"Ponto de acesso ou tethering ativo"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"Toque para configurar."</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering desativado"</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"Fale com seu administrador para saber detalhes"</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Status de ponto de acesso e tethering"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-ro/strings.xml b/packages/Tethering/res/values-ro/strings.xml
index f861f733b4a1..5706a4a69c79 100644
--- a/packages/Tethering/res/values-ro/strings.xml
+++ b/packages/Tethering/res/values-ro/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering sau hotspot activ"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"Atingeți ca să configurați."</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tetheringul este dezactivat"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"Contactați administratorul pentru detalii"</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"Tethering sau hotspot activ"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"Atingeți ca să configurați."</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tetheringul este dezactivat"</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"Contactați administratorul pentru detalii"</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Starea hotspotului și a tetheringului"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-ru/strings.xml b/packages/Tethering/res/values-ru/strings.xml
index 027cb410c54c..7cb6f7db3fc8 100644
--- a/packages/Tethering/res/values-ru/strings.xml
+++ b/packages/Tethering/res/values-ru/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"Включен режим модема"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"Нажмите, чтобы настроить."</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"Включить режим модема нельзя"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"Обратитесь к администратору, чтобы узнать подробности."</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"Включен режим модема или точка доступа"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"Нажмите, чтобы настроить."</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"Использование телефона в качестве модема запрещено"</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"Чтобы узнать подробности, обратитесь к администратору."</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Статус хот-спота и режима модема"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-si/strings.xml b/packages/Tethering/res/values-si/strings.xml
index 7d8599f2c2d9..ec34c22de750 100644
--- a/packages/Tethering/res/values-si/strings.xml
+++ b/packages/Tethering/res/values-si/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"ටෙදරින් හෝ හොට්ස්පොට් සක්‍රීයයි"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"පිහිටුවීමට තට්ටු කරන්න."</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"ටෙදරින් අබල කර ඇත"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"විස්තර සඳහා ඔබගේ පරිපාලක අමතන්න"</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"ටෙදරින් හෝ හොට්ස්පොට් සක්‍රීයයි"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"පිහිටුවීමට තට්ටු කරන්න."</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"ටෙදරින් අබල කර ඇත"</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"විස්තර සඳහා ඔබගේ පරිපාලක අමතන්න"</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"හොට්ස්පොට් &amp; ටෙදරින් තත්ත්වය"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-sk/strings.xml b/packages/Tethering/res/values-sk/strings.xml
index a8fe297c0088..43e787c84f87 100644
--- a/packages/Tethering/res/values-sk/strings.xml
+++ b/packages/Tethering/res/values-sk/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering alebo prístupový bod je aktívny"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"Klepnutím prejdete na nastavenie."</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering je deaktivovaný"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"O podrobnosti požiadajte svojho správcu"</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"Tethering alebo prístupový bod je aktívny"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"Klepnutím prejdete na nastavenie."</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering je deaktivovaný"</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"O podrobnosti požiadajte svojho správcu"</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Stav hotspotu a tetheringu"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-sl/strings.xml b/packages/Tethering/res/values-sl/strings.xml
index b5e5e3856f7b..59433626a115 100644
--- a/packages/Tethering/res/values-sl/strings.xml
+++ b/packages/Tethering/res/values-sl/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"Aktivna povezava z internetom ali dostopna točka sta aktivni"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"Dotaknite se, če želite nastaviti."</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"Povezava z internetom prek mobilnega telefona je onemogočena"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"Za podrobnosti se obrnite na skrbnika"</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"Povezava z internetom prek mobilnega telefona ali dostopna točka je aktivna"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"Dotaknite se, če želite nastaviti."</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"Povezava z internetom prek mobilnega telefona je onemogočena"</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"Za podrobnosti se obrnite na skrbnika"</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Stanje dostopne točke in povezave z internetom prek mobilnega telefona"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-sq/strings.xml b/packages/Tethering/res/values-sq/strings.xml
index fdd4906cc51e..21e11558bb0b 100644
--- a/packages/Tethering/res/values-sq/strings.xml
+++ b/packages/Tethering/res/values-sq/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"Lidhja e çiftimit ose ajo e qasjes në zona publike interneti është aktive"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"Trokit për ta konfiguruar."</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"Lidhja e çiftimit është çaktivizuar"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"Kontakto me administratorin për detaje"</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"Ndarja e internetit ose zona e qasjes së internetit është aktive"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"Trokit për ta konfiguruar."</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"Ndarja e internetit është çaktivizuar"</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"Kontakto me administratorin për detaje"</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Statusi i zonës së qasjes dhe ndarjes së internetit"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-sr/strings.xml b/packages/Tethering/res/values-sr/strings.xml
index 9fab34589724..e2e4dc6361d4 100644
--- a/packages/Tethering/res/values-sr/strings.xml
+++ b/packages/Tethering/res/values-sr/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"Активно повезивање са интернетом преко мобилног уређаја или хотспот"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"Додирните да бисте подесили."</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"Привезивање је онемогућено"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"Потражите детаље од администратора"</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"Привезивање или хотспот је активан"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"Додирните да бисте подесили."</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"Привезивање је онемогућено"</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"Потражите детаље од администратора"</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Статус хотспота и привезивања"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-sv/strings.xml b/packages/Tethering/res/values-sv/strings.xml
index 10eeb0fe12e1..72702c28587d 100644
--- a/packages/Tethering/res/values-sv/strings.xml
+++ b/packages/Tethering/res/values-sv/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"Internetdelning eller surfzon aktiverad"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"Tryck om du vill konfigurera."</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"Internetdelning har inaktiverats"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"Kontakta administratören om du vill veta mer"</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"Internetdelning eller surfzon har aktiverats"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"Tryck om du vill konfigurera."</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"Internetdelning har inaktiverats"</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"Kontakta administratören om du vill veta mer"</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Trådlös surfzon och internetdelning har inaktiverats"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-sw/strings.xml b/packages/Tethering/res/values-sw/strings.xml
index 335396307730..65e4aa8cebb0 100644
--- a/packages/Tethering/res/values-sw/strings.xml
+++ b/packages/Tethering/res/values-sw/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"Kushiriki au kusambaza intaneti kumewashwa"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"Gusa ili uweke mipangilio."</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"Umezima kipengele cha kusambaza mtandao"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"Wasiliana na msimamizi wako ili upate maelezo zaidi"</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"Kusambaza mtandao au mtandaopepe umewashwa"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"Gusa ili uweke mipangilio."</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"Umezima kipengele cha kusambaza mtandao"</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"Wasiliana na msimamizi wako ili upate maelezo zaidi"</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Mtandaopepe na hali ya kusambaza mtandao"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-ta/strings.xml b/packages/Tethering/res/values-ta/strings.xml
index b1e5cc241376..4aba62d4ab46 100644
--- a/packages/Tethering/res/values-ta/strings.xml
+++ b/packages/Tethering/res/values-ta/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"டெதெரிங்/ஹாட்ஸ்பாட் இயங்குகிறது"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"அமைக்க, தட்டவும்."</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"இணைப்பு முறை முடக்கப்பட்டுள்ளது"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"விவரங்களுக்கு, உங்கள் நிர்வாகியைத் தொடர்புகொள்ளவும்"</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"டெதெரிங் அல்லது ஹாட்ஸ்பாட் இயங்குகிறது"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"அமைக்க, தட்டவும்."</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"டெதெரிங் முடக்கப்பட்டுள்ளது"</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"விவரங்களுக்கு உங்கள் நிர்வாகியைத் தொடர்புகொள்ளவும்"</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"ஹாட்ஸ்பாட் &amp; டெதெரிங் நிலை"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-te/strings.xml b/packages/Tethering/res/values-te/strings.xml
index aae40dee40db..1f917913416f 100644
--- a/packages/Tethering/res/values-te/strings.xml
+++ b/packages/Tethering/res/values-te/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"టీథర్ చేయబడినది లేదా హాట్‌స్పాట్ సక్రియంగా ఉండేది"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"సెటప్ చేయడానికి నొక్కండి."</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"టెథెరింగ్ నిలిపివేయబడింది"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"వివరాల కోసం మీ నిర్వాహకులను సంప్రదించండి"</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"టెథరింగ్ లేదా హాట్‌స్పాట్ యాక్టివ్‌గా ఉంది"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"సెటప్ చేయడానికి ట్యాప్ చేయండి."</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"టెథరింగ్ డిజేబుల్ చేయబడింది"</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"వివరాల కోసం మీ అడ్మిన్‌ని సంప్రదించండి"</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"హాట్‌స్పాట్ &amp; టెథరింగ్ స్థితి"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-th/strings.xml b/packages/Tethering/res/values-th/strings.xml
index 1b800565ad1f..44171c0db82f 100644
--- a/packages/Tethering/res/values-th/strings.xml
+++ b/packages/Tethering/res/values-th/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"การปล่อยสัญญาณหรือฮอตสปอตทำงานอยู่"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"แตะเพื่อตั้งค่า"</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"ปิดใช้การเชื่อมต่ออินเทอร์เน็ตผ่านมือถือแล้ว"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"ติดต่อผู้ดูแลระบบเพื่อขอรายละเอียด"</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"การเชื่อมต่ออินเทอร์เน็ตผ่านมือถือหรือฮอตสปอตทำงานอยู่"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"แตะเพื่อตั้งค่า"</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"ปิดใช้การเชื่อมต่ออินเทอร์เน็ตผ่านมือถือแล้ว"</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"ติดต่อผู้ดูแลระบบเพื่อขอรายละเอียด"</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"สถานะฮอตสปอตและการเชื่อมต่ออินเทอร์เน็ตผ่านมือถือ"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-tl/strings.xml b/packages/Tethering/res/values-tl/strings.xml
index 12863f90e15a..7347dd3e6254 100644
--- a/packages/Tethering/res/values-tl/strings.xml
+++ b/packages/Tethering/res/values-tl/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"Pagsasama o aktibong hotspot"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"I-tap upang i-set up."</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"Naka-disable ang pag-tether"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"Makipag-ugnayan sa iyong admin para sa mga detalye"</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"Aktibo ang pag-tether o hotspot"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"I-tap para i-set up."</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"Naka-disable ang pag-tether"</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"Makipag-ugnayan sa iyong admin para sa mga detalye"</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Status ng hotspot at pag-tether"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-tr/strings.xml b/packages/Tethering/res/values-tr/strings.xml
index bfcf1ace2cf7..32030f176574 100644
--- a/packages/Tethering/res/values-tr/strings.xml
+++ b/packages/Tethering/res/values-tr/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering veya hotspot etkin"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"Ayarlamak için dokunun."</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering devre dışı bırakıldı"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"Ayrıntılı bilgi için yöneticinize başvurun"</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"Tethering veya hotspot etkin"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"Ayarlamak için dokunun."</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"Tethering devre dışı bırakıldı"</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"Ayrıntılı bilgi için yöneticinize başvurun"</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Hotspot ve tethering durumu"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-uk/strings.xml b/packages/Tethering/res/values-uk/strings.xml
index 8e159c072350..1ca89b3f7813 100644
--- a/packages/Tethering/res/values-uk/strings.xml
+++ b/packages/Tethering/res/values-uk/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"Прив\'язка чи точка дост. активна"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"Торкніться, щоб налаштувати."</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"Використання телефона в режимі модема вимкнено"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"Щоб дізнатися більше, зв’яжіться з адміністратором"</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"Модем чи точка доступу активні"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"Натисніть, щоб налаштувати."</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"Використання телефона як модема вимкнено"</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"Щоб дізнатися більше, зв\'яжіться з адміністратором"</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Статус точки доступу та модема"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-ur/strings.xml b/packages/Tethering/res/values-ur/strings.xml
index 89195d4aae29..d72c7d419577 100644
--- a/packages/Tethering/res/values-ur/strings.xml
+++ b/packages/Tethering/res/values-ur/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"ٹیدرنگ یا ہاٹ اسپاٹ فعال"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"سیٹ اپ کرنے کیلئے تھپتھپائیں۔"</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"ٹیدرنگ غیر فعال ہے"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"تفصیلات کے لئے اپنے منتظم سے رابطہ کریں"</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"ٹیدرنگ یا ہاٹ اسپاٹ فعال"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"سیٹ اپ کرنے کیلئے تھپتھپائیں۔"</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"ٹیدرنگ غیر فعال ہے"</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"تفصیلات کے لئے اپنے منتظم سے رابطہ کریں"</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"ہاٹ اسپاٹ اور ٹیتھرنگ کا اسٹیٹس"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-uz/strings.xml b/packages/Tethering/res/values-uz/strings.xml
index 0ac4d4a7410a..af3b2ebb3500 100644
--- a/packages/Tethering/res/values-uz/strings.xml
+++ b/packages/Tethering/res/values-uz/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"Modem rejimi yoniq"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"Sozlash uchun bosing."</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"Modem rejimi faolsizlantirildi"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"Tafsilotlari uchun administratoringizga murojaat qiling"</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"Modem rejimi yoki hotspot yoniq"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"Sozlash uchun bosing."</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"Modem rejimi faolsizlantirildi"</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"Tafsilotlari uchun administratoringizga murojaat qiling"</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Hotspot va modem rejimi holati"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-vi/strings.xml b/packages/Tethering/res/values-vi/strings.xml
index 85a4db8aa5da..21a0735922c3 100644
--- a/packages/Tethering/res/values-vi/strings.xml
+++ b/packages/Tethering/res/values-vi/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"Chức năng điểm truy cập Internet hoặc điểm phát sóng đang hoạt động"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"Nhấn để thiết lập."</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"Đã tắt tính năng chia sẻ kết nối"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"Hãy liên hệ với quản trị viên của bạn để biết chi tiết"</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"Tính năng chia sẻ Internet hoặc điểm phát sóng đang hoạt động"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"Hãy nhấn để thiết lập."</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"Đã tắt tính năng chia sẻ Internet"</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"Hãy liên hệ với quản trị viên của bạn để biết chi tiết"</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"Trạng thái điểm phát sóng và chia sẻ Internet"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-zh-rCN/strings.xml b/packages/Tethering/res/values-zh-rCN/strings.xml
index ff1fe039531c..98e3b4b46fdb 100644
--- a/packages/Tethering/res/values-zh-rCN/strings.xml
+++ b/packages/Tethering/res/values-zh-rCN/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"网络共享或热点已启用"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"点按即可进行设置。"</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"网络共享已停用"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"请与您的管理员联系以了解详情"</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"网络共享或热点已启用"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"点按即可设置。"</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"网络共享已停用"</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"如需了解详情,请与您的管理员联系"</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"热点和网络共享状态"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-zh-rHK/strings.xml b/packages/Tethering/res/values-zh-rHK/strings.xml
index 0de39fac97f8..9cafd42dd43f 100644
--- a/packages/Tethering/res/values-zh-rHK/strings.xml
+++ b/packages/Tethering/res/values-zh-rHK/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"已啟用網絡共享或熱點"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"輕按即可設定。"</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"網絡共享已停用"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"請聯絡您的管理員以瞭解詳情"</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"網絡共享或熱點已啟用"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"輕按即可設定。"</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"網絡共享已停用"</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"請聯絡您的管理員以瞭解詳情"</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"熱點和網絡共享狀態"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-zh-rTW/strings.xml b/packages/Tethering/res/values-zh-rTW/strings.xml
index 9a117bbca43f..9d738a76eb0e 100644
--- a/packages/Tethering/res/values-zh-rTW/strings.xml
+++ b/packages/Tethering/res/values-zh-rTW/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"網路共用或無線基地台已啟用"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"輕觸即可進行設定。"</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"數據連線已停用"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"詳情請洽你的管理員"</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"數據連線或無線基地台已啟用"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"輕觸即可進行設定。"</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"數據連線已停用"</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"詳情請洽你的管理員"</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"無線基地台與數據連線狀態"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values-zu/strings.xml b/packages/Tethering/res/values-zu/strings.xml
index 8fe10d86cb03..f210f8726ee5 100644
--- a/packages/Tethering/res/values-zu/strings.xml
+++ b/packages/Tethering/res/values-zu/strings.xml
@@ -1,8 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="tethered_notification_title" msgid="3146694234398202601">"Ukusebenzisa njengemodemu noma i-hotspot ephathekayo kuvuliwe"</string>
- <string name="tethered_notification_message" msgid="2113628520792055377">"Thepha ukuze usethe."</string>
- <string name="disable_tether_notification_title" msgid="7526977944111313195">"Ukusebenzisa ifoni njengemodemu kukhutshaziwe"</string>
- <string name="disable_tether_notification_message" msgid="2913366428516852495">"Xhumana nomphathi wakho ukuze uthole imininingwane"</string>
+ <string name="tethered_notification_title" msgid="6426563586025792944">"Ukusebenzisa njengemodemu noma i-hotspot ephathekayo kuvuliwe"</string>
+ <string name="tethered_notification_message" msgid="64800879503420696">"Thepha ukuze usethe."</string>
+ <string name="disable_tether_notification_title" msgid="3004509127903564191">"Ukusebenzisa ifoni njengemodemu kukhutshaziwe"</string>
+ <string name="disable_tether_notification_message" msgid="6717523799293901476">"Xhumana nomphathi wakho ukuze uthole imininingwane"</string>
+ <string name="notification_channel_tethering_status" msgid="2663463891530932727">"I-Hotspot nesimo sokusebenzisa ifoni njengemodemu"</string>
+ <string name="no_upstream_notification_title" msgid="1204601824631788482"></string>
+ <string name="no_upstream_notification_message" msgid="8586582938243032621"></string>
+ <string name="no_upstream_notification_disable_button" msgid="8800919436924640822"></string>
+ <string name="upstream_roaming_notification_title" msgid="4772373823198997030"></string>
+ <string name="upstream_roaming_notification_message" msgid="3985577843181551650"></string>
</resources>
diff --git a/packages/Tethering/res/values/config.xml b/packages/Tethering/res/values/config.xml
index 66fbefca9456..83c99d22fda7 100644
--- a/packages/Tethering/res/values/config.xml
+++ b/packages/Tethering/res/values/config.xml
@@ -158,51 +158,6 @@
<!-- ComponentName of the service used to run no ui tether provisioning. -->
<string translatable="false" name="config_wifi_tether_enable">com.android.settings/.wifi.tether.TetherService</string>
- <!-- Enable tethering notification -->
- <!-- Icons for showing tether enable notification.
- Each item should have two elements and be separated with ";".
-
- The first element is downstream types which is one of tethering. This element has to be
- made by WIFI, USB, BT, and OR'd with the others. Use "|" to combine multiple downstream
- types and use "," to separate each combinations. Such as
-
- USB|BT,WIFI|USB|BT
-
- The second element is icon for the item. This element has to be composed by
- <package name>:drawable/<resource name>. Such as
-
- 1. com.android.networkstack.tethering:drawable/stat_sys_tether_general
- 2. android:drawable/xxx
-
- So the entire string of each item would be
-
- USB|BT,WIFI|USB|BT;com.android.networkstack.tethering:drawable/stat_sys_tether_general
-
- NOTE: One config can be separated into two or more for readability. Such as
-
- WIFI|USB,WIFI|BT,USB|BT,WIFI|USB|BT;android:drawable/xxx
-
- can be separated into
-
- WIFI|USB;android:drawable/xxx
- WIFI|BT;android:drawable/xxx
- USB|BT;android:drawable/xxx
- WIFI|USB|BT;android:drawable/xxx
-
- Notification will not show if the downstream type isn't listed in array.
- Empty array means disable notifications. -->
- <!-- In AOSP, hotspot is configured to no notification by default. Because status bar has showed
- an icon on the right side already -->
- <string-array translatable="false" name="tethering_notification_icons">
- <item>USB;com.android.networkstack.tethering:drawable/stat_sys_tether_usb</item>
- <item>BT;com.android.networkstack.tethering:drawable/stat_sys_tether_bluetooth</item>
- <item>WIFI|USB,WIFI|BT,USB|BT,WIFI|USB|BT;com.android.networkstack.tethering:drawable/stat_sys_tether_general</item>
- </string-array>
- <!-- String for tether enable notification title. -->
- <string name="tethering_notification_title">@string/tethered_notification_title</string>
- <!-- String for tether enable notification message. -->
- <string name="tethering_notification_message">@string/tethered_notification_message</string>
-
<!-- No upstream notification is shown when there is a downstream but no upstream that is able
to do the tethering. -->
<!-- Delay(millisecond) to show no upstream notification after there's no Backhaul. Set delay to
diff --git a/packages/Tethering/res/values/overlayable.xml b/packages/Tethering/res/values/overlayable.xml
index bbba3f30a292..16ae8ade19da 100644
--- a/packages/Tethering/res/values/overlayable.xml
+++ b/packages/Tethering/res/values/overlayable.xml
@@ -32,44 +32,6 @@
<item type="string" name="config_mobile_hotspot_provision_response"/>
<item type="integer" name="config_mobile_hotspot_provision_check_period"/>
<item type="string" name="config_wifi_tether_enable"/>
- <!-- Configuration values for TetheringNotificationUpdater -->
- <!-- Icons for showing tether enable notification.
- Each item should have two elements and be separated with ";".
-
- The first element is downstream types which is one of tethering. This element has to be
- made by WIFI, USB, BT, and OR'd with the others. Use "|" to combine multiple downstream
- types and use "," to separate each combinations. Such as
-
- USB|BT,WIFI|USB|BT
-
- The second element is icon for the item. This element has to be composed by
- <package name>:drawable/<resource name>. Such as
-
- 1. com.android.networkstack.tethering:drawable/stat_sys_tether_general
- 2. android:drawable/xxx
-
- So the entire string of each item would be
-
- USB|BT,WIFI|USB|BT;com.android.networkstack.tethering:drawable/stat_sys_tether_general
-
- NOTE: One config can be separated into two or more for readability. Such as
-
- WIFI|USB,WIFI|BT,USB|BT,WIFI|USB|BT;android:drawable/xxx
-
- can be separated into
-
- WIFI|USB;android:drawable/xxx
- WIFI|BT;android:drawable/xxx
- USB|BT;android:drawable/xxx
- WIFI|USB|BT;android:drawable/xxx
-
- Notification will not show if the downstream type isn't listed in array.
- Empty array means disable notifications. -->
- <item type="array" name="tethering_notification_icons"/>
- <!-- String for tether enable notification title. -->
- <item type="string" name="tethering_notification_title"/>
- <!-- String for tether enable notification message. -->
- <item type="string" name="tethering_notification_message"/>
<!-- Params from config.xml that can be overlaid -->
</policy>
</overlayable>
diff --git a/packages/Tethering/res/values/strings.xml b/packages/Tethering/res/values/strings.xml
index 4fa60d412566..d63c7c5063cc 100644
--- a/packages/Tethering/res/values/strings.xml
+++ b/packages/Tethering/res/values/strings.xml
@@ -19,9 +19,6 @@
<string name="tethered_notification_title">Tethering or hotspot active</string>
<!-- String for tethered notification message [CHAR LIMIT=200] -->
<string name="tethered_notification_message">Tap to set up.</string>
- <!-- String for tethered notification title with client number info. -->
- <plurals name="tethered_notification_title_with_client_number">
- </plurals>
<!-- This notification is shown when tethering has been disabled on a user's device.
The device is managed by the user's employer. Tethering can't be turned on unless the
@@ -47,6 +44,4 @@
<string name="upstream_roaming_notification_title"></string>
<!-- String for cellular roaming notification message [CHAR LIMIT=500] -->
<string name="upstream_roaming_notification_message"></string>
- <!-- String for cellular roaming notification continue button [CHAR LIMIT=200] -->
- <string name="upstream_roaming_notification_continue_button"></string>
</resources>
diff --git a/packages/Tethering/src/com/android/networkstack/tethering/OffloadHardwareInterface.java b/packages/Tethering/src/com/android/networkstack/tethering/OffloadHardwareInterface.java
index 85a23fb83fb2..55344fc75d65 100644
--- a/packages/Tethering/src/com/android/networkstack/tethering/OffloadHardwareInterface.java
+++ b/packages/Tethering/src/com/android/networkstack/tethering/OffloadHardwareInterface.java
@@ -142,7 +142,7 @@ public class OffloadHardwareInterface {
public boolean initOffloadConfig() {
IOffloadConfig offloadConfig;
try {
- offloadConfig = IOffloadConfig.getService();
+ offloadConfig = IOffloadConfig.getService(true /*retry*/);
} catch (RemoteException e) {
mLog.e("getIOffloadConfig error " + e);
return false;
diff --git a/packages/Tethering/src/com/android/networkstack/tethering/TetheringNotificationUpdater.java b/packages/Tethering/src/com/android/networkstack/tethering/TetheringNotificationUpdater.java
index f490cc4719fa..7fd6b61ccdbe 100644
--- a/packages/Tethering/src/com/android/networkstack/tethering/TetheringNotificationUpdater.java
+++ b/packages/Tethering/src/com/android/networkstack/tethering/TetheringNotificationUpdater.java
@@ -17,9 +17,6 @@
package com.android.networkstack.tethering;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING;
-import static android.net.TetheringManager.TETHERING_BLUETOOTH;
-import static android.net.TetheringManager.TETHERING_USB;
-import static android.net.TetheringManager.TETHERING_WIFI;
import static android.text.TextUtils.isEmpty;
import android.app.Notification;
@@ -39,10 +36,8 @@ import android.os.UserHandle;
import android.provider.Settings;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
-import android.util.Log;
import android.util.SparseArray;
-import androidx.annotation.ArrayRes;
import androidx.annotation.DrawableRes;
import androidx.annotation.IntDef;
import androidx.annotation.IntRange;
@@ -77,9 +72,6 @@ public class TetheringNotificationUpdater {
private static final boolean NO_NOTIFY = false;
@VisibleForTesting
static final int EVENT_SHOW_NO_UPSTREAM = 1;
- // Id to update and cancel enable notification. Must be unique within the tethering app.
- @VisibleForTesting
- static final int ENABLE_NOTIFICATION_ID = 1000;
// Id to update and cancel restricted notification. Must be unique within the tethering app.
@VisibleForTesting
static final int RESTRICTED_NOTIFICATION_ID = 1001;
@@ -120,7 +112,6 @@ public class TetheringNotificationUpdater {
@Retention(RetentionPolicy.SOURCE)
@IntDef(value = {
- ENABLE_NOTIFICATION_ID,
RESTRICTED_NOTIFICATION_ID,
NO_UPSTREAM_NOTIFICATION_ID,
ROAMING_NOTIFICATION_ID
@@ -223,7 +214,6 @@ public class TetheringNotificationUpdater {
final boolean tetheringActiveChanged =
(downstreamTypes == DOWNSTREAM_NONE) != (mDownstreamTypesMask == DOWNSTREAM_NONE);
final boolean subIdChanged = subId != mActiveDataSubId;
- final boolean downstreamChanged = downstreamTypes != mDownstreamTypesMask;
final boolean upstreamChanged = noUpstream != mNoUpstream;
final boolean roamingChanged = isRoaming != mRoaming;
final boolean updateAll = tetheringActiveChanged || subIdChanged;
@@ -232,19 +222,10 @@ public class TetheringNotificationUpdater {
mNoUpstream = noUpstream;
mRoaming = isRoaming;
- if (updateAll || downstreamChanged) updateEnableNotification();
if (updateAll || upstreamChanged) updateNoUpstreamNotification();
if (updateAll || roamingChanged) updateRoamingNotification();
}
- private void updateEnableNotification() {
- final boolean tetheringInactive = mDownstreamTypesMask == DOWNSTREAM_NONE;
-
- if (tetheringInactive || setupNotification() == NO_NOTIFY) {
- clearNotification(ENABLE_NOTIFICATION_ID);
- }
- }
-
private void updateNoUpstreamNotification() {
final boolean tetheringInactive = mDownstreamTypesMask == DOWNSTREAM_NONE;
@@ -310,64 +291,6 @@ public class TetheringNotificationUpdater {
NO_UPSTREAM_NOTIFICATION_ID, null /* pendingIntent */, action);
}
- /**
- * Returns the downstream types mask which convert from given string.
- *
- * @param types This string has to be made by "WIFI", "USB", "BT", and OR'd with the others.
- *
- * @return downstream types mask value.
- */
- @VisibleForTesting
- @IntRange(from = 0, to = 7)
- int getDownstreamTypesMask(@NonNull final String types) {
- int downstreamTypesMask = DOWNSTREAM_NONE;
- final String[] downstreams = types.split("\\|");
- for (String downstream : downstreams) {
- if (USB_DOWNSTREAM.equals(downstream.trim())) {
- downstreamTypesMask |= (1 << TETHERING_USB);
- } else if (WIFI_DOWNSTREAM.equals(downstream.trim())) {
- downstreamTypesMask |= (1 << TETHERING_WIFI);
- } else if (BLUETOOTH_DOWNSTREAM.equals(downstream.trim())) {
- downstreamTypesMask |= (1 << TETHERING_BLUETOOTH);
- }
- }
- return downstreamTypesMask;
- }
-
- /**
- * Returns the icons {@link android.util.SparseArray} which get from given string-array resource
- * id.
- *
- * @param id String-array resource id
- *
- * @return {@link android.util.SparseArray} with downstream types and icon id info.
- */
- @NonNull
- @VisibleForTesting
- SparseArray<Integer> getIcons(@ArrayRes int id, @NonNull Resources res) {
- final String[] array = res.getStringArray(id);
- final SparseArray<Integer> icons = new SparseArray<>();
- for (String config : array) {
- if (isEmpty(config)) continue;
-
- final String[] elements = config.split(";");
- if (elements.length != 2) {
- Log.wtf(TAG,
- "Unexpected format in Tethering notification configuration : " + config);
- continue;
- }
-
- final String[] types = elements[0].split(",");
- for (String type : types) {
- int mask = getDownstreamTypesMask(type);
- if (mask == DOWNSTREAM_NONE) continue;
- icons.put(mask, res.getIdentifier(
- elements[1].trim(), null /* defType */, null /* defPackage */));
- }
- }
- return icons;
- }
-
private boolean setupRoamingNotification() {
final Resources res = getResourcesForSubId(mContext, mActiveDataSubId);
final boolean upstreamRoamingNotification =
@@ -403,29 +326,6 @@ public class TetheringNotificationUpdater {
return NOTIFY_DONE;
}
- private boolean setupNotification() {
- final Resources res = getResourcesForSubId(mContext, mActiveDataSubId);
- final SparseArray<Integer> downstreamIcons =
- getIcons(R.array.tethering_notification_icons, res);
-
- final int iconId = downstreamIcons.get(mDownstreamTypesMask, NO_ICON_ID);
- if (iconId == NO_ICON_ID) return NO_NOTIFY;
-
- final String title = res.getString(R.string.tethering_notification_title);
- final String message = res.getString(R.string.tethering_notification_message);
- if (isEmpty(title) || isEmpty(message)) return NO_NOTIFY;
-
- final PendingIntent pi = PendingIntent.getActivity(
- mContext.createContextAsUser(UserHandle.CURRENT, 0 /* flags */),
- 0 /* requestCode */,
- new Intent(Settings.ACTION_TETHER_SETTINGS),
- Intent.FLAG_ACTIVITY_NEW_TASK,
- null /* options */);
-
- showNotification(iconId, title, message, ENABLE_NOTIFICATION_ID, pi, new Action[0]);
- return NOTIFY_DONE;
- }
-
private void showNotification(@DrawableRes final int iconId, @NonNull final String title,
@NonNull final String message, @NotificationId final int id, @Nullable PendingIntent pi,
@NonNull final Action... actions) {
diff --git a/packages/Tethering/tests/integration/Android.bp b/packages/Tethering/tests/integration/Android.bp
index 6b751afdf58b..3305ed084481 100644
--- a/packages/Tethering/tests/integration/Android.bp
+++ b/packages/Tethering/tests/integration/Android.bp
@@ -69,6 +69,7 @@ android_test {
test_config: "AndroidTest_Coverage.xml",
defaults: ["libnetworkstackutilsjni_deps"],
static_libs: [
+ "NetworkStaticLibTestsLib",
"NetworkStackTestsLib",
"TetheringTestsLib",
"TetheringIntegrationTestsLib",
diff --git a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringNotificationUpdaterTest.kt b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringNotificationUpdaterTest.kt
index 04f31a7a2880..745468fdf378 100644
--- a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringNotificationUpdaterTest.kt
+++ b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringNotificationUpdaterTest.kt
@@ -20,8 +20,6 @@ import android.app.Notification
import android.app.NotificationManager
import android.content.Context
import android.content.res.Resources
-import android.net.ConnectivityManager.TETHERING_BLUETOOTH
-import android.net.ConnectivityManager.TETHERING_USB
import android.net.ConnectivityManager.TETHERING_WIFI
import android.os.Handler
import android.os.HandlerThread
@@ -29,14 +27,12 @@ import android.os.Looper
import android.net.NetworkCapabilities
import android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING
import android.os.UserHandle
-import android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID
import android.telephony.TelephonyManager
import androidx.test.filters.SmallTest
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.runner.AndroidJUnit4
import com.android.internal.util.test.BroadcastInterceptingContext
import com.android.networkstack.tethering.TetheringNotificationUpdater.DOWNSTREAM_NONE
-import com.android.networkstack.tethering.TetheringNotificationUpdater.ENABLE_NOTIFICATION_ID
import com.android.networkstack.tethering.TetheringNotificationUpdater.EVENT_SHOW_NO_UPSTREAM
import com.android.networkstack.tethering.TetheringNotificationUpdater.NO_UPSTREAM_NOTIFICATION_ID
import com.android.networkstack.tethering.TetheringNotificationUpdater.RESTRICTED_NOTIFICATION_ID
@@ -63,17 +59,9 @@ import org.mockito.Mockito.verifyZeroInteractions
import org.mockito.MockitoAnnotations
const val TEST_SUBID = 1
-const val WIFI_ICON_ID = 1
-const val USB_ICON_ID = 2
-const val BT_ICON_ID = 3
-const val GENERAL_ICON_ID = 4
const val WIFI_MASK = 1 shl TETHERING_WIFI
-const val USB_MASK = 1 shl TETHERING_USB
-const val BT_MASK = 1 shl TETHERING_BLUETOOTH
-const val TITLE = "Tethering active"
-const val MESSAGE = "Tap here to set up."
-const val TEST_TITLE = "Hotspot active"
-const val TEST_MESSAGE = "Tap to set up hotspot."
+const val TEST_DISALLOW_TITLE = "Tether function is disallowed"
+const val TEST_DISALLOW_MESSAGE = "Please contact your admin"
const val TEST_NO_UPSTREAM_TITLE = "Hotspot has no internet access"
const val TEST_NO_UPSTREAM_MESSAGE = "Device cannot connect to internet."
const val TEST_NO_UPSTREAM_BUTTON = "Turn off hotspot"
@@ -88,7 +76,6 @@ class TetheringNotificationUpdaterTest {
@Mock private lateinit var mockContext: Context
@Mock private lateinit var notificationManager: NotificationManager
@Mock private lateinit var telephonyManager: TelephonyManager
- @Mock private lateinit var defaultResources: Resources
@Mock private lateinit var testResources: Resources
// lateinit for these classes under test, as they should be reset to a different instance for
@@ -97,11 +84,6 @@ class TetheringNotificationUpdaterTest {
private lateinit var notificationUpdater: TetheringNotificationUpdater
private lateinit var fakeTetheringThread: HandlerThread
- private val ENABLE_ICON_CONFIGS = arrayOf(
- "USB;android.test:drawable/usb", "BT;android.test:drawable/bluetooth",
- "WIFI|BT;android.test:drawable/general", "WIFI|USB;android.test:drawable/general",
- "USB|BT;android.test:drawable/general", "WIFI|USB|BT;android.test:drawable/general")
-
private val ROAMING_CAPABILITIES = NetworkCapabilities()
private val HOME_CAPABILITIES = NetworkCapabilities().addCapability(NET_CAPABILITY_NOT_ROAMING)
private val NOTIFICATION_ICON_ID = R.drawable.stat_sys_tether_general
@@ -117,29 +99,19 @@ class TetheringNotificationUpdaterTest {
private inner class WrappedNotificationUpdater(c: Context, looper: Looper)
: TetheringNotificationUpdater(c, looper) {
- override fun getResourcesForSubId(context: Context, subId: Int) =
- when (subId) {
- TEST_SUBID -> testResources
- INVALID_SUBSCRIPTION_ID -> defaultResources
- else -> super.getResourcesForSubId(context, subId)
- }
+ override fun getResourcesForSubId(c: Context, subId: Int) =
+ if (subId == TEST_SUBID) testResources else super.getResourcesForSubId(c, subId)
}
private fun setupResources() {
- doReturn(ENABLE_ICON_CONFIGS).`when`(defaultResources)
- .getStringArray(R.array.tethering_notification_icons)
- doReturn(arrayOf("WIFI;android.test:drawable/wifi")).`when`(testResources)
- .getStringArray(R.array.tethering_notification_icons)
doReturn(5).`when`(testResources)
.getInteger(R.integer.delay_to_show_no_upstream_after_no_backhaul)
doReturn(true).`when`(testResources)
.getBoolean(R.bool.config_upstream_roaming_notification)
- doReturn(TITLE).`when`(defaultResources).getString(R.string.tethering_notification_title)
- doReturn(MESSAGE).`when`(defaultResources)
- .getString(R.string.tethering_notification_message)
- doReturn(TEST_TITLE).`when`(testResources).getString(R.string.tethering_notification_title)
- doReturn(TEST_MESSAGE).`when`(testResources)
- .getString(R.string.tethering_notification_message)
+ doReturn(TEST_DISALLOW_TITLE).`when`(testResources)
+ .getString(R.string.disable_tether_notification_title)
+ doReturn(TEST_DISALLOW_MESSAGE).`when`(testResources)
+ .getString(R.string.disable_tether_notification_message)
doReturn(TEST_NO_UPSTREAM_TITLE).`when`(testResources)
.getString(R.string.no_upstream_notification_title)
doReturn(TEST_NO_UPSTREAM_MESSAGE).`when`(testResources)
@@ -150,14 +122,6 @@ class TetheringNotificationUpdaterTest {
.getString(R.string.upstream_roaming_notification_title)
doReturn(TEST_ROAMING_MESSAGE).`when`(testResources)
.getString(R.string.upstream_roaming_notification_message)
- doReturn(USB_ICON_ID).`when`(defaultResources)
- .getIdentifier(eq("android.test:drawable/usb"), any(), any())
- doReturn(BT_ICON_ID).`when`(defaultResources)
- .getIdentifier(eq("android.test:drawable/bluetooth"), any(), any())
- doReturn(GENERAL_ICON_ID).`when`(defaultResources)
- .getIdentifier(eq("android.test:drawable/general"), any(), any())
- doReturn(WIFI_ICON_ID).`when`(testResources)
- .getIdentifier(eq("android.test:drawable/wifi"), any(), any())
}
@Before
@@ -206,119 +170,27 @@ class TetheringNotificationUpdaterTest {
}
@Test
- fun testNotificationWithDownstreamChanged() {
- // Wifi downstream. No notification.
- notificationUpdater.onDownstreamChanged(WIFI_MASK)
- verifyNotificationCancelled(listOf(ENABLE_NOTIFICATION_ID))
-
- // Same downstream changed. Nothing happened.
- notificationUpdater.onDownstreamChanged(WIFI_MASK)
- verifyZeroInteractions(notificationManager)
-
- // Wifi and usb downstreams. Show enable notification
- notificationUpdater.onDownstreamChanged(WIFI_MASK or USB_MASK)
- verifyNotification(GENERAL_ICON_ID, TITLE, MESSAGE, ENABLE_NOTIFICATION_ID)
-
- // Usb downstream. Still show enable notification.
- notificationUpdater.onDownstreamChanged(USB_MASK)
- verifyNotification(USB_ICON_ID, TITLE, MESSAGE, ENABLE_NOTIFICATION_ID)
-
- // No downstream. No notification.
- notificationUpdater.onDownstreamChanged(DOWNSTREAM_NONE)
- verifyNotificationCancelled(listOf(ENABLE_NOTIFICATION_ID, NO_UPSTREAM_NOTIFICATION_ID,
- ROAMING_NOTIFICATION_ID))
- }
-
- @Test
- fun testNotificationWithActiveDataSubscriptionIdChanged() {
- // Usb downstream. Showed enable notification with default resource.
- notificationUpdater.onDownstreamChanged(USB_MASK)
- verifyNotification(USB_ICON_ID, TITLE, MESSAGE, ENABLE_NOTIFICATION_ID)
-
- // Same subId changed. Nothing happened.
- notificationUpdater.onActiveDataSubscriptionIdChanged(INVALID_SUBSCRIPTION_ID)
- verifyZeroInteractions(notificationManager)
-
- // Set test sub id. Clear notification with test resource.
+ fun testRestrictedNotification() {
+ // Set test sub id.
notificationUpdater.onActiveDataSubscriptionIdChanged(TEST_SUBID)
- verifyNotificationCancelled(listOf(ENABLE_NOTIFICATION_ID, NO_UPSTREAM_NOTIFICATION_ID,
- ROAMING_NOTIFICATION_ID))
-
- // Wifi downstream. Show enable notification with test resource.
- notificationUpdater.onDownstreamChanged(WIFI_MASK)
- verifyNotification(WIFI_ICON_ID, TEST_TITLE, TEST_MESSAGE, ENABLE_NOTIFICATION_ID)
-
- // No downstream. No notification.
- notificationUpdater.onDownstreamChanged(DOWNSTREAM_NONE)
- verifyNotificationCancelled(listOf(ENABLE_NOTIFICATION_ID, NO_UPSTREAM_NOTIFICATION_ID,
- ROAMING_NOTIFICATION_ID))
- }
-
- private fun assertIconNumbers(number: Int, configs: Array<String?>) {
- doReturn(configs).`when`(defaultResources)
- .getStringArray(R.array.tethering_notification_icons)
- assertEquals(number, notificationUpdater.getIcons(
- R.array.tethering_notification_icons, defaultResources).size())
- }
-
- @Test
- fun testGetIcons() {
- assertIconNumbers(0, arrayOfNulls<String>(0))
- assertIconNumbers(0, arrayOf(null, ""))
- assertIconNumbers(3, arrayOf(
- // These configurations are invalid with wrong strings or symbols.
- ";", ",", "|", "|,;", "WIFI", "1;2", " U SB; ", "bt;", "WIFI;USB;BT", "WIFI|USB|BT",
- "WIFI,BT,USB", " WIFI| | | USB, test:drawable/test",
- // This configuration is valid with two downstream types (USB, BT).
- "USB|,,,,,|BT;drawable/test ",
- // This configuration is valid with one downstream types (WIFI).
- " WIFI ; android.test:drawable/xxx "))
- }
-
- @Test
- fun testGetDownstreamTypesMask() {
- assertEquals(DOWNSTREAM_NONE, notificationUpdater.getDownstreamTypesMask(""))
- assertEquals(DOWNSTREAM_NONE, notificationUpdater.getDownstreamTypesMask("1"))
- assertEquals(DOWNSTREAM_NONE, notificationUpdater.getDownstreamTypesMask("WIFI_P2P"))
- assertEquals(DOWNSTREAM_NONE, notificationUpdater.getDownstreamTypesMask("usb"))
- assertEquals(WIFI_MASK, notificationUpdater.getDownstreamTypesMask(" WIFI "))
- assertEquals(USB_MASK, notificationUpdater.getDownstreamTypesMask("USB | B T"))
- assertEquals(BT_MASK, notificationUpdater.getDownstreamTypesMask(" WIFI: | BT"))
- assertEquals(WIFI_MASK or USB_MASK,
- notificationUpdater.getDownstreamTypesMask("1|2|USB|WIFI|BLUETOOTH||"))
- }
-
- @Test
- fun testSetupRestrictedNotification() {
- val title = context.resources.getString(R.string.disable_tether_notification_title)
- val message = context.resources.getString(R.string.disable_tether_notification_message)
- val disallowTitle = "Tether function is disallowed"
- val disallowMessage = "Please contact your admin"
- doReturn(title).`when`(defaultResources)
- .getString(R.string.disable_tether_notification_title)
- doReturn(message).`when`(defaultResources)
- .getString(R.string.disable_tether_notification_message)
- doReturn(disallowTitle).`when`(testResources)
- .getString(R.string.disable_tether_notification_title)
- doReturn(disallowMessage).`when`(testResources)
- .getString(R.string.disable_tether_notification_message)
+ verifyNotificationCancelled(listOf(NO_UPSTREAM_NOTIFICATION_ID, ROAMING_NOTIFICATION_ID))
// User restrictions on. Show restricted notification.
notificationUpdater.notifyTetheringDisabledByRestriction()
- verifyNotification(NOTIFICATION_ICON_ID, title, message, RESTRICTED_NOTIFICATION_ID)
+ verifyNotification(NOTIFICATION_ICON_ID, TEST_DISALLOW_TITLE, TEST_DISALLOW_MESSAGE,
+ RESTRICTED_NOTIFICATION_ID)
// User restrictions off. Clear notification.
notificationUpdater.tetheringRestrictionLifted()
verifyNotificationCancelled(listOf(RESTRICTED_NOTIFICATION_ID))
- // Set test sub id. No notification.
- notificationUpdater.onActiveDataSubscriptionIdChanged(TEST_SUBID)
- verifyNotificationCancelled(listOf(ENABLE_NOTIFICATION_ID, NO_UPSTREAM_NOTIFICATION_ID,
- ROAMING_NOTIFICATION_ID))
+ // No downstream.
+ notificationUpdater.onDownstreamChanged(DOWNSTREAM_NONE)
+ verifyZeroInteractions(notificationManager)
- // User restrictions on again. Show restricted notification with test resource.
+ // User restrictions on again. Show restricted notification.
notificationUpdater.notifyTetheringDisabledByRestriction()
- verifyNotification(NOTIFICATION_ICON_ID, disallowTitle, disallowMessage,
+ verifyNotification(NOTIFICATION_ICON_ID, TEST_DISALLOW_TITLE, TEST_DISALLOW_MESSAGE,
RESTRICTED_NOTIFICATION_ID)
}
@@ -356,15 +228,14 @@ class TetheringNotificationUpdaterTest {
}
@Test
- fun testNotificationWithUpstreamCapabilitiesChanged_NoUpstream() {
- // Set test sub id. No notification.
+ fun testNoUpstreamNotification() {
+ // Set test sub id.
notificationUpdater.onActiveDataSubscriptionIdChanged(TEST_SUBID)
- verifyNotificationCancelled(listOf(ENABLE_NOTIFICATION_ID, NO_UPSTREAM_NOTIFICATION_ID,
- ROAMING_NOTIFICATION_ID))
+ verifyNotificationCancelled(listOf(NO_UPSTREAM_NOTIFICATION_ID, ROAMING_NOTIFICATION_ID))
- // Wifi downstream. Show enable notification with test resource.
+ // Wifi downstream.
notificationUpdater.onDownstreamChanged(WIFI_MASK)
- verifyNotification(WIFI_ICON_ID, TEST_TITLE, TEST_MESSAGE, ENABLE_NOTIFICATION_ID)
+ verifyNotificationCancelled(listOf(NO_UPSTREAM_NOTIFICATION_ID, ROAMING_NOTIFICATION_ID))
// There is no upstream. Show no upstream notification.
notificationUpdater.onUpstreamCapabilitiesChanged(null)
@@ -386,15 +257,14 @@ class TetheringNotificationUpdaterTest {
verifyNotification(NOTIFICATION_ICON_ID, TEST_NO_UPSTREAM_TITLE, TEST_NO_UPSTREAM_MESSAGE,
NO_UPSTREAM_NOTIFICATION_ID)
- // No downstream. No notification.
+ // No downstream.
notificationUpdater.onDownstreamChanged(DOWNSTREAM_NONE)
- verifyNotificationCancelled(listOf(ENABLE_NOTIFICATION_ID, NO_UPSTREAM_NOTIFICATION_ID,
- ROAMING_NOTIFICATION_ID))
+ verifyNotificationCancelled(listOf(NO_UPSTREAM_NOTIFICATION_ID, ROAMING_NOTIFICATION_ID))
- // Put up enable notification with wifi downstream and home capabilities.
+ // Wifi downstream and home capabilities.
notificationUpdater.onDownstreamChanged(WIFI_MASK)
notificationUpdater.onUpstreamCapabilitiesChanged(HOME_CAPABILITIES)
- verifyNotification(WIFI_ICON_ID, TEST_TITLE, TEST_MESSAGE, ENABLE_NOTIFICATION_ID)
+ verifyNotificationCancelled(listOf(NO_UPSTREAM_NOTIFICATION_ID, ROAMING_NOTIFICATION_ID))
// Set R.integer.delay_to_show_no_upstream_after_no_backhaul to -1 and change to no upstream
// again. Don't put up no upstream notification.
@@ -429,15 +299,14 @@ class TetheringNotificationUpdaterTest {
}
@Test
- fun testNotificationWithUpstreamCapabilitiesChanged_Roaming() {
- // Set test sub id. Clear notification.
+ fun testRoamingNotification() {
+ // Set test sub id.
notificationUpdater.onActiveDataSubscriptionIdChanged(TEST_SUBID)
- verifyNotificationCancelled(listOf(ENABLE_NOTIFICATION_ID, NO_UPSTREAM_NOTIFICATION_ID,
- ROAMING_NOTIFICATION_ID))
+ verifyNotificationCancelled(listOf(NO_UPSTREAM_NOTIFICATION_ID, ROAMING_NOTIFICATION_ID))
- // Wifi downstream. Show enable notification with test resource.
+ // Wifi downstream.
notificationUpdater.onDownstreamChanged(WIFI_MASK)
- verifyNotification(WIFI_ICON_ID, TEST_TITLE, TEST_MESSAGE, ENABLE_NOTIFICATION_ID)
+ verifyNotificationCancelled(listOf(NO_UPSTREAM_NOTIFICATION_ID, ROAMING_NOTIFICATION_ID))
// Upstream capabilities changed to roaming state. Show roaming notification.
notificationUpdater.onUpstreamCapabilitiesChanged(ROAMING_CAPABILITIES)
@@ -464,14 +333,16 @@ class TetheringNotificationUpdaterTest {
verifyNotification(NOTIFICATION_ICON_ID, TEST_NO_UPSTREAM_TITLE, TEST_NO_UPSTREAM_MESSAGE,
NO_UPSTREAM_NOTIFICATION_ID)
- // No downstream. No notification.
+ // No downstream.
notificationUpdater.onDownstreamChanged(DOWNSTREAM_NONE)
- verifyNotificationCancelled(listOf(ENABLE_NOTIFICATION_ID, NO_UPSTREAM_NOTIFICATION_ID,
- ROAMING_NOTIFICATION_ID))
+ verifyNotificationCancelled(listOf(NO_UPSTREAM_NOTIFICATION_ID, ROAMING_NOTIFICATION_ID))
- // Wifi downstream again. Show enable notification with test resource.
+ // Wifi downstream again.
notificationUpdater.onDownstreamChanged(WIFI_MASK)
- verifyNotification(WIFI_ICON_ID, TEST_TITLE, TEST_MESSAGE, ENABLE_NOTIFICATION_ID)
+ notificationUpdater.handler.waitForDelayedMessage(EVENT_SHOW_NO_UPSTREAM, TIMEOUT_MS)
+ verifyNotificationCancelled(listOf(ROAMING_NOTIFICATION_ID), false)
+ verifyNotification(NOTIFICATION_ICON_ID, TEST_NO_UPSTREAM_TITLE, TEST_NO_UPSTREAM_MESSAGE,
+ NO_UPSTREAM_NOTIFICATION_ID)
// Set R.bool.config_upstream_roaming_notification to false and change upstream
// network to roaming state again. No roaming notification.
diff --git a/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_corp.xml b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_corp.xml
index b0001462bfff..a05a38996ed8 100644
--- a/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_corp.xml
+++ b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_corp.xml
@@ -1,29 +1,26 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2019 The Android Open Source Project
+<!-- Copyright (C) 2020 The Android Open Source Project
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
+ 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
+ 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.
+ 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:tint="?android:attr/textColorHint"
- android:viewportHeight="24"
android:viewportWidth="24"
- android:width="24dp" >
- <path
- android:fillColor="@android:color/white"
- android:pathData="M16,4c0-1.1-0.9-2-2-2h-4C8.9,2,8,2.9,8,4v2H2v12c0,1.7,1.3,3,3,3h14c1.7,0,3-1.3,3-3V6h-6V4z M9.5,4 c0-0.3,0.2-0.5,0.5-0.5h4c0.3,0,0.5,0.2,0.5,0.5v2h-5V4z M20.5,7.5V18c0,0.8-0.7,1.5-1.5,1.5H5c-0.8,0-1.5-0.7-1.5-1.5V7.5H20.5z" />
- <path
- android:fillColor="@android:color/white"
- android:pathData="M 12 12.3 C 12.6627416998 12.3 13.2 12.8372583002 13.2 13.5 C 13.2 14.1627416998 12.6627416998 14.7 12 14.7 C 11.3372583002 14.7 10.8 14.1627416998 10.8 13.5 C 10.8 12.8372583002 11.3372583002 12.3 12 12.3 Z" />
+ android:viewportHeight="24">
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M19.75,6H16c0,0 0,0 0,0c0,-2.05 -0.95,-4 -4,-4C8.96,2 8,3.97 8,6c0,0 0,0 0,0H4.25C3.01,6 2,7.01 2,8.25v10.5C2,19.99 3.01,21 4.25,21h15.5c1.24,0 2.25,-1.01 2.25,-2.25V8.25C22,7.01 20.99,6 19.75,6zM12,3.5c0.54,-0.01 2.5,-0.11 2.5,2.5c0,0 0,0 0,0h-5c0,0 0,0 0,0C9.5,3.39 11.45,3.48 12,3.5zM20.5,18.75c0,0.41 -0.34,0.75 -0.75,0.75H4.25c-0.41,0 -0.75,-0.34 -0.75,-0.75V8.25c0,-0.41 0.34,-0.75 0.75,-0.75h15.5c0.41,0 0.75,0.34 0.75,0.75V18.75z"/>
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M12,12c-0.05,0 -1.5,-0.09 -1.5,1.5c0,1.59 1.43,1.5 1.5,1.5c0.05,0 1.5,0.09 1.5,-1.5C13.5,11.91 12.07,12 12,12z"/>
</vector> \ No newline at end of file
diff --git a/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_corp_off.xml b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_corp_off.xml
new file mode 100644
index 000000000000..a8102519361b
--- /dev/null
+++ b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_corp_off.xml
@@ -0,0 +1,26 @@
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M19.5,19.5l-6,-6L12,12L7.5,7.5L6,6L2.81,2.81L1.75,3.87l2.17,2.17C2.83,6.2 2,7.12 2,8.25v10.5C2,19.99 3.01,21 4.25,21h14.63l1.25,1.25l1.06,-1.06l-0.44,-0.44L19.5,19.5zM4.25,19.5c-0.41,0 -0.75,-0.34 -0.75,-0.75V8.25c0,-0.41 0.34,-0.75 0.75,-0.75h1.13l5.27,5.27c-0.09,0.19 -0.15,0.42 -0.15,0.73c0,1.59 1.43,1.5 1.5,1.5c0.02,0 0.38,0.02 0.74,-0.14l4.64,4.64H4.25z"/>
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M9.62,7.5h10.13c0.41,0 0.75,0.34 0.75,0.75v10.13l1.28,1.28c0.13,-0.28 0.22,-0.58 0.22,-0.91V8.25C22,7.01 20.99,6 19.75,6H16c0,0 0,0 0,0c0,-2.05 -0.95,-4 -4,-4C9.01,2 8.04,3.9 8.01,5.89L9.62,7.5zM12,3.5c0.54,-0.01 2.5,-0.11 2.5,2.5c0,0 0,0 0,0h-5c0,0 0,0 0,0C9.5,3.39 11.45,3.48 12,3.5z"/>
+</vector>
diff --git a/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_screenshot.xml b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_screenshot.xml
new file mode 100644
index 000000000000..e8608a598fbf
--- /dev/null
+++ b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_screenshot.xml
@@ -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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M16.75,1h-9.5C6.01,1 5,2.01 5,3.25v17.5C5,21.99 6.01,23 7.25,23h9.5c1.24,0 2.25,-1.01 2.25,-2.25V3.25C19,2.01 17.99,1 16.75,1zM7.25,2.5h9.5c0.41,0 0.75,0.34 0.75,0.75v1h-11v-1C6.5,2.84 6.84,2.5 7.25,2.5zM17.5,5.75v12.5h-11V5.75H17.5zM16.75,21.5h-9.5c-0.41,0 -0.75,-0.34 -0.75,-0.75v-1h11v1C17.5,21.16 17.16,21.5 16.75,21.5z"/>
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M9.5,11V8.5H12V7H8.75C8.34,7 8,7.34 8,7.75V11H9.5z"/>
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M12,17h3.25c0.41,0 0.75,-0.34 0.75,-0.75V13h-1.5v2.5H12V17z"/>
+</vector>
diff --git a/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_select.xml b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_select.xml
new file mode 100644
index 000000000000..4e265fd9c5d5
--- /dev/null
+++ b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_select.xml
@@ -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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M11.25,1h1.5v3h-1.5z"/>
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M15.5983,5.3402l2.1213,-2.1213l1.0606,1.0606l-2.1213,2.1213z"/>
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M5.2187,4.2803l1.0606,-1.0606l2.1213,2.1213l-1.0606,1.0606z"/>
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M15.5,12.5l-1.25,0V8.12C14.25,6.95 13.3,6 12.12,6S10,6.95 10,8.12v7.9L8.03,15.5c-0.39,-0.1 -1.23,-0.36 -2.56,0.97c-0.29,0.29 -0.29,0.75 -0.01,1.05l3.79,3.98c0,0 0,0 0,0.01c1.37,1.41 3.28,1.51 4.04,1.49l2.2,0c2.12,0.06 5.25,-1.01 5.25,-5.25C20.75,13.19 17.23,12.46 15.5,12.5zM15.5,21.5l-2.25,0c-0.44,0.01 -1.93,-0.02 -2.92,-1.03l-3.27,-3.43c0.17,-0.1 0.38,-0.13 0.58,-0.08l2.91,0.78c0.47,0.12 0.94,-0.23 0.94,-0.72V8.12c0,-0.34 0.28,-0.62 0.62,-0.62s0.62,0.28 0.62,0.62v5.12c0,0.41 0.33,0.75 0.75,0.75l2.05,0c1.26,-0.03 3.7,0.37 3.7,3.75C19.25,21.14 16.78,21.53 15.5,21.5z"/>
+</vector>
diff --git a/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_share.xml b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_share.xml
new file mode 100644
index 000000000000..726d1aa5e1c2
--- /dev/null
+++ b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_share.xml
@@ -0,0 +1,39 @@
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M17.88,3.5l0.06,0l0.04,0H18l0.04,0l0.02,0l0.06,0c1.38,0 1.38,1.01 1.38,1.5s0,1.5 -1.38,1.5l-0.06,0l-0.04,0H18l-0.04,0l-0.02,0l-0.06,0C16.5,6.5 16.5,5.49 16.5,5S16.5,3.5 17.88,3.5M17.88,2C17.33,2 15,2.15 15,5c0,2.85 2.31,3 2.88,3c0.06,0 0.11,0 0.12,0c0.01,0 0.05,0 0.12,0C18.67,8 21,7.85 21,5c0,-2.85 -2.31,-3 -2.88,-3C18.06,2 18.01,2 18,2C17.99,2 17.95,2 17.88,2L17.88,2z"/>
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M17.88,17.5l0.06,0l0.04,0H18l0.04,0l0.02,0l0.06,0c1.38,0 1.38,1.01 1.38,1.5s0,1.5 -1.38,1.5l-0.06,0l-0.04,0H18l-0.04,0l-0.02,0l-0.06,0c-1.38,0 -1.38,-1.01 -1.38,-1.5S16.5,17.5 17.88,17.5M17.88,16C17.33,16 15,16.15 15,19c0,2.85 2.31,3 2.88,3c0.06,0 0.11,0 0.12,0c0.01,0 0.05,0 0.12,0c0.56,0 2.88,-0.15 2.88,-3c0,-2.85 -2.31,-3 -2.88,-3c-0.06,0 -0.11,0 -0.12,0C17.99,16 17.95,16 17.88,16L17.88,16z"/>
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M5.88,10.5l0.06,0l0.04,0H6l0.04,0l0.02,0l0.06,0c1.38,0 1.38,1.01 1.38,1.5s0,1.5 -1.38,1.5l-0.06,0l-0.04,0H6l-0.04,0l-0.02,0l-0.06,0C4.5,13.5 4.5,12.49 4.5,12S4.5,10.5 5.88,10.5M5.88,9C5.33,9 3,9.15 3,12c0,2.85 2.31,3 2.88,3c0.06,0 0.11,0 0.12,0c0.01,0 0.05,0 0.12,0C6.67,15 9,14.85 9,12c0,-2.85 -2.31,-3 -2.88,-3C6.06,9 6.01,9 6,9C5.99,9 5.95,9 5.88,9L5.88,9z"/>
+ <path
+ android:pathData="M16.01,6.16L8,10.83"
+ android:strokeWidth="1.5"
+ android:fillColor="#00000000"
+ android:strokeColor="#000000"/>
+ <path
+ android:pathData="M16.06,17.87L8.19,13.28"
+ android:strokeWidth="1.5"
+ android:fillColor="#00000000"
+ android:strokeColor="#000000"/>
+</vector>
diff --git a/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_corp.xml b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_corp.xml
index 7139313a9ef9..0dfaf8188f8d 100644
--- a/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_corp.xml
+++ b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_corp.xml
@@ -1,27 +1,23 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2019 The Android Open Source Project
+<!-- Copyright (C) 2020 The Android Open Source Project
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
+ 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
+ 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.
+ 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:tint="?android:attr/textColorHint"
- android:viewportHeight="24"
android:viewportWidth="24"
- android:width="24dp" >
- <path android:pathData="M 10 4 H 14 V 6 H 10 V 4 Z" />
- <path
- android:fillColor="@android:color/white"
- android:pathData="M20,6h-4V4c0-1.1-0.9-2-2-2h-4C8.9,2,8,2.9,8,4v2H4C2.9,6,2,6.9,2,8l0,11c0,1.1,0.9,2,2,2h16c1.1,0,2-0.9,2-2V8 C22,6.9,21.1,6,20,6z M12,15c-0.8,0-1.5-0.7-1.5-1.5S11.2,12,12,12s1.5,0.7,1.5,1.5S12.8,15,12,15z M14,6h-4V4h4V6z" />
-</vector> \ No newline at end of file
+ android:viewportHeight="24">
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M19,6h-3c0,-2.21 -1.79,-4 -4,-4S8,3.79 8,6H5C3.34,6 2,7.34 2,9v9c0,1.66 1.34,3 3,3h14c1.66,0 3,-1.34 3,-3V9C22,7.34 20.66,6 19,6zM12,15c-0.83,0 -1.5,-0.67 -1.5,-1.5S11.17,12 12,12s1.5,0.67 1.5,1.5S12.83,15 12,15zM10,6c0,-1.1 0.9,-2 2,-2s2,0.9 2,2H10z"/>
+</vector>
diff --git a/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_corp_off.xml b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_corp_off.xml
new file mode 100644
index 000000000000..b3f353a16943
--- /dev/null
+++ b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_corp_off.xml
@@ -0,0 +1,26 @@
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M21.81,18.98C21.92,18.67 22,18.35 22,18V9c0,-1.66 -1.34,-3 -3,-3h-3c0,-2.21 -1.79,-4 -4,-4c-1.95,0 -3.57,1.4 -3.92,3.24L21.81,18.98zM12,4c1.1,0 2,0.9 2,2h-4C10,4.9 10.9,4 12,4z"/>
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M20.56,20.55l-17,-17c0,0 0,0 0,0L3.45,3.44c-0.39,-0.39 -1.02,-0.39 -1.41,0s-0.39,1.02 0,1.41l1.53,1.53C2.64,6.89 2,7.87 2,9v9c0,1.66 1.34,3 3,3h13.18l0.96,0.96c0.2,0.2 0.45,0.29 0.71,0.29s0.51,-0.1 0.71,-0.29C20.94,21.57 20.94,20.94 20.56,20.55C20.56,20.55 20.56,20.55 20.56,20.55zM12,15c-0.83,0 -1.5,-0.67 -1.5,-1.5c0,-0.06 0.01,-0.11 0.02,-0.16l1.65,1.65C12.11,14.99 12.06,15 12,15z"/>
+</vector>
diff --git a/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_screenshot.xml b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_screenshot.xml
new file mode 100644
index 000000000000..1d291c93fb4d
--- /dev/null
+++ b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_screenshot.xml
@@ -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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M8.75,11c0.41,0 0.75,-0.34 0.75,-0.75V8.5h1.75C11.66,8.5 12,8.16 12,7.75C12,7.34 11.66,7 11.25,7H9C8.45,7 8,7.45 8,8v2.25C8,10.66 8.34,11 8.75,11z"/>
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M12.75,17H15c0.55,0 1,-0.45 1,-1v-2.25c0,-0.41 -0.34,-0.75 -0.75,-0.75s-0.75,0.34 -0.75,0.75v1.75h-1.75c-0.41,0 -0.75,0.34 -0.75,0.75C12,16.66 12.34,17 12.75,17z"/>
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M16,1H8C6.34,1 5,2.34 5,4v16c0,1.65 1.35,3 3,3h8c1.65,0 3,-1.35 3,-3V4C19,2.34 17.66,1 16,1zM17,18H7V6h10V18z"/>
+</vector>
diff --git a/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_select.xml b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_select.xml
new file mode 100644
index 000000000000..df4525d48777
--- /dev/null
+++ b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_select.xml
@@ -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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M17.59,5.83l0.71,-0.71c0.39,-0.39 0.39,-1.02 0,-1.41l0,0c-0.39,-0.39 -1.02,-0.39 -1.41,0l-0.71,0.71c-0.39,0.39 -0.39,1.02 0,1.41C16.56,6.21 17.2,6.21 17.59,5.83z"/>
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M12,4c0.55,0 1,-0.45 1,-1V2c0,-0.55 -0.45,-1 -1,-1s-1,0.45 -1,1v1C11,3.55 11.45,4 12,4z"/>
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M6.42,5.83c0.39,0.39 1.02,0.39 1.41,0c0.39,-0.39 0.39,-1.02 0,-1.41L7.12,3.71c-0.39,-0.39 -1.02,-0.39 -1.41,0l0,0c-0.39,0.39 -0.39,1.02 0,1.41L6.42,5.83z"/>
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M17.95,14.43l-3.23,-1.61c-0.42,-0.21 -0.88,-0.32 -1.34,-0.32H13v-5C13,6.67 12.33,6 11.5,6C10.67,6 10,6.67 10,7.5v9.12c0,0.32 -0.29,0.55 -0.6,0.49l-2.84,-0.6c-0.37,-0.08 -0.76,0.04 -1.03,0.31c-0.43,0.44 -0.43,1.14 0.01,1.58l3.71,3.71C9.81,22.68 10.58,23 11.37,23h4.82c1.49,0 2.76,-1.1 2.97,-2.58l0.41,-2.89C19.76,16.26 19.1,15.01 17.95,14.43z"/>
+</vector>
diff --git a/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_share.xml b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_share.xml
new file mode 100644
index 000000000000..89ee5274e48f
--- /dev/null
+++ b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_share.xml
@@ -0,0 +1,39 @@
+<!-- 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="M18,5L6,12"
+ android:strokeWidth="2"
+ android:fillColor="#00000000"
+ android:strokeColor="#000000"/>
+ <path
+ android:pathData="M18,19L6,12"
+ android:strokeWidth="2"
+ android:fillColor="#00000000"
+ android:strokeColor="#000000"/>
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M18,5m-3,0a3,3 0,1 1,6 0a3,3 0,1 1,-6 0"/>
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M18,19m-3,0a3,3 0,1 1,6 0a3,3 0,1 1,-6 0"/>
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M6,12m-3,0a3,3 0,1 1,6 0a3,3 0,1 1,-6 0"/>
+</vector>
diff --git a/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_corp.xml b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_corp.xml
index 38f515fdb22d..be31fb9171bf 100644
--- a/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_corp.xml
+++ b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_corp.xml
@@ -1,29 +1,26 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2019 The Android Open Source Project
+<!-- Copyright (C) 2020 The Android Open Source Project
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
+ 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
+ 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.
+ 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:tint="?android:attr/textColorHint"
- android:viewportHeight="24"
android:viewportWidth="24"
- android:width="24dp" >
- <path
- android:fillColor="@android:color/white"
- android:pathData="M20,6h-4V4c0-1.1-0.9-2-2-2h-4C8.9,2,8,2.9,8,4v2H4C2.9,6,2,6.9,2,8v11c0,1.1,0.9,2,2,2h16c1.1,0,2-0.9,2-2V8 C22,6.9,21.1,6,20,6z M9.5,4c0-0.3,0.2-0.5,0.5-0.5h4c0.3,0,0.5,0.2,0.5,0.5v2h-5V4z M20.5,19c0,0.3-0.2,0.5-0.5,0.5H4 c-0.3,0-0.5-0.2-0.5-0.5V8c0-0.3,0.2-0.5,0.5-0.5h16c0.3,0,0.5,0.2,0.5,0.5V19z" />
- <path
- android:fillColor="@android:color/white"
- android:pathData="M 12 12.3 C 12.6627416998 12.3 13.2 12.8372583002 13.2 13.5 C 13.2 14.1627416998 12.6627416998 14.7 12 14.7 C 11.3372583002 14.7 10.8 14.1627416998 10.8 13.5 C 10.8 12.8372583002 11.3372583002 12.3 12 12.3 Z" />
-</vector> \ No newline at end of file
+ android:viewportHeight="24">
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M20.59,6H16V3.41L14.59,2H9.41L8,3.41V6H3.41L2,7.41v12.17L3.41,21h17.17L22,19.59V7.41L20.59,6zM9.5,3.5h5V6h-5V3.5zM20.5,19.5h-17v-12h17V19.5z"/>
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M12,13.5m-1.5,0a1.5,1.5 0,1 1,3 0a1.5,1.5 0,1 1,-3 0"/>
+</vector>
diff --git a/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_corp_off.xml b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_corp_off.xml
new file mode 100644
index 000000000000..8d298f7cbc97
--- /dev/null
+++ b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_corp_off.xml
@@ -0,0 +1,26 @@
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M19.5,19.5l-6,-6L12,12L7.5,7.5L6,6L2.81,2.81L1.75,3.87L3.88,6H3.41L2,7.41v12.17L3.41,21h15.46l1.25,1.25l1.06,-1.06l-0.4,-0.4L19.5,19.5zM3.5,19.5v-12h1.88l5.3,5.3c-0.11,0.21 -0.18,0.44 -0.18,0.7c0,0.83 0.67,1.5 1.5,1.5c0.25,0 0.49,-0.07 0.7,-0.18l4.68,4.68H3.5z"/>
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M9.62,7.5H20.5v10.88l1.35,1.35L22,19.59V7.41L20.59,6H16V3.41L14.59,2H9.41L8,3.41v2.46L9.62,7.5zM9.5,3.5h5V6h-5V3.5z"/>
+</vector>
diff --git a/packages/Tethering/res/values-mcc310-mnc120/strings.xml b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_screenshot.xml
index 618df90c7105..ed90b85c8b87 100644
--- a/packages/Tethering/res/values-mcc310-mnc120/strings.xml
+++ b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_screenshot.xml
@@ -1,4 +1,3 @@
-<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2020 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
@@ -13,10 +12,18 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- String for tethered notification title with client number info. -->
- <plurals name="tethered_notification_title_with_client_number">
- <item quantity="one"><xliff:g>%1$d</xliff:g> device connected.</item>
- <item quantity="other"><xliff:g>%1$d</xliff:g> devices connected.</item>
- </plurals>
-</resources> \ No newline at end of file
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M17.59,1H6.41L5,2.41v19.17L6.41,23h11.17L19,21.59V2.41L17.59,1zM17.5,2.5v1.75h-11V2.5H17.5zM17.5,5.75v12.5h-11V5.75H17.5zM6.5,21.5v-1.75h11v1.75H6.5z"/>
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M9.5,11l0,-2.5l2.5,0l0,-1.5l-4,0l0,4z"/>
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M12,17l4,0l0,-4l-1.5,0l0,2.5l-2.5,0z"/>
+</vector>
diff --git a/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_select.xml b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_select.xml
new file mode 100644
index 000000000000..b699a4444d76
--- /dev/null
+++ b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_select.xml
@@ -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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M16.19,12.5h-1.94V8.12C14.25,6.95 13.3,6 12.12,6S10,6.95 10,8.12v7.9l-3.22,-0.86l-1.82,1.82L10.68,23h8.6l1.57,-7.96L16.19,12.5zM18.04,21.5h-6.72l-4.27,-4.49l0.18,-0.18l4.28,1.14V8.12c0,-0.34 0.28,-0.62 0.62,-0.62s0.62,0.28 0.62,0.62V14h3.06l3.35,1.83L18.04,21.5z"/>
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M11.25,1h1.5v3h-1.5z"/>
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M15.5983,5.3402l2.1213,-2.1213l1.0606,1.0606l-2.1213,2.1213z"/>
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M5.2187,4.2803l1.0606,-1.0606l2.1213,2.1213l-1.0606,1.0606z"/>
+</vector>
diff --git a/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_share.xml b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_share.xml
new file mode 100644
index 000000000000..36dd3baa8994
--- /dev/null
+++ b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_share.xml
@@ -0,0 +1,39 @@
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M18,3.5c0.83,0 1.5,0.67 1.5,1.5S18.83,6.5 18,6.5S16.5,5.83 16.5,5S17.17,3.5 18,3.5M18,2c-1.66,0 -3,1.34 -3,3s1.34,3 3,3s3,-1.34 3,-3S19.66,2 18,2L18,2z"/>
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M18,17.5c0.83,0 1.5,0.67 1.5,1.5s-0.67,1.5 -1.5,1.5s-1.5,-0.67 -1.5,-1.5S17.17,17.5 18,17.5M18,16c-1.66,0 -3,1.34 -3,3s1.34,3 3,3s3,-1.34 3,-3S19.66,16 18,16L18,16z"/>
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M6,10.5c0.83,0 1.5,0.67 1.5,1.5S6.83,13.5 6,13.5S4.5,12.83 4.5,12S5.17,10.5 6,10.5M6,9c-1.66,0 -3,1.34 -3,3s1.34,3 3,3s3,-1.34 3,-3S7.66,9 6,9L6,9z"/>
+ <path
+ android:pathData="M16.01,6.16L8,10.83"
+ android:strokeWidth="1.5"
+ android:fillColor="#00000000"
+ android:strokeColor="#000000"/>
+ <path
+ android:pathData="M16.06,17.87L8.19,13.28"
+ android:strokeWidth="1.5"
+ android:fillColor="#00000000"
+ android:strokeColor="#000000"/>
+</vector>
diff --git a/services/core/java/com/android/server/UiModeManagerService.java b/services/core/java/com/android/server/UiModeManagerService.java
index 58c388ed08c6..b09d74180c4b 100644
--- a/services/core/java/com/android/server/UiModeManagerService.java
+++ b/services/core/java/com/android/server/UiModeManagerService.java
@@ -122,7 +122,6 @@ final class UiModeManagerService extends SystemService {
private boolean mVrHeadset;
private boolean mComputedNightMode;
private int mCarModeEnableFlags;
- private boolean mSetupWizardComplete;
// flag set by resource, whether to enable Car dock launch when starting car mode.
private boolean mEnableCarDockLaunch = true;
@@ -164,12 +163,6 @@ final class UiModeManagerService extends SystemService {
mConfiguration.setToDefaults();
}
- @VisibleForTesting
- protected UiModeManagerService(Context context, boolean setupWizardComplete) {
- this(context);
- mSetupWizardComplete = setupWizardComplete;
- }
-
private static Intent buildHomeIntent(String category) {
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(category);
@@ -283,25 +276,6 @@ final class UiModeManagerService extends SystemService {
}
};
- private final ContentObserver mSetupWizardObserver = new ContentObserver(mHandler) {
- @Override
- public void onChange(boolean selfChange, Uri uri) {
- synchronized (mLock) {
- // setup wizard is done now so we can unblock
- if (setupWizardCompleteForCurrentUser() && !selfChange) {
- mSetupWizardComplete = true;
- getContext().getContentResolver()
- .unregisterContentObserver(mSetupWizardObserver);
- // update night mode
- Context context = getContext();
- updateNightModeFromSettingsLocked(context, context.getResources(),
- UserHandle.getCallingUserId());
- updateLocked(0, 0);
- }
- }
- }
- };
-
private final ContentObserver mDarkThemeObserver = new ContentObserver(mHandler) {
@Override
public void onChange(boolean selfChange, Uri uri) {
@@ -319,13 +293,6 @@ final class UiModeManagerService extends SystemService {
}
@Override
- public void onSwitchUser(int userHandle) {
- super.onSwitchUser(userHandle);
- getContext().getContentResolver().unregisterContentObserver(mSetupWizardObserver);
- verifySetupWizardCompleted();
- }
-
- @Override
public void onBootPhase(int phase) {
if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
synchronized (mLock) {
@@ -351,6 +318,8 @@ final class UiModeManagerService extends SystemService {
context.registerReceiver(mBatteryReceiver, batteryFilter);
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_USER_SWITCHED);
+ context.registerReceiver(mSettingsRestored,
+ new IntentFilter(Intent.ACTION_SETTING_RESTORED));
context.registerReceiver(new UserSwitchedReceiver(), filter, null, mHandler);
updateConfigurationLocked();
applyConfigurationExternallyLocked();
@@ -361,9 +330,6 @@ final class UiModeManagerService extends SystemService {
@Override
public void onStart() {
final Context context = getContext();
- // If setup isn't complete for this user listen for completion so we can unblock
- // being able to send a night mode configuration change event
- verifySetupWizardCompleted();
final Resources res = context.getResources();
mDefaultUiModeType = res.getInteger(
@@ -438,20 +404,6 @@ final class UiModeManagerService extends SystemService {
return mConfiguration;
}
- // Records whether setup wizard has happened or not and adds an observer for this user if not.
- private void verifySetupWizardCompleted() {
- final Context context = getContext();
- final int userId = UserHandle.getCallingUserId();
- if (!setupWizardCompleteForCurrentUser()) {
- mSetupWizardComplete = false;
- context.getContentResolver().registerContentObserver(
- Secure.getUriFor(
- Secure.USER_SETUP_COMPLETE), false, mSetupWizardObserver, userId);
- } else {
- mSetupWizardComplete = true;
- }
- }
-
private boolean setupWizardCompleteForCurrentUser() {
return Secure.getIntForUser(getContext().getContentResolver(),
Secure.USER_SETUP_COMPLETE, 0, UserHandle.getCallingUserId()) == 1;
@@ -480,28 +432,20 @@ final class UiModeManagerService extends SystemService {
final int defaultNightMode = res.getInteger(
com.android.internal.R.integer.config_defaultNightMode);
int oldNightMode = mNightMode;
- if (mSetupWizardComplete) {
- mNightMode = Secure.getIntForUser(context.getContentResolver(),
- Secure.UI_NIGHT_MODE, defaultNightMode, userId);
- mOverrideNightModeOn = Secure.getIntForUser(context.getContentResolver(),
- Secure.UI_NIGHT_MODE_OVERRIDE_ON, 0, userId) != 0;
- mOverrideNightModeOff = Secure.getIntForUser(context.getContentResolver(),
- Secure.UI_NIGHT_MODE_OVERRIDE_OFF, 0, userId) != 0;
- mCustomAutoNightModeStartMilliseconds = LocalTime.ofNanoOfDay(
- Secure.getLongForUser(context.getContentResolver(),
- Secure.DARK_THEME_CUSTOM_START_TIME,
- DEFAULT_CUSTOM_NIGHT_START_TIME.toNanoOfDay() / 1000L, userId) * 1000);
- mCustomAutoNightModeEndMilliseconds = LocalTime.ofNanoOfDay(
- Secure.getLongForUser(context.getContentResolver(),
- Secure.DARK_THEME_CUSTOM_END_TIME,
- DEFAULT_CUSTOM_NIGHT_END_TIME.toNanoOfDay() / 1000L, userId) * 1000);
- } else {
- mNightMode = defaultNightMode;
- mCustomAutoNightModeEndMilliseconds = DEFAULT_CUSTOM_NIGHT_END_TIME;
- mCustomAutoNightModeStartMilliseconds = DEFAULT_CUSTOM_NIGHT_START_TIME;
- mOverrideNightModeOn = false;
- mOverrideNightModeOff = false;
- }
+ mNightMode = Secure.getIntForUser(context.getContentResolver(),
+ Secure.UI_NIGHT_MODE, defaultNightMode, userId);
+ mOverrideNightModeOn = Secure.getIntForUser(context.getContentResolver(),
+ Secure.UI_NIGHT_MODE_OVERRIDE_ON, 0, userId) != 0;
+ mOverrideNightModeOff = Secure.getIntForUser(context.getContentResolver(),
+ Secure.UI_NIGHT_MODE_OVERRIDE_OFF, 0, userId) != 0;
+ mCustomAutoNightModeStartMilliseconds = LocalTime.ofNanoOfDay(
+ Secure.getLongForUser(context.getContentResolver(),
+ Secure.DARK_THEME_CUSTOM_START_TIME,
+ DEFAULT_CUSTOM_NIGHT_START_TIME.toNanoOfDay() / 1000L, userId) * 1000);
+ mCustomAutoNightModeEndMilliseconds = LocalTime.ofNanoOfDay(
+ Secure.getLongForUser(context.getContentResolver(),
+ Secure.DARK_THEME_CUSTOM_END_TIME,
+ DEFAULT_CUSTOM_NIGHT_END_TIME.toNanoOfDay() / 1000L, userId) * 1000);
return oldNightMode != mNightMode;
}
@@ -644,10 +588,6 @@ final class UiModeManagerService extends SystemService {
Slog.e(TAG, "Night mode locked, requires MODIFY_DAY_NIGHT_MODE permission");
return;
}
- if (!mSetupWizardComplete) {
- Slog.d(TAG, "Night mode cannot be changed before setup wizard completes.");
- return;
- }
switch (mode) {
case UiModeManager.MODE_NIGHT_NO:
case UiModeManager.MODE_NIGHT_YES:
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 21760cdf02eb..419389f7abef 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -119,7 +119,6 @@ import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Comparator;
-import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.function.Predicate;
@@ -1753,8 +1752,8 @@ public final class ActiveServices {
private void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) {
boolean anyForeground = false;
int fgServiceTypes = 0;
- for (int i = proc.services.size() - 1; i >= 0; i--) {
- ServiceRecord sr = proc.services.valueAt(i);
+ for (int i = proc.numberOfRunningServices() - 1; i >= 0; i--) {
+ ServiceRecord sr = proc.getRunningServiceAt(i);
if (sr.isForeground || sr.fgRequired) {
anyForeground = true;
fgServiceTypes |= sr.foregroundServiceType;
@@ -1765,8 +1764,8 @@ public final class ActiveServices {
private void updateWhitelistManagerLocked(ProcessRecord proc) {
proc.whitelistManager = false;
- for (int i=proc.services.size()-1; i>=0; i--) {
- ServiceRecord sr = proc.services.valueAt(i);
+ for (int i = proc.numberOfRunningServices() - 1; i >= 0; i--) {
+ ServiceRecord sr = proc.getRunningServiceAt(i);
if (sr.whitelistManager) {
proc.whitelistManager = true;
break;
@@ -1802,8 +1801,8 @@ public final class ActiveServices {
}
boolean anyClientActivities = false;
- for (int i=proc.services.size()-1; i>=0 && !anyClientActivities; i--) {
- ServiceRecord sr = proc.services.valueAt(i);
+ for (int i = proc.numberOfRunningServices() - 1; i >= 0 && !anyClientActivities; i--) {
+ ServiceRecord sr = proc.getRunningServiceAt(i);
ArrayMap<IBinder, ArrayList<ConnectionRecord>> connections = sr.getConnections();
for (int conni = connections.size() - 1; conni >= 0 && !anyClientActivities; conni--) {
ArrayList<ConnectionRecord> clist = connections.valueAt(conni);
@@ -2995,7 +2994,7 @@ public final class ActiveServices {
r.setProcess(app);
r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
- final boolean newService = app.services.add(r);
+ final boolean newService = app.startService(r);
bumpServiceExecutingLocked(r, execInFg, "create");
mAm.updateLruProcessLocked(app, false, null);
updateServiceForegroundLocked(r.app, /* oomAdj= */ false);
@@ -3036,7 +3035,7 @@ public final class ActiveServices {
// Cleanup.
if (newService) {
- app.services.remove(r);
+ app.stopService(r);
r.setProcess(null);
}
@@ -3362,7 +3361,7 @@ public final class ActiveServices {
synchronized (r.stats.getBatteryStats()) {
r.stats.stopLaunchedLocked();
}
- r.app.services.remove(r);
+ r.app.stopService(r);
r.app.updateBoundClientUids();
if (r.whitelistManager) {
updateWhitelistManagerLocked(r.app);
@@ -3652,7 +3651,7 @@ public final class ActiveServices {
}
if (finishing) {
if (r.app != null && !r.app.isPersistent()) {
- r.app.services.remove(r);
+ r.app.stopService(r);
r.app.updateBoundClientUids();
if (r.whitelistManager) {
updateWhitelistManagerLocked(r.app);
@@ -3748,7 +3747,7 @@ public final class ActiveServices {
didSomething = true;
Slog.i(TAG, " Force stopping service " + service);
if (service.app != null && !service.app.isPersistent()) {
- service.app.services.remove(service);
+ service.app.stopService(service);
service.app.updateBoundClientUids();
if (service.whitelistManager) {
updateWhitelistManagerLocked(service.app);
@@ -3861,24 +3860,22 @@ public final class ActiveServices {
if (false) {
// XXX we are letting the client link to the service for
// death notifications.
- if (app.services.size() > 0) {
- Iterator<ServiceRecord> it = app.services.iterator();
- while (it.hasNext()) {
- ServiceRecord r = it.next();
- ArrayMap<IBinder, ArrayList<ConnectionRecord>> connections = r.getConnections();
- for (int conni=connections.size()-1; conni>=0; conni--) {
- ArrayList<ConnectionRecord> cl = connections.valueAt(conni);
- for (int i=0; i<cl.size(); i++) {
- ConnectionRecord c = cl.get(i);
- if (c.binding.client != app) {
- try {
- //c.conn.connected(r.className, null);
- } catch (Exception e) {
- // todo: this should be asynchronous!
- Slog.w(TAG, "Exception thrown disconnected servce "
- + r.shortInstanceName
- + " from app " + app.processName, e);
- }
+ int numberOfRunningServices = app.numberOfRunningServices();
+ for (int sIndex = 0; sIndex < numberOfRunningServices; sIndex++) {
+ ServiceRecord r = app.getRunningServiceAt(sIndex);
+ ArrayMap<IBinder, ArrayList<ConnectionRecord>> connections = r.getConnections();
+ for (int conni = connections.size() - 1; conni >= 0; conni--) {
+ ArrayList<ConnectionRecord> cl = connections.valueAt(conni);
+ for (int i = 0; i < cl.size(); i++) {
+ ConnectionRecord c = cl.get(i);
+ if (c.binding.client != app) {
+ try {
+ //c.conn.connected(r.className, null);
+ } catch (Exception e) {
+ // todo: this should be asynchronous!
+ Slog.w(TAG, "Exception thrown disconnected servce "
+ + r.shortInstanceName
+ + " from app " + app.processName, e);
}
}
}
@@ -3897,13 +3894,13 @@ public final class ActiveServices {
app.whitelistManager = false;
// Clear app state from services.
- for (int i = app.services.size() - 1; i >= 0; i--) {
- ServiceRecord sr = app.services.valueAt(i);
+ for (int i = app.numberOfRunningServices() - 1; i >= 0; i--) {
+ ServiceRecord sr = app.getRunningServiceAt(i);
synchronized (sr.stats.getBatteryStats()) {
sr.stats.stopLaunchedLocked();
}
if (sr.app != app && sr.app != null && !sr.app.isPersistent()) {
- sr.app.services.remove(sr);
+ sr.app.stopService(sr);
sr.app.updateBoundClientUids();
}
sr.setProcess(null);
@@ -3962,13 +3959,13 @@ public final class ActiveServices {
ServiceMap smap = getServiceMapLocked(app.userId);
// Now do remaining service cleanup.
- for (int i=app.services.size()-1; i>=0; i--) {
- ServiceRecord sr = app.services.valueAt(i);
+ for (int i = app.numberOfRunningServices() - 1; i >= 0; i--) {
+ ServiceRecord sr = app.getRunningServiceAt(i);
// Unless the process is persistent, this process record is going away,
// so make sure the service is cleaned out of it.
if (!app.isPersistent()) {
- app.services.removeAt(i);
+ app.stopService(sr);
app.updateBoundClientUids();
}
@@ -4018,7 +4015,7 @@ public final class ActiveServices {
}
if (!allowRestart) {
- app.services.clear();
+ app.stopAllServices();
app.clearBoundClientUids();
// Make sure there are no more restarting services for this process.
@@ -4920,8 +4917,8 @@ public final class ActiveServices {
if (pr.uid != uid) {
continue;
}
- for (int j = pr.services.size() - 1; j >= 0; j--) {
- ServiceRecord r = pr.services.valueAt(j);
+ for (int j = pr.numberOfRunningServices() - 1; j >= 0; j--) {
+ ServiceRecord r = pr.getRunningServiceAt(j);
if (!r.isForeground) {
continue;
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index a22b44225b70..5d7590d7a458 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -18172,7 +18172,7 @@ public class ActivityManagerService extends IActivityManager.Stub
for (int i = mProcessList.mRemovedProcesses.size() - 1; i >= 0; i--) {
final ProcessRecord app = mProcessList.mRemovedProcesses.get(i);
if (!app.hasActivitiesOrRecentTasks()
- && app.curReceivers.isEmpty() && app.services.size() == 0) {
+ && app.curReceivers.isEmpty() && app.numberOfRunningServices() == 0) {
Slog.i(
TAG, "Exiting empty application process "
+ app.toShortString() + " ("
diff --git a/services/core/java/com/android/server/am/AppErrors.java b/services/core/java/com/android/server/am/AppErrors.java
index b1fc0296518b..50d2cab0af81 100644
--- a/services/core/java/com/android/server/am/AppErrors.java
+++ b/services/core/java/com/android/server/am/AppErrors.java
@@ -702,10 +702,10 @@ class AppErrors {
}
// Bump up the crash count of any services currently running in the proc.
- for (int i = app.services.size() - 1; i >= 0; i--) {
+ for (int i = app.numberOfRunningServices() - 1; i >= 0; i--) {
// Any services running in the application need to be placed
// back in the pending list.
- ServiceRecord sr = app.services.valueAt(i);
+ ServiceRecord sr = app.getRunningServiceAt(i);
// If the service was restarted a while ago, then reset crash count, else increment it.
if (now > sr.restartTime + ProcessList.MIN_CRASH_INTERVAL) {
sr.crashCount = 1;
diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java
index 2d6ef81faf1c..ad858533c430 100644
--- a/services/core/java/com/android/server/am/OomAdjuster.java
+++ b/services/core/java/com/android/server/am/OomAdjuster.java
@@ -837,7 +837,8 @@ public final class OomAdjuster {
break;
}
- if (app.isolated && app.services.size() <= 0 && app.isolatedEntryPoint == null) {
+ if (app.isolated && app.numberOfRunningServices() <= 0
+ && app.isolatedEntryPoint == null) {
// If this is an isolated process, there are no services
// running in it, and it's not a special process with a
// custom entry point, then the process is no longer
@@ -1446,12 +1447,12 @@ public final class OomAdjuster {
}
int capabilityFromFGS = 0; // capability from foreground service.
- for (int is = app.services.size() - 1;
+ for (int is = app.numberOfRunningServices() - 1;
is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
|| schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
|| procState > PROCESS_STATE_TOP);
is--) {
- ServiceRecord s = app.services.valueAt(is);
+ ServiceRecord s = app.getRunningServiceAt(is);
if (s.startRequested) {
app.hasStartedServices = true;
if (procState > PROCESS_STATE_SERVICE) {
diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java
index 61ebc361b6af..a1ec07cda8a8 100644
--- a/services/core/java/com/android/server/am/ProcessRecord.java
+++ b/services/core/java/com/android/server/am/ProcessRecord.java
@@ -261,9 +261,9 @@ class ProcessRecord implements WindowProcessListener {
// Controller for error dialogs
private final ErrorDialogController mDialogController = new ErrorDialogController();
// Controller for driving the process state on the window manager side.
- final private WindowProcessController mWindowProcessController;
+ private final WindowProcessController mWindowProcessController;
// all ServiceRecord running in this process
- final ArraySet<ServiceRecord> services = new ArraySet<>();
+ private final ArraySet<ServiceRecord> mServices = new ArraySet<>();
// services that are currently executing code (need to remain foreground).
final ArraySet<ServiceRecord> executingServices = new ArraySet<>();
// All ConnectionRecord this process holds
@@ -577,10 +577,10 @@ class ProcessRecord implements WindowProcessListener {
pw.println(Arrays.toString(isolatedEntryPointArgs));
}
mWindowProcessController.dump(pw, prefix);
- if (services.size() > 0) {
+ if (mServices.size() > 0) {
pw.print(prefix); pw.println("Services:");
- for (int i=0; i<services.size(); i++) {
- pw.print(prefix); pw.print(" - "); pw.println(services.valueAt(i));
+ for (int i = 0; i < mServices.size(); i++) {
+ pw.print(prefix); pw.print(" - "); pw.println(mServices.valueAt(i));
}
}
if (executingServices.size() > 0) {
@@ -735,6 +735,60 @@ class ProcessRecord implements WindowProcessListener {
}
}
+ /**
+ * Records a service as running in the process. Note that this method does not actually start
+ * the service, but records the service as started for bookkeeping.
+ *
+ * @return true if the service was added, false otherwise.
+ */
+ boolean startService(ServiceRecord record) {
+ if (record == null) {
+ return false;
+ }
+ boolean added = mServices.add(record);
+ if (added && record.serviceInfo != null) {
+ mWindowProcessController.onServiceStarted(record.serviceInfo);
+ }
+ return added;
+ }
+
+ /**
+ * Records a service as stopped. Note that like {@link #startService(ServiceRecord)} this method
+ * does not actually stop the service, but records the service as stopped for bookkeeping.
+ *
+ * @return true if the service was removed, false otherwise.
+ */
+ boolean stopService(ServiceRecord record) {
+ return mServices.remove(record);
+ }
+
+ /**
+ * The same as calling {@link #stopService(ServiceRecord)} on all current running services.
+ */
+ void stopAllServices() {
+ mServices.clear();
+ }
+
+ /**
+ * Returns the number of services added with {@link #startService(ServiceRecord)} and not yet
+ * removed by a call to {@link #stopService(ServiceRecord)} or {@link #stopAllServices()}.
+ *
+ * @see #startService(ServiceRecord)
+ * @see #stopService(ServiceRecord)
+ */
+ int numberOfRunningServices() {
+ return mServices.size();
+ }
+
+ /**
+ * Returns the service at the specified {@code index}.
+ *
+ * @see #numberOfRunningServices()
+ */
+ ServiceRecord getRunningServiceAt(int index) {
+ return mServices.valueAt(index);
+ }
+
void setCached(boolean cached) {
if (mCached != cached) {
mCached = cached;
@@ -768,9 +822,9 @@ class ProcessRecord implements WindowProcessListener {
return true;
}
- final int servicesSize = services.size();
+ final int servicesSize = mServices.size();
for (int i = 0; i < servicesSize; i++) {
- ServiceRecord r = services.valueAt(i);
+ ServiceRecord r = mServices.valueAt(i);
if (r.isForeground) {
return true;
}
@@ -1289,16 +1343,16 @@ class ProcessRecord implements WindowProcessListener {
}
void updateBoundClientUids() {
- if (services.isEmpty()) {
+ if (mServices.isEmpty()) {
clearBoundClientUids();
return;
}
// grab a set of clientUids of all connections of all services
ArraySet<Integer> boundClientUids = new ArraySet<>();
- final int K = services.size();
- for (int j = 0; j < K; j++) {
+ final int serviceCount = mServices.size();
+ for (int j = 0; j < serviceCount; j++) {
ArrayMap<IBinder, ArrayList<ConnectionRecord>> conns =
- services.valueAt(j).getConnections();
+ mServices.valueAt(j).getConnections();
final int N = conns.size();
for (int conni = 0; conni < N; conni++) {
ArrayList<ConnectionRecord> c = conns.valueAt(conni);
diff --git a/services/core/java/com/android/server/audio/AudioDeviceBroker.java b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
index c2c79d361996..032ad63a8570 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceBroker.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
@@ -30,6 +30,7 @@ import android.media.AudioRoutesInfo;
import android.media.AudioSystem;
import android.media.IAudioRoutesObserver;
import android.media.IStrategyPreferredDeviceDispatcher;
+import android.media.MediaMetrics;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
@@ -668,6 +669,13 @@ import java.io.PrintWriter;
}
AudioService.sForceUseLogger.log(
new AudioServiceEvents.ForceUseEvent(useCase, config, eventSource));
+ new MediaMetrics.Item(MediaMetrics.Name.AUDIO_FORCE_USE + MediaMetrics.SEPARATOR
+ + AudioSystem.forceUseUsageToString(useCase))
+ .set(MediaMetrics.Property.EVENT, "onSetForceUse")
+ .set(MediaMetrics.Property.FORCE_USE_DUE_TO, eventSource)
+ .set(MediaMetrics.Property.FORCE_USE_MODE,
+ AudioSystem.forceUseConfigToString(config))
+ .record();
AudioSystem.setForceUse(useCase, config);
}
diff --git a/services/core/java/com/android/server/audio/AudioDeviceInventory.java b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
index c17ed3e292ef..3e97a1e136c6 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceInventory.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
@@ -33,6 +33,7 @@ import android.media.AudioRoutesInfo;
import android.media.AudioSystem;
import android.media.IAudioRoutesObserver;
import android.media.IStrategyPreferredDeviceDispatcher;
+import android.media.MediaMetrics;
import android.os.Binder;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
@@ -64,10 +65,69 @@ public class AudioDeviceInventory {
// lock to synchronize all access to mConnectedDevices and mApmConnectedDevices
private final Object mDevicesLock = new Object();
+ //Audio Analytics ids.
+ private static final String mMetricsId = "audio.device.";
+
// List of connected devices
// Key for map created from DeviceInfo.makeDeviceListKey()
@GuardedBy("mDevicesLock")
- private final LinkedHashMap<String, DeviceInfo> mConnectedDevices = new LinkedHashMap<>();
+ private final LinkedHashMap<String, DeviceInfo> mConnectedDevices = new LinkedHashMap<>() {
+ @Override
+ public DeviceInfo put(String key, DeviceInfo value) {
+ final DeviceInfo result = super.put(key, value);
+ record("put", true /* connected */, key, value);
+ return result;
+ }
+
+ @Override
+ public DeviceInfo putIfAbsent(String key, DeviceInfo value) {
+ final DeviceInfo result = super.putIfAbsent(key, value);
+ if (result == null) {
+ record("putIfAbsent", true /* connected */, key, value);
+ }
+ return result;
+ }
+
+ @Override
+ public DeviceInfo remove(Object key) {
+ final DeviceInfo result = super.remove(key);
+ if (result != null) {
+ record("remove", false /* connected */, (String) key, result);
+ }
+ return result;
+ }
+
+ @Override
+ public boolean remove(Object key, Object value) {
+ final boolean result = super.remove(key, value);
+ if (result) {
+ record("remove", false /* connected */, (String) key, (DeviceInfo) value);
+ }
+ return result;
+ }
+
+ // Not overridden
+ // clear
+ // compute
+ // computeIfAbsent
+ // computeIfPresent
+ // merge
+ // putAll
+ // replace
+ // replaceAll
+ private void record(String event, boolean connected, String key, DeviceInfo value) {
+ // DeviceInfo - int mDeviceType;
+ // DeviceInfo - int mDeviceCodecFormat;
+ new MediaMetrics.Item(MediaMetrics.Name.AUDIO_DEVICE
+ + MediaMetrics.SEPARATOR + AudioSystem.getDeviceName(value.mDeviceType))
+ .set(MediaMetrics.Property.ADDRESS, value.mDeviceAddress)
+ .set(MediaMetrics.Property.EVENT, event)
+ .set(MediaMetrics.Property.NAME, value.mDeviceName)
+ .set(MediaMetrics.Property.STATE, connected
+ ? MediaMetrics.Value.CONNECTED : MediaMetrics.Value.DISCONNECTED)
+ .record();
+ }
+ };
// List of devices actually connected to AudioPolicy (through AudioSystem), only one
// by device type, which is used as the key, value is the DeviceInfo generated key.
@@ -236,6 +296,16 @@ public class AudioDeviceInventory {
+ " codec=" + a2dpCodec
+ " vol=" + a2dpVolume));
+ new MediaMetrics.Item(mMetricsId + "a2dp")
+ .set(MediaMetrics.Property.ADDRESS, address)
+ .set(MediaMetrics.Property.ENCODING, AudioSystem.audioFormatToString(a2dpCodec))
+ .set(MediaMetrics.Property.EVENT, "onSetA2dpSinkConnectionState")
+ .set(MediaMetrics.Property.INDEX, a2dpVolume)
+ .set(MediaMetrics.Property.STATE,
+ state == BluetoothProfile.STATE_CONNECTED
+ ? MediaMetrics.Value.CONNECTED : MediaMetrics.Value.DISCONNECTED)
+ .record();
+
synchronized (mDevicesLock) {
final String key = DeviceInfo.makeDeviceListKey(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP,
btDevice.getAddress());
@@ -284,6 +354,15 @@ public class AudioDeviceInventory {
final DeviceInfo di = mConnectedDevices.get(key);
boolean isConnected = di != null;
+ new MediaMetrics.Item(mMetricsId + "onSetA2dpSourceConnectionState")
+ .set(MediaMetrics.Property.ADDRESS, address)
+ .set(MediaMetrics.Property.DEVICE,
+ AudioSystem.getDeviceName(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP))
+ .set(MediaMetrics.Property.STATE,
+ state == BluetoothProfile.STATE_CONNECTED
+ ? MediaMetrics.Value.CONNECTED : MediaMetrics.Value.DISCONNECTED)
+ .record();
+
if (isConnected && state != BluetoothProfile.STATE_CONNECTED) {
makeA2dpSrcUnavailable(address);
} else if (!isConnected && state == BluetoothProfile.STATE_CONNECTED) {
@@ -301,6 +380,17 @@ public class AudioDeviceInventory {
AudioService.sDeviceLogger.log(new AudioEventLogger.StringEvent(
"onSetHearingAidConnectionState addr=" + address));
+ new MediaMetrics.Item(mMetricsId + "onSetHearingAidConnectionState")
+ .set(MediaMetrics.Property.ADDRESS, address)
+ .set(MediaMetrics.Property.DEVICE,
+ AudioSystem.getDeviceName(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP))
+ .set(MediaMetrics.Property.STATE,
+ state == BluetoothProfile.STATE_CONNECTED
+ ? MediaMetrics.Value.CONNECTED : MediaMetrics.Value.DISCONNECTED)
+ .set(MediaMetrics.Property.STREAM_TYPE,
+ AudioSystem.streamToString(streamType))
+ .record();
+
synchronized (mDevicesLock) {
final String key = DeviceInfo.makeDeviceListKey(AudioSystem.DEVICE_OUT_HEARING_AID,
btDevice.getAddress());
@@ -317,10 +407,15 @@ public class AudioDeviceInventory {
}
@GuardedBy("AudioDeviceBroker.mDeviceStateLock")
- /*package*/ void onBluetoothA2dpActiveDeviceChange(
+ /*package*/ void onBluetoothA2dpActiveDeviceChange(
@NonNull BtHelper.BluetoothA2dpDeviceInfo btInfo, int event) {
+ MediaMetrics.Item mmi = new MediaMetrics.Item(mMetricsId
+ + "onBluetoothA2dpActiveDeviceChange")
+ .set(MediaMetrics.Property.EVENT, BtHelper.a2dpDeviceEventToString(event));
+
final BluetoothDevice btDevice = btInfo.getBtDevice();
if (btDevice == null) {
+ mmi.set(MediaMetrics.Property.EARLY_RETURN, "btDevice null").record();
return;
}
if (AudioService.DEBUG_DEVICES) {
@@ -341,6 +436,8 @@ public class AudioDeviceInventory {
if (mDeviceBroker.hasScheduledA2dpSinkConnectionState(btDevice)) {
AudioService.sDeviceLogger.log(new AudioEventLogger.StringEvent(
"A2dp config change ignored (scheduled connection change)"));
+ mmi.set(MediaMetrics.Property.EARLY_RETURN, "A2dp config change ignored")
+ .record();
return;
}
final String key = DeviceInfo.makeDeviceListKey(
@@ -348,9 +445,16 @@ public class AudioDeviceInventory {
final DeviceInfo di = mConnectedDevices.get(key);
if (di == null) {
Log.e(TAG, "invalid null DeviceInfo in onBluetoothA2dpActiveDeviceChange");
+ mmi.set(MediaMetrics.Property.EARLY_RETURN, "null DeviceInfo").record();
return;
}
+ mmi.set(MediaMetrics.Property.ADDRESS, address)
+ .set(MediaMetrics.Property.ENCODING,
+ AudioSystem.audioFormatToString(a2dpCodec))
+ .set(MediaMetrics.Property.INDEX, a2dpVolume)
+ .set(MediaMetrics.Property.NAME, di.mDeviceName);
+
if (event == BtHelper.EVENT_ACTIVE_DEVICE_CHANGE) {
// Device is connected
if (a2dpVolume != -1) {
@@ -388,6 +492,7 @@ public class AudioDeviceInventory {
+ address + " codec=" + a2dpCodec).printLog(TAG));
}
}
+ mmi.record();
}
/*package*/ void onMakeA2dpDeviceUnavailableNow(String address, int a2dpCodec) {
@@ -399,6 +504,9 @@ public class AudioDeviceInventory {
/*package*/ void onReportNewRoutes() {
int n = mRoutesObservers.beginBroadcast();
if (n > 0) {
+ new MediaMetrics.Item(mMetricsId + "onReportNewRoutes")
+ .set(MediaMetrics.Property.OBSERVERS, n)
+ .record();
AudioRoutesInfo routes;
synchronized (mCurAudioRoutes) {
routes = new AudioRoutesInfo(mCurAudioRoutes);
@@ -428,6 +536,13 @@ public class AudioDeviceInventory {
AudioDeviceInventory.WiredDeviceConnectionState wdcs) {
AudioService.sDeviceLogger.log(new AudioServiceEvents.WiredDevConnectEvent(wdcs));
+ MediaMetrics.Item mmi = new MediaMetrics.Item(mMetricsId
+ + "onSetWiredDeviceConnectionState")
+ .set(MediaMetrics.Property.ADDRESS, wdcs.mAddress)
+ .set(MediaMetrics.Property.DEVICE, AudioSystem.getDeviceName(wdcs.mType))
+ .set(MediaMetrics.Property.STATE,
+ wdcs.mState == AudioService.CONNECTION_STATE_DISCONNECTED
+ ? MediaMetrics.Value.DISCONNECTED : MediaMetrics.Value.CONNECTED);
synchronized (mDevicesLock) {
if ((wdcs.mState == AudioService.CONNECTION_STATE_DISCONNECTED)
&& DEVICE_OVERRIDE_A2DP_ROUTE_ON_PLUG_SET.contains(wdcs.mType)) {
@@ -438,6 +553,8 @@ public class AudioDeviceInventory {
if (!handleDeviceConnection(wdcs.mState == AudioService.CONNECTION_STATE_CONNECTED,
wdcs.mType, wdcs.mAddress, wdcs.mName)) {
// change of connection state failed, bailout
+ mmi.set(MediaMetrics.Property.EARLY_RETURN, "change of connection state failed")
+ .record();
return;
}
if (wdcs.mState != AudioService.CONNECTION_STATE_DISCONNECTED) {
@@ -453,15 +570,20 @@ public class AudioDeviceInventory {
sendDeviceConnectionIntent(wdcs.mType, wdcs.mState, wdcs.mAddress, wdcs.mName);
updateAudioRoutes(wdcs.mType, wdcs.mState);
}
+ mmi.record();
}
/*package*/ void onToggleHdmi() {
+ MediaMetrics.Item mmi = new MediaMetrics.Item(mMetricsId + "onToggleHdmi")
+ .set(MediaMetrics.Property.DEVICE,
+ AudioSystem.getDeviceName(AudioSystem.DEVICE_OUT_HDMI));
synchronized (mDevicesLock) {
// Is HDMI connected?
final String key = DeviceInfo.makeDeviceListKey(AudioSystem.DEVICE_OUT_HDMI, "");
final DeviceInfo di = mConnectedDevices.get(key);
if (di == null) {
Log.e(TAG, "invalid null DeviceInfo in onToggleHdmi");
+ mmi.set(MediaMetrics.Property.EARLY_RETURN, "invalid null DeviceInfo").record();
return;
}
// Toggle HDMI to retrigger broadcast with proper formats.
@@ -472,6 +594,7 @@ public class AudioDeviceInventory {
AudioSystem.DEVICE_STATE_AVAILABLE, "", "",
"android"); // reconnect
}
+ mmi.record();
}
/*package*/ void onSaveSetPreferredDevice(int strategy, @NonNull AudioDeviceAttributes device) {
@@ -535,6 +658,12 @@ public class AudioDeviceInventory {
+ Integer.toHexString(device) + " address:" + address
+ " name:" + deviceName + ")");
}
+ MediaMetrics.Item mmi = new MediaMetrics.Item(mMetricsId + "handleDeviceConnection")
+ .set(MediaMetrics.Property.ADDRESS, address)
+ .set(MediaMetrics.Property.DEVICE, AudioSystem.getDeviceName(device))
+ .set(MediaMetrics.Property.MODE, connect
+ ? MediaMetrics.Value.CONNECT : MediaMetrics.Value.DISCONNECT)
+ .set(MediaMetrics.Property.NAME, deviceName);
synchronized (mDevicesLock) {
final String deviceKey = DeviceInfo.makeDeviceListKey(device, address);
if (AudioService.DEBUG_DEVICES) {
@@ -550,13 +679,18 @@ public class AudioDeviceInventory {
AudioSystem.DEVICE_STATE_AVAILABLE, address, deviceName,
AudioSystem.AUDIO_FORMAT_DEFAULT);
if (res != AudioSystem.AUDIO_STATUS_OK) {
- Slog.e(TAG, "not connecting device 0x" + Integer.toHexString(device)
- + " due to command error " + res);
+ final String reason = "not connecting device 0x" + Integer.toHexString(device)
+ + " due to command error " + res;
+ Slog.e(TAG, reason);
+ mmi.set(MediaMetrics.Property.EARLY_RETURN, reason)
+ .set(MediaMetrics.Property.STATE, MediaMetrics.Value.DISCONNECTED)
+ .record();
return false;
}
mConnectedDevices.put(deviceKey, new DeviceInfo(
device, deviceName, address, AudioSystem.AUDIO_FORMAT_DEFAULT));
mDeviceBroker.postAccessoryPlugMediaUnmute(device);
+ mmi.set(MediaMetrics.Property.STATE, MediaMetrics.Value.CONNECTED).record();
return true;
} else if (!connect && isConnected) {
mAudioSystem.setDeviceConnectionState(device,
@@ -564,11 +698,13 @@ public class AudioDeviceInventory {
AudioSystem.AUDIO_FORMAT_DEFAULT);
// always remove even if disconnection failed
mConnectedDevices.remove(deviceKey);
+ mmi.set(MediaMetrics.Property.STATE, MediaMetrics.Value.CONNECTED).record();
return true;
}
Log.w(TAG, "handleDeviceConnection() failed, deviceKey=" + deviceKey
+ ", deviceSpec=" + di + ", connect=" + connect);
}
+ mmi.set(MediaMetrics.Property.STATE, MediaMetrics.Value.DISCONNECTED).record();
return false;
}
@@ -582,6 +718,8 @@ public class AudioDeviceInventory {
toRemove.add(deviceInfo.mDeviceAddress);
}
});
+ new MediaMetrics.Item(mMetricsId + "disconnectA2dp")
+ .record();
if (toRemove.size() > 0) {
final int delay = checkSendBecomingNoisyIntentInt(
AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP,
@@ -602,6 +740,8 @@ public class AudioDeviceInventory {
toRemove.add(deviceInfo.mDeviceAddress);
}
});
+ new MediaMetrics.Item(mMetricsId + "disconnectA2dpSink")
+ .record();
toRemove.stream().forEach(deviceAddress -> makeA2dpSrcUnavailable(deviceAddress));
}
}
@@ -615,6 +755,8 @@ public class AudioDeviceInventory {
toRemove.add(deviceInfo.mDeviceAddress);
}
});
+ new MediaMetrics.Item(mMetricsId + "disconnectHearingAid")
+ .record();
if (toRemove.size() > 0) {
final int delay = checkSendBecomingNoisyIntentInt(
AudioSystem.DEVICE_OUT_HEARING_AID, 0, AudioSystem.DEVICE_NONE);
@@ -743,6 +885,8 @@ public class AudioDeviceInventory {
final int res = mAudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP,
AudioSystem.DEVICE_STATE_AVAILABLE, address, name, a2dpCodec);
+ // TODO: log in MediaMetrics once distinction between connection failure and
+ // double connection is made.
if (res != AudioSystem.AUDIO_STATUS_OK) {
AudioService.sDeviceLogger.log(new AudioEventLogger.StringEvent(
"APM failed to make available A2DP device addr=" + address
@@ -771,7 +915,12 @@ public class AudioDeviceInventory {
@GuardedBy("mDevicesLock")
private void makeA2dpDeviceUnavailableNow(String address, int a2dpCodec) {
+ MediaMetrics.Item mmi = new MediaMetrics.Item(mMetricsId + "a2dp." + address)
+ .set(MediaMetrics.Property.ENCODING, AudioSystem.audioFormatToString(a2dpCodec))
+ .set(MediaMetrics.Property.EVENT, "makeA2dpDeviceUnavailableNow");
+
if (address == null) {
+ mmi.set(MediaMetrics.Property.EARLY_RETURN, "address null").record();
return;
}
final String deviceToRemoveKey =
@@ -783,6 +932,9 @@ public class AudioDeviceInventory {
// removing A2DP device not currently used by AudioPolicy, log but don't act on it
AudioService.sDeviceLogger.log((new AudioEventLogger.StringEvent(
"A2DP device " + address + " made unavailable, was not used")).printLog(TAG));
+ mmi.set(MediaMetrics.Property.EARLY_RETURN,
+ "A2DP device made unavailable, was not used")
+ .record();
return;
}
@@ -804,6 +956,7 @@ public class AudioDeviceInventory {
mApmConnectedDevices.remove(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP);
// Remove A2DP routes as well
setCurrentAudioRouteNameIfPossible(null);
+ mmi.record();
}
@GuardedBy("mDevicesLock")
@@ -862,6 +1015,14 @@ public class AudioDeviceInventory {
mDeviceBroker.postApplyVolumeOnDevice(streamType,
AudioSystem.DEVICE_OUT_HEARING_AID, "makeHearingAidDeviceAvailable");
setCurrentAudioRouteNameIfPossible(name);
+ new MediaMetrics.Item(mMetricsId + "makeHearingAidDeviceAvailable")
+ .set(MediaMetrics.Property.ADDRESS, address != null ? address : "")
+ .set(MediaMetrics.Property.DEVICE,
+ AudioSystem.getDeviceName(AudioSystem.DEVICE_OUT_HEARING_AID))
+ .set(MediaMetrics.Property.NAME, name)
+ .set(MediaMetrics.Property.STREAM_TYPE,
+ AudioSystem.streamToString(streamType))
+ .record();
}
@GuardedBy("mDevicesLock")
@@ -873,6 +1034,11 @@ public class AudioDeviceInventory {
DeviceInfo.makeDeviceListKey(AudioSystem.DEVICE_OUT_HEARING_AID, address));
// Remove Hearing Aid routes as well
setCurrentAudioRouteNameIfPossible(null);
+ new MediaMetrics.Item(mMetricsId + "makeHearingAidDeviceUnavailable")
+ .set(MediaMetrics.Property.ADDRESS, address != null ? address : "")
+ .set(MediaMetrics.Property.DEVICE,
+ AudioSystem.getDeviceName(AudioSystem.DEVICE_OUT_HEARING_AID))
+ .record();
}
@GuardedBy("mDevicesLock")
@@ -919,10 +1085,18 @@ public class AudioDeviceInventory {
@GuardedBy("mDevicesLock")
private int checkSendBecomingNoisyIntentInt(int device,
@AudioService.ConnectionState int state, int musicDevice) {
+ MediaMetrics.Item mmi = new MediaMetrics.Item(mMetricsId
+ + "checkSendBecomingNoisyIntentInt")
+ .set(MediaMetrics.Property.DEVICE, AudioSystem.getDeviceName(device))
+ .set(MediaMetrics.Property.STATE,
+ state == AudioService.CONNECTION_STATE_CONNECTED
+ ? MediaMetrics.Value.CONNECTED : MediaMetrics.Value.DISCONNECTED);
if (state != AudioService.CONNECTION_STATE_DISCONNECTED) {
+ mmi.set(MediaMetrics.Property.DELAY_MS, 0).record(); // OK to return
return 0;
}
if (!BECOMING_NOISY_INTENT_DEVICES_SET.contains(device)) {
+ mmi.set(MediaMetrics.Property.DELAY_MS, 0).record(); // OK to return
return 0;
}
int delay = 0;
@@ -950,12 +1124,14 @@ public class AudioDeviceInventory {
// the pausing of some apps that are playing remotely
AudioService.sDeviceLogger.log((new AudioEventLogger.StringEvent(
"dropping ACTION_AUDIO_BECOMING_NOISY")).printLog(TAG));
+ mmi.set(MediaMetrics.Property.DELAY_MS, 0).record(); // OK to return
return 0;
}
mDeviceBroker.postBroadcastBecomingNoisy();
delay = AudioService.BECOMING_NOISY_DELAY_MS;
}
+ mmi.set(MediaMetrics.Property.DELAY_MS, delay).record();
return delay;
}
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index f840f2d359d5..7cac376ea7ae 100755
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -88,6 +88,7 @@ import android.media.IStrategyPreferredDeviceDispatcher;
import android.media.IVolumeController;
import android.media.MediaExtractor;
import android.media.MediaFormat;
+import android.media.MediaMetrics;
import android.media.PlayerBase;
import android.media.VolumePolicy;
import android.media.audiofx.AudioEffect;
@@ -1880,6 +1881,16 @@ public class AudioService extends IAudioService.Stub
synchronized (mExtVolumeControllerLock) {
extVolCtlr = mExtVolumeController;
}
+ new MediaMetrics.Item(mMetricsId + "adjustSuggestedStreamVolume")
+ .setUid(Binder.getCallingUid())
+ .set(MediaMetrics.Property.CALLING_PACKAGE, callingPackage)
+ .set(MediaMetrics.Property.CLIENT_NAME, caller)
+ .set(MediaMetrics.Property.DIRECTION, direction > 0
+ ? MediaMetrics.Value.UP : MediaMetrics.Value.DOWN)
+ .set(MediaMetrics.Property.EXTERNAL, extVolCtlr != null
+ ? MediaMetrics.Value.YES : MediaMetrics.Value.NO)
+ .set(MediaMetrics.Property.FLAGS, flags)
+ .record();
if (extVolCtlr != null) {
sendMsg(mAudioHandler, MSG_NOTIFY_VOL_EVENT, SENDMSG_QUEUE,
direction, 0 /*ignored*/,
@@ -3141,21 +3152,32 @@ public class AudioService extends IAudioService.Stub
if (uid == android.os.Process.SYSTEM_UID) {
uid = UserHandle.getUid(userId, UserHandle.getAppId(uid));
}
+ MediaMetrics.Item mmi = new MediaMetrics.Item(MediaMetrics.Name.AUDIO_MIC)
+ .setUid(uid)
+ .set(MediaMetrics.Property.CALLING_PACKAGE, callingPackage)
+ .set(MediaMetrics.Property.EVENT, "setMicrophoneMute")
+ .set(MediaMetrics.Property.REQUEST, on
+ ? MediaMetrics.Value.MUTE : MediaMetrics.Value.UNMUTE);
+
// If OP_MUTE_MICROPHONE is set, disallow unmuting.
if (!on && mAppOps.noteOp(AppOpsManager.OP_MUTE_MICROPHONE, uid, callingPackage)
!= AppOpsManager.MODE_ALLOWED) {
+ mmi.set(MediaMetrics.Property.EARLY_RETURN, "disallow unmuting").record();
return;
}
if (!checkAudioSettingsPermission("setMicrophoneMute()")) {
+ mmi.set(MediaMetrics.Property.EARLY_RETURN, "!checkAudioSettingsPermission").record();
return;
}
if (userId != UserHandle.getCallingUserId() &&
mContext.checkCallingOrSelfPermission(
android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
!= PackageManager.PERMISSION_GRANTED) {
+ mmi.set(MediaMetrics.Property.EARLY_RETURN, "permission").record();
return;
}
mMicMuteFromApi = on;
+ mmi.record(); // record now, the no caller check will set the mute state.
setMicrophoneMuteNoCallerCheck(userId);
}
@@ -3167,6 +3189,12 @@ public class AudioService extends IAudioService.Stub
return;
}
mMicMuteFromSwitch = on;
+ new MediaMetrics.Item(MediaMetrics.Name.AUDIO_MIC)
+ .setUid(userId)
+ .set(MediaMetrics.Property.EVENT, "setMicrophoneMuteFromSwitch")
+ .set(MediaMetrics.Property.REQUEST, on
+ ? MediaMetrics.Value.MUTE : MediaMetrics.Value.UNMUTE)
+ .record();
setMicrophoneMuteNoCallerCheck(userId);
}
@@ -3207,6 +3235,17 @@ public class AudioService extends IAudioService.Stub
Log.e(TAG, "Error changing mic mute state to " + muted + " current:"
+ mMicMuteFromSystemCached);
}
+
+ new MediaMetrics.Item(MediaMetrics.Name.AUDIO_MIC)
+ .setUid(userId)
+ .set(MediaMetrics.Property.EVENT, "setMicrophoneMuteNoCallerCheck")
+ .set(MediaMetrics.Property.MUTE, mMicMuteFromSystemCached
+ ? MediaMetrics.Value.ON : MediaMetrics.Value.OFF)
+ .set(MediaMetrics.Property.REQUEST, muted
+ ? MediaMetrics.Value.MUTE : MediaMetrics.Value.UNMUTE)
+ .set(MediaMetrics.Property.STATUS, ret)
+ .record();
+
try {
// send the intent even if there was a failure to change the actual mute state:
// the AudioManager.setMicrophoneMute API doesn't have a return value to
@@ -3941,10 +3980,20 @@ public class AudioService extends IAudioService.Stub
}
// for logging only
+ final int uid = Binder.getCallingUid();
+ final int pid = Binder.getCallingPid();
final String eventSource = new StringBuilder("setSpeakerphoneOn(").append(on)
- .append(") from u/pid:").append(Binder.getCallingUid()).append("/")
- .append(Binder.getCallingPid()).toString();
+ .append(") from u/pid:").append(uid).append("/")
+ .append(pid).toString();
final boolean stateChanged = mDeviceBroker.setSpeakerphoneOn(on, eventSource);
+ new MediaMetrics.Item(MediaMetrics.Name.AUDIO_DEVICE
+ + MediaMetrics.SEPARATOR + "setSpeakerphoneOn")
+ .setUid(uid)
+ .setPid(pid)
+ .set(MediaMetrics.Property.STATE, on
+ ? MediaMetrics.Value.ON : MediaMetrics.Value.OFF)
+ .record();
+
if (stateChanged) {
final long ident = Binder.clearCallingIdentity();
try {
@@ -3975,9 +4024,19 @@ public class AudioService extends IAudioService.Stub
}
// for logging only
+ final int uid = Binder.getCallingUid();
+ final int pid = Binder.getCallingPid();
final String eventSource = new StringBuilder("setBluetoothScoOn(").append(on)
- .append(") from u/pid:").append(Binder.getCallingUid()).append("/")
- .append(Binder.getCallingPid()).toString();
+ .append(") from u/pid:").append(uid).append("/").append(pid).toString();
+
+ //bt sco
+ new MediaMetrics.Item(MediaMetrics.Name.AUDIO_DEVICE
+ + MediaMetrics.SEPARATOR + "setBluetoothScoOn")
+ .setUid(uid)
+ .setPid(pid)
+ .set(MediaMetrics.Property.STATE, on
+ ? MediaMetrics.Value.ON : MediaMetrics.Value.OFF)
+ .record();
mDeviceBroker.setBluetoothScoOn(on, eventSource);
}
@@ -3993,9 +4052,20 @@ public class AudioService extends IAudioService.Stub
/** @see AudioManager#setBluetoothA2dpOn(boolean) */
public void setBluetoothA2dpOn(boolean on) {
// for logging only
+ final int uid = Binder.getCallingUid();
+ final int pid = Binder.getCallingPid();
final String eventSource = new StringBuilder("setBluetoothA2dpOn(").append(on)
- .append(") from u/pid:").append(Binder.getCallingUid()).append("/")
- .append(Binder.getCallingPid()).toString();
+ .append(") from u/pid:").append(uid).append("/")
+ .append(pid).toString();
+
+ new MediaMetrics.Item(MediaMetrics.Name.AUDIO_DEVICE
+ + MediaMetrics.SEPARATOR + "setBluetoothA2dpOn")
+ .setUid(uid)
+ .setPid(pid)
+ .set(MediaMetrics.Property.STATE, on
+ ? MediaMetrics.Value.ON : MediaMetrics.Value.OFF)
+ .record();
+
mDeviceBroker.setBluetoothA2dpOn_Async(on, eventSource);
}
@@ -4006,31 +4076,59 @@ public class AudioService extends IAudioService.Stub
/** @see AudioManager#startBluetoothSco() */
public void startBluetoothSco(IBinder cb, int targetSdkVersion) {
+ final int uid = Binder.getCallingUid();
+ final int pid = Binder.getCallingPid();
final int scoAudioMode =
(targetSdkVersion < Build.VERSION_CODES.JELLY_BEAN_MR2) ?
BtHelper.SCO_MODE_VIRTUAL_CALL : BtHelper.SCO_MODE_UNDEFINED;
final String eventSource = new StringBuilder("startBluetoothSco()")
- .append(") from u/pid:").append(Binder.getCallingUid()).append("/")
- .append(Binder.getCallingPid()).toString();
+ .append(") from u/pid:").append(uid).append("/")
+ .append(pid).toString();
+
+ new MediaMetrics.Item(MediaMetrics.Name.AUDIO_BLUETOOTH)
+ .setUid(uid)
+ .setPid(pid)
+ .set(MediaMetrics.Property.EVENT, "startBluetoothSco")
+ .set(MediaMetrics.Property.SCO_AUDIO_MODE,
+ BtHelper.scoAudioModeToString(scoAudioMode))
+ .record();
startBluetoothScoInt(cb, scoAudioMode, eventSource);
+
}
/** @see AudioManager#startBluetoothScoVirtualCall() */
public void startBluetoothScoVirtualCall(IBinder cb) {
+ final int uid = Binder.getCallingUid();
+ final int pid = Binder.getCallingPid();
final String eventSource = new StringBuilder("startBluetoothScoVirtualCall()")
- .append(") from u/pid:").append(Binder.getCallingUid()).append("/")
- .append(Binder.getCallingPid()).toString();
+ .append(") from u/pid:").append(uid).append("/")
+ .append(pid).toString();
+
+ new MediaMetrics.Item(MediaMetrics.Name.AUDIO_BLUETOOTH)
+ .setUid(uid)
+ .setPid(pid)
+ .set(MediaMetrics.Property.EVENT, "startBluetoothScoVirtualCall")
+ .set(MediaMetrics.Property.SCO_AUDIO_MODE,
+ BtHelper.scoAudioModeToString(BtHelper.SCO_MODE_VIRTUAL_CALL))
+ .record();
startBluetoothScoInt(cb, BtHelper.SCO_MODE_VIRTUAL_CALL, eventSource);
}
void startBluetoothScoInt(IBinder cb, int scoAudioMode, @NonNull String eventSource) {
+ MediaMetrics.Item mmi = new MediaMetrics.Item(MediaMetrics.Name.AUDIO_BLUETOOTH)
+ .set(MediaMetrics.Property.EVENT, "startBluetoothScoInt")
+ .set(MediaMetrics.Property.SCO_AUDIO_MODE,
+ BtHelper.scoAudioModeToString(scoAudioMode));
+
if (!checkAudioSettingsPermission("startBluetoothSco()") ||
!mSystemReady) {
+ mmi.set(MediaMetrics.Property.EARLY_RETURN, "permission or systemReady").record();
return;
}
synchronized (mDeviceBroker.mSetModeLock) {
mDeviceBroker.startBluetoothScoForClient_Sync(cb, scoAudioMode, eventSource);
}
+ mmi.record();
}
/** @see AudioManager#stopBluetoothSco() */
@@ -4039,12 +4137,21 @@ public class AudioService extends IAudioService.Stub
!mSystemReady) {
return;
}
+ final int uid = Binder.getCallingUid();
+ final int pid = Binder.getCallingPid();
final String eventSource = new StringBuilder("stopBluetoothSco()")
- .append(") from u/pid:").append(Binder.getCallingUid()).append("/")
- .append(Binder.getCallingPid()).toString();
+ .append(") from u/pid:").append(uid).append("/")
+ .append(pid).toString();
synchronized (mDeviceBroker.mSetModeLock) {
mDeviceBroker.stopBluetoothScoForClient_Sync(cb, eventSource);
}
+ new MediaMetrics.Item(MediaMetrics.Name.AUDIO_BLUETOOTH)
+ .setUid(uid)
+ .setPid(pid)
+ .set(MediaMetrics.Property.EVENT, "stopBluetoothSco")
+ .set(MediaMetrics.Property.SCO_AUDIO_MODE,
+ BtHelper.scoAudioModeToString(BtHelper.SCO_MODE_UNDEFINED))
+ .record();
}
@@ -4806,6 +4913,14 @@ public class AudioService extends IAudioService.Stub
&& state != CONNECTION_STATE_DISCONNECTED) {
throw new IllegalArgumentException("Invalid state " + state);
}
+ new MediaMetrics.Item(mMetricsId + "setWiredDeviceConnectionState")
+ .set(MediaMetrics.Property.ADDRESS, address)
+ .set(MediaMetrics.Property.CLIENT_NAME, caller)
+ .set(MediaMetrics.Property.DEVICE, AudioSystem.getDeviceName(type))
+ .set(MediaMetrics.Property.NAME, name)
+ .set(MediaMetrics.Property.STATE,
+ state == CONNECTION_STATE_CONNECTED ? "connected" : "disconnected")
+ .record();
mDeviceBroker.setWiredDeviceConnectionState(type, state, address, name, caller);
}
@@ -5266,7 +5381,32 @@ public class AudioService extends IAudioService.Stub
private String mVolumeIndexSettingName;
private int mObservedDevices;
- private final SparseIntArray mIndexMap = new SparseIntArray(8);
+ private final SparseIntArray mIndexMap = new SparseIntArray(8) {
+ @Override
+ public void put(int key, int value) {
+ super.put(key, value);
+ record("put", key, value);
+ }
+ @Override
+ public void setValueAt(int index, int value) {
+ super.setValueAt(index, value);
+ record("setValueAt", keyAt(index), value);
+ }
+
+ // Record all changes in the VolumeStreamState
+ private void record(String event, int key, int value) {
+ final String device = key == AudioSystem.DEVICE_OUT_DEFAULT ? "default"
+ : AudioSystem.getOutputDeviceName(key);
+ new MediaMetrics.Item(MediaMetrics.Name.AUDIO_VOLUME + MediaMetrics.SEPARATOR
+ + AudioSystem.streamToString(mStreamType)
+ + "." + device)
+ .set(MediaMetrics.Property.EVENT, event)
+ .set(MediaMetrics.Property.INDEX, value)
+ .set(MediaMetrics.Property.MIN_INDEX, mIndexMin)
+ .set(MediaMetrics.Property.MAX_INDEX, mIndexMax)
+ .record();
+ }
+ };
private final Intent mVolumeChanged;
private final Intent mStreamDevicesChanged;
@@ -5949,6 +6089,13 @@ public class AudioService extends IAudioService.Stub
+ eventSource);
break;
}
+ new MediaMetrics.Item(MediaMetrics.Name.AUDIO_FORCE_USE
+ + MediaMetrics.SEPARATOR + AudioSystem.forceUseUsageToString(useCase))
+ .set(MediaMetrics.Property.EVENT, "setForceUse")
+ .set(MediaMetrics.Property.FORCE_USE_DUE_TO, eventSource)
+ .set(MediaMetrics.Property.FORCE_USE_MODE,
+ AudioSystem.forceUseConfigToString(config))
+ .record();
sForceUseLogger.log(
new AudioServiceEvents.ForceUseEvent(useCase, config, eventSource));
AudioSystem.setForceUse(useCase, config);
@@ -6450,23 +6597,42 @@ public class AudioService extends IAudioService.Stub
public int requestAudioFocus(AudioAttributes aa, int durationHint, IBinder cb,
IAudioFocusDispatcher fd, String clientId, String callingPackageName, int flags,
IAudioPolicyCallback pcb, int sdk) {
+ final int uid = Binder.getCallingUid();
+ MediaMetrics.Item mmi = new MediaMetrics.Item(mMetricsId + "focus")
+ .setUid(uid)
+ //.putInt("durationHint", durationHint)
+ .set(MediaMetrics.Property.CALLING_PACKAGE, callingPackageName)
+ .set(MediaMetrics.Property.CLIENT_NAME, clientId)
+ .set(MediaMetrics.Property.EVENT, "requestAudioFocus")
+ .set(MediaMetrics.Property.FLAGS, flags);
+
// permission checks
if (aa != null && !isValidAudioAttributesUsage(aa)) {
- Log.w(TAG, "Request using unsupported usage.");
+ final String reason = "Request using unsupported usage";
+ Log.w(TAG, reason);
+ mmi.set(MediaMetrics.Property.EARLY_RETURN, reason)
+ .record();
return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
}
if ((flags & AudioManager.AUDIOFOCUS_FLAG_LOCK) == AudioManager.AUDIOFOCUS_FLAG_LOCK) {
if (AudioSystem.IN_VOICE_COMM_FOCUS_ID.equals(clientId)) {
if (PackageManager.PERMISSION_GRANTED != mContext.checkCallingOrSelfPermission(
android.Manifest.permission.MODIFY_PHONE_STATE)) {
- Log.e(TAG, "Invalid permission to (un)lock audio focus", new Exception());
+ final String reason = "Invalid permission to (un)lock audio focus";
+ Log.e(TAG, reason, new Exception());
+ mmi.set(MediaMetrics.Property.EARLY_RETURN, reason)
+ .record();
return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
}
} else {
// only a registered audio policy can be used to lock focus
synchronized (mAudioPolicies) {
if (!mAudioPolicies.containsKey(pcb.asBinder())) {
- Log.e(TAG, "Invalid unregistered AudioPolicy to (un)lock audio focus");
+ final String reason =
+ "Invalid unregistered AudioPolicy to (un)lock audio focus";
+ Log.e(TAG, reason);
+ mmi.set(MediaMetrics.Property.EARLY_RETURN, reason)
+ .record();
return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
}
}
@@ -6474,25 +6640,40 @@ public class AudioService extends IAudioService.Stub
}
if (callingPackageName == null || clientId == null || aa == null) {
- Log.e(TAG, "Invalid null parameter to request audio focus");
+ final String reason = "Invalid null parameter to request audio focus";
+ Log.e(TAG, reason);
+ mmi.set(MediaMetrics.Property.EARLY_RETURN, reason)
+ .record();
return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
}
-
+ mmi.record();
return mMediaFocusControl.requestAudioFocus(aa, durationHint, cb, fd,
clientId, callingPackageName, flags, sdk,
- forceFocusDuckingForAccessibility(aa, durationHint, Binder.getCallingUid()));
+ forceFocusDuckingForAccessibility(aa, durationHint, uid));
}
public int abandonAudioFocus(IAudioFocusDispatcher fd, String clientId, AudioAttributes aa,
String callingPackageName) {
+ MediaMetrics.Item mmi = new MediaMetrics.Item(mMetricsId + "focus")
+ .set(MediaMetrics.Property.CALLING_PACKAGE, callingPackageName)
+ .set(MediaMetrics.Property.CLIENT_NAME, clientId)
+ .set(MediaMetrics.Property.EVENT, "abandonAudioFocus");
+
if (aa != null && !isValidAudioAttributesUsage(aa)) {
Log.w(TAG, "Request using unsupported usage.");
+ mmi.set(MediaMetrics.Property.EARLY_RETURN, "unsupported usage").record();
+
return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
}
+ mmi.record();
return mMediaFocusControl.abandonAudioFocus(fd, clientId, aa, callingPackageName);
}
public void unregisterAudioFocusClient(String clientId) {
+ new MediaMetrics.Item(mMetricsId + "focus")
+ .set(MediaMetrics.Property.CLIENT_NAME, clientId)
+ .set(MediaMetrics.Property.EVENT, "unregisterAudioFocusClient")
+ .record();
mMediaFocusControl.unregisterAudioFocusClient(clientId);
}
@@ -7066,6 +7247,12 @@ public class AudioService extends IAudioService.Stub
}
}
+ /**
+ * Audio Analytics ids.
+ */
+ private static final String mMetricsId = MediaMetrics.Name.AUDIO_SERVICE
+ + MediaMetrics.SEPARATOR;
+
private static String safeMediaVolumeStateToString(int state) {
switch(state) {
case SAFE_MEDIA_VOLUME_NOT_CONFIGURED: return "SAFE_MEDIA_VOLUME_NOT_CONFIGURED";
diff --git a/services/core/java/com/android/server/audio/AudioServiceEvents.java b/services/core/java/com/android/server/audio/AudioServiceEvents.java
index add620e74df0..591356746e38 100644
--- a/services/core/java/com/android/server/audio/AudioServiceEvents.java
+++ b/services/core/java/com/android/server/audio/AudioServiceEvents.java
@@ -19,6 +19,7 @@ package com.android.server.audio;
import android.media.AudioAttributes;
import android.media.AudioManager;
import android.media.AudioSystem;
+import android.media.MediaMetrics;
import com.android.server.audio.AudioDeviceInventory.WiredDeviceConnectionState;
@@ -120,6 +121,7 @@ public class AudioServiceEvents {
mCaller = caller;
mGroupName = null;
mAudioAttributes = null;
+ logMetricEvent();
}
/** used for VOL_SET_HEARING_AID_VOL*/
@@ -132,6 +134,7 @@ public class AudioServiceEvents {
mCaller = null;
mGroupName = null;
mAudioAttributes = null;
+ logMetricEvent();
}
/** used for VOL_SET_AVRCP_VOL */
@@ -144,6 +147,7 @@ public class AudioServiceEvents {
mCaller = null;
mGroupName = null;
mAudioAttributes = null;
+ logMetricEvent();
}
/** used for VOL_VOICE_ACTIVITY_HEARING_AID */
@@ -156,6 +160,7 @@ public class AudioServiceEvents {
mCaller = null;
mGroupName = null;
mAudioAttributes = null;
+ logMetricEvent();
}
/** used for VOL_MODE_CHANGE_HEARING_AID */
@@ -168,6 +173,7 @@ public class AudioServiceEvents {
mCaller = null;
mGroupName = null;
mAudioAttributes = null;
+ logMetricEvent();
}
/** used for VOL_SET_GROUP_VOL */
@@ -179,6 +185,102 @@ public class AudioServiceEvents {
mCaller = caller;
mGroupName = group;
mAudioAttributes = aa;
+ logMetricEvent();
+ }
+
+
+ /**
+ * Audio Analytics unique Id.
+ */
+ private static final String mMetricsId = MediaMetrics.Name.AUDIO_VOLUME_EVENT;
+
+ /**
+ * Log mediametrics event
+ */
+ private void logMetricEvent() {
+ switch (mOp) {
+ case VOL_ADJUST_SUGG_VOL:
+ case VOL_ADJUST_VOL_UID:
+ case VOL_ADJUST_STREAM_VOL: {
+ String eventName;
+ switch (mOp) {
+ case VOL_ADJUST_SUGG_VOL:
+ eventName = "adjustSuggestedStreamVolume";
+ break;
+ case VOL_ADJUST_STREAM_VOL:
+ eventName = "adjustStreamVolume";
+ break;
+ case VOL_ADJUST_VOL_UID:
+ eventName = "adjustStreamVolumeForUid";
+ break;
+ default:
+ return; // not possible, just return here
+ }
+ new MediaMetrics.Item(mMetricsId)
+ .set(MediaMetrics.Property.CALLING_PACKAGE, mCaller)
+ .set(MediaMetrics.Property.DIRECTION, mVal1 > 0 ? "up" : "down")
+ .set(MediaMetrics.Property.EVENT, eventName)
+ .set(MediaMetrics.Property.FLAGS, mVal2)
+ .set(MediaMetrics.Property.STREAM_TYPE,
+ AudioSystem.streamToString(mStream))
+ .record();
+ return;
+ }
+ case VOL_SET_STREAM_VOL:
+ new MediaMetrics.Item(mMetricsId)
+ .set(MediaMetrics.Property.CALLING_PACKAGE, mCaller)
+ .set(MediaMetrics.Property.EVENT, "setStreamVolume")
+ .set(MediaMetrics.Property.FLAGS, mVal2)
+ .set(MediaMetrics.Property.INDEX, mVal1)
+ .set(MediaMetrics.Property.STREAM_TYPE,
+ AudioSystem.streamToString(mStream))
+ .record();
+ return;
+ case VOL_SET_HEARING_AID_VOL:
+ new MediaMetrics.Item(mMetricsId)
+ .set(MediaMetrics.Property.EVENT, "setHearingAidVolume")
+ .set(MediaMetrics.Property.GAIN_DB, (double) mVal2)
+ .set(MediaMetrics.Property.INDEX, mVal1)
+ .record();
+ return;
+ case VOL_SET_AVRCP_VOL:
+ new MediaMetrics.Item(mMetricsId)
+ .set(MediaMetrics.Property.EVENT, "setAvrcpVolume")
+ .set(MediaMetrics.Property.INDEX, mVal1)
+ .record();
+ return;
+ case VOL_VOICE_ACTIVITY_HEARING_AID:
+ new MediaMetrics.Item(mMetricsId)
+ .set(MediaMetrics.Property.EVENT, "voiceActivityHearingAid")
+ .set(MediaMetrics.Property.INDEX, mVal1)
+ .set(MediaMetrics.Property.STATE,
+ mVal2 == 1 ? "active" : "inactive")
+ .set(MediaMetrics.Property.STREAM_TYPE,
+ AudioSystem.streamToString(mStream))
+ .record();
+ return;
+ case VOL_MODE_CHANGE_HEARING_AID:
+ new MediaMetrics.Item(mMetricsId)
+ .set(MediaMetrics.Property.EVENT, "modeChangeHearingAid")
+ .set(MediaMetrics.Property.INDEX, mVal1)
+ .set(MediaMetrics.Property.MODE, AudioSystem.modeToString(mVal2))
+ .set(MediaMetrics.Property.STREAM_TYPE,
+ AudioSystem.streamToString(mStream))
+ .record();
+ return;
+ case VOL_SET_GROUP_VOL:
+ new MediaMetrics.Item(mMetricsId)
+ .set(MediaMetrics.Property.ATTRIBUTES, mAudioAttributes.toString())
+ .set(MediaMetrics.Property.CALLING_PACKAGE, mCaller)
+ .set(MediaMetrics.Property.EVENT, "setVolumeIndexForAttributes")
+ .set(MediaMetrics.Property.FLAGS, mVal2)
+ .set(MediaMetrics.Property.GROUP, mGroupName)
+ .set(MediaMetrics.Property.INDEX, mVal1)
+ .record();
+ return;
+ default:
+ return;
+ }
}
@Override
diff --git a/services/core/java/com/android/server/audio/BtHelper.java b/services/core/java/com/android/server/audio/BtHelper.java
index 93d1bede9de8..accb90cc3c0c 100644
--- a/services/core/java/com/android/server/audio/BtHelper.java
+++ b/services/core/java/com/android/server/audio/BtHelper.java
@@ -113,6 +113,24 @@ public class BtHelper {
private static final int BT_HEARING_AID_GAIN_MIN = -128;
+ /**
+ * Returns a string representation of the scoAudioMode.
+ */
+ public static String scoAudioModeToString(int scoAudioMode) {
+ switch (scoAudioMode) {
+ case SCO_MODE_UNDEFINED:
+ return "SCO_MODE_UNDEFINED";
+ case SCO_MODE_VIRTUAL_CALL:
+ return "SCO_MODE_VIRTUAL_CALL";
+ case SCO_MODE_RAW:
+ return "SCO_MODE_RAW";
+ case SCO_MODE_VR:
+ return "SCO_MODE_VR";
+ default:
+ return "SCO_MODE_(" + scoAudioMode + ")";
+ }
+ }
+
//----------------------------------------------------------------------
/*package*/ static class BluetoothA2dpDeviceInfo {
private final @NonNull BluetoothDevice mBtDevice;
@@ -965,4 +983,27 @@ public class BtHelper {
return AudioSystem.AUDIO_FORMAT_DEFAULT;
}
}
+
+ /**
+ * Returns the String equivalent of the btCodecType.
+ *
+ * This uses an "ENCODING_" prefix for consistency with Audio;
+ * we could alternately use the "SOURCE_CODEC_TYPE_" prefix from Bluetooth.
+ */
+ public static String bluetoothCodecToEncodingString(int btCodecType) {
+ switch (btCodecType) {
+ case BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC:
+ return "ENCODING_SBC";
+ case BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC:
+ return "ENCODING_AAC";
+ case BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX:
+ return "ENCODING_APTX";
+ case BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD:
+ return "ENCODING_APTX_HD";
+ case BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC:
+ return "ENCODING_LDAC";
+ default:
+ return "ENCODING_BT_CODEC_TYPE(" + btCodecType + ")";
+ }
+ }
}
diff --git a/services/core/java/com/android/server/audio/MediaFocusControl.java b/services/core/java/com/android/server/audio/MediaFocusControl.java
index bfab9919258c..26281b739436 100755
--- a/services/core/java/com/android/server/audio/MediaFocusControl.java
+++ b/services/core/java/com/android/server/audio/MediaFocusControl.java
@@ -25,6 +25,7 @@ import android.media.AudioFocusInfo;
import android.media.AudioManager;
import android.media.AudioSystem;
import android.media.IAudioFocusDispatcher;
+import android.media.MediaMetrics;
import android.media.audiopolicy.IAudioPolicyCallback;
import android.os.Binder;
import android.os.Build;
@@ -144,6 +145,8 @@ public class MediaFocusControl implements PlayerFocusEnforcer {
private static final AudioEventLogger mEventLogger = new AudioEventLogger(50,
"focus commands as seen by MediaFocusControl");
+ private static final String mMetricsId = MediaMetrics.Name.AUDIO_FOCUS;
+
/*package*/ void noFocusForSuspendedApp(@NonNull String packageName, int uid) {
synchronized (mAudioFocusLock) {
final Iterator<FocusRequester> stackIterator = mFocusStack.iterator();
@@ -818,6 +821,17 @@ public class MediaFocusControl implements PlayerFocusEnforcer {
protected int requestAudioFocus(@NonNull AudioAttributes aa, int focusChangeHint, IBinder cb,
IAudioFocusDispatcher fd, @NonNull String clientId, @NonNull String callingPackageName,
int flags, int sdk, boolean forceDuck) {
+ new MediaMetrics.Item(mMetricsId)
+ .setUid(Binder.getCallingUid())
+ .set(MediaMetrics.Property.CALLING_PACKAGE, callingPackageName)
+ .set(MediaMetrics.Property.CLIENT_NAME, clientId)
+ .set(MediaMetrics.Property.EVENT, "requestAudioFocus")
+ .set(MediaMetrics.Property.FLAGS, flags)
+ .set(MediaMetrics.Property.FOCUS_CHANGE_HINT,
+ AudioManager.audioFocusToString(focusChangeHint))
+ //.set(MediaMetrics.Property.SDK, sdk)
+ .record();
+
mEventLogger.log((new AudioEventLogger.StringEvent(
"requestAudioFocus() from uid/pid " + Binder.getCallingUid()
+ "/" + Binder.getCallingPid()
@@ -982,6 +996,13 @@ public class MediaFocusControl implements PlayerFocusEnforcer {
* */
protected int abandonAudioFocus(IAudioFocusDispatcher fl, String clientId, AudioAttributes aa,
String callingPackageName) {
+ new MediaMetrics.Item(mMetricsId)
+ .setUid(Binder.getCallingUid())
+ .set(MediaMetrics.Property.CALLING_PACKAGE, callingPackageName)
+ .set(MediaMetrics.Property.CLIENT_NAME, clientId)
+ .set(MediaMetrics.Property.EVENT, "abandonAudioFocus")
+ .record();
+
// AudioAttributes are currently ignored, to be used for zones / a11y
mEventLogger.log((new AudioEventLogger.StringEvent(
"abandonAudioFocus() from uid/pid " + Binder.getCallingUid()
diff --git a/services/core/java/com/android/server/display/AutomaticBrightnessController.java b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
index f4d7f9ac5a5e..36d69c93c1cb 100644
--- a/services/core/java/com/android/server/display/AutomaticBrightnessController.java
+++ b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
@@ -89,10 +89,8 @@ class AutomaticBrightnessController {
private final BrightnessMappingStrategy mBrightnessMapper;
// The minimum and maximum screen brightnesses.
- private final int mScreenBrightnessRangeMinimum;
- private final int mScreenBrightnessRangeMaximum;
- private final float mScreenBrightnessRangeMinimumFloat;
- private final float mScreenBrightnessRangeMaximumFloat;
+ private final float mScreenBrightnessRangeMinimum;
+ private final float mScreenBrightnessRangeMaximum;
// How much to scale doze brightness by (should be (0, 1.0]).
private final float mDozeScaleFactor;
@@ -156,7 +154,6 @@ class AutomaticBrightnessController {
// The screen brightness threshold at which to brighten or darken the screen.
private float mScreenBrighteningThreshold;
private float mScreenDarkeningThreshold;
-
// The most recent light sample.
private float mLastObservedLux;
@@ -177,8 +174,9 @@ class AutomaticBrightnessController {
// We preserve this value even when we stop using the light sensor so
// that we can quickly revert to the previous auto-brightness level
// while the light sensor warms up.
- // Use -1 if there is no current auto-brightness value available.
- private int mScreenAutoBrightness = PowerManager.BRIGHTNESS_INVALID;
+ // Use PowerManager.BRIGHTNESS_INVALID_FLOAT if there is no current auto-brightness value
+ // available.
+ private float mScreenAutoBrightness = PowerManager.BRIGHTNESS_INVALID_FLOAT;
// The current display policy. This is useful, for example, for knowing when we're dozing,
// where the light sensor may not be available.
@@ -188,7 +186,7 @@ class AutomaticBrightnessController {
// for the initial state of the sample.
private boolean mBrightnessAdjustmentSamplePending;
private float mBrightnessAdjustmentSampleOldLux;
- private int mBrightnessAdjustmentSampleOldBrightness;
+ private float mBrightnessAdjustmentSampleOldBrightness;
// When the short term model is invalidated, we don't necessarily reset it (i.e. clear the
// user's adjustment) immediately, but wait for a drastic enough change in the ambient light.
@@ -243,13 +241,8 @@ class AutomaticBrightnessController {
mCallbacks = callbacks;
mSensorManager = sensorManager;
mBrightnessMapper = mapper;
- mScreenBrightnessRangeMinimum =
- BrightnessSynchronizer.brightnessFloatToInt(mContext, brightnessMin);
- mScreenBrightnessRangeMaximum =
- com.android.internal.BrightnessSynchronizer.brightnessFloatToInt(
- mContext, brightnessMax);
- mScreenBrightnessRangeMinimumFloat = brightnessMin;
- mScreenBrightnessRangeMaximumFloat = brightnessMax;
+ mScreenBrightnessRangeMinimum = brightnessMin;
+ mScreenBrightnessRangeMaximum = brightnessMax;
mLightSensorWarmUpTimeConfig = lightSensorWarmUpTime;
mDozeScaleFactor = dozeScaleFactor;
mNormalLightSensorRate = lightSensorRate;
@@ -299,12 +292,12 @@ class AutomaticBrightnessController {
return true;
}
- public int getAutomaticScreenBrightness() {
+ public float getAutomaticScreenBrightness() {
if (!mAmbientLuxValid) {
- return -1;
+ return PowerManager.BRIGHTNESS_INVALID_FLOAT;
}
if (mDisplayPolicy == DisplayPowerRequest.POLICY_DOZE) {
- return Math.round(mScreenAutoBrightness * mDozeScaleFactor);
+ return mScreenAutoBrightness * mDozeScaleFactor;
}
return mScreenAutoBrightness;
}
@@ -385,7 +378,7 @@ class AutomaticBrightnessController {
private boolean setScreenBrightnessByUser(float brightness) {
if (!mAmbientLuxValid) {
- // If we don't have a valid ambient lux then we don't have a valid brightness anyways,
+ // If we don't have a valid ambient lux then we don't have a valid brightness anyway,
// and we can't use this data to add a new control point to the short-term model.
return false;
}
@@ -486,7 +479,7 @@ class AutomaticBrightnessController {
} else if (mLightSensorEnabled) {
mLightSensorEnabled = false;
mAmbientLuxValid = !mResetAmbientLuxAfterWarmUpConfig;
- mScreenAutoBrightness = PowerManager.BRIGHTNESS_INVALID;
+ mScreenAutoBrightness = PowerManager.BRIGHTNESS_INVALID_FLOAT;
mRecentLightSamples = 0;
mAmbientLightRingBuffer.clear();
mCurrentLightSensorRate = -1;
@@ -735,29 +728,28 @@ class AutomaticBrightnessController {
float value = mBrightnessMapper.getBrightness(mAmbientLux, mForegroundAppPackageName,
mForegroundAppCategory);
- int newScreenAutoBrightness = BrightnessSynchronizer.brightnessFloatToInt(
- mContext, clampScreenBrightnessFloat(value));
+ float newScreenAutoBrightness = clampScreenBrightness(value);
// If screenAutoBrightness is set, we should have screen{Brightening,Darkening}Threshold,
// in which case we ignore the new screen brightness if it doesn't differ enough from the
// previous one.
- if (mScreenAutoBrightness != -1
+ if (!Float.isNaN(mScreenAutoBrightness)
&& !isManuallySet
&& newScreenAutoBrightness > mScreenDarkeningThreshold
&& newScreenAutoBrightness < mScreenBrighteningThreshold) {
if (mLoggingEnabled) {
- Slog.d(TAG, "ignoring newScreenAutoBrightness: " + mScreenDarkeningThreshold
- + " < " + newScreenAutoBrightness + " < " + mScreenBrighteningThreshold);
+ Slog.d(TAG, "ignoring newScreenAutoBrightness: "
+ + mScreenDarkeningThreshold + " < " + newScreenAutoBrightness
+ + " < " + mScreenBrighteningThreshold);
}
return;
}
-
- if (mScreenAutoBrightness != newScreenAutoBrightness) {
+ if (!BrightnessSynchronizer.floatEquals(mScreenAutoBrightness,
+ newScreenAutoBrightness)) {
if (mLoggingEnabled) {
- Slog.d(TAG, "updateAutoBrightness: " +
- "mScreenAutoBrightness=" + mScreenAutoBrightness + ", " +
- "newScreenAutoBrightness=" + newScreenAutoBrightness);
+ Slog.d(TAG, "updateAutoBrightness: "
+ + "mScreenAutoBrightness=" + mScreenAutoBrightness + ", "
+ + "newScreenAutoBrightness=" + newScreenAutoBrightness);
}
-
mScreenAutoBrightness = newScreenAutoBrightness;
mScreenBrighteningThreshold = clampScreenBrightness(
mScreenBrightnessThresholds.getBrighteningThreshold(newScreenAutoBrightness));
@@ -770,19 +762,12 @@ class AutomaticBrightnessController {
}
}
- // Clamps values with float range [1.0-255.0]
- // TODO(brightnessfloat): convert everything that uses this to float system
+ // Clamps values with float range [0.0-1.0]
private float clampScreenBrightness(float value) {
return MathUtils.constrain(value,
mScreenBrightnessRangeMinimum, mScreenBrightnessRangeMaximum);
}
- // Clamps values with float range [0.0-1.0]
- private float clampScreenBrightnessFloat(float value) {
- return MathUtils.constrain(value,
- mScreenBrightnessRangeMinimumFloat, mScreenBrightnessRangeMaximumFloat);
- }
-
private void prepareBrightnessAdjustmentSample() {
if (!mBrightnessAdjustmentSamplePending) {
mBrightnessAdjustmentSamplePending = true;
@@ -806,12 +791,13 @@ class AutomaticBrightnessController {
private void collectBrightnessAdjustmentSample() {
if (mBrightnessAdjustmentSamplePending) {
mBrightnessAdjustmentSamplePending = false;
- if (mAmbientLuxValid && mScreenAutoBrightness >= 0) {
+ if (mAmbientLuxValid && (mScreenAutoBrightness >= PowerManager.BRIGHTNESS_MIN
+ || mScreenAutoBrightness == PowerManager.BRIGHTNESS_OFF_FLOAT)) {
if (mLoggingEnabled) {
- Slog.d(TAG, "Auto-brightness adjustment changed by user: " +
- "lux=" + mAmbientLux + ", " +
- "brightness=" + mScreenAutoBrightness + ", " +
- "ring=" + mAmbientLightRingBuffer);
+ Slog.d(TAG, "Auto-brightness adjustment changed by user: "
+ + "lux=" + mAmbientLux + ", "
+ + "brightness=" + mScreenAutoBrightness + ", "
+ + "ring=" + mAmbientLightRingBuffer);
}
EventLog.writeEvent(EventLogTags.AUTO_BRIGHTNESS_ADJ,
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index 48e30bf42c2d..bafeb77c55e6 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -948,8 +948,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
if (Float.isNaN(brightnessState)) {
float newAutoBrightnessAdjustment = autoBrightnessAdjustment;
if (autoBrightnessEnabled) {
- brightnessState = BrightnessSynchronizer.brightnessIntToFloat(
- mContext, mAutomaticBrightnessController.getAutomaticScreenBrightness());
+ brightnessState = mAutomaticBrightnessController.getAutomaticScreenBrightness();
newAutoBrightnessAdjustment =
mAutomaticBrightnessController.getAutomaticScreenBrightnessAdjustment();
}
diff --git a/services/core/java/com/android/server/display/HysteresisLevels.java b/services/core/java/com/android/server/display/HysteresisLevels.java
index f0a505d4d818..2b565698ff8c 100644
--- a/services/core/java/com/android/server/display/HysteresisLevels.java
+++ b/services/core/java/com/android/server/display/HysteresisLevels.java
@@ -64,8 +64,8 @@ public class HysteresisLevels {
* Return the brightening hysteresis threshold for the given value level.
*/
public float getBrighteningThreshold(float value) {
- float brightConstant = getReferenceLevel(value, mBrighteningThresholds);
- float brightThreshold = value * (1.0f + brightConstant);
+ final float brightConstant = getReferenceLevel(value, mBrighteningThresholds);
+ final float brightThreshold = value * (1.0f + brightConstant);
if (DEBUG) {
Slog.d(TAG, "bright hysteresis constant=" + brightConstant + ", threshold="
+ brightThreshold + ", value=" + value);
@@ -77,8 +77,8 @@ public class HysteresisLevels {
* Return the darkening hysteresis threshold for the given value level.
*/
public float getDarkeningThreshold(float value) {
- float darkConstant = getReferenceLevel(value, mDarkeningThresholds);
- float darkThreshold = value * (1.0f - darkConstant);
+ final float darkConstant = getReferenceLevel(value, mDarkeningThresholds);
+ final float darkThreshold = value * (1.0f - darkConstant);
if (DEBUG) {
Slog.d(TAG, "dark hysteresis constant=: " + darkConstant + ", threshold="
+ darkThreshold + ", value=" + value);
diff --git a/services/core/java/com/android/server/pm/DataLoaderManagerService.java b/services/core/java/com/android/server/pm/DataLoaderManagerService.java
index ae9c38498b10..062e9e15b519 100644
--- a/services/core/java/com/android/server/pm/DataLoaderManagerService.java
+++ b/services/core/java/com/android/server/pm/DataLoaderManagerService.java
@@ -38,6 +38,8 @@ import android.util.SparseArray;
import com.android.internal.annotations.GuardedBy;
import com.android.server.SystemService;
+import libcore.io.IoUtils;
+
import java.util.List;
/**
@@ -64,31 +66,52 @@ public class DataLoaderManagerService extends SystemService {
publishBinderService(Context.DATA_LOADER_MANAGER_SERVICE, mBinderService);
}
+ private static void closeQuietly(FileSystemControlParcel control) {
+ if (control == null || control.incremental == null) {
+ return;
+ }
+ IoUtils.closeQuietly(control.incremental.cmd);
+ IoUtils.closeQuietly(control.incremental.pendingReads);
+ IoUtils.closeQuietly(control.incremental.log);
+ }
+
final class DataLoaderManagerBinderService extends IDataLoaderManager.Stub {
@Override
public boolean initializeDataLoader(int dataLoaderId, DataLoaderParamsParcel params,
FileSystemControlParcel control, IDataLoaderStatusListener listener) {
- synchronized (mLock) {
- if (mServiceConnections.get(dataLoaderId) != null) {
- Slog.e(TAG, "Data loader of ID=" + dataLoaderId + " already exists.");
+ DataLoaderServiceConnection connection = null;
+ try {
+ synchronized (mLock) {
+ if (mServiceConnections.get(dataLoaderId) != null) {
+ Slog.e(TAG, "Data loader of ID=" + dataLoaderId + " already exists.");
+ return false;
+ }
+ }
+ ComponentName componentName =
+ new ComponentName(params.packageName, params.className);
+ ComponentName dataLoaderComponent = resolveDataLoaderComponentName(componentName);
+ if (dataLoaderComponent == null) {
return false;
}
- }
- ComponentName componentName = new ComponentName(params.packageName, params.className);
- ComponentName dataLoaderComponent = resolveDataLoaderComponentName(componentName);
- if (dataLoaderComponent == null) {
- return false;
- }
- // Binds to the specific data loader service
- DataLoaderServiceConnection connection =
- new DataLoaderServiceConnection(dataLoaderId, params, control, listener);
- Intent intent = new Intent();
- intent.setComponent(dataLoaderComponent);
- if (!mContext.bindServiceAsUser(intent, connection, Context.BIND_AUTO_CREATE,
- UserHandle.of(UserHandle.getCallingUserId()))) {
- Slog.e(TAG, "Failed to bind to data loader binder service.");
- mContext.unbindService(connection);
- return false;
+ // Binds to the specific data loader service
+ connection =
+ new DataLoaderServiceConnection(dataLoaderId, params,
+ control, listener);
+ control = null; // now connection manages it
+ Intent intent = new Intent();
+ intent.setComponent(dataLoaderComponent);
+ if (!mContext.bindServiceAsUser(intent, connection, Context.BIND_AUTO_CREATE,
+ UserHandle.of(UserHandle.getCallingUserId()))) {
+ Slog.e(TAG, "Failed to bind to data loader binder service.");
+ mContext.unbindService(connection);
+ return false;
+ }
+ connection = null;
+ } finally {
+ DataLoaderManagerService.closeQuietly(control);
+ if (connection != null) {
+ connection.close();
+ }
}
return true;
}
@@ -173,7 +196,7 @@ public class DataLoaderManagerService extends SystemService {
}
}
- class DataLoaderServiceConnection implements ServiceConnection {
+ class DataLoaderServiceConnection implements ServiceConnection, AutoCloseable {
final int mId;
final DataLoaderParamsParcel mParams;
final FileSystemControlParcel mControl;
@@ -204,15 +227,34 @@ public class DataLoaderManagerService extends SystemService {
@Override
public void onServiceDisconnected(ComponentName arg0) {
- if (mListener != null) {
- try {
- mListener.onStatusChanged(mId, IDataLoaderStatusListener.DATA_LOADER_DESTROYED);
- } catch (RemoteException ignored) {
- }
- }
+ Slog.i(TAG, "DataLoader " + mId + " disconnected, but will try to recover");
+ callListener(IDataLoaderStatusListener.DATA_LOADER_DESTROYED);
remove();
}
+ @Override
+ public void onBindingDied(ComponentName name) {
+ Slog.i(TAG, "DataLoader " + mId + " died");
+ callListener(IDataLoaderStatusListener.DATA_LOADER_DESTROYED);
+ mContext.unbindService(this);
+ close();
+ remove();
+ }
+
+ @Override
+ public void onNullBinding(ComponentName name) {
+ Slog.i(TAG, "DataLoader " + mId + " failed to start");
+ callListener(IDataLoaderStatusListener.DATA_LOADER_DESTROYED);
+ mContext.unbindService(this);
+ close();
+ remove();
+ }
+
+ @Override
+ public void close() {
+ DataLoaderManagerService.closeQuietly(mControl);
+ }
+
IDataLoader getDataLoader() {
return mDataLoader;
}
@@ -223,6 +265,8 @@ public class DataLoaderManagerService extends SystemService {
} catch (RemoteException ignored) {
}
mContext.unbindService(this);
+ close();
+ remove();
}
private void remove() {
@@ -230,5 +274,14 @@ public class DataLoaderManagerService extends SystemService {
mServiceConnections.remove(mId);
}
}
+
+ private void callListener(int status) {
+ if (mListener != null) {
+ try {
+ mListener.onStatusChanged(mId, status);
+ } catch (RemoteException ignored) {
+ }
+ }
+ }
}
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 7adafe3ed658..28987ed8e7b3 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -11203,8 +11203,16 @@ public class PackageManagerService extends IPackageManager.Stub
boolean needToDeriveAbi = (scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) != 0;
if (!needToDeriveAbi) {
if (pkgSetting != null) {
- primaryCpuAbiFromSettings = pkgSetting.primaryCpuAbiString;
- secondaryCpuAbiFromSettings = pkgSetting.secondaryCpuAbiString;
+ // TODO(b/154610922): if it is not first boot or upgrade, we should directly use
+ // API info from existing package setting. However, stub packages currently do not
+ // preserve ABI info, thus the special condition check here. Remove the special
+ // check after we fix the stub generation.
+ if (pkgSetting.pkg != null && pkgSetting.pkg.isStub()) {
+ needToDeriveAbi = true;
+ } else {
+ primaryCpuAbiFromSettings = pkgSetting.primaryCpuAbiString;
+ secondaryCpuAbiFromSettings = pkgSetting.secondaryCpuAbiString;
+ }
} else {
// Re-scanning a system package after uninstalling updates; need to derive ABI
needToDeriveAbi = true;
@@ -20826,8 +20834,11 @@ public class PackageManagerService extends IPackageManager.Stub
final int[] instantUserIds = isInstantApp ? new int[] { userId } : EMPTY_INT_ARRAY;
final SparseArray<int[]> broadcastWhitelist;
synchronized (mLock) {
- broadcastWhitelist = isInstantApp ? null : mAppsFilter.getVisibilityWhitelist(
- getPackageSettingInternal(packageName, Process.SYSTEM_UID),
+ PackageSetting setting = getPackageSettingInternal(packageName, Process.SYSTEM_UID);
+ if (setting == null) {
+ return;
+ }
+ broadcastWhitelist = isInstantApp ? null : mAppsFilter.getVisibilityWhitelist(setting,
userIds, mSettings.mPackages);
}
sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED, packageName, extras, flags, null, null,
diff --git a/services/core/java/com/android/server/pm/parsing/pkg/AndroidPackageUtils.java b/services/core/java/com/android/server/pm/parsing/pkg/AndroidPackageUtils.java
index 780b2347287a..4a1a6a766726 100644
--- a/services/core/java/com/android/server/pm/parsing/pkg/AndroidPackageUtils.java
+++ b/services/core/java/com/android/server/pm/parsing/pkg/AndroidPackageUtils.java
@@ -31,6 +31,7 @@ import android.content.pm.parsing.component.ParsedActivity;
import android.content.pm.parsing.component.ParsedInstrumentation;
import android.content.pm.parsing.component.ParsedProvider;
import android.content.pm.parsing.component.ParsedService;
+import android.os.incremental.IncrementalManager;
import android.text.TextUtils;
import com.android.internal.content.NativeLibraryHelper;
@@ -141,8 +142,15 @@ public class AndroidPackageUtils {
public static boolean canHaveOatDir(AndroidPackage pkg, boolean isUpdatedSystemApp) {
// The following app types CANNOT have oat directory
- // - non-updated system apps
- return !pkg.isSystem() || isUpdatedSystemApp;
+ // - non-updated system apps,
+ // - incrementally installed apps.
+ if (pkg.isSystem() && !isUpdatedSystemApp) {
+ return false;
+ }
+ if (IncrementalManager.isIncrementalPath(pkg.getCodePath())) {
+ return false;
+ }
+ return true;
}
public static boolean hasComponentClassName(AndroidPackage pkg, String className) {
diff --git a/services/core/java/com/android/server/soundtrigger_middleware/OWNERS b/services/core/java/com/android/server/soundtrigger_middleware/OWNERS
new file mode 100644
index 000000000000..e5d037003ac4
--- /dev/null
+++ b/services/core/java/com/android/server/soundtrigger_middleware/OWNERS
@@ -0,0 +1,2 @@
+ytai@google.com
+elaurent@google.com
diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java
index abccf99579b7..785ca908b703 100644
--- a/services/core/java/com/android/server/wm/AccessibilityController.java
+++ b/services/core/java/com/android/server/wm/AccessibilityController.java
@@ -45,6 +45,7 @@ import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.util.ArraySet;
+import android.util.IntArray;
import android.util.Slog;
import android.util.SparseArray;
import android.util.TypedValue;
@@ -66,6 +67,7 @@ import com.android.server.policy.WindowManagerPolicy;
import com.android.server.wm.WindowManagerInternal.MagnificationCallbacks;
import com.android.server.wm.WindowManagerInternal.WindowsForAccessibilityCallback;
+import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
@@ -127,14 +129,13 @@ final class AccessibilityController {
*/
public boolean setWindowsForAccessibilityCallbackLocked(int displayId,
WindowsForAccessibilityCallback callback) {
- if (callback != null) {
- final DisplayContent dc = mService.mRoot.getDisplayContentOrCreate(displayId);
- if (dc == null) {
- return false;
- }
+ final DisplayContent dc = mService.mRoot.getDisplayContentOrCreate(displayId);
+ if (dc == null) {
+ return false;
+ }
- final Display display = dc.getDisplay();
- if (display.getType() == Display.TYPE_VIRTUAL && dc.getParentWindow() != null) {
+ if (callback != null) {
+ if (isEmbeddedDisplay(dc)) {
// If this display is an embedded one, its window observer should have been set from
// window manager after setting its parent window. But if its window observer is
// empty, that means this mapping didn't be set, and needs to do this again.
@@ -151,13 +152,22 @@ final class AccessibilityController {
mWindowsForAccessibilityObserver.put(displayId,
new WindowsForAccessibilityObserver(mService, displayId, callback));
} else {
+ if (isEmbeddedDisplay(dc)) {
+ // If this display is an embedded one, its window observer should be removed along
+ // with the window observer of its parent display removed because the window
+ // observer of the embedded display and its parent display is the same, and would
+ // be removed together when stopping the window tracking of its parent display. So
+ // here don't need to do removing window observer of the embedded display again.
+ return true;
+ }
final WindowsForAccessibilityObserver windowsForA11yObserver =
mWindowsForAccessibilityObserver.get(displayId);
- if (windowsForA11yObserver == null) {
+ if (windowsForA11yObserver == null) {
throw new IllegalStateException(
"Windows for accessibility callback of display " + displayId
+ " already cleared!");
}
+ removeObserverOfEmbeddedDisplay(windowsForA11yObserver);
mWindowsForAccessibilityObserver.remove(displayId);
}
return true;
@@ -331,6 +341,7 @@ final class AccessibilityController {
mWindowsForAccessibilityObserver.get(parentDisplayId);
if (windowsForA11yObserver != null) {
+ windowsForA11yObserver.addEmbeddedDisplay(embeddedDisplayId);
// Replaces the observer of embedded display to the one of parent display
mWindowsForAccessibilityObserver.put(embeddedDisplayId, windowsForA11yObserver);
}
@@ -341,6 +352,33 @@ final class AccessibilityController {
windowState.getTransformationMatrix(sTempFloats, outMatrix);
}
+ void dump(PrintWriter pw, String prefix) {
+ for (int i = 0; i < mDisplayMagnifiers.size(); i++) {
+ final DisplayMagnifier displayMagnifier = mDisplayMagnifiers.valueAt(i);
+ if (displayMagnifier != null) {
+ displayMagnifier.dump(pw, prefix
+ + "Magnification display# " + mDisplayMagnifiers.keyAt(i));
+ }
+ }
+ }
+
+ private void removeObserverOfEmbeddedDisplay(WindowsForAccessibilityObserver
+ observerOfParentDisplay) {
+ final IntArray embeddedDisplayIdList =
+ observerOfParentDisplay.getAndClearEmbeddedDisplayIdList();
+
+ for (int index = 0; index < embeddedDisplayIdList.size(); index++) {
+ final int embeddedDisplayId = embeddedDisplayIdList.get(index);
+ mWindowsForAccessibilityObserver.remove(embeddedDisplayId);
+ }
+ }
+
+ private static boolean isEmbeddedDisplay(DisplayContent dc) {
+ final Display display = dc.getDisplay();
+
+ return display.getType() == Display.TYPE_VIRTUAL && dc.getParentWindow() != null;
+ }
+
/**
* This class encapsulates the functionality related to display magnification.
*/
@@ -551,6 +589,10 @@ final class AccessibilityController {
mMagnifedViewport.drawWindowIfNeededLocked(t);
}
+ void dump(PrintWriter pw, String prefix) {
+ mMagnifedViewport.dump(pw, prefix);
+ }
+
private final class MagnifiedViewport {
private final SparseArray<WindowState> mTempWindowStates =
@@ -820,6 +862,10 @@ final class AccessibilityController {
}, false /* traverseTopToBottom */ );
}
+ void dump(PrintWriter pw, String prefix) {
+ mWindow.dump(pw, prefix);
+ }
+
private final class ViewportWindow {
private static final String SURFACE_TITLE = "Magnification Overlay";
@@ -985,6 +1031,14 @@ final class AccessibilityController {
mSurface.release();
}
+ void dump(PrintWriter pw, String prefix) {
+ pw.println(prefix
+ + " mBounds= " + mBounds
+ + " mDirtyRect= " + mDirtyRect
+ + " mWidth= " + mSurfaceControl.getWidth()
+ + " mHeight= " + mSurfaceControl.getHeight());
+ }
+
private final class AnimationController extends Handler {
private static final String PROPERTY_NAME_ALPHA = "alpha";
@@ -1152,6 +1206,8 @@ final class AccessibilityController {
private final long mRecurringAccessibilityEventsIntervalMillis;
+ private final IntArray mEmbeddedDisplayIdList = new IntArray(0);
+
public WindowsForAccessibilityObserver(WindowManagerService windowManagerService,
int displayId,
WindowsForAccessibilityCallback callback) {
@@ -1176,6 +1232,21 @@ final class AccessibilityController {
}
}
+ IntArray getAndClearEmbeddedDisplayIdList() {
+ final IntArray returnedArray = new IntArray(mEmbeddedDisplayIdList.size());
+ returnedArray.addAll(mEmbeddedDisplayIdList);
+ mEmbeddedDisplayIdList.clear();
+
+ return returnedArray;
+ }
+
+ void addEmbeddedDisplay(int displayId) {
+ if (displayId == mDisplayId) {
+ return;
+ }
+ mEmbeddedDisplayIdList.add(displayId);
+ }
+
/**
* Check if windows have changed, and send them to the accessibility subsystem if they have.
*
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 2648c86d3c6a..c058317bf6ae 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -1188,12 +1188,15 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
final boolean inPictureInPictureMode = inPinnedWindowingMode() && targetStackBounds != null;
if (inPictureInPictureMode != mLastReportedPictureInPictureMode || forceUpdate) {
- // Picture-in-picture mode changes also trigger a multi-window mode change as well, so
- // update that here in order. Set the last reported MW state to the same as the PiP
- // state since we haven't yet actually resized the task (these callbacks need to
- // preceed the configuration change from the resiez.
+ // Picture-in-picture mode change normal triggers also multi-window mode change
+ // except transitions between pip and split screen mode, so update that here in order.
+ // Set the last reported MW state to the same as the PiP state since we haven't yet
+ // actually resized the task (these callbacks need to proceed the configuration change
+ // from the resize).
// TODO(110009072): Once we move these callbacks to the client, remove all logic related
// to forcing the update of the picture-in-picture mode as a part of the PiP animation.
+ final boolean shouldScheduleMultiWindowModeChange =
+ mLastReportedMultiWindowMode != inMultiWindowMode();
mLastReportedPictureInPictureMode = inPictureInPictureMode;
mLastReportedMultiWindowMode = inPictureInPictureMode;
final Configuration newConfig = new Configuration();
@@ -1204,7 +1207,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
task.computeConfigResourceOverrides(newConfig, task.getParent().getConfiguration());
}
schedulePictureInPictureModeChanged(newConfig);
- scheduleMultiWindowModeChanged(newConfig);
+ if (shouldScheduleMultiWindowModeChange) {
+ scheduleMultiWindowModeChanged(newConfig);
+ }
}
}
@@ -3137,7 +3142,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
commitVisibility(false /* visible */, true /* performLayout */);
getDisplayContent().mOpeningApps.remove(this);
- getDisplayContent().mChangingContainers.remove(this);
getDisplayContent().mUnknownAppVisibilityController.appRemovedOrHidden(this);
mWmService.mTaskSnapshotController.onAppRemoved(this);
mStackSupervisor.getActivityMetricsLogger().notifyActivityRemoved(this);
@@ -6130,19 +6134,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
@Override
void cancelAnimation() {
- cancelAnimationOnly();
- clearThumbnail();
- mSurfaceFreezer.unfreeze(getPendingTransaction());
- }
-
- /**
- * This only cancels the animation. It doesn't do other teardown like cleaning-up thumbnail
- * or interim leashes.
- * <p>
- * Used when canceling in preparation for starting a new animation.
- */
- void cancelAnimationOnly() {
super.cancelAnimation();
+ clearThumbnail();
}
@VisibleForTesting
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index 0754a348740b..8edc84fc8f37 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -168,7 +168,6 @@ class ActivityStarter {
// The task display area to launch the activity onto, barring any strong reason to do otherwise.
private TaskDisplayArea mPreferredTaskDisplayArea;
- // The windowing mode to apply to the root task, if possible
private int mPreferredWindowingMode;
private Task mInTask;
@@ -1560,9 +1559,6 @@ class ActivityStarter {
if (!mAvoidMoveToFront && mDoResume) {
mTargetStack.getStack().moveToFront("reuseOrNewTask", targetTask);
if (mOptions != null) {
- if (mPreferredWindowingMode != WINDOWING_MODE_UNDEFINED) {
- mTargetStack.setWindowingMode(mPreferredWindowingMode);
- }
if (mOptions.getTaskAlwaysOnTop()) {
mTargetStack.setAlwaysOnTop(true);
}
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 93a757449564..02f6a696f598 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -6604,7 +6604,6 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
}
return;
}
- process.mIsImeProcess = true;
process.registerDisplayConfigurationListener(displayContent);
}
}
diff --git a/services/core/java/com/android/server/wm/InsetsPolicy.java b/services/core/java/com/android/server/wm/InsetsPolicy.java
index 61a199a816df..5a9bf809fa4a 100644
--- a/services/core/java/com/android/server/wm/InsetsPolicy.java
+++ b/services/core/java/com/android/server/wm/InsetsPolicy.java
@@ -126,13 +126,22 @@ class InsetsPolicy {
mPolicy.getStatusBarManagerInternal().showTransient(mDisplayContent.getDisplayId(),
mShowingTransientTypes.toArray());
updateBarControlTarget(mFocusedWin);
- InsetsState state = new InsetsState(mStateController.getRawInsetsState());
- startAnimation(true /* show */, () -> {
+
+ // The leashes can be created while updating bar control target. The surface transaction
+ // of the new leashes might not be applied yet. The callback posted here ensures we can
+ // get the valid leashes because the surface transaction will be applied in the next
+ // animation frame which will be triggered if a new leash is created.
+ mDisplayContent.mWmService.mAnimator.getChoreographer().postFrameCallback(time -> {
synchronized (mDisplayContent.mWmService.mGlobalLock) {
- mStateController.notifyInsetsChanged();
+ final InsetsState state = new InsetsState(mStateController.getRawInsetsState());
+ startAnimation(true /* show */, () -> {
+ synchronized (mDisplayContent.mWmService.mGlobalLock) {
+ mStateController.notifyInsetsChanged();
+ }
+ }, state);
+ mStateController.onInsetsModified(mDummyControlTarget, state);
}
- }, state);
- mStateController.onInsetsModified(mDummyControlTarget, state);
+ });
}
}
diff --git a/services/core/java/com/android/server/wm/InsetsSourceProvider.java b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
index 1ca82ceeb570..351743f962b9 100644
--- a/services/core/java/com/android/server/wm/InsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
@@ -66,6 +66,7 @@ class InsetsSourceProvider {
private TriConsumer<DisplayFrames, WindowState, Rect> mFrameProvider;
private TriConsumer<DisplayFrames, WindowState, Rect> mImeFrameProvider;
private final Rect mImeOverrideFrame = new Rect();
+ private boolean mIsLeashReadyForDispatching;
/** The visibility override from the current controlling window. */
private boolean mClientVisible;
@@ -266,9 +267,14 @@ class InsetsSourceProvider {
if (getSource().getType() == ITYPE_IME) {
setClientVisible(InsetsState.getDefaultVisibility(mSource.getType()));
}
- final Transaction t = mDisplayContent.mWmService.mTransactionFactory.get();
+ final Transaction t = mDisplayContent.getPendingTransaction();
mWin.startAnimation(t, mAdapter, !mClientVisible /* hidden */,
ANIMATION_TYPE_INSETS_CONTROL, null /* animationFinishedCallback */);
+
+ // The leash was just created. We cannot dispatch it until its surface transaction is
+ // applied. Otherwise, the client's operation to the leash might be overwritten by us.
+ mIsLeashReadyForDispatching = false;
+
final SurfaceControl leash = mAdapter.mCapturedLeash;
final long frameNumber = mFinishSeamlessRotateFrameNumber;
mFinishSeamlessRotateFrameNumber = -1;
@@ -281,9 +287,6 @@ class InsetsSourceProvider {
t.deferTransactionUntil(mWin.getSurfaceControl(), barrier, frameNumber);
t.deferTransactionUntil(leash, barrier, frameNumber);
}
- // Applying the transaction here can prevent the client from applying its transaction sooner
- // than us which makes us overwrite the client's operation to the leash.
- t.apply();
mControlTarget = target;
mControl = new InsetsSourceControl(mSource.getType(), leash,
new Point(mWin.getWindowFrames().mFrame.left, mWin.getWindowFrames().mFrame.top));
@@ -313,6 +316,10 @@ class InsetsSourceProvider {
return true;
}
+ void onSurfaceTransactionApplied() {
+ mIsLeashReadyForDispatching = true;
+ }
+
private void setClientVisible(boolean clientVisible) {
if (mClientVisible == clientVisible) {
return;
@@ -334,6 +341,13 @@ class InsetsSourceProvider {
InsetsSourceControl getControl(InsetsControlTarget target) {
if (target == mControlTarget) {
+ if (!mIsLeashReadyForDispatching && mControl != null) {
+ // The surface transaction of preparing leash is not applied yet. We don't send it
+ // to the client in case that the client applies its transaction sooner than ours
+ // that we could unexpectedly overwrite the surface state.
+ return new InsetsSourceControl(mControl.getType(), null /* leash */,
+ mControl.getSurfacePosition());
+ }
return mControl;
}
if (target == mFakeControlTarget) {
diff --git a/services/core/java/com/android/server/wm/InsetsStateController.java b/services/core/java/com/android/server/wm/InsetsStateController.java
index 4ac319ddf6ce..765f98065dd0 100644
--- a/services/core/java/com/android/server/wm/InsetsStateController.java
+++ b/services/core/java/com/android/server/wm/InsetsStateController.java
@@ -407,6 +407,10 @@ class InsetsStateController {
return;
}
mDisplayContent.mWmService.mAnimator.addAfterPrepareSurfacesRunnable(() -> {
+ for (int i = mProviders.size() - 1; i >= 0; i--) {
+ final InsetsSourceProvider provider = mProviders.valueAt(i);
+ provider.onSurfaceTransactionApplied();
+ }
for (int i = mPendingControlChanged.size() - 1; i >= 0; i--) {
final InsetsControlTarget controlTarget = mPendingControlChanged.valueAt(i);
controlTarget.notifyInsetsControlChanged();
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 66e1b1758d85..5bf49a6aa092 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -1943,12 +1943,15 @@ class Task extends WindowContainer<WindowContainer> {
final int prevWinMode = getWindowingMode();
mTmpPrevBounds.set(getBounds());
final boolean wasInMultiWindowMode = inMultiWindowMode();
+ final boolean wasInPictureInPicture = inPinnedWindowingMode();
super.onConfigurationChanged(newParentConfig);
// Only need to update surface size here since the super method will handle updating
// surface position.
updateSurfaceSize(getPendingTransaction());
- if (wasInMultiWindowMode != inMultiWindowMode()) {
+ if (wasInPictureInPicture != inPinnedWindowingMode()) {
+ mStackSupervisor.scheduleUpdatePictureInPictureModeIfNeeded(this, getStack());
+ } else if (wasInMultiWindowMode != inMultiWindowMode()) {
mStackSupervisor.scheduleUpdateMultiWindowMode(this);
}
@@ -1992,7 +1995,8 @@ class Task extends WindowContainer<WindowContainer> {
if (mWmService.mDisableTransitionAnimation
|| !isVisible()
|| getDisplayContent().mAppTransition.isTransitionSet()
- || getSurfaceControl() == null) {
+ || getSurfaceControl() == null
+ || !isLeafTask()) {
return false;
}
// Only do an animation into and out-of freeform mode for now. Other mode
@@ -2897,22 +2901,12 @@ class Task extends WindowContainer<WindowContainer> {
if (!isRootTask) {
adjustBoundsForDisplayChangeIfNeeded(dc);
}
- final DisplayContent prevDc = mDisplayContent;
super.onDisplayChanged(dc);
if (!isRootTask) {
final int displayId = (dc != null) ? dc.getDisplayId() : INVALID_DISPLAY;
mWmService.mAtmService.getTaskChangeNotificationController().notifyTaskDisplayChanged(
mTaskId, displayId);
}
- if (prevDc != null && prevDc.mChangingContainers.remove(this)) {
- // This gets called *after* this has been reparented to the new display.
- // That reparenting resulted in this window changing modes (eg. FREEFORM -> FULLSCREEN),
- // so this token is now "frozen" while waiting for the animation to start on prevDc
- // (which will be cancelled since the window is no-longer a child). However, since this
- // is no longer a child of prevDc, this won't be notified of the cancelled animation,
- // so we need to cancel the change transition here.
- mSurfaceFreezer.unfreeze(getPendingTransaction());
- }
}
boolean isResizeable(boolean checkSupportsPip) {
diff --git a/services/core/java/com/android/server/wm/WallpaperWindowToken.java b/services/core/java/com/android/server/wm/WallpaperWindowToken.java
index 203ca25ecf6e..5f3c63352015 100644
--- a/services/core/java/com/android/server/wm/WallpaperWindowToken.java
+++ b/services/core/java/com/android/server/wm/WallpaperWindowToken.java
@@ -16,6 +16,7 @@
package com.android.server.wm;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYERS;
@@ -45,6 +46,7 @@ class WallpaperWindowToken extends WindowToken {
DisplayContent dc, boolean ownerCanManageAppTokens) {
super(service, token, TYPE_WALLPAPER, explicit, dc, ownerCanManageAppTokens);
dc.mWallpaperController.addWallpaperToken(this);
+ setWindowingMode(WINDOWING_MODE_FULLSCREEN);
}
@Override
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index f3e2992d5913..591bc5475cd7 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -526,6 +526,11 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
*/
@CallSuper
void removeImmediately() {
+ final DisplayContent dc = getDisplayContent();
+ if (dc != null) {
+ mSurfaceFreezer.unfreeze(getPendingTransaction());
+ dc.mChangingContainers.remove(this);
+ }
while (!mChildren.isEmpty()) {
final E child = mChildren.peekLast();
child.removeImmediately();
@@ -718,6 +723,10 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
* @param dc The display this container is on after changes.
*/
void onDisplayChanged(DisplayContent dc) {
+ if (mDisplayContent != null && mDisplayContent.mChangingContainers.remove(this)) {
+ // Cancel any change transition queued-up for this container on the old display.
+ mSurfaceFreezer.unfreeze(getPendingTransaction());
+ }
mDisplayContent = dc;
if (dc != null && dc != this) {
dc.getPendingTransaction().merge(mPendingTransaction);
@@ -2033,6 +2042,7 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
void cancelAnimation() {
mSurfaceAnimator.cancelAnimation();
+ mSurfaceFreezer.unfreeze(getPendingTransaction());
}
@Override
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 51095ee85eea..fbdea01deb77 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -6111,15 +6111,6 @@ public class WindowManagerService extends IWindowManager.Stub
pw.print(" mInputMethodInputTarget in display# "); pw.print(displayId);
pw.print(' '); pw.println(inputMethodInputTarget);
}
- if (mAccessibilityController != null) {
- final Region magnificationRegion = new Region();
- mAccessibilityController.getMagnificationRegionLocked(displayId,
- magnificationRegion);
- pw.print(" mMagnificationRegion in display# ");
- pw.print(displayId);
- pw.print(' ');
- pw.println(magnificationRegion);
- }
});
pw.print(" mInTouchMode="); pw.println(mInTouchMode);
pw.print(" mLastDisplayFreezeDuration=");
@@ -6135,6 +6126,9 @@ public class WindowManagerService extends IWindowManager.Stub
mInputManagerCallback.dump(pw, " ");
mTaskSnapshotController.dump(pw, " ");
+ if (mAccessibilityController != null) {
+ mAccessibilityController.dump(pw, " ");
+ }
if (dumpAll) {
final WindowState imeWindow = mRoot.getCurrentInputMethodWindow();
@@ -7656,15 +7650,8 @@ public class WindowManagerService extends IWindowManager.Stub
Slog.w(TAG, "Cannot find window which accessibility connection is added to");
return;
}
- try (SurfaceControl.Transaction t = new SurfaceControl.Transaction()) {
- t.setMetadata(
- state.mSurfaceControl,
- SurfaceControl.METADATA_ACCESSIBILITY_ID,
- accessibilityWindowId);
- t.apply();
- } finally {
- SurfaceControl.closeTransaction();
- }
+ mTransaction.setMetadata(state.mSurfaceControl,
+ SurfaceControl.METADATA_ACCESSIBILITY_ID, accessibilityWindowId).apply();
}
}
diff --git a/services/core/java/com/android/server/wm/WindowProcessController.java b/services/core/java/com/android/server/wm/WindowProcessController.java
index 194ed3ec3b0e..41bd70726e71 100644
--- a/services/core/java/com/android/server/wm/WindowProcessController.java
+++ b/services/core/java/com/android/server/wm/WindowProcessController.java
@@ -40,6 +40,7 @@ import static com.android.server.wm.ActivityTaskManagerService.INSTRUMENTATION_K
import static com.android.server.wm.ActivityTaskManagerService.KEY_DISPATCHING_TIMEOUT_MS;
import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_NONE;
+import android.Manifest;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityThread;
@@ -50,6 +51,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
+import android.content.pm.ServiceInfo;
import android.content.res.Configuration;
import android.os.Build;
import android.os.Message;
@@ -165,7 +167,8 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
// Thread currently set for VR scheduling
int mVrThreadTid;
- boolean mIsImeProcess;
+ // Whether this process has ever started a service with the BIND_INPUT_METHOD permission.
+ private volatile boolean mHasImeService;
// all activities running in the process
private final ArrayList<ActivityRecord> mActivities = new ArrayList<>();
@@ -187,6 +190,8 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
// Registered display id as a listener to override config change
private int mDisplayId;
private ActivityRecord mConfigActivityRecord;
+ // Whether the activity config override is allowed for this process.
+ private volatile boolean mIsActivityConfigOverrideAllowed = true;
/**
* Activities that hosts some UI drawn by the current process. The activities live
* in another process. This is used to check if the process is currently showing anything
@@ -201,9 +206,6 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
/** Whether our process is currently running a {@link IRemoteAnimationRunner} */
private boolean mRunningRemoteAnimation;
- /** Whether this process is owned by the System UI package. */
- final boolean mIsSysUiPackage;
-
public WindowProcessController(@NonNull ActivityTaskManagerService atm, ApplicationInfo info,
String name, int uid, int userId, Object owner, WindowProcessListener listener) {
mInfo = info;
@@ -215,8 +217,13 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
mAtm = atm;
mDisplayId = INVALID_DISPLAY;
- mIsSysUiPackage = info.packageName.equals(
+ boolean isSysUiPackage = info.packageName.equals(
mAtm.getSysUiServiceComponentLocked().getPackageName());
+ if (isSysUiPackage || mUid == Process.SYSTEM_UID) {
+ // This is a system owned process and should not use an activity config.
+ // TODO(b/151161907): Remove after support for display-independent (raw) SysUi configs.
+ mIsActivityConfigOverrideAllowed = false;
+ }
onConfigurationChanged(atm.getGlobalConfiguration());
}
@@ -1095,9 +1102,7 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
* always track the configuration of the non-finishing activity last added to the process.
*/
private void updateActivityConfigurationListener() {
- if (mIsSysUiPackage || mUid == Process.SYSTEM_UID) {
- // This is a system owned process and should not use an activity config.
- // TODO(b/151161907): Remove after support for display-independent (raw) SysUi configs.
+ if (!mIsActivityConfigOverrideAllowed) {
return;
}
@@ -1132,7 +1137,7 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
final Configuration config = getConfiguration();
if (mLastReportedConfiguration.diff(config) == 0) {
// Nothing changed.
- if (Build.IS_DEBUGGABLE && mIsImeProcess) {
+ if (Build.IS_DEBUGGABLE && mHasImeService) {
// TODO (b/135719017): Temporary log for debugging IME service.
Slog.w(TAG_CONFIGURATION, "Current config: " + config
+ " unchanged for IME proc " + mName);
@@ -1156,7 +1161,7 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
private void dispatchConfigurationChange(Configuration config) {
if (mThread == null) {
- if (Build.IS_DEBUGGABLE && mIsImeProcess) {
+ if (Build.IS_DEBUGGABLE && mHasImeService) {
// TODO (b/135719017): Temporary log for debugging IME service.
Slog.w(TAG_CONFIGURATION, "Unable to send config for IME proc " + mName
+ ": no app thread");
@@ -1166,7 +1171,7 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
if (DEBUG_CONFIGURATION) {
Slog.v(TAG_CONFIGURATION, "Sending to proc " + mName + " new config " + config);
}
- if (Build.IS_DEBUGGABLE && mIsImeProcess) {
+ if (Build.IS_DEBUGGABLE && mHasImeService) {
// TODO (b/135719017): Temporary log for debugging IME service.
Slog.v(TAG_CONFIGURATION, "Sending to IME proc " + mName + " new config " + config);
}
@@ -1286,6 +1291,35 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
}
}
+ /**
+ * Called to notify {@link WindowProcessController} of a started service.
+ *
+ * @param serviceInfo information describing the started service.
+ */
+ public void onServiceStarted(ServiceInfo serviceInfo) {
+ String permission = serviceInfo.permission;
+ if (permission == null) {
+ return;
+ }
+
+ // TODO: Audit remaining services for disabling activity override (Wallpaper, Dream, etc).
+ switch (permission) {
+ case Manifest.permission.BIND_INPUT_METHOD:
+ mHasImeService = true;
+ // Fall-through
+ case Manifest.permission.BIND_ACCESSIBILITY_SERVICE:
+ case Manifest.permission.BIND_VOICE_INTERACTION:
+ // We want to avoid overriding the config of these services with that of the
+ // activity as it could lead to incorrect display metrics. For ex, IME services
+ // expect their config to match the config of the display with the IME window
+ // showing.
+ mIsActivityConfigOverrideAllowed = false;
+ break;
+ default:
+ break;
+ }
+ }
+
@HotPath(caller = HotPath.OOM_ADJUSTMENT)
public void onTopProcChanged() {
synchronized (mAtm.mGlobalLockWithoutBoost) {
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 99577077d65d..bfe3b2890bc1 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -884,8 +884,8 @@ class WindowStateAnimator {
clipRect = mTmpClipRect;
}
- if (mSurfaceResized && (mAttrType == TYPE_BASE_APPLICATION) &&
- (task != null) && (task.getMainWindowSizeChangeTransaction() != null)) {
+ if (w.mInRelayout && (mAttrType == TYPE_BASE_APPLICATION) && (task != null)
+ && (task.getMainWindowSizeChangeTransaction() != null)) {
mSurfaceController.deferTransactionUntil(mWin.getClientViewRootSurface(),
mWin.getFrameNumber());
SurfaceControl.mergeToGlobalTransaction(task.getMainWindowSizeChangeTransaction());
@@ -1476,6 +1476,7 @@ class WindowStateAnimator {
if (dumpAll) {
pw.print(prefix); pw.print("mDrawState="); pw.print(drawStateToString());
pw.print(prefix); pw.print(" mLastHidden="); pw.println(mLastHidden);
+ pw.print(prefix); pw.print("mEnterAnimationPending=" + mEnterAnimationPending);
pw.print(prefix); pw.print("mSystemDecorRect="); mSystemDecorRect.printShortString(pw);
pw.print(" mLastClipRect="); mLastClipRect.printShortString(pw);
diff --git a/services/core/jni/com_android_server_tv_TvUinputBridge.cpp b/services/core/jni/com_android_server_tv_TvUinputBridge.cpp
index 6e2e2c54518b..99deab4fd652 100644
--- a/services/core/jni/com_android_server_tv_TvUinputBridge.cpp
+++ b/services/core/jni/com_android_server_tv_TvUinputBridge.cpp
@@ -106,7 +106,7 @@ static int getGamepadkeyCode(int32_t androidKeyCode) {
static const GamepadAxis* getGamepadAxis(int32_t androidAxisCode) {
std::unordered_map<int32_t, int>::iterator it =
gamepadAndroidAxisToIndexMap.find(androidAxisCode);
- if (it == gamepadAndroidToLinuxKeyMap.end()) {
+ if (it == gamepadAndroidAxisToIndexMap.end()) {
return nullptr;
}
return &GAMEPAD_AXES[it->second];
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 7b845557cf73..5d5e424db017 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -403,11 +403,14 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
private static final long EXPIRATION_GRACE_PERIOD_MS = 5 * MS_PER_DAY; // 5 days, in ms
private static final long MANAGED_PROFILE_MAXIMUM_TIME_OFF_THRESHOLD = 3 * MS_PER_DAY;
+ /** When to warn the user about the approaching work profile off deadline: 1 day before */
+ private static final long MANAGED_PROFILE_OFF_WARNING_PERIOD = 1 * MS_PER_DAY;
private static final String ACTION_EXPIRED_PASSWORD_NOTIFICATION =
"com.android.server.ACTION_EXPIRED_PASSWORD_NOTIFICATION";
- private static final String ACTION_PROFILE_OFF_DEADLINE =
+ @VisibleForTesting
+ static final String ACTION_PROFILE_OFF_DEADLINE =
"com.android.server.ACTION_PROFILE_OFF_DEADLINE";
private static final String ATTR_PERMISSION_PROVIDER = "permission-provider";
@@ -649,6 +652,13 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
private static final boolean ENABLE_LOCK_GUARD = true;
+ /** Profile off deadline is not set or more than MANAGED_PROFILE_OFF_WARNING_PERIOD away. */
+ private static final int PROFILE_OFF_DEADLINE_DEFAULT = 0;
+ /** Profile off deadline is closer than MANAGED_PROFILE_OFF_WARNING_PERIOD. */
+ private static final int PROFILE_OFF_DEADLINE_WARNING = 1;
+ /** Profile off deadline reached, notify the user that personal apps blocked. */
+ private static final int PROFILE_OFF_DEADLINE_REACHED = 2;
+
interface Stats {
int LOCK_GUARD_GUARD = 0;
@@ -926,11 +936,12 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
mUserData.remove(userHandle);
}
handlePackagesChanged(null /* check all admins */, userHandle);
+ updatePersonalAppsSuspensionOnUserStart(userHandle);
} else if (Intent.ACTION_USER_STOPPED.equals(action)) {
sendDeviceOwnerUserCommand(DeviceAdminReceiver.ACTION_USER_STOPPED, userHandle);
if (isManagedProfile(userHandle)) {
Slog.d(LOG_TAG, "Managed profile was stopped");
- updatePersonalAppSuspension(userHandle, false /* profileIsOn */);
+ updatePersonalAppsSuspension(userHandle, false /* unlocked */);
}
} else if (Intent.ACTION_USER_SWITCHED.equals(action)) {
sendDeviceOwnerUserCommand(DeviceAdminReceiver.ACTION_USER_SWITCHED, userHandle);
@@ -940,7 +951,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
}
if (isManagedProfile(userHandle)) {
Slog.d(LOG_TAG, "Managed profile became unlocked");
- updatePersonalAppSuspension(userHandle, true /* profileIsOn */);
+ updatePersonalAppsSuspension(userHandle, true /* unlocked */);
}
} else if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(action)) {
handlePackagesChanged(null /* check all admins */, userHandle);
@@ -967,7 +978,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
Slog.i(LOG_TAG, "Profile off deadline alarm was triggered");
final int userId = getManagedUserId(UserHandle.USER_SYSTEM);
if (userId >= 0) {
- updatePersonalAppSuspension(userId, mUserManager.isUserUnlocked(userId));
+ updatePersonalAppsSuspension(userId, mUserManager.isUserUnlocked(userId));
} else {
Slog.wtf(LOG_TAG, "Got deadline alarm for nonexistent profile");
}
@@ -2486,6 +2497,16 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
public void runCryptoSelfTest() {
CryptoTestHelper.runAndLogSelfTest();
}
+
+ public String[] getPersonalAppsForSuspension(int userId) {
+ return new PersonalAppsSuspensionHelper(
+ mContext.createContextAsUser(UserHandle.of(userId), 0 /* flags */))
+ .getPersonalAppsForSuspension();
+ }
+
+ public long systemCurrentTimeMillis() {
+ return System.currentTimeMillis();
+ }
}
/**
@@ -4045,10 +4066,6 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
applyManagedProfileRestrictionIfDeviceOwnerLocked();
}
maybeStartSecurityLogMonitorOnActivityManagerReady();
- final int userId = getManagedUserId(UserHandle.USER_SYSTEM);
- if (userId >= 0) {
- updatePersonalAppSuspension(userId, false /* running */);
- }
break;
case SystemService.PHASE_BOOT_COMPLETED:
ensureDeviceOwnerUserStarted(); // TODO Consider better place to do this.
@@ -4056,6 +4073,16 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
}
}
+ private void updatePersonalAppsSuspensionOnUserStart(int userHandle) {
+ final int profileUserHandle = getManagedUserId(userHandle);
+ if (profileUserHandle >= 0) {
+ // Given that the parent user has just started, profile should be locked.
+ updatePersonalAppsSuspension(profileUserHandle, false /* unlocked */);
+ } else {
+ suspendPersonalAppsInternal(userHandle, false);
+ }
+ }
+
private void onLockSettingsReady() {
getUserData(UserHandle.USER_SYSTEM);
loadOwners();
@@ -15893,11 +15920,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
}
}
- final int suspendedState = suspended
- ? PERSONAL_APPS_SUSPENDED_EXPLICITLY
- : PERSONAL_APPS_NOT_SUSPENDED;
- mInjector.binderWithCleanCallingIdentity(
- () -> applyPersonalAppsSuspension(callingUserId, suspendedState));
+ mInjector.binderWithCleanCallingIdentity(() -> updatePersonalAppsSuspension(
+ callingUserId, mUserManager.isUserUnlocked(callingUserId)));
DevicePolicyEventLogger
.createEvent(DevicePolicyEnums.SET_PERSONAL_APPS_SUSPENDED)
@@ -15907,44 +15931,54 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
}
/**
- * Checks whether there is a policy that requires personal apps to be suspended and if so,
- * applies it.
- * @param running whether the profile is currently considered running.
+ * Checks whether personal apps should be suspended according to the policy and applies the
+ * change if needed.
+ *
+ * @param unlocked whether the profile is currently running unlocked.
*/
- private void updatePersonalAppSuspension(int profileUserId, boolean running) {
- final int suspensionState;
+ private void updatePersonalAppsSuspension(int profileUserId, boolean unlocked) {
+ final boolean suspended;
synchronized (getLockObject()) {
final ActiveAdmin profileOwner = getProfileOwnerAdminLocked(profileUserId);
if (profileOwner != null) {
- final boolean deadlineReached =
- updateProfileOffDeadlineLocked(profileUserId, profileOwner, running);
- suspensionState = makeSuspensionReasons(
- profileOwner.mSuspendPersonalApps, deadlineReached);
- Slog.d(LOG_TAG,
- String.format("New personal apps suspension state: %d", suspensionState));
+ final int deadlineState =
+ updateProfileOffDeadlineLocked(profileUserId, profileOwner, unlocked);
+ suspended = profileOwner.mSuspendPersonalApps
+ || deadlineState == PROFILE_OFF_DEADLINE_REACHED;
+ Slog.d(LOG_TAG, String.format("Personal apps suspended: %b, deadline state: %d",
+ suspended, deadlineState));
+ updateProfileOffDeadlineNotificationLocked(profileUserId, profileOwner,
+ unlocked ? PROFILE_OFF_DEADLINE_DEFAULT : deadlineState);
} else {
- suspensionState = PERSONAL_APPS_NOT_SUSPENDED;
+ suspended = false;
}
}
- applyPersonalAppsSuspension(profileUserId, suspensionState);
+ final int parentUserId = getProfileParentId(profileUserId);
+ suspendPersonalAppsInternal(parentUserId, suspended);
}
/**
* Checks work profile time off policy, scheduling personal apps suspension via alarm if
* necessary.
- * @return whether the apps should be suspended based on maximum time off policy.
+ * @return profile deadline state
*/
- private boolean updateProfileOffDeadlineLocked(
+ private int updateProfileOffDeadlineLocked(
int profileUserId, ActiveAdmin profileOwner, boolean unlocked) {
- final long now = System.currentTimeMillis();
+ final long now = mInjector.systemCurrentTimeMillis();
if (profileOwner.mProfileOffDeadline != 0 && now > profileOwner.mProfileOffDeadline) {
// Profile off deadline is already reached.
Slog.i(LOG_TAG, "Profile off deadline has been reached.");
- return true;
+ return PROFILE_OFF_DEADLINE_REACHED;
}
boolean shouldSaveSettings = false;
- if (profileOwner.mProfileOffDeadline != 0
+ if (profileOwner.mSuspendPersonalApps) {
+ // When explicit suspension is active, deadline shouldn't be set.
+ if (profileOwner.mProfileOffDeadline != 0) {
+ profileOwner.mProfileOffDeadline = 0;
+ shouldSaveSettings = true;
+ }
+ } else if (profileOwner.mProfileOffDeadline != 0
&& (profileOwner.mProfileMaximumTimeOffMillis == 0 || unlocked)) {
// There is a deadline but either there is no policy or the profile is unlocked -> clear
// the deadline.
@@ -15960,52 +15994,51 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
shouldSaveSettings = true;
}
- updateProfileOffAlarm(profileOwner.mProfileOffDeadline);
-
if (shouldSaveSettings) {
saveSettingsLocked(profileUserId);
}
- return false;
- }
- private void updateProfileOffAlarm(long profileOffDeadline) {
+ final long alarmTime;
+ final int deadlineState;
+ if (profileOwner.mProfileOffDeadline == 0) {
+ alarmTime = 0;
+ deadlineState = PROFILE_OFF_DEADLINE_DEFAULT;
+ } else if (profileOwner.mProfileOffDeadline - now < MANAGED_PROFILE_OFF_WARNING_PERIOD) {
+ // The deadline is close, upon the alarm personal apps should be suspended.
+ alarmTime = profileOwner.mProfileOffDeadline;
+ deadlineState = PROFILE_OFF_DEADLINE_WARNING;
+ } else {
+ // The deadline is quite far, upon the alarm we should warn the user first, so the
+ // alarm is scheduled earlier than the actual deadline.
+ alarmTime = profileOwner.mProfileOffDeadline - MANAGED_PROFILE_OFF_WARNING_PERIOD;
+ deadlineState = PROFILE_OFF_DEADLINE_DEFAULT;
+ }
+
final AlarmManager am = mInjector.getAlarmManager();
final PendingIntent pi = mInjector.pendingIntentGetBroadcast(
mContext, REQUEST_PROFILE_OFF_DEADLINE, new Intent(ACTION_PROFILE_OFF_DEADLINE),
PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_UPDATE_CURRENT);
- am.cancel(pi);
- if (profileOffDeadline != 0) {
- Slog.i(LOG_TAG, "Profile off deadline alarm is set.");
- am.set(AlarmManager.RTC, profileOffDeadline, pi);
- } else {
- Slog.i(LOG_TAG, "Profile off deadline alarm is removed.");
- }
- }
-
- private void applyPersonalAppsSuspension(
- int profileUserId, @PersonalAppsSuspensionReason int suspensionState) {
- final boolean suspended = getUserData(UserHandle.USER_SYSTEM).mAppsSuspended;
- final boolean shouldSuspend = suspensionState != PERSONAL_APPS_NOT_SUSPENDED;
- if (suspended != shouldSuspend) {
- suspendPersonalAppsInternal(shouldSuspend, UserHandle.USER_SYSTEM);
- }
- if (suspensionState == PERSONAL_APPS_SUSPENDED_PROFILE_TIMEOUT) {
- sendPersonalAppsSuspendedNotification(profileUserId);
+ if (alarmTime == 0) {
+ Slog.i(LOG_TAG, "Profile off deadline alarm is removed.");
+ am.cancel(pi);
} else {
- clearPersonalAppsSuspendedNotification();
+ Slog.i(LOG_TAG, "Profile off deadline alarm is set.");
+ am.set(AlarmManager.RTC, alarmTime, pi);
}
+
+ return deadlineState;
}
- private void suspendPersonalAppsInternal(boolean suspended, int userId) {
+ private void suspendPersonalAppsInternal(int userId, boolean suspended) {
+ if (getUserData(userId).mAppsSuspended == suspended) {
+ return;
+ }
Slog.i(LOG_TAG, String.format("%s personal apps for user %d",
suspended ? "Suspending" : "Unsuspending", userId));
mInjector.binderWithCleanCallingIdentity(() -> {
try {
- final String[] appsToSuspend =
- new PersonalAppsSuspensionHelper(
- mContext.createContextAsUser(UserHandle.of(userId), 0 /* flags */))
- .getPersonalAppsForSuspension();
+ final String[] appsToSuspend = mInjector.getPersonalAppsForSuspension(userId);
final String[] failedPackages = mIPackageManager.setPackagesSuspendedAsUser(
appsToSuspend, suspended, null, null, null, PLATFORM_PACKAGE_NAME, userId);
if (!ArrayUtils.isEmpty(failedPackages)) {
@@ -16024,37 +16057,38 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
}
}
- private void clearPersonalAppsSuspendedNotification() {
- mInjector.binderWithCleanCallingIdentity(() ->
- mInjector.getNotificationManager().cancel(
- SystemMessage.NOTE_PERSONAL_APPS_SUSPENDED));
- }
+ private void updateProfileOffDeadlineNotificationLocked(int profileUserId,
+ @Nullable ActiveAdmin profileOwner, int notificationState) {
- private void sendPersonalAppsSuspendedNotification(int userId) {
- final String profileOwnerPackageName;
- final long maxTimeOffDays;
- synchronized (getLockObject()) {
- profileOwnerPackageName = mOwners.getProfileOwnerComponent(userId).getPackageName();
- final ActiveAdmin poAdmin = getProfileOwnerAdminLocked(userId);
- maxTimeOffDays = TimeUnit.MILLISECONDS.toDays(poAdmin.mProfileMaximumTimeOffMillis);
+ if (notificationState == PROFILE_OFF_DEADLINE_DEFAULT) {
+ mInjector.getNotificationManager().cancel(SystemMessage.NOTE_PERSONAL_APPS_SUSPENDED);
+ return;
}
+ final String profileOwnerPackageName = profileOwner.info.getPackageName();
+ final long maxTimeOffDays =
+ TimeUnit.MILLISECONDS.toDays(profileOwner.mProfileMaximumTimeOffMillis);
+
final Intent intent = new Intent(DevicePolicyManager.ACTION_CHECK_POLICY_COMPLIANCE);
intent.setPackage(profileOwnerPackageName);
final PendingIntent pendingIntent = mInjector.pendingIntentGetActivityAsUser(mContext,
- 0 /* requestCode */, intent, PendingIntent.FLAG_UPDATE_CURRENT, null /* options */,
- UserHandle.of(userId));
+ 0 /* requestCode */, intent, PendingIntent.FLAG_UPDATE_CURRENT,
+ null /* options */, UserHandle.of(profileUserId));
+
+ // TODO(b/149075510): Only the first of the notifications should be dismissible.
+ final String title = mContext.getString(
+ notificationState == PROFILE_OFF_DEADLINE_WARNING
+ ? R.string.personal_apps_suspended_tomorrow_title
+ : R.string.personal_apps_suspended_title);
final Notification notification =
new Notification.Builder(mContext, SystemNotificationChannels.DEVICE_ADMIN)
.setSmallIcon(android.R.drawable.stat_sys_warning)
.setOngoing(true)
- .setContentTitle(
- mContext.getString(
- R.string.personal_apps_suspended_title))
+ .setContentTitle(title)
.setContentText(mContext.getString(
- R.string.personal_apps_suspended_text, maxTimeOffDays))
+ R.string.personal_apps_suspended_text, maxTimeOffDays))
.setColor(mContext.getColor(R.color.system_notification_accent_color))
.setContentIntent(pendingIntent)
.build();
@@ -16086,7 +16120,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
}
mInjector.binderWithCleanCallingIdentity(
- () -> updatePersonalAppSuspension(userId, mUserManager.isUserUnlocked()));
+ () -> updatePersonalAppsSuspension(userId, mUserManager.isUserUnlocked()));
DevicePolicyEventLogger
.createEvent(DevicePolicyEnums.SET_MANAGED_PROFILE_MAXIMUM_TIME_OFF)
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/PersonalAppsSuspensionHelper.java b/services/devicepolicy/java/com/android/server/devicepolicy/PersonalAppsSuspensionHelper.java
index d9db17eba887..da716eaed82b 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/PersonalAppsSuspensionHelper.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/PersonalAppsSuspensionHelper.java
@@ -51,6 +51,10 @@ import java.util.Set;
public class PersonalAppsSuspensionHelper {
private static final String LOG_TAG = DevicePolicyManagerService.LOG_TAG;
+ // Flags to get all packages even if the user is still locked.
+ private static final int PACKAGE_QUERY_FLAGS =
+ PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
+
private final Context mContext;
private final PackageManager mPackageManager;
@@ -67,7 +71,7 @@ public class PersonalAppsSuspensionHelper {
*/
String[] getPersonalAppsForSuspension() {
final List<PackageInfo> installedPackageInfos =
- mPackageManager.getInstalledPackages(0 /* flags */);
+ mPackageManager.getInstalledPackages(PACKAGE_QUERY_FLAGS);
final Set<String> result = new ArraySet<>();
for (final PackageInfo packageInfo : installedPackageInfos) {
final ApplicationInfo info = packageInfo.applicationInfo;
@@ -97,7 +101,7 @@ public class PersonalAppsSuspensionHelper {
final Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
final List<ResolveInfo> matchingActivities =
- mPackageManager.queryIntentActivities(intent, 0);
+ mPackageManager.queryIntentActivities(intent, PACKAGE_QUERY_FLAGS);
for (final ResolveInfo resolveInfo : matchingActivities) {
if (resolveInfo.activityInfo == null
|| TextUtils.isEmpty(resolveInfo.activityInfo.packageName)) {
@@ -107,7 +111,7 @@ public class PersonalAppsSuspensionHelper {
final String packageName = resolveInfo.activityInfo.packageName;
try {
final ApplicationInfo applicationInfo =
- mPackageManager.getApplicationInfo(packageName, 0);
+ mPackageManager.getApplicationInfo(packageName, PACKAGE_QUERY_FLAGS);
if (applicationInfo.isSystemApp() || applicationInfo.isUpdatedSystemApp()) {
result.add(packageName);
}
@@ -147,7 +151,8 @@ public class PersonalAppsSuspensionHelper {
private String getSettingsPackageName() {
final Intent intent = new Intent(Settings.ACTION_SETTINGS);
intent.addCategory(Intent.CATEGORY_DEFAULT);
- final ResolveInfo resolveInfo = mPackageManager.resolveActivity(intent, /* flags= */ 0);
+ final ResolveInfo resolveInfo =
+ mPackageManager.resolveActivity(intent, PACKAGE_QUERY_FLAGS);
if (resolveInfo != null) {
return resolveInfo.activityInfo.packageName;
}
@@ -164,7 +169,7 @@ public class PersonalAppsSuspensionHelper {
intentToResolve.addCategory(Intent.CATEGORY_LAUNCHER);
intentToResolve.setPackage(packageName);
final List<ResolveInfo> resolveInfos =
- mPackageManager.queryIntentActivities(intentToResolve, /* flags= */ 0);
+ mPackageManager.queryIntentActivities(intentToResolve, PACKAGE_QUERY_FLAGS);
return resolveInfos != null && !resolveInfos.isEmpty();
}
diff --git a/services/incremental/Android.bp b/services/incremental/Android.bp
index b13d33054e19..b8bd3b4a4563 100644
--- a/services/incremental/Android.bp
+++ b/services/incremental/Android.bp
@@ -62,6 +62,7 @@ filegroup {
srcs: [
"incremental_service.c",
"IncrementalService.cpp",
+ "IncrementalServiceValidation.cpp",
"BinderIncrementalService.cpp",
"path.cpp",
"ServiceWrappers.cpp",
diff --git a/services/incremental/BinderIncrementalService.cpp b/services/incremental/BinderIncrementalService.cpp
index fc8c6feac22b..847667427593 100644
--- a/services/incremental/BinderIncrementalService.cpp
+++ b/services/incremental/BinderIncrementalService.cpp
@@ -18,6 +18,7 @@
#include <android-base/logging.h>
#include <android-base/no_destructor.h>
+#include <android/os/IVold.h>
#include <binder/IResultReceiver.h>
#include <binder/PermissionCache.h>
#include <incfs.h>
@@ -117,11 +118,12 @@ binder::Status BinderIncrementalService::openStorage(const std::string& path,
}
binder::Status BinderIncrementalService::createStorage(
- const std::string& path, const DataLoaderParamsParcel& params,
+ const std::string& path, const content::pm::DataLoaderParamsParcel& params,
const ::android::sp<::android::content::pm::IDataLoaderStatusListener>& listener,
int32_t createMode, int32_t* _aidl_return) {
*_aidl_return =
- mImpl.createStorage(path, const_cast<DataLoaderParamsParcel&&>(params), listener,
+ mImpl.createStorage(path, const_cast<content::pm::DataLoaderParamsParcel&&>(params),
+ listener,
android::incremental::IncrementalService::CreateOptions(
createMode));
return ok();
@@ -238,11 +240,8 @@ binder::Status BinderIncrementalService::isFileRangeLoaded(int32_t storageId,
binder::Status BinderIncrementalService::getMetadataByPath(int32_t storageId,
const std::string& path,
std::vector<uint8_t>* _aidl_return) {
- auto fid = mImpl.nodeFor(storageId, path);
- if (fid != kIncFsInvalidFileId) {
- auto metadata = mImpl.getMetadata(storageId, fid);
- _aidl_return->assign(metadata.begin(), metadata.end());
- }
+ auto metadata = mImpl.getMetadata(storageId, path);
+ _aidl_return->assign(metadata.begin(), metadata.end());
return ok();
}
diff --git a/services/incremental/IncrementalService.cpp b/services/incremental/IncrementalService.cpp
index f423119d240a..dc05cb69d4c5 100644
--- a/services/incremental/IncrementalService.cpp
+++ b/services/incremental/IncrementalService.cpp
@@ -18,32 +18,26 @@
#include "IncrementalService.h"
-#include <android-base/file.h>
#include <android-base/logging.h>
#include <android-base/no_destructor.h>
#include <android-base/properties.h>
#include <android-base/stringprintf.h>
-#include <android-base/strings.h>
-#include <android/content/pm/IDataLoaderStatusListener.h>
-#include <android/os/IVold.h>
-#include <binder/BinderService.h>
+#include <binder/AppOpsManager.h>
#include <binder/Nullable.h>
-#include <binder/ParcelFileDescriptor.h>
#include <binder/Status.h>
#include <sys/stat.h>
#include <uuid/uuid.h>
#include <charconv>
#include <ctime>
-#include <filesystem>
#include <iterator>
#include <span>
#include <type_traits>
+#include "IncrementalServiceValidation.h"
#include "Metadata.pb.h"
using namespace std::literals;
-using namespace android::content::pm;
namespace fs = std::filesystem;
constexpr const char* kDataUsageStats = "android.permission.LOADER_USAGE_STATS";
@@ -51,10 +45,13 @@ constexpr const char* kOpUsage = "android:loader_usage_stats";
namespace android::incremental {
+using content::pm::DataLoaderParamsParcel;
+using content::pm::FileSystemControlParcel;
+using content::pm::IDataLoader;
+
namespace {
-using IncrementalFileSystemControlParcel =
- ::android::os::incremental::IncrementalFileSystemControlParcel;
+using IncrementalFileSystemControlParcel = os::incremental::IncrementalFileSystemControlParcel;
struct Constants {
static constexpr auto backing = "backing_store"sv;
@@ -105,10 +102,13 @@ static std::string toMountKey(std::string_view path) {
if (path::isAbsolute(path)) {
path.remove_prefix(1);
}
+ if (path.size() > 16) {
+ path = path.substr(0, 16);
+ }
std::string res(path);
- std::replace(res.begin(), res.end(), '/', '_');
- std::replace(res.begin(), res.end(), '@', '_');
- return std::string(constants().mountKeyPrefix) + res;
+ std::replace_if(
+ res.begin(), res.end(), [](char c) { return c == '/' || c == '@'; }, '_');
+ return std::string(constants().mountKeyPrefix) += res;
}
static std::pair<std::string, std::string> makeMountDir(std::string_view incrementalDir,
@@ -125,8 +125,26 @@ static std::pair<std::string, std::string> makeMountDir(std::string_view increme
return {};
}
+template <class Map>
+typename Map::const_iterator findParentPath(const Map& map, std::string_view path) {
+ const auto nextIt = map.upper_bound(path);
+ if (nextIt == map.begin()) {
+ return map.end();
+ }
+ const auto suspectIt = std::prev(nextIt);
+ if (!path::startsWith(path, suspectIt->first)) {
+ return map.end();
+ }
+ return suspectIt;
+}
+
+static base::unique_fd dup(base::borrowed_fd fd) {
+ const auto res = fcntl(fd.get(), F_DUPFD_CLOEXEC, 0);
+ return base::unique_fd(res);
+}
+
template <class ProtoMessage, class Control>
-static ProtoMessage parseFromIncfs(const IncFsWrapper* incfs, Control&& control,
+static ProtoMessage parseFromIncfs(const IncFsWrapper* incfs, const Control& control,
std::string_view path) {
auto md = incfs->getMetadata(control, path);
ProtoMessage message;
@@ -155,20 +173,18 @@ std::string makeBindMdName() {
}
} // namespace
-const bool IncrementalService::sEnablePerfLogging =
- android::base::GetBoolProperty("incremental.perflogging", false);
-
IncrementalService::IncFsMount::~IncFsMount() {
if (dataLoaderStub) {
dataLoaderStub->cleanupResources();
dataLoaderStub = {};
}
+ control.close();
LOG(INFO) << "Unmounting and cleaning up mount " << mountId << " with root '" << root << '\'';
for (auto&& [target, _] : bindPoints) {
- LOG(INFO) << "\tbind: " << target;
+ LOG(INFO) << " bind: " << target;
incrementalService.mVold->unmountIncFs(target);
}
- LOG(INFO) << "\troot: " << root;
+ LOG(INFO) << " root: " << root;
incrementalService.mVold->unmountIncFs(path::join(root, constants().mount));
cleanupFilesystem(root);
}
@@ -193,8 +209,19 @@ auto IncrementalService::IncFsMount::makeStorage(StorageId id) -> StorageMap::it
return storages.end();
}
-static std::unique_ptr<DIR, decltype(&::closedir)> openDir(const char* path) {
- return {::opendir(path), ::closedir};
+template <class Func>
+static auto makeCleanup(Func&& f) {
+ auto deleter = [f = std::move(f)](auto) { f(); };
+ // &f is a dangling pointer here, but we actually never use it as deleter moves it in.
+ return std::unique_ptr<Func, decltype(deleter)>(&f, std::move(deleter));
+}
+
+static std::unique_ptr<DIR, decltype(&::closedir)> openDir(const char* dir) {
+ return {::opendir(dir), ::closedir};
+}
+
+static auto openDir(std::string_view dir) {
+ return openDir(path::c_str(dir));
}
static int rmDirContent(const char* path) {
@@ -206,7 +233,7 @@ static int rmDirContent(const char* path) {
if (entry->d_name == "."sv || entry->d_name == ".."sv) {
continue;
}
- auto fullPath = android::base::StringPrintf("%s/%s", path, entry->d_name);
+ auto fullPath = base::StringPrintf("%s/%s", path, entry->d_name);
if (entry->d_type == DT_DIR) {
if (const auto err = rmDirContent(fullPath.c_str()); err != 0) {
PLOG(WARNING) << "Failed to delete " << fullPath << " content";
@@ -256,7 +283,8 @@ IncrementalService::IncrementalService(ServiceManagerWrapper&& sm, std::string_v
runJobProcessing();
});
- mountExistingImages();
+ const auto mountedRootNames = adoptMountedInstances();
+ mountExistingImages(mountedRootNames);
}
IncrementalService::~IncrementalService() {
@@ -268,15 +296,7 @@ IncrementalService::~IncrementalService() {
mJobProcessor.join();
}
-inline const char* toString(TimePoint t) {
- using SystemClock = std::chrono::system_clock;
- time_t time = SystemClock::to_time_t(
- SystemClock::now() +
- std::chrono::duration_cast<SystemClock::duration>(t - Clock::now()));
- return std::ctime(&time);
-}
-
-inline const char* toString(IncrementalService::BindKind kind) {
+static const char* toString(IncrementalService::BindKind kind) {
switch (kind) {
case IncrementalService::BindKind::Temporary:
return "Temporary";
@@ -291,38 +311,48 @@ void IncrementalService::onDump(int fd) {
std::unique_lock l(mLock);
- dprintf(fd, "Mounts (%d):\n", int(mMounts.size()));
+ dprintf(fd, "Mounts (%d): {\n", int(mMounts.size()));
for (auto&& [id, ifs] : mMounts) {
- const IncFsMount& mnt = *ifs.get();
- dprintf(fd, "\t[%d]:\n", id);
- dprintf(fd, "\t\tmountId: %d\n", mnt.mountId);
- dprintf(fd, "\t\troot: %s\n", mnt.root.c_str());
- dprintf(fd, "\t\tnextStorageDirNo: %d\n", mnt.nextStorageDirNo.load());
- if (mnt.dataLoaderStub) {
- mnt.dataLoaderStub->onDump(fd);
- }
- dprintf(fd, "\t\tstorages (%d):\n", int(mnt.storages.size()));
- for (auto&& [storageId, storage] : mnt.storages) {
- dprintf(fd, "\t\t\t[%d] -> [%s]\n", storageId, storage.name.c_str());
- }
-
- dprintf(fd, "\t\tbindPoints (%d):\n", int(mnt.bindPoints.size()));
- for (auto&& [target, bind] : mnt.bindPoints) {
- dprintf(fd, "\t\t\t[%s]->[%d]:\n", target.c_str(), bind.storage);
- dprintf(fd, "\t\t\t\tsavedFilename: %s\n", bind.savedFilename.c_str());
- dprintf(fd, "\t\t\t\tsourceDir: %s\n", bind.sourceDir.c_str());
- dprintf(fd, "\t\t\t\tkind: %s\n", toString(bind.kind));
+ const IncFsMount& mnt = *ifs;
+ dprintf(fd, " [%d]: {\n", id);
+ if (id != mnt.mountId) {
+ dprintf(fd, " reference to mountId: %d\n", mnt.mountId);
+ } else {
+ dprintf(fd, " mountId: %d\n", mnt.mountId);
+ dprintf(fd, " root: %s\n", mnt.root.c_str());
+ dprintf(fd, " nextStorageDirNo: %d\n", mnt.nextStorageDirNo.load());
+ if (mnt.dataLoaderStub) {
+ mnt.dataLoaderStub->onDump(fd);
+ } else {
+ dprintf(fd, " dataLoader: null\n");
+ }
+ dprintf(fd, " storages (%d): {\n", int(mnt.storages.size()));
+ for (auto&& [storageId, storage] : mnt.storages) {
+ dprintf(fd, " [%d] -> [%s]\n", storageId, storage.name.c_str());
+ }
+ dprintf(fd, " }\n");
+
+ dprintf(fd, " bindPoints (%d): {\n", int(mnt.bindPoints.size()));
+ for (auto&& [target, bind] : mnt.bindPoints) {
+ dprintf(fd, " [%s]->[%d]:\n", target.c_str(), bind.storage);
+ dprintf(fd, " savedFilename: %s\n", bind.savedFilename.c_str());
+ dprintf(fd, " sourceDir: %s\n", bind.sourceDir.c_str());
+ dprintf(fd, " kind: %s\n", toString(bind.kind));
+ }
+ dprintf(fd, " }\n");
}
+ dprintf(fd, " }\n");
}
-
- dprintf(fd, "Sorted binds (%d):\n", int(mBindsByPath.size()));
+ dprintf(fd, "}\n");
+ dprintf(fd, "Sorted binds (%d): {\n", int(mBindsByPath.size()));
for (auto&& [target, mountPairIt] : mBindsByPath) {
const auto& bind = mountPairIt->second;
- dprintf(fd, "\t\t[%s]->[%d]:\n", target.c_str(), bind.storage);
- dprintf(fd, "\t\t\tsavedFilename: %s\n", bind.savedFilename.c_str());
- dprintf(fd, "\t\t\tsourceDir: %s\n", bind.sourceDir.c_str());
- dprintf(fd, "\t\t\tkind: %s\n", toString(bind.kind));
+ dprintf(fd, " [%s]->[%d]:\n", target.c_str(), bind.storage);
+ dprintf(fd, " savedFilename: %s\n", bind.savedFilename.c_str());
+ dprintf(fd, " sourceDir: %s\n", bind.sourceDir.c_str());
+ dprintf(fd, " kind: %s\n", toString(bind.kind));
}
+ dprintf(fd, "}\n");
}
void IncrementalService::onSystemReady() {
@@ -471,9 +501,9 @@ StorageId IncrementalService::createStorage(
metadata::Mount m;
m.mutable_storage()->set_id(ifs->mountId);
m.mutable_loader()->set_type((int)dataLoaderParams.type);
- m.mutable_loader()->set_package_name(dataLoaderParams.packageName);
- m.mutable_loader()->set_class_name(dataLoaderParams.className);
- m.mutable_loader()->set_arguments(dataLoaderParams.arguments);
+ m.mutable_loader()->set_allocated_package_name(&dataLoaderParams.packageName);
+ m.mutable_loader()->set_allocated_class_name(&dataLoaderParams.className);
+ m.mutable_loader()->set_allocated_arguments(&dataLoaderParams.arguments);
const auto metadata = m.SerializeAsString();
m.mutable_loader()->release_arguments();
m.mutable_loader()->release_class_name();
@@ -528,7 +558,7 @@ StorageId IncrementalService::createLinkedStorage(std::string_view mountPoint,
}
std::unique_lock l(mLock);
- const auto& ifs = getIfsLocked(linkedStorage);
+ auto ifs = getIfsLocked(linkedStorage);
if (!ifs) {
LOG(ERROR) << "Ifs unavailable";
return kInvalidStorageId;
@@ -552,6 +582,8 @@ StorageId IncrementalService::createLinkedStorage(std::string_view mountPoint,
bk, l);
err < 0) {
LOG(ERROR) << "bindMount failed with error: " << err;
+ (void)mIncFs->unlink(ifs->control, storageIt->second.name);
+ ifs->storages.erase(storageIt);
return kInvalidStorageId;
}
@@ -561,15 +593,7 @@ StorageId IncrementalService::createLinkedStorage(std::string_view mountPoint,
IncrementalService::BindPathMap::const_iterator IncrementalService::findStorageLocked(
std::string_view path) const {
- auto bindPointIt = mBindsByPath.upper_bound(path);
- if (bindPointIt == mBindsByPath.begin()) {
- return mBindsByPath.end();
- }
- --bindPointIt;
- if (!path::startsWith(path, bindPointIt->first)) {
- return mBindsByPath.end();
- }
- return bindPointIt;
+ return findParentPath(mBindsByPath, path);
}
StorageId IncrementalService::findStorageId(std::string_view path) const {
@@ -611,13 +635,12 @@ int IncrementalService::setStorageParams(StorageId storageId, bool enableReadLog
}
binder::Status IncrementalService::applyStorageParams(IncFsMount& ifs, bool enableReadLogs) {
- using unique_fd = ::android::base::unique_fd;
- ::android::os::incremental::IncrementalFileSystemControlParcel control;
- control.cmd.reset(unique_fd(dup(ifs.control.cmd())));
- control.pendingReads.reset(unique_fd(dup(ifs.control.pendingReads())));
+ os::incremental::IncrementalFileSystemControlParcel control;
+ control.cmd.reset(dup(ifs.control.cmd()));
+ control.pendingReads.reset(dup(ifs.control.pendingReads()));
auto logsFd = ifs.control.logs();
if (logsFd >= 0) {
- control.log.reset(unique_fd(dup(logsFd)));
+ control.log.reset(dup(logsFd));
}
std::lock_guard l(mMountOperationLock);
@@ -664,38 +687,6 @@ StorageId IncrementalService::openStorage(std::string_view pathInMount) {
return findStorageId(path::normalize(pathInMount));
}
-FileId IncrementalService::nodeFor(StorageId storage, std::string_view subpath) const {
- const auto ifs = getIfs(storage);
- if (!ifs) {
- return kIncFsInvalidFileId;
- }
- std::unique_lock l(ifs->lock);
- auto storageIt = ifs->storages.find(storage);
- if (storageIt == ifs->storages.end()) {
- return kIncFsInvalidFileId;
- }
- if (subpath.empty() || subpath == "."sv) {
- return kIncFsInvalidFileId;
- }
- auto path = path::join(ifs->root, constants().mount, storageIt->second.name, subpath);
- l.unlock();
- return mIncFs->getFileId(ifs->control, path);
-}
-
-std::pair<FileId, std::string_view> IncrementalService::parentAndNameFor(
- StorageId storage, std::string_view subpath) const {
- auto name = path::basename(subpath);
- if (name.empty()) {
- return {kIncFsInvalidFileId, {}};
- }
- auto dir = path::dirname(subpath);
- if (dir.empty() || dir == "/"sv) {
- return {kIncFsInvalidFileId, {}};
- }
- auto id = nodeFor(storage, dir);
- return {id, name};
-}
-
IncrementalService::IfsMountPtr IncrementalService::getIfs(StorageId storage) const {
std::lock_guard l(mLock);
return getIfsLocked(storage);
@@ -704,7 +695,7 @@ IncrementalService::IfsMountPtr IncrementalService::getIfs(StorageId storage) co
const IncrementalService::IfsMountPtr& IncrementalService::getIfsLocked(StorageId storage) const {
auto it = mMounts.find(storage);
if (it == mMounts.end()) {
- static const android::base::NoDestructor<IfsMountPtr> kEmpty{};
+ static const base::NoDestructor<IfsMountPtr> kEmpty{};
return *kEmpty;
}
return it->second;
@@ -713,21 +704,25 @@ const IncrementalService::IfsMountPtr& IncrementalService::getIfsLocked(StorageI
int IncrementalService::bind(StorageId storage, std::string_view source, std::string_view target,
BindKind kind) {
if (!isValidMountTarget(target)) {
+ LOG(ERROR) << __func__ << ": not a valid bind target " << target;
return -EINVAL;
}
const auto ifs = getIfs(storage);
if (!ifs) {
+ LOG(ERROR) << __func__ << ": no ifs object for storage " << storage;
return -EINVAL;
}
std::unique_lock l(ifs->lock);
const auto storageInfo = ifs->storages.find(storage);
if (storageInfo == ifs->storages.end()) {
+ LOG(ERROR) << "no storage";
return -EINVAL;
}
- std::string normSource = normalizePathToStorageLocked(storageInfo, source);
+ std::string normSource = normalizePathToStorageLocked(*ifs, storageInfo, source);
if (normSource.empty()) {
+ LOG(ERROR) << "invalid source path";
return -EINVAL;
}
l.unlock();
@@ -779,33 +774,37 @@ int IncrementalService::unbind(StorageId storage, std::string_view target) {
}
std::string IncrementalService::normalizePathToStorageLocked(
- IncFsMount::StorageMap::iterator storageIt, std::string_view path) {
- std::string normPath;
- if (path::isAbsolute(path)) {
- normPath = path::normalize(path);
- if (!path::startsWith(normPath, storageIt->second.name)) {
- return {};
- }
- } else {
- normPath = path::normalize(path::join(storageIt->second.name, path));
+ const IncFsMount& incfs, IncFsMount::StorageMap::const_iterator storageIt,
+ std::string_view path) const {
+ if (!path::isAbsolute(path)) {
+ return path::normalize(path::join(storageIt->second.name, path));
}
- return normPath;
+ auto normPath = path::normalize(path);
+ if (path::startsWith(normPath, storageIt->second.name)) {
+ return normPath;
+ }
+ // not that easy: need to find if any of the bind points match
+ const auto bindIt = findParentPath(incfs.bindPoints, normPath);
+ if (bindIt == incfs.bindPoints.end()) {
+ return {};
+ }
+ return path::join(bindIt->second.sourceDir, path::relativize(bindIt->first, normPath));
}
-std::string IncrementalService::normalizePathToStorage(const IncrementalService::IfsMountPtr& ifs,
- StorageId storage, std::string_view path) {
- std::unique_lock l(ifs->lock);
- const auto storageInfo = ifs->storages.find(storage);
- if (storageInfo == ifs->storages.end()) {
+std::string IncrementalService::normalizePathToStorage(const IncFsMount& ifs, StorageId storage,
+ std::string_view path) const {
+ std::unique_lock l(ifs.lock);
+ const auto storageInfo = ifs.storages.find(storage);
+ if (storageInfo == ifs.storages.end()) {
return {};
}
- return normalizePathToStorageLocked(storageInfo, path);
+ return normalizePathToStorageLocked(ifs, storageInfo, path);
}
int IncrementalService::makeFile(StorageId storage, std::string_view path, int mode, FileId id,
incfs::NewFileParams params) {
if (auto ifs = getIfs(storage)) {
- std::string normPath = normalizePathToStorage(ifs, storage, path);
+ std::string normPath = normalizePathToStorage(*ifs, storage, path);
if (normPath.empty()) {
LOG(ERROR) << "Internal error: storageId " << storage
<< " failed to normalize: " << path;
@@ -823,7 +822,7 @@ int IncrementalService::makeFile(StorageId storage, std::string_view path, int m
int IncrementalService::makeDir(StorageId storageId, std::string_view path, int mode) {
if (auto ifs = getIfs(storageId)) {
- std::string normPath = normalizePathToStorage(ifs, storageId, path);
+ std::string normPath = normalizePathToStorage(*ifs, storageId, path);
if (normPath.empty()) {
return -EINVAL;
}
@@ -837,40 +836,41 @@ int IncrementalService::makeDirs(StorageId storageId, std::string_view path, int
if (!ifs) {
return -EINVAL;
}
+ return makeDirs(*ifs, storageId, path, mode);
+}
+
+int IncrementalService::makeDirs(const IncFsMount& ifs, StorageId storageId, std::string_view path,
+ int mode) {
std::string normPath = normalizePathToStorage(ifs, storageId, path);
if (normPath.empty()) {
return -EINVAL;
}
- auto err = mIncFs->makeDir(ifs->control, normPath, mode);
- if (err == -EEXIST) {
- return 0;
- } else if (err != -ENOENT) {
- return err;
- }
- if (auto err = makeDirs(storageId, path::dirname(normPath), mode)) {
- return err;
- }
- return mIncFs->makeDir(ifs->control, normPath, mode);
+ return mIncFs->makeDirs(ifs.control, normPath, mode);
}
int IncrementalService::link(StorageId sourceStorageId, std::string_view oldPath,
StorageId destStorageId, std::string_view newPath) {
- auto ifsSrc = getIfs(sourceStorageId);
- auto ifsDest = sourceStorageId == destStorageId ? ifsSrc : getIfs(destStorageId);
- if (ifsSrc && ifsSrc == ifsDest) {
- std::string normOldPath = normalizePathToStorage(ifsSrc, sourceStorageId, oldPath);
- std::string normNewPath = normalizePathToStorage(ifsDest, destStorageId, newPath);
- if (normOldPath.empty() || normNewPath.empty()) {
- return -EINVAL;
- }
- return mIncFs->link(ifsSrc->control, normOldPath, normNewPath);
+ std::unique_lock l(mLock);
+ auto ifsSrc = getIfsLocked(sourceStorageId);
+ if (!ifsSrc) {
+ return -EINVAL;
}
- return -EINVAL;
+ if (sourceStorageId != destStorageId && getIfsLocked(destStorageId) != ifsSrc) {
+ return -EINVAL;
+ }
+ l.unlock();
+ std::string normOldPath = normalizePathToStorage(*ifsSrc, sourceStorageId, oldPath);
+ std::string normNewPath = normalizePathToStorage(*ifsSrc, destStorageId, newPath);
+ if (normOldPath.empty() || normNewPath.empty()) {
+ LOG(ERROR) << "Invalid paths in link(): " << normOldPath << " | " << normNewPath;
+ return -EINVAL;
+ }
+ return mIncFs->link(ifsSrc->control, normOldPath, normNewPath);
}
int IncrementalService::unlink(StorageId storage, std::string_view path) {
if (auto ifs = getIfs(storage)) {
- std::string normOldPath = normalizePathToStorage(ifs, storage, path);
+ std::string normOldPath = normalizePathToStorage(*ifs, storage, path);
return mIncFs->unlink(ifs->control, normOldPath);
}
return -EINVAL;
@@ -881,10 +881,12 @@ int IncrementalService::addBindMount(IncFsMount& ifs, StorageId storage,
std::string&& target, BindKind kind,
std::unique_lock<std::mutex>& mainLock) {
if (!isValidMountTarget(target)) {
+ LOG(ERROR) << __func__ << ": invalid mount target " << target;
return -EINVAL;
}
std::string mdFileName;
+ std::string metadataFullPath;
if (kind != BindKind::Temporary) {
metadata::BindPoint bp;
bp.set_storage_id(storage);
@@ -894,17 +896,21 @@ int IncrementalService::addBindMount(IncFsMount& ifs, StorageId storage,
bp.release_dest_path();
bp.release_source_subdir();
mdFileName = makeBindMdName();
- auto node =
- mIncFs->makeFile(ifs.control, path::join(ifs.root, constants().mount, mdFileName),
- 0444, idFromMetadata(metadata),
- {.metadata = {metadata.data(), (IncFsSize)metadata.size()}});
+ metadataFullPath = path::join(ifs.root, constants().mount, mdFileName);
+ auto node = mIncFs->makeFile(ifs.control, metadataFullPath, 0444, idFromMetadata(metadata),
+ {.metadata = {metadata.data(), (IncFsSize)metadata.size()}});
if (node) {
+ LOG(ERROR) << __func__ << ": couldn't create a mount node " << mdFileName;
return int(node);
}
}
- return addBindMountWithMd(ifs, storage, std::move(mdFileName), std::move(source),
- std::move(target), kind, mainLock);
+ const auto res = addBindMountWithMd(ifs, storage, std::move(mdFileName), std::move(source),
+ std::move(target), kind, mainLock);
+ if (res) {
+ mIncFs->unlink(ifs.control, metadataFullPath);
+ }
+ return res;
}
int IncrementalService::addBindMountWithMd(IncrementalService::IncFsMount& ifs, StorageId storage,
@@ -929,61 +935,39 @@ int IncrementalService::addBindMountWithMd(IncrementalService::IncFsMount& ifs,
mainLock.lock();
}
std::lock_guard l(ifs.lock);
+ addBindMountRecordLocked(ifs, storage, std::move(metadataName), std::move(source),
+ std::move(target), kind);
+ return 0;
+}
+
+void IncrementalService::addBindMountRecordLocked(IncFsMount& ifs, StorageId storage,
+ std::string&& metadataName, std::string&& source,
+ std::string&& target, BindKind kind) {
const auto [it, _] =
ifs.bindPoints.insert_or_assign(target,
IncFsMount::Bind{storage, std::move(metadataName),
std::move(source), kind});
mBindsByPath[std::move(target)] = it;
- return 0;
}
-RawMetadata IncrementalService::getMetadata(StorageId storage, FileId node) const {
+RawMetadata IncrementalService::getMetadata(StorageId storage, std::string_view path) const {
const auto ifs = getIfs(storage);
if (!ifs) {
return {};
}
- return mIncFs->getMetadata(ifs->control, node);
+ const auto normPath = normalizePathToStorage(*ifs, storage, path);
+ if (normPath.empty()) {
+ return {};
+ }
+ return mIncFs->getMetadata(ifs->control, normPath);
}
-std::vector<std::string> IncrementalService::listFiles(StorageId storage) const {
+RawMetadata IncrementalService::getMetadata(StorageId storage, FileId node) const {
const auto ifs = getIfs(storage);
if (!ifs) {
return {};
}
-
- std::unique_lock l(ifs->lock);
- auto subdirIt = ifs->storages.find(storage);
- if (subdirIt == ifs->storages.end()) {
- return {};
- }
- auto dir = path::join(ifs->root, constants().mount, subdirIt->second.name);
- l.unlock();
-
- const auto prefixSize = dir.size() + 1;
- std::vector<std::string> todoDirs{std::move(dir)};
- std::vector<std::string> result;
- do {
- auto currDir = std::move(todoDirs.back());
- todoDirs.pop_back();
-
- auto d =
- std::unique_ptr<DIR, decltype(&::closedir)>(::opendir(currDir.c_str()), ::closedir);
- while (auto e = ::readdir(d.get())) {
- if (e->d_type == DT_REG) {
- result.emplace_back(
- path::join(std::string_view(currDir).substr(prefixSize), e->d_name));
- continue;
- }
- if (e->d_type == DT_DIR) {
- if (e->d_name == "."sv || e->d_name == ".."sv) {
- continue;
- }
- todoDirs.emplace_back(path::join(currDir, e->d_name));
- continue;
- }
- }
- } while (!todoDirs.empty());
- return result;
+ return mIncFs->getMetadata(ifs->control, node);
}
bool IncrementalService::startLoading(StorageId storage) const {
@@ -1003,16 +987,216 @@ bool IncrementalService::startLoading(StorageId storage) const {
return true;
}
-void IncrementalService::mountExistingImages() {
- for (const auto& entry : fs::directory_iterator(mIncrementalDir)) {
- const auto path = entry.path().u8string();
- const auto name = entry.path().filename().u8string();
- if (!base::StartsWith(name, constants().mountKeyPrefix)) {
+std::unordered_set<std::string_view> IncrementalService::adoptMountedInstances() {
+ std::unordered_set<std::string_view> mountedRootNames;
+ mIncFs->listExistingMounts([this, &mountedRootNames](auto root, auto backingDir, auto binds) {
+ LOG(INFO) << "Existing mount: " << backingDir << "->" << root;
+ for (auto [source, target] : binds) {
+ LOG(INFO) << " bind: '" << source << "'->'" << target << "'";
+ LOG(INFO) << " " << path::join(root, source);
+ }
+
+ // Ensure it's a kind of a mount that's managed by IncrementalService
+ if (path::basename(root) != constants().mount ||
+ path::basename(backingDir) != constants().backing) {
+ return;
+ }
+ const auto expectedRoot = path::dirname(root);
+ if (path::dirname(backingDir) != expectedRoot) {
+ return;
+ }
+ if (path::dirname(expectedRoot) != mIncrementalDir) {
+ return;
+ }
+ if (!path::basename(expectedRoot).starts_with(constants().mountKeyPrefix)) {
+ return;
+ }
+
+ LOG(INFO) << "Looks like an IncrementalService-owned: " << expectedRoot;
+
+ // make sure we clean up the mount if it happens to be a bad one.
+ // Note: unmounting needs to run first, so the cleanup object is created _last_.
+ auto cleanupFiles = makeCleanup([&]() {
+ LOG(INFO) << "Failed to adopt existing mount, deleting files: " << expectedRoot;
+ IncFsMount::cleanupFilesystem(expectedRoot);
+ });
+ auto cleanupMounts = makeCleanup([&]() {
+ LOG(INFO) << "Failed to adopt existing mount, cleaning up: " << expectedRoot;
+ for (auto&& [_, target] : binds) {
+ mVold->unmountIncFs(std::string(target));
+ }
+ mVold->unmountIncFs(std::string(root));
+ });
+
+ auto control = mIncFs->openMount(root);
+ if (!control) {
+ LOG(INFO) << "failed to open mount " << root;
+ return;
+ }
+
+ auto mountRecord =
+ parseFromIncfs<metadata::Mount>(mIncFs.get(), control,
+ path::join(root, constants().infoMdName));
+ if (!mountRecord.has_loader() || !mountRecord.has_storage()) {
+ LOG(ERROR) << "Bad mount metadata in mount at " << expectedRoot;
+ return;
+ }
+
+ auto mountId = mountRecord.storage().id();
+ mNextId = std::max(mNextId, mountId + 1);
+
+ DataLoaderParamsParcel dataLoaderParams;
+ {
+ const auto& loader = mountRecord.loader();
+ dataLoaderParams.type = (content::pm::DataLoaderType)loader.type();
+ dataLoaderParams.packageName = loader.package_name();
+ dataLoaderParams.className = loader.class_name();
+ dataLoaderParams.arguments = loader.arguments();
+ }
+
+ auto ifs = std::make_shared<IncFsMount>(std::string(expectedRoot), mountId,
+ std::move(control), *this);
+ cleanupFiles.release(); // ifs will take care of that now
+
+ std::vector<std::pair<std::string, metadata::BindPoint>> permanentBindPoints;
+ auto d = openDir(root);
+ while (auto e = ::readdir(d.get())) {
+ if (e->d_type == DT_REG) {
+ auto name = std::string_view(e->d_name);
+ if (name.starts_with(constants().mountpointMdPrefix)) {
+ permanentBindPoints
+ .emplace_back(name,
+ parseFromIncfs<metadata::BindPoint>(mIncFs.get(),
+ ifs->control,
+ path::join(root,
+ name)));
+ if (permanentBindPoints.back().second.dest_path().empty() ||
+ permanentBindPoints.back().second.source_subdir().empty()) {
+ permanentBindPoints.pop_back();
+ mIncFs->unlink(ifs->control, path::join(root, name));
+ } else {
+ LOG(INFO) << "Permanent bind record: '"
+ << permanentBindPoints.back().second.source_subdir() << "'->'"
+ << permanentBindPoints.back().second.dest_path() << "'";
+ }
+ }
+ } else if (e->d_type == DT_DIR) {
+ if (e->d_name == "."sv || e->d_name == ".."sv) {
+ continue;
+ }
+ auto name = std::string_view(e->d_name);
+ if (name.starts_with(constants().storagePrefix)) {
+ int storageId;
+ const auto res =
+ std::from_chars(name.data() + constants().storagePrefix.size() + 1,
+ name.data() + name.size(), storageId);
+ if (res.ec != std::errc{} || *res.ptr != '_') {
+ LOG(WARNING) << "Ignoring storage with invalid name '" << name
+ << "' for mount " << expectedRoot;
+ continue;
+ }
+ auto [_, inserted] = mMounts.try_emplace(storageId, ifs);
+ if (!inserted) {
+ LOG(WARNING) << "Ignoring storage with duplicate id " << storageId
+ << " for mount " << expectedRoot;
+ continue;
+ }
+ ifs->storages.insert_or_assign(storageId,
+ IncFsMount::Storage{path::join(root, name)});
+ mNextId = std::max(mNextId, storageId + 1);
+ }
+ }
+ }
+
+ if (ifs->storages.empty()) {
+ LOG(WARNING) << "No valid storages in mount " << root;
+ return;
+ }
+
+ // now match the mounted directories with what we expect to have in the metadata
+ {
+ std::unique_lock l(mLock, std::defer_lock);
+ for (auto&& [metadataFile, bindRecord] : permanentBindPoints) {
+ auto mountedIt = std::find_if(binds.begin(), binds.end(),
+ [&, bindRecord = bindRecord](auto&& bind) {
+ return bind.second == bindRecord.dest_path() &&
+ path::join(root, bind.first) ==
+ bindRecord.source_subdir();
+ });
+ if (mountedIt != binds.end()) {
+ LOG(INFO) << "Matched permanent bound " << bindRecord.source_subdir()
+ << " to mount " << mountedIt->first;
+ addBindMountRecordLocked(*ifs, bindRecord.storage_id(), std::move(metadataFile),
+ std::move(*bindRecord.mutable_source_subdir()),
+ std::move(*bindRecord.mutable_dest_path()),
+ BindKind::Permanent);
+ if (mountedIt != binds.end() - 1) {
+ std::iter_swap(mountedIt, binds.end() - 1);
+ }
+ binds = binds.first(binds.size() - 1);
+ } else {
+ LOG(INFO) << "Didn't match permanent bound " << bindRecord.source_subdir()
+ << ", mounting";
+ // doesn't exist - try mounting back
+ if (addBindMountWithMd(*ifs, bindRecord.storage_id(), std::move(metadataFile),
+ std::move(*bindRecord.mutable_source_subdir()),
+ std::move(*bindRecord.mutable_dest_path()),
+ BindKind::Permanent, l)) {
+ mIncFs->unlink(ifs->control, metadataFile);
+ }
+ }
+ }
+ }
+
+ // if anything stays in |binds| those are probably temporary binds; system restarted since
+ // they were mounted - so let's unmount them all.
+ for (auto&& [source, target] : binds) {
+ if (source.empty()) {
+ continue;
+ }
+ mVold->unmountIncFs(std::string(target));
+ }
+ cleanupMounts.release(); // ifs now manages everything
+
+ if (ifs->bindPoints.empty()) {
+ LOG(WARNING) << "No valid bind points for mount " << expectedRoot;
+ deleteStorage(*ifs);
+ return;
+ }
+
+ prepareDataLoaderLocked(*ifs, std::move(dataLoaderParams));
+ CHECK(ifs->dataLoaderStub);
+
+ mountedRootNames.insert(path::basename(ifs->root));
+
+ // not locking here at all: we're still in the constructor, no other calls can happen
+ mMounts[ifs->mountId] = std::move(ifs);
+ });
+
+ return mountedRootNames;
+}
+
+void IncrementalService::mountExistingImages(
+ const std::unordered_set<std::string_view>& mountedRootNames) {
+ auto dir = openDir(mIncrementalDir);
+ if (!dir) {
+ PLOG(WARNING) << "Couldn't open the root incremental dir " << mIncrementalDir;
+ return;
+ }
+ while (auto entry = ::readdir(dir.get())) {
+ if (entry->d_type != DT_DIR) {
+ continue;
+ }
+ std::string_view name = entry->d_name;
+ if (!name.starts_with(constants().mountKeyPrefix)) {
+ continue;
+ }
+ if (mountedRootNames.find(name) != mountedRootNames.end()) {
continue;
}
const auto root = path::join(mIncrementalDir, name);
if (!mountExistingImage(root)) {
- IncFsMount::cleanupFilesystem(path);
+ IncFsMount::cleanupFilesystem(root);
}
}
}
@@ -1049,7 +1233,7 @@ bool IncrementalService::mountExistingImage(std::string_view root) {
DataLoaderParamsParcel dataLoaderParams;
{
const auto& loader = mount.loader();
- dataLoaderParams.type = (android::content::pm::DataLoaderType)loader.type();
+ dataLoaderParams.type = (content::pm::DataLoaderType)loader.type();
dataLoaderParams.packageName = loader.package_name();
dataLoaderParams.className = loader.class_name();
dataLoaderParams.arguments = loader.arguments();
@@ -1059,7 +1243,7 @@ bool IncrementalService::mountExistingImage(std::string_view root) {
CHECK(ifs->dataLoaderStub);
std::vector<std::pair<std::string, metadata::BindPoint>> bindPoints;
- auto d = openDir(path::c_str(mountTarget));
+ auto d = openDir(mountTarget);
while (auto e = ::readdir(d.get())) {
if (e->d_type == DT_REG) {
auto name = std::string_view(e->d_name);
@@ -1109,12 +1293,14 @@ bool IncrementalService::mountExistingImage(std::string_view root) {
}
int bindCount = 0;
- for (auto&& bp : bindPoints) {
+ {
std::unique_lock l(mLock, std::defer_lock);
- bindCount += !addBindMountWithMd(*ifs, bp.second.storage_id(), std::move(bp.first),
- std::move(*bp.second.mutable_source_subdir()),
- std::move(*bp.second.mutable_dest_path()),
- BindKind::Permanent, l);
+ for (auto&& bp : bindPoints) {
+ bindCount += !addBindMountWithMd(*ifs, bp.second.storage_id(), std::move(bp.first),
+ std::move(*bp.second.mutable_source_subdir()),
+ std::move(*bp.second.mutable_dest_path()),
+ BindKind::Permanent, l);
+ }
}
if (bindCount == 0) {
@@ -1123,30 +1309,35 @@ bool IncrementalService::mountExistingImage(std::string_view root) {
return false;
}
+ // not locking here at all: we're still in the constructor, no other calls can happen
mMounts[ifs->mountId] = std::move(ifs);
return true;
}
IncrementalService::DataLoaderStubPtr IncrementalService::prepareDataLoader(
- IncrementalService::IncFsMount& ifs, DataLoaderParamsParcel&& params,
+ IncFsMount& ifs, DataLoaderParamsParcel&& params,
const DataLoaderStatusListener* externalListener) {
std::unique_lock l(ifs.lock);
+ prepareDataLoaderLocked(ifs, std::move(params), externalListener);
+ return ifs.dataLoaderStub;
+}
+
+void IncrementalService::prepareDataLoaderLocked(IncFsMount& ifs, DataLoaderParamsParcel&& params,
+ const DataLoaderStatusListener* externalListener) {
if (ifs.dataLoaderStub) {
LOG(INFO) << "Skipped data loader preparation because it already exists";
- return ifs.dataLoaderStub;
+ return;
}
FileSystemControlParcel fsControlParcel;
fsControlParcel.incremental = aidl::make_nullable<IncrementalFileSystemControlParcel>();
- fsControlParcel.incremental->cmd.reset(base::unique_fd(::dup(ifs.control.cmd())));
- fsControlParcel.incremental->pendingReads.reset(
- base::unique_fd(::dup(ifs.control.pendingReads())));
- fsControlParcel.incremental->log.reset(base::unique_fd(::dup(ifs.control.logs())));
+ fsControlParcel.incremental->cmd.reset(dup(ifs.control.cmd()));
+ fsControlParcel.incremental->pendingReads.reset(dup(ifs.control.pendingReads()));
+ fsControlParcel.incremental->log.reset(dup(ifs.control.logs()));
fsControlParcel.service = new IncrementalServiceConnector(*this, ifs.mountId);
ifs.dataLoaderStub = new DataLoaderStub(*this, ifs.mountId, std::move(params),
std::move(fsControlParcel), externalListener);
- return ifs.dataLoaderStub;
}
template <class Duration>
@@ -1167,7 +1358,7 @@ bool IncrementalService::configureNativeBinaries(StorageId storage, std::string_
}
// First prepare target directories if they don't exist yet
- if (auto res = makeDirs(storage, libDirRelativePath, 0755)) {
+ if (auto res = makeDirs(*ifs, storage, libDirRelativePath, 0755)) {
LOG(ERROR) << "Failed to prepare target lib directory " << libDirRelativePath
<< " errno: " << res;
return false;
@@ -1205,10 +1396,10 @@ bool IncrementalService::configureNativeBinaries(StorageId storage, std::string_
const auto libName = path::basename(fileName);
const auto targetLibPath = path::join(libDirRelativePath, libName);
- const auto targetLibPathAbsolute = normalizePathToStorage(ifs, storage, targetLibPath);
+ const auto targetLibPathAbsolute = normalizePathToStorage(*ifs, storage, targetLibPath);
// If the extract file already exists, skip
if (access(targetLibPathAbsolute.c_str(), F_OK) == 0) {
- if (sEnablePerfLogging) {
+ if (perfLoggingEnabled()) {
LOG(INFO) << "incfs: Native lib file already exists: " << targetLibPath
<< "; skipping extraction, spent "
<< elapsedMcs(startFileTs, Clock::now()) << "mcs";
@@ -1235,7 +1426,7 @@ bool IncrementalService::configureNativeBinaries(StorageId storage, std::string_
// If it is a zero-byte file, skip data writing
if (entry.uncompressed_length == 0) {
- if (sEnablePerfLogging) {
+ if (perfLoggingEnabled()) {
LOG(INFO) << "incfs: Extracted " << libName
<< "(0 bytes): " << elapsedMcs(startFileTs, makeFileTs) << "mcs";
}
@@ -1248,7 +1439,7 @@ bool IncrementalService::configureNativeBinaries(StorageId storage, std::string_
extractZipFile(ifs.lock(), zipFile.get(), entry, libFileId, libPath, makeFileTs);
});
- if (sEnablePerfLogging) {
+ if (perfLoggingEnabled()) {
auto prepareJobTs = Clock::now();
LOG(INFO) << "incfs: Processed " << libName << ": "
<< elapsedMcs(startFileTs, prepareJobTs)
@@ -1275,7 +1466,7 @@ bool IncrementalService::configureNativeBinaries(StorageId storage, std::string_
mJobCondition.notify_all();
}
- if (sEnablePerfLogging) {
+ if (perfLoggingEnabled()) {
auto end = Clock::now();
LOG(INFO) << "incfs: configureNativeBinaries complete in " << elapsedMcs(start, end)
<< "mcs, make dirs: " << elapsedMcs(start, mkDirsTs)
@@ -1340,7 +1531,7 @@ void IncrementalService::extractZipFile(const IfsMountPtr& ifs, ZipArchiveHandle
return;
}
- if (sEnablePerfLogging) {
+ if (perfLoggingEnabled()) {
auto endFileTs = Clock::now();
LOG(INFO) << "incfs: Extracted " << libName << "(" << entry.compressed_length << " -> "
<< entry.uncompressed_length << " bytes): " << elapsedMcs(startedTs, endFileTs)
@@ -1356,7 +1547,7 @@ bool IncrementalService::waitForNativeBinariesExtraction(StorageId storage) {
struct WaitPrinter {
const Clock::time_point startTs = Clock::now();
~WaitPrinter() noexcept {
- if (sEnablePerfLogging) {
+ if (perfLoggingEnabled()) {
const auto endTs = Clock::now();
LOG(INFO) << "incfs: waitForNativeBinariesExtraction() complete in "
<< elapsedMcs(startTs, endTs) << "mcs";
@@ -1381,6 +1572,11 @@ bool IncrementalService::waitForNativeBinariesExtraction(StorageId storage) {
return mRunning;
}
+bool IncrementalService::perfLoggingEnabled() {
+ static const bool enabled = base::GetBoolProperty("incremental.perflogging", false);
+ return enabled;
+}
+
void IncrementalService::runJobProcessing() {
for (;;) {
std::unique_lock lock(mJobMutex);
@@ -1492,12 +1688,17 @@ bool IncrementalService::DataLoaderStub::requestDestroy() {
return setTargetStatus(IDataLoaderStatusListener::DATA_LOADER_DESTROYED);
}
-bool IncrementalService::DataLoaderStub::setTargetStatus(int status) {
+bool IncrementalService::DataLoaderStub::setTargetStatus(int newStatus) {
+ int oldStatus, curStatus;
{
std::unique_lock lock(mStatusMutex);
- mTargetStatus = status;
+ oldStatus = mTargetStatus;
+ mTargetStatus = newStatus;
mTargetStatusTs = Clock::now();
+ curStatus = mCurrentStatus;
}
+ LOG(DEBUG) << "Target status update for DataLoader " << mId << ": " << oldStatus << " -> "
+ << newStatus << " (current " << curStatus << ")";
return fsmStep();
}
@@ -1596,14 +1797,20 @@ binder::Status IncrementalService::DataLoaderStub::onStatusChanged(MountId mount
return binder::Status::fromServiceSpecificError(-EPERM, "Mount ID mismatch.");
}
+ int targetStatus, oldStatus;
{
std::unique_lock lock(mStatusMutex);
if (mCurrentStatus == newStatus) {
return binder::Status::ok();
}
mCurrentStatus = newStatus;
+ oldStatus = mCurrentStatus;
+ targetStatus = mTargetStatus;
}
+ LOG(DEBUG) << "Current status update for DataLoader " << mId << ": " << oldStatus << " -> "
+ << newStatus << " (target " << targetStatus << ")";
+
if (mListener) {
mListener->onStatusChanged(mountId, newStatus);
}
@@ -1616,17 +1823,19 @@ binder::Status IncrementalService::DataLoaderStub::onStatusChanged(MountId mount
}
void IncrementalService::DataLoaderStub::onDump(int fd) {
- dprintf(fd, "\t\tdataLoader:");
- dprintf(fd, "\t\t\tcurrentStatus: %d\n", mCurrentStatus);
- dprintf(fd, "\t\t\ttargetStatus: %d\n", mTargetStatus);
- dprintf(fd, "\t\t\ttargetStatusTs: %lldmcs\n",
+ dprintf(fd, " dataLoader: {\n");
+ dprintf(fd, " currentStatus: %d\n", mCurrentStatus);
+ dprintf(fd, " targetStatus: %d\n", mTargetStatus);
+ dprintf(fd, " targetStatusTs: %lldmcs\n",
(long long)(elapsedMcs(mTargetStatusTs, Clock::now())));
const auto& params = mParams;
- dprintf(fd, "\t\t\tdataLoaderParams:\n");
- dprintf(fd, "\t\t\t\ttype: %s\n", toString(params.type).c_str());
- dprintf(fd, "\t\t\t\tpackageName: %s\n", params.packageName.c_str());
- dprintf(fd, "\t\t\t\tclassName: %s\n", params.className.c_str());
- dprintf(fd, "\t\t\t\targuments: %s\n", params.arguments.c_str());
+ dprintf(fd, " dataLoaderParams: {\n");
+ dprintf(fd, " type: %s\n", toString(params.type).c_str());
+ dprintf(fd, " packageName: %s\n", params.packageName.c_str());
+ dprintf(fd, " className: %s\n", params.className.c_str());
+ dprintf(fd, " arguments: %s\n", params.arguments.c_str());
+ dprintf(fd, " }\n");
+ dprintf(fd, " }\n");
}
void IncrementalService::AppOpsListener::opChanged(int32_t, const String16&) {
diff --git a/services/incremental/IncrementalService.h b/services/incremental/IncrementalService.h
index bd01d7760a01..0a18e21e9d6d 100644
--- a/services/incremental/IncrementalService.h
+++ b/services/incremental/IncrementalService.h
@@ -16,13 +16,13 @@
#pragma once
-#include <android-base/strings.h>
-#include <android-base/unique_fd.h>
+#include <android/content/pm/BnDataLoaderStatusListener.h>
#include <android/content/pm/DataLoaderParamsParcel.h>
-#include <binder/IServiceManager.h>
+#include <android/content/pm/IDataLoaderStatusListener.h>
+#include <android/os/incremental/BnIncrementalServiceConnector.h>
+#include <binder/IAppOpsCallback.h>
#include <utils/String16.h>
#include <utils/StrongPointer.h>
-#include <utils/Vector.h>
#include <ziparchive/zip_archive.h>
#include <atomic>
@@ -37,21 +37,14 @@
#include <string_view>
#include <thread>
#include <unordered_map>
+#include <unordered_set>
#include <utility>
#include <vector>
#include "ServiceWrappers.h"
-#include "android/content/pm/BnDataLoaderStatusListener.h"
-#include "android/os/incremental/BnIncrementalServiceConnector.h"
#include "incfs.h"
#include "path.h"
-using namespace android::os::incremental;
-
-namespace android::os {
-class IVold;
-}
-
namespace android::incremental {
using MountId = int;
@@ -101,17 +94,14 @@ public:
void onSystemReady();
- StorageId createStorage(std::string_view mountPoint, DataLoaderParamsParcel&& dataLoaderParams,
+ StorageId createStorage(std::string_view mountPoint,
+ content::pm::DataLoaderParamsParcel&& dataLoaderParams,
const DataLoaderStatusListener& dataLoaderStatusListener,
CreateOptions options = CreateOptions::Default);
StorageId createLinkedStorage(std::string_view mountPoint, StorageId linkedStorage,
CreateOptions options = CreateOptions::Default);
StorageId openStorage(std::string_view path);
- FileId nodeFor(StorageId storage, std::string_view path) const;
- std::pair<FileId, std::string_view> parentAndNameFor(StorageId storage,
- std::string_view path) const;
-
int bind(StorageId storage, std::string_view source, std::string_view target, BindKind kind);
int unbind(StorageId storage, std::string_view target);
void deleteStorage(StorageId storage);
@@ -131,9 +121,9 @@ public:
return false;
}
+ RawMetadata getMetadata(StorageId storage, std::string_view path) const;
RawMetadata getMetadata(StorageId storage, FileId node) const;
- std::vector<std::string> listFiles(StorageId storage) const;
bool startLoading(StorageId storage) const;
bool configureNativeBinaries(StorageId storage, std::string_view apkFullPath,
@@ -151,7 +141,7 @@ public:
const std::string packageName;
};
- class IncrementalServiceConnector : public BnIncrementalServiceConnector {
+ class IncrementalServiceConnector : public os::incremental::BnIncrementalServiceConnector {
public:
IncrementalServiceConnector(IncrementalService& incrementalService, int32_t storage)
: incrementalService(incrementalService), storage(storage) {}
@@ -163,14 +153,13 @@ public:
};
private:
- static const bool sEnablePerfLogging;
-
struct IncFsMount;
- class DataLoaderStub : public android::content::pm::BnDataLoaderStatusListener {
+ class DataLoaderStub : public content::pm::BnDataLoaderStatusListener {
public:
- DataLoaderStub(IncrementalService& service, MountId id, DataLoaderParamsParcel&& params,
- FileSystemControlParcel&& control,
+ DataLoaderStub(IncrementalService& service, MountId id,
+ content::pm::DataLoaderParamsParcel&& params,
+ content::pm::FileSystemControlParcel&& control,
const DataLoaderStatusListener* externalListener);
~DataLoaderStub();
// Cleans up the internal state and invalidates DataLoaderStub. Any subsequent calls will
@@ -184,7 +173,7 @@ private:
void onDump(int fd);
MountId id() const { return mId; }
- const DataLoaderParamsParcel& params() const { return mParams; }
+ const content::pm::DataLoaderParamsParcel& params() const { return mParams; }
private:
binder::Status onStatusChanged(MountId mount, int newStatus) final;
@@ -202,14 +191,14 @@ private:
IncrementalService& mService;
MountId mId = kInvalidStorageId;
- DataLoaderParamsParcel mParams;
- FileSystemControlParcel mControl;
+ content::pm::DataLoaderParamsParcel mParams;
+ content::pm::FileSystemControlParcel mControl;
DataLoaderStatusListener mListener;
std::mutex mStatusMutex;
std::condition_variable mStatusCondition;
- int mCurrentStatus = IDataLoaderStatusListener::DATA_LOADER_DESTROYED;
- int mTargetStatus = IDataLoaderStatusListener::DATA_LOADER_DESTROYED;
+ int mCurrentStatus = content::pm::IDataLoaderStatusListener::DATA_LOADER_DESTROYED;
+ int mTargetStatus = content::pm::IDataLoaderStatusListener::DATA_LOADER_DESTROYED;
TimePoint mTargetStatusTs = {};
};
using DataLoaderStubPtr = sp<DataLoaderStub>;
@@ -228,7 +217,7 @@ private:
using Control = incfs::UniqueControl;
- using BindMap = std::map<std::string, Bind>;
+ using BindMap = std::map<std::string, Bind, path::PathLess>;
using StorageMap = std::unordered_map<StorageId, Storage>;
mutable std::mutex lock;
@@ -260,7 +249,10 @@ private:
using MountMap = std::unordered_map<MountId, IfsMountPtr>;
using BindPathMap = std::map<std::string, IncFsMount::BindMap::iterator, path::PathLess>;
- void mountExistingImages();
+ static bool perfLoggingEnabled();
+
+ std::unordered_set<std::string_view> adoptMountedInstances();
+ void mountExistingImages(const std::unordered_set<std::string_view>& mountedRootNames);
bool mountExistingImage(std::string_view root);
IfsMountPtr getIfs(StorageId storage) const;
@@ -273,8 +265,14 @@ private:
std::string&& source, std::string&& target, BindKind kind,
std::unique_lock<std::mutex>& mainLock);
- DataLoaderStubPtr prepareDataLoader(IncFsMount& ifs, DataLoaderParamsParcel&& params,
+ void addBindMountRecordLocked(IncFsMount& ifs, StorageId storage, std::string&& metadataName,
+ std::string&& source, std::string&& target, BindKind kind);
+
+ DataLoaderStubPtr prepareDataLoader(IncFsMount& ifs,
+ content::pm::DataLoaderParamsParcel&& params,
const DataLoaderStatusListener* externalListener = nullptr);
+ void prepareDataLoaderLocked(IncFsMount& ifs, content::pm::DataLoaderParamsParcel&& params,
+ const DataLoaderStatusListener* externalListener = nullptr);
BindPathMap::const_iterator findStorageLocked(std::string_view path) const;
StorageId findStorageId(std::string_view path) const;
@@ -282,11 +280,12 @@ private:
void deleteStorage(IncFsMount& ifs);
void deleteStorageLocked(IncFsMount& ifs, std::unique_lock<std::mutex>&& ifsLock);
MountMap::iterator getStorageSlotLocked();
- std::string normalizePathToStorage(const IfsMountPtr& incfs, StorageId storage,
- std::string_view path);
- std::string normalizePathToStorageLocked(IncFsMount::StorageMap::iterator storageIt,
- std::string_view path);
-
+ std::string normalizePathToStorage(const IncFsMount& incfs, StorageId storage,
+ std::string_view path) const;
+ std::string normalizePathToStorageLocked(const IncFsMount& incfs,
+ IncFsMount::StorageMap::const_iterator storageIt,
+ std::string_view path) const;
+ int makeDirs(const IncFsMount& ifs, StorageId storageId, std::string_view path, int mode);
binder::Status applyStorageParams(IncFsMount& ifs, bool enableReadLogs);
void registerAppOpsCallback(const std::string& packageName);
diff --git a/services/incremental/IncrementalServiceValidation.cpp b/services/incremental/IncrementalServiceValidation.cpp
new file mode 100644
index 000000000000..abadbbf10742
--- /dev/null
+++ b/services/incremental/IncrementalServiceValidation.cpp
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "IncrementalServiceValidation.h"
+
+#include <android-base/stringprintf.h>
+#include <binder/IPCThreadState.h>
+#include <binder/PermissionCache.h>
+#include <binder/PermissionController.h>
+#include <errno.h>
+#include <utils/String16.h>
+
+namespace android::incremental {
+
+binder::Status Ok() {
+ return binder::Status::ok();
+}
+
+binder::Status Exception(uint32_t code, const std::string& msg) {
+ return binder::Status::fromExceptionCode(code, String8(msg.c_str()));
+}
+
+int fromBinderStatus(const binder::Status& status) {
+ return status.exceptionCode() == binder::Status::EX_SERVICE_SPECIFIC
+ ? status.serviceSpecificErrorCode() > 0
+ ? -status.serviceSpecificErrorCode()
+ : status.serviceSpecificErrorCode() == 0 ? -EFAULT
+ : status.serviceSpecificErrorCode()
+ : -EIO;
+}
+
+binder::Status CheckPermissionForDataDelivery(const char* permission, const char* operation,
+ const char* package) {
+ using android::base::StringPrintf;
+
+ int32_t pid;
+ int32_t uid;
+
+ if (!PermissionCache::checkCallingPermission(String16(permission), &pid, &uid)) {
+ return Exception(binder::Status::EX_SECURITY,
+ StringPrintf("UID %d / PID %d lacks permission %s", uid, pid, permission));
+ }
+
+ String16 packageName{package};
+
+ // Caller must also have op granted.
+ PermissionController pc;
+ if (auto packageUid = pc.getPackageUid(packageName, 0); packageUid != uid) {
+ return Exception(binder::Status::EX_SECURITY,
+ StringPrintf("UID %d / PID %d does not own package %s", uid, pid,
+ package));
+ }
+ switch (auto result = pc.noteOp(String16(operation), uid, packageName); result) {
+ case PermissionController::MODE_ALLOWED:
+ case PermissionController::MODE_DEFAULT:
+ return binder::Status::ok();
+ default:
+ return Exception(binder::Status::EX_SECURITY,
+ StringPrintf("UID %d / PID %d / package %s lacks app-op %s, error %d",
+ uid, pid, package, operation, result));
+ }
+}
+
+} // namespace android::incremental
diff --git a/services/incremental/IncrementalServiceValidation.h b/services/incremental/IncrementalServiceValidation.h
index 48894c6926c8..0e50c4db29f4 100644
--- a/services/incremental/IncrementalServiceValidation.h
+++ b/services/incremental/IncrementalServiceValidation.h
@@ -16,61 +16,17 @@
#pragma once
-#include <android-base/stringprintf.h>
-#include <binder/IPCThreadState.h>
-#include <binder/PermissionCache.h>
-#include <binder/PermissionController.h>
#include <binder/Status.h>
+#include <stdint.h>
-namespace android::incremental {
-
-inline binder::Status Ok() {
- return binder::Status::ok();
-}
-
-inline binder::Status Exception(uint32_t code, const std::string& msg) {
- return binder::Status::fromExceptionCode(code, String8(msg.c_str()));
-}
-
-inline int fromBinderStatus(const binder::Status& status) {
- return status.exceptionCode() == binder::Status::EX_SERVICE_SPECIFIC
- ? status.serviceSpecificErrorCode() > 0 ? -status.serviceSpecificErrorCode()
- : status.serviceSpecificErrorCode() == 0
- ? -EFAULT
- : status.serviceSpecificErrorCode()
- : -EIO;
-}
+#include <string>
-inline binder::Status CheckPermissionForDataDelivery(const char* permission, const char* operation,
- const char* package) {
- using android::base::StringPrintf;
-
- int32_t pid;
- int32_t uid;
-
- if (!PermissionCache::checkCallingPermission(String16(permission), &pid, &uid)) {
- return Exception(binder::Status::EX_SECURITY,
- StringPrintf("UID %d / PID %d lacks permission %s", uid, pid, permission));
- }
-
- String16 packageName{package};
+namespace android::incremental {
- // Caller must also have op granted.
- PermissionController pc;
- if (auto packageUid = pc.getPackageUid(packageName, 0); packageUid != uid) {
- return Exception(binder::Status::EX_SECURITY,
- StringPrintf("UID %d / PID %d does not own package %s", uid, pid,
- package));
- }
- switch (auto result = pc.noteOp(String16(operation), uid, packageName); result) {
- case PermissionController::MODE_ALLOWED:
- case PermissionController::MODE_DEFAULT:
- return binder::Status::ok();
- default:
- return Exception(binder::Status::EX_SECURITY,
- StringPrintf("UID %d / PID %d / package %s lacks app-op %s, error %d",
- uid, pid, package, operation, result));
- }
-}
+binder::Status Ok();
+binder::Status Exception(uint32_t code, const std::string& msg);
+int fromBinderStatus(const binder::Status& status);
+binder::Status CheckPermissionForDataDelivery(const char* permission, const char* operation,
+ const char* package);
} // namespace android::incremental
diff --git a/services/incremental/ServiceWrappers.cpp b/services/incremental/ServiceWrappers.cpp
index bf8e696a264c..32aa849c03b9 100644
--- a/services/incremental/ServiceWrappers.cpp
+++ b/services/incremental/ServiceWrappers.cpp
@@ -18,12 +18,18 @@
#include "ServiceWrappers.h"
+#include <MountRegistry.h>
#include <android-base/logging.h>
+#include <android/content/pm/IDataLoaderManager.h>
+#include <android/os/IVold.h>
+#include <binder/AppOpsManager.h>
#include <utils/String16.h>
+#include "IncrementalServiceValidation.h"
+
using namespace std::literals;
-namespace android::os::incremental {
+namespace android::incremental {
static constexpr auto kVoldServiceName = "vold"sv;
static constexpr auto kDataLoaderManagerName = "dataloader_manager"sv;
@@ -32,9 +38,9 @@ class RealVoldService : public VoldServiceWrapper {
public:
RealVoldService(const sp<os::IVold> vold) : mInterface(std::move(vold)) {}
~RealVoldService() = default;
- binder::Status mountIncFs(const std::string& backingPath, const std::string& targetDir,
- int32_t flags,
- IncrementalFileSystemControlParcel* _aidl_return) const final {
+ binder::Status mountIncFs(
+ const std::string& backingPath, const std::string& targetDir, int32_t flags,
+ os::incremental::IncrementalFileSystemControlParcel* _aidl_return) const final {
return mInterface->mountIncFs(backingPath, targetDir, flags, _aidl_return);
}
binder::Status unmountIncFs(const std::string& dir) const final {
@@ -56,16 +62,18 @@ private:
class RealDataLoaderManager : public DataLoaderManagerWrapper {
public:
- RealDataLoaderManager(const sp<content::pm::IDataLoaderManager> manager)
- : mInterface(manager) {}
+ RealDataLoaderManager(sp<content::pm::IDataLoaderManager> manager)
+ : mInterface(std::move(manager)) {}
~RealDataLoaderManager() = default;
- binder::Status initializeDataLoader(MountId mountId, const DataLoaderParamsParcel& params,
- const FileSystemControlParcel& control,
- const sp<IDataLoaderStatusListener>& listener,
+ binder::Status initializeDataLoader(MountId mountId,
+ const content::pm::DataLoaderParamsParcel& params,
+ const content::pm::FileSystemControlParcel& control,
+ const sp<content::pm::IDataLoaderStatusListener>& listener,
bool* _aidl_return) const final {
return mInterface->initializeDataLoader(mountId, params, control, listener, _aidl_return);
}
- binder::Status getDataLoader(MountId mountId, sp<IDataLoader>* _aidl_return) const final {
+ binder::Status getDataLoader(MountId mountId,
+ sp<content::pm::IDataLoader>* _aidl_return) const final {
return mInterface->getDataLoader(mountId, _aidl_return);
}
binder::Status destroyDataLoader(MountId mountId) const final {
@@ -109,21 +117,31 @@ private:
class RealIncFs : public IncFsWrapper {
public:
RealIncFs() = default;
- ~RealIncFs() = default;
+ ~RealIncFs() final = default;
+ void listExistingMounts(const ExistingMountCallback& cb) const final {
+ for (auto mount : incfs::defaultMountRegistry().copyMounts()) {
+ auto binds = mount.binds(); // span() doesn't like rvalue containers, needs to save it.
+ cb(mount.root(), mount.backingDir(), binds);
+ }
+ }
+ Control openMount(std::string_view path) const final { return incfs::open(path); }
Control createControl(IncFsFd cmd, IncFsFd pendingReads, IncFsFd logs) const final {
return incfs::createControl(cmd, pendingReads, logs);
}
ErrorCode makeFile(const Control& control, std::string_view path, int mode, FileId id,
- NewFileParams params) const final {
+ incfs::NewFileParams params) const final {
return incfs::makeFile(control, path, mode, id, params);
}
ErrorCode makeDir(const Control& control, std::string_view path, int mode) const final {
return incfs::makeDir(control, path, mode);
}
- RawMetadata getMetadata(const Control& control, FileId fileid) const final {
+ ErrorCode makeDirs(const Control& control, std::string_view path, int mode) const final {
+ return incfs::makeDirs(control, path, mode);
+ }
+ incfs::RawMetadata getMetadata(const Control& control, FileId fileid) const final {
return incfs::getMetadata(control, fileid);
}
- RawMetadata getMetadata(const Control& control, std::string_view path) const final {
+ incfs::RawMetadata getMetadata(const Control& control, std::string_view path) const final {
return incfs::getMetadata(control, path);
}
FileId getFileId(const Control& control, std::string_view path) const final {
@@ -138,8 +156,8 @@ public:
base::unique_fd openForSpecialOps(const Control& control, FileId id) const final {
return base::unique_fd{incfs::openForSpecialOps(control, id).release()};
}
- ErrorCode writeBlocks(Span<const DataBlock> blocks) const final {
- return incfs::writeBlocks(blocks);
+ ErrorCode writeBlocks(std::span<const incfs::DataBlock> blocks) const final {
+ return incfs::writeBlocks({blocks.data(), size_t(blocks.size())});
}
};
@@ -165,8 +183,9 @@ std::unique_ptr<VoldServiceWrapper> RealServiceManager::getVoldService() {
}
std::unique_ptr<DataLoaderManagerWrapper> RealServiceManager::getDataLoaderManager() {
- sp<IDataLoaderManager> manager =
- RealServiceManager::getRealService<IDataLoaderManager>(kDataLoaderManagerName);
+ sp<content::pm::IDataLoaderManager> manager =
+ RealServiceManager::getRealService<content::pm::IDataLoaderManager>(
+ kDataLoaderManagerName);
if (manager) {
return std::make_unique<RealDataLoaderManager>(manager);
}
@@ -239,4 +258,4 @@ JavaVM* RealJniWrapper::getJvm(JNIEnv* env) {
return getJavaVm(env);
}
-} // namespace android::os::incremental
+} // namespace android::incremental
diff --git a/services/incremental/ServiceWrappers.h b/services/incremental/ServiceWrappers.h
index 142bf2ef32f3..6b0f59e9c3e5 100644
--- a/services/incremental/ServiceWrappers.h
+++ b/services/incremental/ServiceWrappers.h
@@ -16,29 +16,23 @@
#pragma once
-#include "IncrementalServiceValidation.h"
-
-#include <android-base/strings.h>
#include <android-base/unique_fd.h>
#include <android/content/pm/DataLoaderParamsParcel.h>
#include <android/content/pm/FileSystemControlParcel.h>
#include <android/content/pm/IDataLoader.h>
-#include <android/content/pm/IDataLoaderManager.h>
#include <android/content/pm/IDataLoaderStatusListener.h>
-#include <android/os/IVold.h>
-#include <binder/AppOpsManager.h>
+#include <binder/IAppOpsCallback.h>
#include <binder/IServiceManager.h>
+#include <binder/Status.h>
#include <incfs.h>
#include <jni.h>
#include <memory>
+#include <span>
#include <string>
#include <string_view>
-using namespace android::incfs;
-using namespace android::content::pm;
-
-namespace android::os::incremental {
+namespace android::incremental {
// --- Wrapper interfaces ---
@@ -47,42 +41,55 @@ using MountId = int32_t;
class VoldServiceWrapper {
public:
virtual ~VoldServiceWrapper() = default;
- virtual binder::Status mountIncFs(const std::string& backingPath, const std::string& targetDir,
- int32_t flags,
- IncrementalFileSystemControlParcel* _aidl_return) const = 0;
+ virtual binder::Status mountIncFs(
+ const std::string& backingPath, const std::string& targetDir, int32_t flags,
+ os::incremental::IncrementalFileSystemControlParcel* result) const = 0;
virtual binder::Status unmountIncFs(const std::string& dir) const = 0;
virtual binder::Status bindMount(const std::string& sourceDir,
const std::string& targetDir) const = 0;
- virtual binder::Status setIncFsMountOptions(const ::android::os::incremental::IncrementalFileSystemControlParcel& control, bool enableReadLogs) const = 0;
+ virtual binder::Status setIncFsMountOptions(
+ const os::incremental::IncrementalFileSystemControlParcel& control,
+ bool enableReadLogs) const = 0;
};
class DataLoaderManagerWrapper {
public:
virtual ~DataLoaderManagerWrapper() = default;
- virtual binder::Status initializeDataLoader(MountId mountId,
- const DataLoaderParamsParcel& params,
- const FileSystemControlParcel& control,
- const sp<IDataLoaderStatusListener>& listener,
- bool* _aidl_return) const = 0;
- virtual binder::Status getDataLoader(MountId mountId, sp<IDataLoader>* _aidl_return) const = 0;
+ virtual binder::Status initializeDataLoader(
+ MountId mountId, const content::pm::DataLoaderParamsParcel& params,
+ const content::pm::FileSystemControlParcel& control,
+ const sp<content::pm::IDataLoaderStatusListener>& listener, bool* result) const = 0;
+ virtual binder::Status getDataLoader(MountId mountId,
+ sp<content::pm::IDataLoader>* result) const = 0;
virtual binder::Status destroyDataLoader(MountId mountId) const = 0;
};
class IncFsWrapper {
public:
+ using Control = incfs::Control;
+ using FileId = incfs::FileId;
+ using ErrorCode = incfs::ErrorCode;
+
+ using ExistingMountCallback =
+ std::function<void(std::string_view root, std::string_view backingDir,
+ std::span<std::pair<std::string_view, std::string_view>> binds)>;
+
virtual ~IncFsWrapper() = default;
+ virtual void listExistingMounts(const ExistingMountCallback& cb) const = 0;
+ virtual Control openMount(std::string_view path) const = 0;
virtual Control createControl(IncFsFd cmd, IncFsFd pendingReads, IncFsFd logs) const = 0;
virtual ErrorCode makeFile(const Control& control, std::string_view path, int mode, FileId id,
- NewFileParams params) const = 0;
+ incfs::NewFileParams params) const = 0;
virtual ErrorCode makeDir(const Control& control, std::string_view path, int mode) const = 0;
- virtual RawMetadata getMetadata(const Control& control, FileId fileid) const = 0;
- virtual RawMetadata getMetadata(const Control& control, std::string_view path) const = 0;
+ virtual ErrorCode makeDirs(const Control& control, std::string_view path, int mode) const = 0;
+ virtual incfs::RawMetadata getMetadata(const Control& control, FileId fileid) const = 0;
+ virtual incfs::RawMetadata getMetadata(const Control& control, std::string_view path) const = 0;
virtual FileId getFileId(const Control& control, std::string_view path) const = 0;
virtual ErrorCode link(const Control& control, std::string_view from,
std::string_view to) const = 0;
virtual ErrorCode unlink(const Control& control, std::string_view path) const = 0;
virtual base::unique_fd openForSpecialOps(const Control& control, FileId id) const = 0;
- virtual ErrorCode writeBlocks(Span<const DataBlock> blocks) const = 0;
+ virtual ErrorCode writeBlocks(std::span<const incfs::DataBlock> blocks) const = 0;
};
class AppOpsManagerWrapper {
@@ -129,4 +136,4 @@ private:
JavaVM* const mJvm;
};
-} // namespace android::os::incremental
+} // namespace android::incremental
diff --git a/services/incremental/path.cpp b/services/incremental/path.cpp
index 0d86f2a984d6..338659d40b46 100644
--- a/services/incremental/path.cpp
+++ b/services/incremental/path.cpp
@@ -44,7 +44,7 @@ bool PathLess::operator()(std::string_view l, std::string_view r) const {
PathCharsLess());
}
-static void preparePathComponent(std::string_view path, bool trimFront) {
+static void preparePathComponent(std::string_view& path, bool trimFront) {
if (trimFront) {
while (!path.empty() && path.front() == '/') {
path.remove_prefix(1);
diff --git a/services/incremental/test/IncrementalServiceTest.cpp b/services/incremental/test/IncrementalServiceTest.cpp
index bfe92f4f2080..7a8560221beb 100644
--- a/services/incremental/test/IncrementalServiceTest.cpp
+++ b/services/incremental/test/IncrementalServiceTest.cpp
@@ -25,6 +25,7 @@
#include <future>
#include "IncrementalService.h"
+#include "IncrementalServiceValidation.h"
#include "Metadata.pb.h"
#include "ServiceWrappers.h"
@@ -262,11 +263,15 @@ private:
class MockIncFs : public IncFsWrapper {
public:
+ MOCK_CONST_METHOD1(listExistingMounts, void(const ExistingMountCallback& cb));
+ MOCK_CONST_METHOD1(openMount, Control(std::string_view path));
MOCK_CONST_METHOD3(createControl, Control(IncFsFd cmd, IncFsFd pendingReads, IncFsFd logs));
MOCK_CONST_METHOD5(makeFile,
ErrorCode(const Control& control, std::string_view path, int mode, FileId id,
NewFileParams params));
MOCK_CONST_METHOD3(makeDir, ErrorCode(const Control& control, std::string_view path, int mode));
+ MOCK_CONST_METHOD3(makeDirs,
+ ErrorCode(const Control& control, std::string_view path, int mode));
MOCK_CONST_METHOD2(getMetadata, RawMetadata(const Control& control, FileId fileid));
MOCK_CONST_METHOD2(getMetadata, RawMetadata(const Control& control, std::string_view path));
MOCK_CONST_METHOD2(getFileId, FileId(const Control& control, std::string_view path));
@@ -274,10 +279,13 @@ public:
ErrorCode(const Control& control, std::string_view from, std::string_view to));
MOCK_CONST_METHOD2(unlink, ErrorCode(const Control& control, std::string_view path));
MOCK_CONST_METHOD2(openForSpecialOps, base::unique_fd(const Control& control, FileId id));
- MOCK_CONST_METHOD1(writeBlocks, ErrorCode(Span<const DataBlock> blocks));
+ MOCK_CONST_METHOD1(writeBlocks, ErrorCode(std::span<const DataBlock> blocks));
+
+ MockIncFs() { ON_CALL(*this, listExistingMounts(_)).WillByDefault(Return()); }
void makeFileFails() { ON_CALL(*this, makeFile(_, _, _, _, _)).WillByDefault(Return(-1)); }
void makeFileSuccess() { ON_CALL(*this, makeFile(_, _, _, _, _)).WillByDefault(Return(0)); }
+
RawMetadata getMountInfoMetadata(const Control& control, std::string_view path) {
metadata::Mount m;
m.mutable_storage()->set_id(100);
@@ -692,14 +700,14 @@ TEST_F(IncrementalServiceTest, testMakeDirectory) {
IncrementalService::CreateOptions::CreateNew);
std::string dir_path("test");
- std::string tempPath(tempDir.path);
- std::replace(tempPath.begin(), tempPath.end(), '/', '_');
- std::string mount_dir = std::string(mRootDir.path) + "/MT_" + tempPath.substr(1);
- std::string normalized_dir_path = mount_dir + "/mount/st_1_0/" + dir_path;
-
// Expecting incfs to call makeDir on a path like:
- // /data/local/tmp/TemporaryDir-06yixG/data_local_tmp_TemporaryDir-xwdFhT/mount/st_1_0/test
- EXPECT_CALL(*mIncFs, makeDir(_, std::string_view(normalized_dir_path), _));
+ // <root>/*/mount/<storage>/test
+ EXPECT_CALL(*mIncFs,
+ makeDir(_, Truly([&](std::string_view arg) {
+ return arg.starts_with(mRootDir.path) &&
+ arg.ends_with("/mount/st_1_0/" + dir_path);
+ }),
+ _));
auto res = mIncrementalService->makeDir(storageId, dir_path, 0555);
ASSERT_EQ(res, 0);
}
@@ -717,29 +725,15 @@ TEST_F(IncrementalServiceTest, testMakeDirectories) {
auto first = "first"sv;
auto second = "second"sv;
auto third = "third"sv;
-
- std::string tempPath(tempDir.path);
- std::replace(tempPath.begin(), tempPath.end(), '/', '_');
- std::string mount_dir = std::string(mRootDir.path) + "/MT_" + tempPath.substr(1);
-
- InSequence seq;
- auto parent_path = std::string(first) + "/" + std::string(second);
- auto dir_path = parent_path + "/" + std::string(third);
-
- std::string normalized_first_path = mount_dir + "/mount/st_1_0/" + std::string(first);
- std::string normalized_parent_path = mount_dir + "/mount/st_1_0/" + parent_path;
- std::string normalized_dir_path = mount_dir + "/mount/st_1_0/" + dir_path;
-
- EXPECT_CALL(*mIncFs, makeDir(_, std::string_view(normalized_dir_path), _))
- .WillOnce(Return(-ENOENT));
- EXPECT_CALL(*mIncFs, makeDir(_, std::string_view(normalized_parent_path), _))
- .WillOnce(Return(-ENOENT));
- EXPECT_CALL(*mIncFs, makeDir(_, std::string_view(normalized_first_path), _))
- .WillOnce(Return(0));
- EXPECT_CALL(*mIncFs, makeDir(_, std::string_view(normalized_parent_path), _))
- .WillOnce(Return(0));
- EXPECT_CALL(*mIncFs, makeDir(_, std::string_view(normalized_dir_path), _)).WillOnce(Return(0));
- auto res = mIncrementalService->makeDirs(storageId, normalized_dir_path, 0555);
+ auto dir_path = std::string(first) + "/" + std::string(second) + "/" + std::string(third);
+
+ EXPECT_CALL(*mIncFs,
+ makeDirs(_, Truly([&](std::string_view arg) {
+ return arg.starts_with(mRootDir.path) &&
+ arg.ends_with("/mount/st_1_0/" + dir_path);
+ }),
+ _));
+ auto res = mIncrementalService->makeDirs(storageId, dir_path, 0555);
ASSERT_EQ(res, 0);
}
} // namespace android::os::incremental
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 289d79dad367..0fc333f4b38c 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -2174,12 +2174,6 @@ public final class SystemServer {
mPackageManagerService.systemReady();
t.traceEnd();
- if (mIncrementalServiceHandle != 0) {
- t.traceBegin("MakeIncrementalServiceReady");
- setIncrementalServiceSystemReady(mIncrementalServiceHandle);
- t.traceEnd();
- }
-
t.traceBegin("MakeDisplayManagerServiceReady");
try {
// TODO: use boot phase and communicate these flags some other way
@@ -2449,6 +2443,12 @@ public final class SystemServer {
reportWtf("Notifying incident daemon running", e);
}
t.traceEnd();
+
+ if (mIncrementalServiceHandle != 0) {
+ t.traceBegin("MakeIncrementalServiceReady");
+ setIncrementalServiceSystemReady(mIncrementalServiceHandle);
+ t.traceEnd();
+ }
}, t);
t.traceEnd(); // startOtherServices
diff --git a/services/net/Android.bp b/services/net/Android.bp
index 9f2979906d42..bb5409b3e032 100644
--- a/services/net/Android.bp
+++ b/services/net/Android.bp
@@ -41,6 +41,7 @@ java_library {
sdk_version: "module_current",
libs: [
"unsupportedappusage",
+ "framework-wifi-util-lib",
],
static_libs: [
"dnsresolver_aidl_interface-V2-java",
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
index 7a175ca1b7f5..2983d585c45a 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
@@ -541,7 +541,7 @@ public class MockingOomAdjusterTests {
doReturn(new ArrayMap<IBinder, ArrayList<ConnectionRecord>>()).when(s).getConnections();
s.startRequested = true;
s.lastActivity = SystemClock.uptimeMillis();
- app.services.add(s);
+ app.startService(s);
sService.mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
sService.mOomAdjuster.updateOomAdjLocked(app, false, OomAdjuster.OOM_ADJ_REASON_NONE);
@@ -585,7 +585,7 @@ public class MockingOomAdjusterTests {
doReturn(new ArrayMap<IBinder, ArrayList<ConnectionRecord>>()).when(s).getConnections();
s.startRequested = true;
s.lastActivity = SystemClock.uptimeMillis();
- app.services.add(s);
+ app.startService(s);
sService.mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
sService.mOomAdjuster.updateOomAdjLocked(app, false, OomAdjuster.OOM_ADJ_REASON_NONE);
@@ -1593,7 +1593,7 @@ public class MockingOomAdjusterTests {
s.app = app3;
setFieldValue(ServiceRecord.class, s, "connections",
new ArrayMap<IBinder, ArrayList<ConnectionRecord>>());
- app3.services.add(s);
+ app3.startService(s);
doCallRealMethod().when(s).getConnections();
s.startRequested = true;
s.lastActivity = now;
@@ -1698,7 +1698,7 @@ public class MockingOomAdjusterTests {
record.app = service;
setFieldValue(ServiceRecord.class, record, "connections",
new ArrayMap<IBinder, ArrayList<ConnectionRecord>>());
- service.services.add(record);
+ service.startService(record);
doCallRealMethod().when(record).getConnections();
}
AppBindRecord binding = new AppBindRecord(record, null, client);
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java
index 3e5c21c67bb3..cbe49eb12f95 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java
@@ -124,6 +124,9 @@ public class DevicePolicyManagerServiceTestable extends DevicePolicyManagerServi
// Key is a pair of uri and userId
private final Map<Pair<Uri, Integer>, ContentObserver> mContentObservers = new ArrayMap<>();
+ // Used as an override when set to nonzero.
+ private long mCurrentTimeMillis = 0;
+
public MockInjector(MockSystemServices services, DpmMockContext context) {
super(context);
this.services = services;
@@ -470,5 +473,19 @@ public class DevicePolicyManagerServiceTestable extends DevicePolicyManagerServi
@Override
public void runCryptoSelfTest() {}
+
+ @Override
+ public String[] getPersonalAppsForSuspension(int userId) {
+ return new String[]{};
+ }
+
+ public void setSystemCurrentTimeMillis(long value) {
+ mCurrentTimeMillis = value;
+ }
+
+ @Override
+ public long systemCurrentTimeMillis() {
+ return mCurrentTimeMillis != 0 ? mCurrentTimeMillis : System.currentTimeMillis();
+ }
}
}
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
index 57039e53429e..b042e7794666 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -44,6 +44,7 @@ import static org.mockito.Matchers.eq;
import static org.mockito.Matchers.isNull;
import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.atMost;
+import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.never;
@@ -62,6 +63,7 @@ import android.Manifest.permission;
import android.app.Activity;
import android.app.AppOpsManager;
import android.app.Notification;
+import android.app.PendingIntent;
import android.app.admin.DeviceAdminReceiver;
import android.app.admin.DevicePolicyManager;
import android.app.admin.DevicePolicyManagerInternal;
@@ -96,6 +98,7 @@ import android.util.Pair;
import androidx.test.filters.SmallTest;
import com.android.internal.R;
+import com.android.internal.messages.nano.SystemMessageProto;
import com.android.internal.widget.LockscreenCredential;
import com.android.server.LocalServices;
import com.android.server.SystemService;
@@ -103,6 +106,7 @@ import com.android.server.devicepolicy.DevicePolicyManagerService.RestrictionsLi
import org.hamcrest.BaseMatcher;
import org.hamcrest.Description;
+import org.hamcrest.Matcher;
import org.mockito.Mockito;
import org.mockito.internal.util.collections.Sets;
import org.mockito.stubbing.Answer;
@@ -181,6 +185,20 @@ public class DevicePolicyManagerTest extends DpmTestBase {
"wQ==\n" +
"-----END CERTIFICATE-----\n";
+ // Constants for testing setManagedProfileMaximumTimeOff:
+ // Profile maximum time off value
+ private static final long PROFILE_OFF_TIMEOUT = TimeUnit.DAYS.toMillis(5);
+ // Synthetic time at the beginning of test.
+ private static final long PROFILE_OFF_START = 1;
+ // Time when warning notification should be posted,
+ private static final long PROFILE_OFF_WARNING_TIME =
+ PROFILE_OFF_START + PROFILE_OFF_TIMEOUT - TimeUnit.DAYS.toMillis(1);
+ // Time when the apps should be suspended
+ private static final long PROFILE_OFF_DEADLINE = PROFILE_OFF_START + PROFILE_OFF_TIMEOUT;
+ // Notification titles for setManagedProfileMaximumTimeOff tests:
+ private static final String PROFILE_OFF_WARNING_TITLE = "suspended_tomorrow";
+ private static final String PROFILE_OFF_SUSPENDED_TITLE = "suspended";
+
@Override
protected void setUp() throws Exception {
super.setUp();
@@ -1558,20 +1576,7 @@ public class DevicePolicyManagerTest extends DpmTestBase {
dpms.approveCaCert(fourCerts.getList().get(1), userId, true);
// a notification should be shown saying that there are two certificates left to approve.
verify(getServices().notificationManager, timeout(1000))
- .notifyAsUser(anyString(), anyInt(), argThat(
- new BaseMatcher<Notification>() {
- @Override
- public boolean matches(Object item) {
- final Notification noti = (Notification) item;
- return TEST_STRING.equals(
- noti.extras.getString(Notification.EXTRA_TITLE));
- }
- @Override
- public void describeTo(Description description) {
- description.appendText(
- "Notification{title=\"" + TEST_STRING + "\"}");
- }
- }), eq(user));
+ .notifyAsUser(anyString(), anyInt(), argThat(hasTitle(TEST_STRING)), eq(user));
}
/**
@@ -6272,7 +6277,214 @@ public class DevicePolicyManagerTest extends DpmTestBase {
assertThat(dpm.getAccountTypesWithManagementDisabled()).isEmpty();
}
- // admin1 is the outgoing DPC, adminAnotherPakcage is the incoming one.
+ /**
+ * Tests the case when the user doesn't turn the profile on in time, verifies that the user is
+ * warned with a notification and then the apps get suspended.
+ */
+ public void testMaximumProfileTimeOff_profileOffTimeExceeded() throws Exception {
+ prepareMocksForSetMaximumProfileTimeOff();
+
+ mContext.binder.callingUid = DpmMockContext.CALLER_UID;
+ dpm.setManagedProfileMaximumTimeOff(admin1, PROFILE_OFF_TIMEOUT);
+
+ mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
+ // The profile is running, neither alarm nor notification should be posted.
+ verify(getServices().alarmManager, never())
+ .set(anyInt(), anyLong(), any(PendingIntent.class));
+ verify(getServices().notificationManager, never())
+ .notify(anyInt(), any(Notification.class));
+ // Apps shouldn't be suspended.
+ verifyZeroInteractions(getServices().ipackageManager);
+ clearInvocations(getServices().alarmManager);
+
+ sendUserStoppedBroadcastForProfile();
+
+ // Verify the alarm was scheduled for time when the warning should be shown.
+ verify(getServices().alarmManager, times(1))
+ .set(anyInt(), eq(PROFILE_OFF_WARNING_TIME), any());
+ // But still no notification should be posted at this point.
+ verify(getServices().notificationManager, never())
+ .notify(anyInt(), any(Notification.class));
+ // Apps shouldn't be suspended.
+ verifyZeroInteractions(getServices().ipackageManager);
+ clearInvocations(getServices().alarmManager);
+
+ // Pretend the alarm went off.
+ dpms.mMockInjector.setSystemCurrentTimeMillis(PROFILE_OFF_WARNING_TIME + 10);
+ sendProfileOffDeadlineAlarmBroadcast();
+
+ // Verify the alarm was scheduled for the actual deadline this time.
+ verify(getServices().alarmManager, times(1)).set(anyInt(), eq(PROFILE_OFF_DEADLINE), any());
+ // Now the user should see a warning notification.
+ verify(getServices().notificationManager, times(1))
+ .notify(anyInt(), argThat(hasTitle(PROFILE_OFF_WARNING_TITLE)));
+ // Apps shouldn't be suspended yet.
+ verifyZeroInteractions(getServices().ipackageManager);
+ clearInvocations(getServices().alarmManager);
+ clearInvocations(getServices().notificationManager);
+
+ // Pretend the alarm went off.
+ dpms.mMockInjector.setSystemCurrentTimeMillis(PROFILE_OFF_DEADLINE + 10);
+ sendProfileOffDeadlineAlarmBroadcast();
+
+ // Verify the alarm was not set.
+ verifyZeroInteractions(getServices().alarmManager);
+ // Now the user should see a notification about suspended apps.
+ verify(getServices().notificationManager, times(1))
+ .notify(anyInt(), argThat(hasTitle(PROFILE_OFF_SUSPENDED_TITLE)));
+ // Verify that the apps are suspended.
+ verify(getServices().ipackageManager, times(1)).setPackagesSuspendedAsUser(
+ any(), eq(true), any(), any(), any(), any(), anyInt());
+ }
+
+ /**
+ * Tests the case when the user turns the profile back on long before the deadline (> 1 day).
+ */
+ public void testMaximumProfileTimeOff_turnOnBeforeWarning() throws Exception {
+ prepareMocksForSetMaximumProfileTimeOff();
+
+ mContext.binder.callingUid = DpmMockContext.CALLER_UID;
+ dpm.setManagedProfileMaximumTimeOff(admin1, PROFILE_OFF_TIMEOUT);
+
+ mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
+ sendUserStoppedBroadcastForProfile();
+ clearInvocations(getServices().alarmManager);
+ sendUserUnlockedBroadcastForProfile();
+
+ // Verify that the alarm got discharged.
+ verify(getServices().alarmManager, times(1)).cancel((PendingIntent) null);
+ }
+
+ /**
+ * Tests the case when the user turns the profile back on after the warning notification.
+ */
+ public void testMaximumProfileTimeOff_turnOnAfterWarning() throws Exception {
+ prepareMocksForSetMaximumProfileTimeOff();
+
+ mContext.binder.callingUid = DpmMockContext.CALLER_UID;
+ dpm.setManagedProfileMaximumTimeOff(admin1, PROFILE_OFF_TIMEOUT);
+
+ mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
+ sendUserStoppedBroadcastForProfile();
+
+ // Pretend the alarm went off.
+ dpms.mMockInjector.setSystemCurrentTimeMillis(PROFILE_OFF_WARNING_TIME + 10);
+ sendProfileOffDeadlineAlarmBroadcast();
+
+ clearInvocations(getServices().alarmManager);
+ clearInvocations(getServices().notificationManager);
+ sendUserUnlockedBroadcastForProfile();
+
+ // Verify that the alarm got discharged.
+ verify(getServices().alarmManager, times(1)).cancel((PendingIntent) null);
+ // Verify that the notification is removed.
+ verify(getServices().notificationManager, times(1))
+ .cancel(eq(SystemMessageProto.SystemMessage.NOTE_PERSONAL_APPS_SUSPENDED));
+ }
+
+ /**
+ * Tests the case when the user turns the profile back on when the apps are already suspended.
+ */
+ public void testMaximumProfileTimeOff_turnOnAfterDeadline() throws Exception {
+ prepareMocksForSetMaximumProfileTimeOff();
+
+ mContext.binder.callingUid = DpmMockContext.CALLER_UID;
+ dpm.setManagedProfileMaximumTimeOff(admin1, PROFILE_OFF_TIMEOUT);
+
+ mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
+ sendUserStoppedBroadcastForProfile();
+
+ // Pretend the alarm went off after the deadline.
+ dpms.mMockInjector.setSystemCurrentTimeMillis(PROFILE_OFF_DEADLINE + 10);
+ sendProfileOffDeadlineAlarmBroadcast();
+
+ clearInvocations(getServices().alarmManager);
+ clearInvocations(getServices().notificationManager);
+ clearInvocations(getServices().ipackageManager);
+
+ sendUserUnlockedBroadcastForProfile();
+
+ // Verify that the notification is removed (at this point DPC should show it).
+ verify(getServices().notificationManager, times(1))
+ .cancel(eq(SystemMessageProto.SystemMessage.NOTE_PERSONAL_APPS_SUSPENDED));
+ // Verify that the apps are NOT unsuspeded.
+ verify(getServices().ipackageManager, never()).setPackagesSuspendedAsUser(
+ any(), eq(false), any(), any(), any(), any(), anyInt());
+ }
+
+ private void sendUserUnlockedBroadcastForProfile() throws Exception {
+ when(getServices().userManager.isUserUnlocked(eq(DpmMockContext.CALLER_USER_HANDLE)))
+ .thenReturn(true);
+ final Intent unlockedIntent = new Intent(Intent.ACTION_USER_UNLOCKED)
+ .putExtra(Intent.EXTRA_USER_HANDLE, DpmMockContext.CALLER_USER_HANDLE);
+ getServices().injectBroadcast(
+ mServiceContext, unlockedIntent, DpmMockContext.CALLER_USER_HANDLE);
+ flushTasks();
+ }
+
+
+ private void sendProfileOffDeadlineAlarmBroadcast() throws Exception {
+ final Intent deadlineAlarmIntent =
+ new Intent(DevicePolicyManagerService.ACTION_PROFILE_OFF_DEADLINE);
+ getServices().injectBroadcast(
+ mServiceContext, deadlineAlarmIntent, DpmMockContext.CALLER_USER_HANDLE);
+ flushTasks();
+ }
+
+ private void sendUserStoppedBroadcastForProfile() throws Exception {
+ when(getServices().userManager.isUserUnlocked(eq(DpmMockContext.CALLER_USER_HANDLE)))
+ .thenReturn(false);
+ final Intent stoppedIntent = new Intent(Intent.ACTION_USER_STOPPED)
+ .putExtra(Intent.EXTRA_USER_HANDLE, DpmMockContext.CALLER_USER_HANDLE);
+ getServices().injectBroadcast(mServiceContext, stoppedIntent,
+ DpmMockContext.CALLER_USER_HANDLE);
+ flushTasks();
+ }
+
+ private void prepareMocksForSetMaximumProfileTimeOff() throws Exception {
+ addManagedProfile(admin1, DpmMockContext.CALLER_UID, admin1);
+ configureProfileOwnerOfOrgOwnedDevice(admin1, DpmMockContext.CALLER_USER_HANDLE);
+
+ when(getServices().userManager.isUserUnlocked()).thenReturn(true);
+
+ // Pretend our admin handles CHECK_POLICY_COMPLIANCE intent.
+ final Intent intent = new Intent(DevicePolicyManager.ACTION_CHECK_POLICY_COMPLIANCE);
+ intent.setPackage(admin1.getPackageName());
+
+ doReturn(Collections.singletonList(new ResolveInfo()))
+ .when(getServices().packageManager).queryIntentActivitiesAsUser(
+ any(Intent.class), anyInt(), eq(DpmMockContext.CALLER_USER_HANDLE));
+
+ dpms.mMockInjector.setSystemCurrentTimeMillis(PROFILE_OFF_START);
+ // To allow creation of Notification via Notification.Builder
+ mContext.applicationInfo = mRealTestContext.getApplicationInfo();
+
+ // Setup notification titles.
+ when(mServiceContext.resources
+ .getString(R.string.personal_apps_suspended_tomorrow_title))
+ .thenReturn(PROFILE_OFF_WARNING_TITLE);
+ when(mServiceContext.resources
+ .getString(R.string.personal_apps_suspended_title))
+ .thenReturn(PROFILE_OFF_SUSPENDED_TITLE);
+
+ clearInvocations(getServices().ipackageManager);
+ }
+
+ private static Matcher<Notification> hasTitle(String expected) {
+ return new BaseMatcher<Notification>() {
+ @Override
+ public boolean matches(Object item) {
+ final Notification notification = (Notification) item;
+ return expected.equals(notification.extras.getString(Notification.EXTRA_TITLE));
+ }
+ @Override
+ public void describeTo(Description description) {
+ description.appendText("Notification{title=\"" + expected + "\"}");
+ }
+ };
+ }
+
+ // admin1 is the outgoing DPC, adminAnotherPackage is the incoming one.
private void assertDeviceOwnershipRevertedWithFakeTransferMetadata() throws Exception {
writeFakeTransferMetadataFile(UserHandle.USER_SYSTEM,
TransferOwnershipMetadataManager.ADMIN_TYPE_DEVICE_OWNER);
@@ -6299,7 +6511,7 @@ public class DevicePolicyManagerTest extends DpmTestBase {
mServiceContext.binder.restoreCallingIdentity(ident);
}
- // admin1 is the outgoing DPC, adminAnotherPakcage is the incoming one.
+ // admin1 is the outgoing DPC, adminAnotherPackage is the incoming one.
private void assertProfileOwnershipRevertedWithFakeTransferMetadata() throws Exception {
writeFakeTransferMetadataFile(DpmMockContext.CALLER_USER_HANDLE,
TransferOwnershipMetadataManager.ADMIN_TYPE_PROFILE_OWNER);
diff --git a/services/tests/servicestests/src/com/android/server/display/AutomaticBrightnessControllerTest.java b/services/tests/servicestests/src/com/android/server/display/AutomaticBrightnessControllerTest.java
index 7b3417a67857..b69cc47ba738 100644
--- a/services/tests/servicestests/src/com/android/server/display/AutomaticBrightnessControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/AutomaticBrightnessControllerTest.java
@@ -107,9 +107,10 @@ public class AutomaticBrightnessControllerTest {
eq(INITIAL_LIGHT_SENSOR_RATE * 1000), any(Handler.class));
SensorEventListener listener = listenerCaptor.getValue();
- // Set up system to return 5 as a brightness value
+ // Set up system to return 0.02f as a brightness value
float lux1 = 100.0f;
- float normalizedBrightness1 = 0.0158f; //float equivalent of 5 out of 255
+ // Brightness as float (from 0.0f to 1.0f)
+ float normalizedBrightness1 = 0.02f;
when(mAmbientBrightnessThresholds.getBrighteningThreshold(lux1))
.thenReturn(lux1);
when(mAmbientBrightnessThresholds.getDarkeningThreshold(lux1))
@@ -120,14 +121,14 @@ public class AutomaticBrightnessControllerTest {
// This is the important bit: When the new brightness is set, make sure the new
// brightening threshold is beyond the maximum brightness value...so that we can test that
// our threshold clamping works.
- when(mScreenBrightnessThresholds.getBrighteningThreshold(5)).thenReturn(1.0f);
+ when(mScreenBrightnessThresholds.getBrighteningThreshold(normalizedBrightness1))
+ .thenReturn(1.0f);
// Send new sensor value and verify
listener.onSensorChanged(TestUtils.createSensorEvent(lightSensor, (int) lux1));
- assertEquals(5, controller.getAutomaticScreenBrightness());
+ assertEquals(normalizedBrightness1, controller.getAutomaticScreenBrightness(), 0.001f);
-
- // Set up system to return 255 as a brightness value
+ // Set up system to return 0.0f (minimum possible brightness) as a brightness value
float lux2 = 10.0f;
float normalizedBrightness2 = 0.0f;
when(mAmbientBrightnessThresholds.getBrighteningThreshold(lux2))
@@ -139,7 +140,7 @@ public class AutomaticBrightnessControllerTest {
// Send new sensor value and verify
listener.onSensorChanged(TestUtils.createSensorEvent(lightSensor, (int) lux2));
- assertEquals(1, controller.getAutomaticScreenBrightness());
+ assertEquals(normalizedBrightness2, controller.getAutomaticScreenBrightness(), 0.001f);
}
@Test
@@ -153,9 +154,9 @@ public class AutomaticBrightnessControllerTest {
eq(INITIAL_LIGHT_SENSOR_RATE * 1000), any(Handler.class));
SensorEventListener listener = listenerCaptor.getValue();
- // Set up system to return 250 as a brightness value
+ // Set up system to return 0.98f as a brightness value
float lux1 = 100.0f;
- float normalizedBrightness1 = 0.981f; //float equivalent of 250 out of 255
+ float normalizedBrightness1 = 0.98f;
when(mAmbientBrightnessThresholds.getBrighteningThreshold(lux1))
.thenReturn(lux1);
when(mAmbientBrightnessThresholds.getDarkeningThreshold(lux1))
@@ -166,14 +167,15 @@ public class AutomaticBrightnessControllerTest {
// This is the important bit: When the new brightness is set, make sure the new
// brightening threshold is beyond the maximum brightness value...so that we can test that
// our threshold clamping works.
- when(mScreenBrightnessThresholds.getBrighteningThreshold(250)).thenReturn(260.0f);
+ when(mScreenBrightnessThresholds.getBrighteningThreshold(normalizedBrightness1))
+ .thenReturn(1.1f);
// Send new sensor value and verify
listener.onSensorChanged(TestUtils.createSensorEvent(lightSensor, (int) lux1));
- assertEquals(250, controller.getAutomaticScreenBrightness());
+ assertEquals(normalizedBrightness1, controller.getAutomaticScreenBrightness(), 0.001f);
- // Set up system to return 255 as a brightness value
+ // Set up system to return 1.0f as a brightness value (brightness_max)
float lux2 = 110.0f;
float normalizedBrightness2 = 1.0f;
when(mAmbientBrightnessThresholds.getBrighteningThreshold(lux2))
@@ -185,7 +187,7 @@ public class AutomaticBrightnessControllerTest {
// Send new sensor value and verify
listener.onSensorChanged(TestUtils.createSensorEvent(lightSensor, (int) lux2));
- assertEquals(255, controller.getAutomaticScreenBrightness());
+ assertEquals(normalizedBrightness2, controller.getAutomaticScreenBrightness(), 0.001f);
}
@Test
@@ -204,10 +206,10 @@ public class AutomaticBrightnessControllerTest {
// User sets brightness to 100
controller.configure(true /* enable */, null /* configuration */,
- 100 /* brightness */, true /* userChangedBrightness */, 0 /* adjustment */,
+ 0.5f /* brightness */, true /* userChangedBrightness */, 0 /* adjustment */,
false /* userChanged */, DisplayPowerRequest.POLICY_BRIGHT);
// There should be a user data point added to the mapper.
- verify(mBrightnessMappingStrategy).addUserDataPoint(1000f, 100);
+ verify(mBrightnessMappingStrategy).addUserDataPoint(1000f, 0.5f);
}
}
diff --git a/services/tests/uiservicestests/src/com/android/server/UiModeManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/UiModeManagerServiceTest.java
index 69ef499749a9..df92b6ed95e8 100644
--- a/services/tests/uiservicestests/src/com/android/server/UiModeManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/UiModeManagerServiceTest.java
@@ -31,7 +31,6 @@ import android.os.PowerManager;
import android.os.PowerManagerInternal;
import android.os.PowerSaveState;
import android.os.RemoteException;
-import android.provider.Settings;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import com.android.server.twilight.TwilightManager;
@@ -55,7 +54,6 @@ import static junit.framework.TestCase.assertFalse;
import static junit.framework.TestCase.assertTrue;
import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.anyString;
@@ -146,7 +144,7 @@ public class UiModeManagerServiceTest extends UiServiceTestCase {
addLocalService(PowerManagerInternal.class, mLocalPowerManager);
addLocalService(TwilightManager.class, mTwilightManager);
- mUiManagerService = new UiModeManagerService(mContext, true);
+ mUiManagerService = new UiModeManagerService(mContext);
try {
mUiManagerService.onBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY);
} catch (SecurityException e) {/* ignore for permission denial */}
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java b/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java
index 9b7ffd69da15..e8fab2b0243b 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java
@@ -37,7 +37,6 @@ import android.view.RemoteAnimationAdapter;
import android.view.RemoteAnimationDefinition;
import android.view.RemoteAnimationTarget;
-import androidx.test.filters.FlakyTest;
import androidx.test.filters.SmallTest;
import org.junit.Test;
@@ -97,7 +96,6 @@ public class AppChangeTransitionTests extends WindowTestsBase {
}
@Test
- @FlakyTest(bugId = 131005232)
public void testModeChangeRemoteAnimatorNoSnapshot() {
// setup currently defaults to no snapshot.
setUpOnDisplay(mDisplayContent);
@@ -115,7 +113,6 @@ public class AppChangeTransitionTests extends WindowTestsBase {
}
@Test
- @FlakyTest(bugId = 131005232)
public void testCancelPendingChangeOnRemove() {
// setup currently defaults to no snapshot.
setUpOnDisplay(mDisplayContent);
@@ -135,8 +132,7 @@ public class AppChangeTransitionTests extends WindowTestsBase {
}
@Test
- @FlakyTest(bugId = 131005232)
- public void testNoChangeWhenMoveDisplay() {
+ public void testNoChangeOnOldDisplayWhenMoveDisplay() {
mDisplayContent.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
final DisplayContent dc1 = createNewDisplay(Display.STATE_ON);
dc1.setWindowingMode(WINDOWING_MODE_FREEFORM);
@@ -151,9 +147,8 @@ public class AppChangeTransitionTests extends WindowTestsBase {
assertEquals(WINDOWING_MODE_FULLSCREEN, mTask.getWindowingMode());
- // Make sure we're not waiting for a change animation (no leash)
- assertFalse(mTask.isInChangeTransition());
- assertNull(mActivity.mSurfaceFreezer.mSnapshot);
+ // Make sure the change transition is not the old display
+ assertFalse(dc1.mChangingContainers.contains(mTask));
waitUntilHandlersIdle();
mActivity.removeImmediately();
diff --git a/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java b/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java
index b6eb9010ce90..f83128705a2a 100644
--- a/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java
@@ -50,6 +50,7 @@ import android.view.test.InsetsModeSession;
import androidx.test.filters.SmallTest;
import org.junit.AfterClass;
+import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -72,6 +73,11 @@ public class InsetsPolicyTest extends WindowTestsBase {
sInsetsModeSession.close();
}
+ @Before
+ public void setup() {
+ mWm.mAnimator.ready();
+ }
+
@Test
public void testControlsForDispatch_regular() {
addWindow(TYPE_STATUS_BAR, "statusBar");
@@ -194,6 +200,7 @@ public class InsetsPolicyTest extends WindowTestsBase {
policy.updateBarControlTarget(mAppWindow);
policy.showTransient(
IntArray.wrap(new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR}));
+ waitUntilWindowAnimatorIdle();
final InsetsSourceControl[] controls =
mDisplayContent.getInsetsStateController().getControlsForDispatch(mAppWindow);
@@ -221,6 +228,7 @@ public class InsetsPolicyTest extends WindowTestsBase {
policy.updateBarControlTarget(mAppWindow);
policy.showTransient(
IntArray.wrap(new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR}));
+ waitUntilWindowAnimatorIdle();
final InsetsSourceControl[] controls =
mDisplayContent.getInsetsStateController().getControlsForDispatch(mAppWindow);
@@ -249,6 +257,7 @@ public class InsetsPolicyTest extends WindowTestsBase {
policy.updateBarControlTarget(mAppWindow);
policy.showTransient(
IntArray.wrap(new int[]{ITYPE_STATUS_BAR, ITYPE_NAVIGATION_BAR}));
+ waitUntilWindowAnimatorIdle();
InsetsSourceControl[] controls =
mDisplayContent.getInsetsStateController().getControlsForDispatch(mAppWindow);
@@ -262,6 +271,7 @@ public class InsetsPolicyTest extends WindowTestsBase {
state.setSourceVisible(ITYPE_STATUS_BAR, true);
state.setSourceVisible(ITYPE_NAVIGATION_BAR, true);
policy.onInsetsModified(mAppWindow, state);
+ waitUntilWindowAnimatorIdle();
controls = mDisplayContent.getInsetsStateController().getControlsForDispatch(mAppWindow);
diff --git a/services/tests/wmtests/src/com/android/server/wm/SystemServiceTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/SystemServiceTestsBase.java
index f6ed31455f18..d7462f810bb7 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SystemServiceTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SystemServiceTestsBase.java
@@ -40,6 +40,11 @@ class SystemServiceTestsBase {
mLockRule.waitForLocked(mSystemServicesTestRule::waitUntilWindowManagerHandlersIdle);
}
+ /** Waits until the choreographer of WindowAnimator has processed all callbacks. */
+ void waitUntilWindowAnimatorIdle() {
+ mLockRule.waitForLocked(mSystemServicesTestRule::waitUntilWindowAnimatorIdle);
+ }
+
void cleanupWindowManagerHandlers() {
mLockRule.waitForLocked(mSystemServicesTestRule::cleanupWindowManagerHandlers);
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
index af3ec38631ae..dea9294ff75b 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
@@ -429,6 +429,31 @@ public class SystemServicesTestRule implements TestRule {
}
}
+ void waitUntilWindowAnimatorIdle() {
+ final WindowManagerService wm = getWindowManagerService();
+ if (wm == null) {
+ return;
+ }
+ synchronized (mCurrentMessagesProcessed) {
+ // Add a message to the handler queue and make sure it is fully processed before we move
+ // on. This makes sure all previous messages in the handler are fully processed vs. just
+ // popping them from the message queue.
+ mCurrentMessagesProcessed.set(false);
+ wm.mAnimator.getChoreographer().postFrameCallback(time -> {
+ synchronized (mCurrentMessagesProcessed) {
+ mCurrentMessagesProcessed.set(true);
+ mCurrentMessagesProcessed.notifyAll();
+ }
+ });
+ while (!mCurrentMessagesProcessed.get()) {
+ try {
+ mCurrentMessagesProcessed.wait();
+ } catch (InterruptedException e) {
+ }
+ }
+ }
+ }
+
/**
* Throws if caller doesn't hold the given lock.
* @param lock the lock
diff --git a/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java
index a4f1487dde1e..520ac19b89a8 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java
@@ -16,6 +16,9 @@
package com.android.server.wm;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
@@ -251,6 +254,22 @@ public class WallpaperControllerTests extends WindowTestsBase {
assertEquals(otherWindowInitialZoom, wallpaperWindow.mWallpaperZoomOut, .01f);
}
+ /**
+ * Tests that the windowing mode of the wallpaper window must always be fullscreen.
+ */
+ @Test
+ public void testWallpaperTokenWindowingMode() {
+ final DisplayContent dc = mWm.mRoot.getDefaultDisplay();
+ final WallpaperWindowToken token = new WallpaperWindowToken(mWm, mock(IBinder.class),
+ true, dc, true /* ownerCanManageAppTokens */);
+
+ // The wallpaper should have requested override fullscreen windowing mode, so the
+ // configuration (windowing mode) propagation from display won't change it.
+ dc.setWindowingMode(WINDOWING_MODE_FREEFORM);
+ assertEquals(WINDOWING_MODE_FULLSCREEN, token.getWindowingMode());
+ dc.setWindowingMode(WINDOWING_MODE_UNDEFINED);
+ assertEquals(WINDOWING_MODE_FULLSCREEN, token.getWindowingMode());
+ }
private WindowState createWallpaperTargetWindow(DisplayContent dc) {
final ActivityRecord homeActivity = new ActivityTestsBase.ActivityBuilder(mWm.mAtmService)
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java
index 07a6179c00bd..cdf8eb4faf1d 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java
@@ -28,9 +28,11 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.when;
+import android.Manifest;
import android.app.IApplicationThread;
import android.content.ComponentName;
import android.content.pm.ApplicationInfo;
+import android.content.pm.ServiceInfo;
import android.content.res.Configuration;
import android.platform.test.annotations.Presubmit;
@@ -200,6 +202,57 @@ public class WindowProcessControllerTests extends ActivityTestsBase {
assertFalse(wpc.registeredForActivityConfigChanges());
}
+ @Test
+ public void testActivityNotOverridingImeProcessConfig() {
+ ServiceInfo serviceInfo = new ServiceInfo();
+ serviceInfo.permission = Manifest.permission.BIND_INPUT_METHOD;
+ // Notify WPC that this process has started an IME service.
+ mWpc.onServiceStarted(serviceInfo);
+
+ final ActivityRecord activity = new ActivityBuilder(mService)
+ .setCreateTask(true)
+ .setUseProcess(mWpc)
+ .build();
+
+ mWpc.addActivityIfNeeded(activity);
+ // IME processes should not be registered for activity config changes.
+ assertFalse(mWpc.registeredForActivityConfigChanges());
+ }
+
+ @Test
+ public void testActivityNotOverridingAllyProcessConfig() {
+ ServiceInfo serviceInfo = new ServiceInfo();
+ serviceInfo.permission = Manifest.permission.BIND_ACCESSIBILITY_SERVICE;
+ // Notify WPC that this process has started an ally service.
+ mWpc.onServiceStarted(serviceInfo);
+
+ final ActivityRecord activity = new ActivityBuilder(mService)
+ .setCreateTask(true)
+ .setUseProcess(mWpc)
+ .build();
+
+ mWpc.addActivityIfNeeded(activity);
+ // Ally processes should not be registered for activity config changes.
+ assertFalse(mWpc.registeredForActivityConfigChanges());
+ }
+
+ @Test
+ public void testActivityNotOverridingVoiceInteractionProcessConfig() {
+ ServiceInfo serviceInfo = new ServiceInfo();
+ serviceInfo.permission = Manifest.permission.BIND_VOICE_INTERACTION;
+ // Notify WPC that this process has started an voice interaction service.
+ mWpc.onServiceStarted(serviceInfo);
+
+ final ActivityRecord activity = new ActivityBuilder(mService)
+ .setCreateTask(true)
+ .setUseProcess(mWpc)
+ .build();
+
+ mWpc.addActivityIfNeeded(activity);
+ // Voice interaction service processes should not be registered for activity config changes.
+ assertFalse(mWpc.registeredForActivityConfigChanges());
+ }
+
private TestDisplayContent createTestDisplayContentInContainer() {
return new TestDisplayContent.Builder(mService, 1000, 1500).build();
}
diff --git a/tests/BlobStoreTestUtils/src/com/android/utils/blob/DummyBlobData.java b/tests/BlobStoreTestUtils/src/com/android/utils/blob/DummyBlobData.java
index 35a6c26ec73f..371375c0d932 100644
--- a/tests/BlobStoreTestUtils/src/com/android/utils/blob/DummyBlobData.java
+++ b/tests/BlobStoreTestUtils/src/com/android/utils/blob/DummyBlobData.java
@@ -77,7 +77,7 @@ public class DummyBlobData {
return mRandomSeed;
}
- public Builder setFileSize(int fileSize) {
+ public Builder setFileSize(long fileSize) {
mFileSize = fileSize;
return this;
}
diff --git a/tests/BlobStoreTestUtils/src/com/android/utils/blob/Utils.java b/tests/BlobStoreTestUtils/src/com/android/utils/blob/Utils.java
index 482b23f129fd..6927e86213d8 100644
--- a/tests/BlobStoreTestUtils/src/com/android/utils/blob/Utils.java
+++ b/tests/BlobStoreTestUtils/src/com/android/utils/blob/Utils.java
@@ -34,6 +34,9 @@ import java.io.OutputStream;
public class Utils {
public static final int BUFFER_SIZE_BYTES = 16 * 1024;
+ public static final long KB_IN_BYTES = 1000;
+ public static final long MB_IN_BYTES = KB_IN_BYTES * 1000;
+
public static void copy(InputStream in, OutputStream out, long lengthBytes)
throws IOException {
final byte[] buffer = new byte[BUFFER_SIZE_BYTES];
diff --git a/wifi/java/android/net/wifi/WifiNetworkSpecifier.java b/wifi/java/android/net/wifi/WifiNetworkSpecifier.java
index 737b7c7b9caf..b0213b0ef502 100644
--- a/wifi/java/android/net/wifi/WifiNetworkSpecifier.java
+++ b/wifi/java/android/net/wifi/WifiNetworkSpecifier.java
@@ -384,7 +384,8 @@ public final class WifiNetworkSpecifier extends NetworkSpecifier implements Parc
*
* For example:
* To connect to an open network with a SSID prefix of "test" and a BSSID OUI of "10:03:23":
- * {@code
+ *
+ * <pre>{@code
* final NetworkSpecifier specifier =
* new Builder()
* .setSsidPattern(new PatternMatcher("test", PatterMatcher.PATTERN_PREFIX))
@@ -406,7 +407,7 @@ public final class WifiNetworkSpecifier extends NetworkSpecifier implements Parc
* // etc.
* };
* connectivityManager.requestNetwork(request, networkCallback);
- * }
+ * }</pre>
*
* @return Instance of {@link NetworkSpecifier}.
* @throws IllegalStateException on invalid params set.