summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--api/current.txt17
-rw-r--r--cmds/stagefright/Android.mk8
-rw-r--r--core/java/android/accounts/AccountManagerService.java6
-rw-r--r--core/java/android/app/Activity.java43
-rw-r--r--core/java/android/app/ActivityManagerNative.java14
-rw-r--r--core/java/android/app/ActivityOptions.java141
-rw-r--r--core/java/android/app/Fragment.java7
-rw-r--r--core/java/android/app/IActivityManager.java2
-rw-r--r--core/java/android/app/PendingIntent.java86
-rw-r--r--core/java/android/content/ContentProvider.java87
-rw-r--r--core/java/android/content/Context.java12
-rw-r--r--core/java/android/content/pm/IPackageManager.aidl3
-rw-r--r--core/java/android/content/pm/PackageManager.java5
-rw-r--r--core/java/android/net/Downloads.java644
-rw-r--r--core/java/android/net/NetworkPolicy.java14
-rw-r--r--core/java/android/os/Process.java6
-rw-r--r--core/java/android/provider/Downloads.java16
-rw-r--r--core/java/android/view/HardwareRenderer.java9
-rw-r--r--core/java/android/view/View.java168
-rw-r--r--core/java/android/view/ViewGroup.java14
-rw-r--r--core/java/android/view/ViewRootImpl.java4
-rw-r--r--core/java/android/webkit/BrowserFrame.java4
-rw-r--r--core/java/android/webkit/HTML5Audio.java2
-rw-r--r--core/java/android/webkit/HTML5VideoViewProxy.java8
-rw-r--r--core/java/android/webkit/WebSettingsClassic.java2
-rw-r--r--core/java/android/webkit/WebView.java7
-rw-r--r--core/java/android/webkit/WebViewClassic.java33
-rw-r--r--core/java/android/webkit/WebViewCore.java206
-rw-r--r--core/java/android/webkit/WebViewProvider.java3
-rw-r--r--core/java/android/widget/DatePicker.java37
-rw-r--r--core/java/android/widget/HorizontalScrollView.java12
-rw-r--r--core/java/android/widget/NumberPicker.java1299
-rw-r--r--core/java/android/widget/ScrollView.java54
-rw-r--r--core/java/android/widget/TextView.java2
-rw-r--r--core/java/android/widget/TimePicker.java31
-rw-r--r--core/java/com/android/internal/view/menu/MenuItemImpl.java5
-rw-r--r--core/java/com/android/internal/widget/multiwaveview/MultiWaveView.java48
-rw-r--r--core/java/com/android/internal/widget/multiwaveview/TargetDrawable.java22
-rw-r--r--core/jni/Android.mk1
-rw-r--r--core/jni/android/graphics/BitmapFactory.cpp256
-rw-r--r--core/res/res/drawable-hdpi/ic_facial_backup.pngbin0 -> 583 bytes
-rw-r--r--core/res/res/drawable-hdpi/intro_bg.pngbin0 -> 202336 bytes
-rw-r--r--core/res/res/drawable-hdpi/numberpicker_down_disabled_focused_holo_dark.pngbin634 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/numberpicker_down_disabled_focused_holo_light.pngbin489 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/numberpicker_down_disabled_holo_dark.pngbin444 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/numberpicker_down_disabled_holo_light.pngbin418 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/numberpicker_down_focused_holo_dark.pngbin661 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/numberpicker_down_focused_holo_light.pngbin514 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/numberpicker_down_longpressed_holo_dark.pngbin555 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/numberpicker_down_longpressed_holo_light.pngbin555 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/numberpicker_down_normal_holo_dark.pngbin439 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/numberpicker_down_normal_holo_light.pngbin441 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/numberpicker_down_pressed_holo_dark.pngbin564 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/numberpicker_down_pressed_holo_light.pngbin564 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/numberpicker_up_disabled_focused_holo_dark.pngbin605 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/numberpicker_up_disabled_focused_holo_light.pngbin457 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/numberpicker_up_disabled_holo_dark.pngbin416 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/numberpicker_up_disabled_holo_light.pngbin407 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/numberpicker_up_focused_holo_dark.pngbin652 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/numberpicker_up_focused_holo_light.pngbin497 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/numberpicker_up_longpressed_holo_dark.pngbin536 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/numberpicker_up_longpressed_holo_light.pngbin536 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/numberpicker_up_normal_holo_dark.pngbin426 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/numberpicker_up_normal_holo_light.pngbin427 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/numberpicker_up_pressed_holo_dark.pngbin542 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/numberpicker_up_pressed_holo_light.pngbin542 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_facial_backup.pngbin0 -> 520 bytes
-rw-r--r--core/res/res/drawable-mdpi/intro_bg.pngbin0 -> 90061 bytes
-rw-r--r--core/res/res/drawable-mdpi/numberpicker_down_disabled_focused_holo_dark.pngbin561 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/numberpicker_down_disabled_focused_holo_light.pngbin426 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/numberpicker_down_disabled_holo_dark.pngbin398 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/numberpicker_down_disabled_holo_light.pngbin384 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/numberpicker_down_focused_holo_dark.pngbin575 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/numberpicker_down_focused_holo_light.pngbin446 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/numberpicker_down_longpressed_holo_dark.pngbin473 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/numberpicker_down_longpressed_holo_light.pngbin473 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/numberpicker_down_normal_holo_dark.pngbin423 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/numberpicker_down_normal_holo_light.pngbin412 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/numberpicker_down_pressed_holo_dark.pngbin473 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/numberpicker_down_pressed_holo_light.pngbin473 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/numberpicker_up_disabled_focused_holo_dark.pngbin535 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/numberpicker_up_disabled_focused_holo_light.pngbin410 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/numberpicker_up_disabled_holo_dark.pngbin394 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/numberpicker_up_disabled_holo_light.pngbin383 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/numberpicker_up_focused_holo_dark.pngbin556 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/numberpicker_up_focused_holo_light.pngbin429 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/numberpicker_up_longpressed_holo_dark.pngbin466 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/numberpicker_up_longpressed_holo_light.pngbin466 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/numberpicker_up_normal_holo_dark.pngbin404 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/numberpicker_up_normal_holo_light.pngbin408 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/numberpicker_up_pressed_holo_dark.pngbin468 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/numberpicker_up_pressed_holo_light.pngbin468 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_facial_backup.pngbin0 -> 841 bytes
-rw-r--r--core/res/res/drawable-xhdpi/intro_bg.pngbin0 -> 343210 bytes
-rw-r--r--core/res/res/drawable-xhdpi/numberpicker_down_disabled_focused_holo_dark.pngbin748 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/numberpicker_down_disabled_focused_holo_light.pngbin556 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/numberpicker_down_disabled_holo_dark.pngbin480 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/numberpicker_down_disabled_holo_light.pngbin459 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/numberpicker_down_focused_holo_dark.pngbin785 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/numberpicker_down_focused_holo_light.pngbin627 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/numberpicker_down_longpressed_holo_dark.pngbin698 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/numberpicker_down_longpressed_holo_light.pngbin698 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/numberpicker_down_normal_holo_dark.pngbin494 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/numberpicker_down_normal_holo_light.pngbin503 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/numberpicker_down_pressed_holo_dark.pngbin696 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/numberpicker_down_pressed_holo_light.pngbin696 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/numberpicker_up_disabled_focused_holo_dark.pngbin741 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/numberpicker_up_disabled_focused_holo_light.pngbin554 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/numberpicker_up_disabled_holo_dark.pngbin474 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/numberpicker_up_disabled_holo_light.pngbin463 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/numberpicker_up_focused_holo_dark.pngbin780 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/numberpicker_up_focused_holo_light.pngbin617 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/numberpicker_up_longpressed_holo_dark.pngbin674 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/numberpicker_up_longpressed_holo_light.pngbin674 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/numberpicker_up_normal_holo_dark.pngbin485 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/numberpicker_up_normal_holo_light.pngbin490 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/numberpicker_up_pressed_holo_dark.pngbin670 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/numberpicker_up_pressed_holo_light.pngbin670 -> 0 bytes
-rw-r--r--core/res/res/drawable/numberpicker_down_btn_holo_dark.xml43
-rw-r--r--core/res/res/drawable/numberpicker_down_btn_holo_light.xml43
-rw-r--r--core/res/res/drawable/numberpicker_up_btn_holo_dark.xml43
-rw-r--r--core/res/res/drawable/numberpicker_up_btn_holo_light.xml43
-rw-r--r--core/res/res/layout-sw600dp/keyguard_screen_password_landscape.xml25
-rw-r--r--core/res/res/layout-sw600dp/keyguard_screen_password_portrait.xml25
-rw-r--r--core/res/res/layout-sw600dp/keyguard_screen_unlock_landscape.xml25
-rw-r--r--core/res/res/layout-sw600dp/keyguard_screen_unlock_portrait.xml25
-rw-r--r--core/res/res/layout/keyguard_screen_password_landscape.xml25
-rw-r--r--core/res/res/layout/keyguard_screen_password_portrait.xml25
-rw-r--r--core/res/res/layout/keyguard_screen_unlock_landscape.xml25
-rw-r--r--core/res/res/layout/keyguard_screen_unlock_portrait.xml25
-rw-r--r--core/res/res/layout/number_picker.xml15
-rw-r--r--core/res/res/layout/number_picker_with_selector_wheel.xml31
-rw-r--r--core/res/res/layout/preference_child_holo.xml2
-rw-r--r--core/res/res/layout/preference_holo.xml2
-rw-r--r--core/res/res/layout/preference_information_holo.xml2
-rw-r--r--core/res/res/values-af-rZA/donottranslate-maps.xml (renamed from core/res/res/values-af-rZA/arrays.xml)0
-rw-r--r--core/res/res/values-af/strings.xml22
-rw-r--r--core/res/res/values-am-rET/donottranslate-maps.xml (renamed from core/res/res/values-am-rET/arrays.xml)0
-rw-r--r--core/res/res/values-am/strings.xml12
-rw-r--r--core/res/res/values-ar-rEG/donottranslate-maps.xml (renamed from core/res/res/values-ar-rEG/arrays.xml)0
-rw-r--r--core/res/res/values-ar-rIL/donottranslate-maps.xml (renamed from core/res/res/values-ar-rIL/arrays.xml)0
-rw-r--r--core/res/res/values-ar/strings.xml18
-rw-r--r--core/res/res/values-be/strings.xml18
-rw-r--r--core/res/res/values-bg-rBG/donottranslate-maps.xml (renamed from core/res/res/values-bg-rBG/arrays.xml)0
-rw-r--r--core/res/res/values-bg/strings.xml18
-rw-r--r--core/res/res/values-ca-rES/donottranslate-maps.xml (renamed from core/res/res/values-ca-rES/arrays.xml)0
-rw-r--r--core/res/res/values-cs-rCZ/donottranslate-maps.xml (renamed from core/res/res/values-cs-rCZ/arrays.xml)0
-rw-r--r--core/res/res/values-cs/strings.xml18
-rw-r--r--core/res/res/values-da-rDK/donottranslate-maps.xml (renamed from core/res/res/values-da-rDK/arrays.xml)0
-rw-r--r--core/res/res/values-da/strings.xml22
-rw-r--r--core/res/res/values-de-rAT/donottranslate-maps.xml (renamed from core/res/res/values-de-rAT/arrays.xml)0
-rw-r--r--core/res/res/values-de-rCH/donottranslate-maps.xml (renamed from core/res/res/values-de-rCH/arrays.xml)0
-rw-r--r--core/res/res/values-de-rDE/donottranslate-maps.xml (renamed from core/res/res/values-de-rDE/arrays.xml)0
-rw-r--r--core/res/res/values-de-rLI/donottranslate-maps.xml (renamed from core/res/res/values-de-rLI/arrays.xml)0
-rw-r--r--core/res/res/values-de/strings.xml22
-rw-r--r--core/res/res/values-el-rGR/donottranslate-maps.xml (renamed from core/res/res/values-el-rGR/arrays.xml)0
-rw-r--r--core/res/res/values-el/strings.xml18
-rw-r--r--core/res/res/values-en-rAU/donottranslate-maps.xml (renamed from core/res/res/values-en-rAU/arrays.xml)0
-rw-r--r--core/res/res/values-en-rCA/donottranslate-maps.xml (renamed from core/res/res/values-en-rCA/arrays.xml)0
-rw-r--r--core/res/res/values-en-rGB/donottranslate-maps.xml (renamed from core/res/res/values-en-rGB/arrays.xml)0
-rw-r--r--core/res/res/values-en-rIE/donottranslate-maps.xml (renamed from core/res/res/values-en-rIE/arrays.xml)0
-rw-r--r--core/res/res/values-en-rIN/donottranslate-maps.xml (renamed from core/res/res/values-en-rIN/arrays.xml)0
-rw-r--r--core/res/res/values-en-rNZ/donottranslate-maps.xml (renamed from core/res/res/values-en-rNZ/arrays.xml)0
-rw-r--r--core/res/res/values-en-rSG/donottranslate-maps.xml (renamed from core/res/res/values-en-rSG/arrays.xml)0
-rw-r--r--core/res/res/values-en-rZA/donottranslate-maps.xml (renamed from core/res/res/values-en-rZA/arrays.xml)0
-rw-r--r--core/res/res/values-es-rES/donottranslate-maps.xml (renamed from core/res/res/values-es-rES/arrays.xml)0
-rw-r--r--core/res/res/values-es-rUS/strings.xml30
-rw-r--r--core/res/res/values-et/strings.xml18
-rw-r--r--core/res/res/values-fa-rIR/donottranslate-maps.xml (renamed from core/res/res/values-fa-rIR/arrays.xml)0
-rw-r--r--core/res/res/values-fa/strings.xml18
-rw-r--r--core/res/res/values-fi-rFI/donottranslate-maps.xml (renamed from core/res/res/values-fi-rFI/arrays.xml)0
-rw-r--r--core/res/res/values-fi/strings.xml18
-rw-r--r--core/res/res/values-fr-rBE/donottranslate-maps.xml (renamed from core/res/res/values-fr-rBE/arrays.xml)0
-rw-r--r--core/res/res/values-fr-rCA/donottranslate-maps.xml (renamed from core/res/res/values-fr-rCA/arrays.xml)0
-rw-r--r--core/res/res/values-fr-rCH/donottranslate-maps.xml (renamed from core/res/res/values-fr-rCH/arrays.xml)0
-rw-r--r--core/res/res/values-fr-rFR/donottranslate-maps.xml (renamed from core/res/res/values-fr-rFR/arrays.xml)0
-rw-r--r--core/res/res/values-fr/strings.xml2
-rw-r--r--core/res/res/values-hi-rIN/donottranslate-maps.xml (renamed from core/res/res/values-hi-rIN/arrays.xml)0
-rw-r--r--core/res/res/values-hi/strings.xml18
-rw-r--r--core/res/res/values-hr/strings.xml18
-rw-r--r--core/res/res/values-hu-rHU/donottranslate-maps.xml (renamed from core/res/res/values-hu-rHU/arrays.xml)0
-rw-r--r--core/res/res/values-hu/strings.xml18
-rw-r--r--core/res/res/values-in-rID/donottranslate-maps.xml (renamed from core/res/res/values-in-rID/arrays.xml)0
-rw-r--r--core/res/res/values-in/strings.xml30
-rw-r--r--core/res/res/values-it-rCH/donottranslate-maps.xml (renamed from core/res/res/values-it-rCH/arrays.xml)0
-rw-r--r--core/res/res/values-it-rIT/donottranslate-maps.xml (renamed from core/res/res/values-it-rIT/arrays.xml)0
-rw-r--r--core/res/res/values-iw-rIL/donottranslate-maps.xml (renamed from core/res/res/values-iw-rIL/arrays.xml)0
-rw-r--r--core/res/res/values-iw/strings.xml10
-rw-r--r--core/res/res/values-ja-rJP/donottranslate-maps.xml (renamed from core/res/res/values-ja-rJP/arrays.xml)0
-rw-r--r--core/res/res/values-ja/strings.xml18
-rw-r--r--core/res/res/values-ko-rKR/donottranslate-maps.xml (renamed from core/res/res/values-ko-rKR/arrays.xml)0
-rw-r--r--core/res/res/values-ko/strings.xml20
-rw-r--r--core/res/res/values-lt-rLT/donottranslate-maps.xml (renamed from core/res/res/values-lt-rLT/arrays.xml)0
-rw-r--r--core/res/res/values-lt/strings.xml20
-rw-r--r--core/res/res/values-lv-rLV/donottranslate-maps.xml (renamed from core/res/res/values-lv-rLV/arrays.xml)0
-rw-r--r--core/res/res/values-lv/strings.xml18
-rw-r--r--core/res/res/values-mcc204/donottranslate-maps.xml (renamed from core/res/res/values-mcc204/arrays.xml)0
-rw-r--r--core/res/res/values-mcc230/donottranslate-maps.xml (renamed from core/res/res/values-mcc230/arrays.xml)0
-rw-r--r--core/res/res/values-mcc232/donottranslate-maps.xml (renamed from core/res/res/values-mcc232/arrays.xml)0
-rw-r--r--core/res/res/values-mcc260/donottranslate-maps.xml (renamed from core/res/res/values-mcc260/arrays.xml)0
-rw-r--r--core/res/res/values-mcc262/donottranslate-maps.xml (renamed from core/res/res/values-mcc262/arrays.xml)0
-rw-r--r--core/res/res/values-ms-rMY/donottranslate-maps.xml (renamed from core/res/res/values-ms-rMY/arrays.xml)0
-rw-r--r--core/res/res/values-ms/strings.xml30
-rw-r--r--core/res/res/values-nb-rNO/donottranslate-maps.xml (renamed from core/res/res/values-nb-rNO/arrays.xml)0
-rw-r--r--core/res/res/values-nb/strings.xml20
-rw-r--r--core/res/res/values-nl-rBE/donottranslate-maps.xml (renamed from core/res/res/values-nl-rBE/arrays.xml)0
-rw-r--r--core/res/res/values-nl-rNL/donottranslate-maps.xml (renamed from core/res/res/values-nl-rNL/arrays.xml)0
-rw-r--r--core/res/res/values-nl/strings.xml30
-rw-r--r--core/res/res/values-pl-rPL/donottranslate-maps.xml (renamed from core/res/res/values-pl-rPL/arrays.xml)0
-rw-r--r--core/res/res/values-pl/strings.xml20
-rw-r--r--core/res/res/values-pt-rBR/donottranslate-maps.xml (renamed from core/res/res/values-pt-rBR/arrays.xml)0
-rw-r--r--core/res/res/values-pt-rPT/donottranslate-maps.xml (renamed from core/res/res/values-pt-rPT/arrays.xml)0
-rw-r--r--core/res/res/values-pt-rPT/strings.xml8
-rw-r--r--core/res/res/values-pt/strings.xml12
-rw-r--r--core/res/res/values-rm-rCH/donottranslate-maps.xml (renamed from core/res/res/values-rm-rCH/arrays.xml)0
-rw-r--r--core/res/res/values-ro-rRO/donottranslate-maps.xml (renamed from core/res/res/values-ro-rRO/arrays.xml)0
-rw-r--r--core/res/res/values-ro/strings.xml18
-rw-r--r--core/res/res/values-ru-rRU/donottranslate-maps.xml (renamed from core/res/res/values-ru-rRU/arrays.xml)0
-rw-r--r--core/res/res/values-ru/strings.xml18
-rw-r--r--core/res/res/values-sk-rSK/donottranslate-maps.xml (renamed from core/res/res/values-sk-rSK/arrays.xml)0
-rw-r--r--core/res/res/values-sk/strings.xml20
-rw-r--r--core/res/res/values-sl-rSI/donottranslate-maps.xml (renamed from core/res/res/values-sl-rSI/arrays.xml)0
-rw-r--r--core/res/res/values-sl/strings.xml18
-rw-r--r--core/res/res/values-sr-rRS/donottranslate-maps.xml (renamed from core/res/res/values-sr-rRS/arrays.xml)0
-rw-r--r--core/res/res/values-sr/strings.xml30
-rw-r--r--core/res/res/values-sv-rSE/donottranslate-maps.xml (renamed from core/res/res/values-sv-rSE/arrays.xml)0
-rw-r--r--core/res/res/values-sw-rTZ/donottranslate-maps.xml (renamed from core/res/res/values-sw-rTZ/arrays.xml)0
-rw-r--r--core/res/res/values-sw/strings.xml18
-rw-r--r--core/res/res/values-th-rTH/donottranslate-maps.xml (renamed from core/res/res/values-th-rTH/arrays.xml)0
-rw-r--r--core/res/res/values-th/strings.xml22
-rw-r--r--core/res/res/values-tl-rPH/donottranslate-maps.xml (renamed from core/res/res/values-tl-rPH/arrays.xml)0
-rw-r--r--core/res/res/values-tl/strings.xml18
-rw-r--r--core/res/res/values-tr-rTR/donottranslate-maps.xml (renamed from core/res/res/values-tr-rTR/arrays.xml)0
-rw-r--r--core/res/res/values-tr/strings.xml18
-rw-r--r--core/res/res/values-uk-rUA/donottranslate-maps.xml (renamed from core/res/res/values-uk-rUA/arrays.xml)0
-rw-r--r--core/res/res/values-uk/strings.xml18
-rw-r--r--core/res/res/values-vi-rVN/donottranslate-maps.xml (renamed from core/res/res/values-vi-rVN/arrays.xml)0
-rw-r--r--core/res/res/values-vi/strings.xml18
-rw-r--r--core/res/res/values-zh-rCN/donottranslate-maps.xml (renamed from core/res/res/values-zh-rCN/arrays.xml)0
-rw-r--r--core/res/res/values-zh-rCN/strings.xml30
-rw-r--r--core/res/res/values-zh-rTW/donottranslate-maps.xml (renamed from core/res/res/values-zh-rTW/arrays.xml)0
-rw-r--r--core/res/res/values-zh-rTW/strings.xml18
-rw-r--r--core/res/res/values-zu-rZA/donottranslate-maps.xml (renamed from core/res/res/values-zu-rZA/arrays.xml)0
-rw-r--r--core/res/res/values-zu/strings.xml10
-rw-r--r--core/res/res/values/arrays.xml10
-rwxr-xr-xcore/res/res/values/attrs.xml14
-rw-r--r--core/res/res/values/colors.xml2
-rw-r--r--core/res/res/values/donottranslate-maps.xml32
-rw-r--r--core/res/res/values/public.xml3
-rwxr-xr-xcore/res/res/values/strings.xml2
-rw-r--r--core/res/res/values/styles.xml61
-rw-r--r--core/res/res/values/styles_device_defaults.xml18
-rw-r--r--core/res/res/values/themes.xml15
-rw-r--r--core/res/res/values/themes_device_defaults.xml10
-rw-r--r--core/tests/utillib/src/android/test/BandwidthTest.java (renamed from test-runner/src/android/test/BandwidthTest.java)4
-rw-r--r--core/tests/utillib/src/android/test/BandwidthTestCase.java140
-rw-r--r--docs/html/guide/developing/debugging/ddms.jd85
-rw-r--r--docs/html/images/developing/ddms-network.pngbin0 -> 87432 bytes
-rw-r--r--docs/html/sdk/android-4.0.3.jd22
-rw-r--r--docs/html/sdk/compatibility-library.jd31
-rw-r--r--docs/html/sdk/eclipse-adt.jd112
-rw-r--r--docs/html/sdk/index.jd24
-rw-r--r--docs/html/sdk/requirements.jd10
-rw-r--r--docs/html/sdk/sdk_toc.cs9
-rw-r--r--docs/html/sdk/tools-notes.jd107
-rw-r--r--graphics/java/android/graphics/BitmapFactory.java65
-rw-r--r--include/common_time/local_clock.h2
-rw-r--r--include/media/AudioTrack.h5
-rw-r--r--include/media/stagefright/MetaData.h2
-rw-r--r--libs/hwui/DisplayListRenderer.h2
-rw-r--r--media/java/android/media/MediaRecorder.java8
-rw-r--r--media/jni/Android.mk1
-rw-r--r--media/jni/audioeffect/Android.mk3
-rw-r--r--media/jni/soundpool/Android.mk3
-rw-r--r--media/libaah_rtp/Android.mk2
-rw-r--r--media/libmedia/Android.mk2
-rw-r--r--media/libmedia/AudioTrack.cpp3
-rw-r--r--media/libmediaplayerservice/Android.mk1
-rw-r--r--media/libstagefright/Android.mk1
-rwxr-xr-xmedia/libstagefright/CameraSource.cpp10
-rw-r--r--media/libstagefright/MP3Extractor.cpp43
-rw-r--r--media/libstagefright/XINGSeeker.cpp32
-rw-r--r--media/libstagefright/id3/ID3.cpp47
-rw-r--r--media/libstagefright/include/ID3.h3
-rw-r--r--media/libstagefright/include/XINGSeeker.h5
-rw-r--r--media/libstagefright/timedtext/TimedText3GPPSource.cpp14
-rw-r--r--media/libstagefright/timedtext/TimedText3GPPSource.h3
-rw-r--r--media/libstagefright/timedtext/TimedTextPlayer.cpp30
-rw-r--r--media/libstagefright/timedtext/TimedTextPlayer.h1
-rw-r--r--media/libstagefright/timedtext/TimedTextSRTSource.cpp12
-rw-r--r--media/libstagefright/timedtext/TimedTextSRTSource.h3
-rw-r--r--media/libstagefright/timedtext/TimedTextSource.h3
-rw-r--r--packages/SystemUI/res/layout/navigation_bar.xml8
-rw-r--r--packages/SystemUI/src/com/android/systemui/recent/RecentTasksLoader.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/DeadZone.java41
-rw-r--r--policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java20
-rw-r--r--policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java55
-rw-r--r--policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java58
-rw-r--r--policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java380
-rw-r--r--policy/src/com/android/internal/policy/impl/LockScreen.java211
-rw-r--r--policy/src/com/android/internal/policy/impl/SimPukUnlockScreen.java2
-rw-r--r--services/audioflinger/Android.mk2
-rw-r--r--services/audioflinger/AudioFlinger.cpp45
-rw-r--r--services/audioflinger/AudioMixer.cpp2
-rw-r--r--services/camera/libcameraservice/Android.mk1
-rw-r--r--services/java/com/android/server/BootReceiver.java7
-rw-r--r--services/java/com/android/server/am/ActivityManagerService.java17
-rw-r--r--services/java/com/android/server/am/ActivityRecord.java24
-rw-r--r--services/java/com/android/server/am/ActivityStack.java31
-rw-r--r--services/java/com/android/server/am/PendingIntentRecord.java11
-rw-r--r--services/java/com/android/server/net/NetworkPolicyManagerService.java25
-rw-r--r--services/java/com/android/server/pm/PackageManagerService.java50
-rw-r--r--services/java/com/android/server/pm/Settings.java21
-rw-r--r--services/java/com/android/server/wm/AppWindowToken.java4
-rw-r--r--services/java/com/android/server/wm/WindowManagerService.java1
-rw-r--r--services/java/com/android/server/wm/WindowState.java12
-rw-r--r--test-runner/src/android/test/BandwidthTestRunner.java92
-rw-r--r--tests/TileBenchmark/src/com/test/tilebenchmark/PlaybackGraphs.java10
-rw-r--r--tests/TileBenchmark/src/com/test/tilebenchmark/RunData.java3
-rw-r--r--tools/aapt/Bundle.h8
-rw-r--r--tools/aapt/Images.cpp4
-rw-r--r--tools/aapt/Images.h4
-rw-r--r--tools/aapt/Resource.cpp48
-rw-r--r--tools/aapt/StringPool.cpp21
-rw-r--r--tools/aapt/StringPool.h2
-rw-r--r--voip/jni/rtp/Android.mk1
-rw-r--r--voip/jni/rtp/AudioGroup.cpp6
327 files changed, 3671 insertions, 3157 deletions
diff --git a/api/current.txt b/api/current.txt
index 541ce5116b57..665b0548adba 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -2864,6 +2864,12 @@ package android.app {
field public android.content.ComponentName topActivity;
}
+ public class ActivityOptions {
+ method public void join(android.app.ActivityOptions);
+ method public static android.app.ActivityOptions makeCustomAnimation(android.content.Context, int, int);
+ method public android.os.Bundle toBundle();
+ }
+
public class AlarmManager {
method public void cancel(android.app.PendingIntent);
method public void set(int, long, android.app.PendingIntent);
@@ -3728,7 +3734,9 @@ package android.app {
method public void cancel();
method public int describeContents();
method public static android.app.PendingIntent getActivities(android.content.Context, int, android.content.Intent[], int);
+ method public static android.app.PendingIntent getActivities(android.content.Context, int, android.content.Intent[], int, android.os.Bundle);
method public static android.app.PendingIntent getActivity(android.content.Context, int, android.content.Intent, int);
+ method public static android.app.PendingIntent getActivity(android.content.Context, int, android.content.Intent, int, android.os.Bundle);
method public static android.app.PendingIntent getBroadcast(android.content.Context, int, android.content.Intent, int);
method public android.content.IntentSender getIntentSender();
method public static android.app.PendingIntent getService(android.content.Context, int, android.content.Intent, int);
@@ -23592,10 +23600,10 @@ package android.view {
field public static final int LAYER_TYPE_HARDWARE = 2; // 0x2
field public static final int LAYER_TYPE_NONE = 0; // 0x0
field public static final int LAYER_TYPE_SOFTWARE = 1; // 0x1
- field public static final int LAYOUT_DIRECTION_INHERIT = -2147483648; // 0x80000000
- field public static final int LAYOUT_DIRECTION_LOCALE = -1073741824; // 0xc0000000
- field public static final int LAYOUT_DIRECTION_LTR = 0; // 0x0
- field public static final int LAYOUT_DIRECTION_RTL = 1073741824; // 0x40000000
+ field public static final int LAYOUT_DIRECTION_INHERIT = 4; // 0x4
+ field public static final int LAYOUT_DIRECTION_LOCALE = 8; // 0x8
+ field public static final int LAYOUT_DIRECTION_LTR = 1; // 0x1
+ field public static final int LAYOUT_DIRECTION_RTL = 2; // 0x2
field public static final int MEASURED_HEIGHT_STATE_SHIFT = 16; // 0x10
field public static final int MEASURED_SIZE_MASK = 16777215; // 0xffffff
field public static final int MEASURED_STATE_MASK = -16777216; // 0xff000000
@@ -26950,7 +26958,6 @@ package android.widget {
method public void setOnValueChangedListener(android.widget.NumberPicker.OnValueChangeListener);
method public void setValue(int);
method public void setWrapSelectorWheel(boolean);
- field public static final int SELECTOR_WHEEL_ITEM_COUNT = 5; // 0x5
}
public static abstract interface NumberPicker.Formatter {
diff --git a/cmds/stagefright/Android.mk b/cmds/stagefright/Android.mk
index e41b66605d68..30be7fad30f9 100644
--- a/cmds/stagefright/Android.mk
+++ b/cmds/stagefright/Android.mk
@@ -7,7 +7,7 @@ LOCAL_SRC_FILES:= \
SineSource.cpp
LOCAL_SHARED_LIBRARIES := \
- libstagefright libmedia libutils libbinder libstagefright_foundation \
+ libstagefright libmedia libmedia_native libutils libbinder libstagefright_foundation \
libskia libgui
LOCAL_C_INCLUDES:= \
@@ -108,7 +108,7 @@ LOCAL_SRC_FILES:= \
LOCAL_SHARED_LIBRARIES := \
libstagefright liblog libutils libbinder libgui \
- libstagefright_foundation libmedia
+ libstagefright_foundation libmedia libmedia_native
LOCAL_C_INCLUDES:= \
$(JNI_H_INCLUDE) \
@@ -132,7 +132,7 @@ LOCAL_SRC_FILES:= \
LOCAL_SHARED_LIBRARIES := \
libstagefright liblog libutils libbinder libstagefright_foundation \
- libmedia libgui libcutils libui
+ libmedia libmedia_native libgui libcutils libui
LOCAL_C_INCLUDES:= \
$(JNI_H_INCLUDE) \
@@ -157,7 +157,7 @@ LOCAL_SRC_FILES:= \
LOCAL_SHARED_LIBRARIES := \
libstagefright liblog libutils libbinder libstagefright_foundation \
- libmedia libgui libcutils libui
+ libmedia libmedia_native libgui libcutils libui
LOCAL_C_INCLUDES:= \
$(JNI_H_INCLUDE) \
diff --git a/core/java/android/accounts/AccountManagerService.java b/core/java/android/accounts/AccountManagerService.java
index 28b7dd3c9c61..27c9c8b37964 100644
--- a/core/java/android/accounts/AccountManagerService.java
+++ b/core/java/android/accounts/AccountManagerService.java
@@ -217,10 +217,10 @@ public class AccountManagerService
mAuthenticatorCache = authenticatorCache;
mAuthenticatorCache.setListener(this, null /* Handler */);
- UserAccounts accounts = initUser(0);
-
sThis.set(this);
+ UserAccounts accounts = initUser(0);
+
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
intentFilter.addDataScheme("package");
@@ -1780,7 +1780,7 @@ public class AccountManagerService
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "performing bindService to " + authenticatorInfo.componentName);
}
- if (!mContext.bindService(intent, this, Context.BIND_AUTO_CREATE)) {
+ if (!mContext.bindService(intent, this, Context.BIND_AUTO_CREATE, mAccounts.userId)) {
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "bindService to " + authenticatorInfo.componentName + " failed");
}
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index dc12acd51c0f..ea3274595ad4 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -32,7 +32,6 @@ import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.content.res.TypedArray;
-import android.content.res.Resources.Theme;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.Canvas;
@@ -55,7 +54,6 @@ import android.util.AttributeSet;
import android.util.EventLog;
import android.util.Log;
import android.util.SparseArray;
-import android.util.TypedValue;
import android.view.ActionMode;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
@@ -3208,7 +3206,8 @@ public class Activity extends ContextThemeWrapper
* @param requestCode If >= 0, this code will be returned in
* onActivityResult() when the activity exits.
* @param options Additional options for how the Activity should be started.
- * May be null if there are no options.
+ * See {@link android.content.Context#startActivity(Intent, Bundle)
+ * Context.startActivity(Intent, Bundle)} for more details.
*
* @throws android.content.ActivityNotFoundException
*
@@ -3288,7 +3287,10 @@ public class Activity extends ContextThemeWrapper
* <var>flagsMask</var>
* @param extraFlags Always set to 0.
* @param options Additional options for how the Activity should be started.
- * May be null if there are no options.
+ * See {@link android.content.Context#startActivity(Intent, Bundle)
+ * Context.startActivity(Intent, Bundle)} for more details. If options
+ * have also been supplied by the IntentSender, options given here will
+ * override any that conflict with those given by the IntentSender.
*/
public void startIntentSenderForResult(IntentSender intent, int requestCode,
Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags,
@@ -3369,7 +3371,8 @@ public class Activity extends ContextThemeWrapper
*
* @param intent The intent to start.
* @param options Additional options for how the Activity should be started.
- * May be null if there are no options.
+ * See {@link android.content.Context#startActivity(Intent, Bundle)
+ * Context.startActivity(Intent, Bundle)} for more details.
*
* @throws android.content.ActivityNotFoundException
*
@@ -3417,7 +3420,8 @@ public class Activity extends ContextThemeWrapper
*
* @param intents The intents to start.
* @param options Additional options for how the Activity should be started.
- * May be null if there are no options.
+ * See {@link android.content.Context#startActivity(Intent, Bundle)
+ * Context.startActivity(Intent, Bundle)} for more details.
*
* @throws android.content.ActivityNotFoundException
*
@@ -3465,7 +3469,10 @@ public class Activity extends ContextThemeWrapper
* <var>flagsMask</var>
* @param extraFlags Always set to 0.
* @param options Additional options for how the Activity should be started.
- * May be null if there are no options.
+ * See {@link android.content.Context#startActivity(Intent, Bundle)
+ * Context.startActivity(Intent, Bundle)} for more details. If options
+ * have also been supplied by the IntentSender, options given here will
+ * override any that conflict with those given by the IntentSender.
*/
public void startIntentSender(IntentSender intent,
Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags,
@@ -3521,7 +3528,8 @@ public class Activity extends ContextThemeWrapper
* onActivityResult() when the activity exits, as described in
* {@link #startActivityForResult}.
* @param options Additional options for how the Activity should be started.
- * May be null if there are no options.
+ * See {@link android.content.Context#startActivity(Intent, Bundle)
+ * Context.startActivity(Intent, Bundle)} for more details.
*
* @return If a new activity was launched then true is returned; otherwise
* false is returned and you must handle the Intent yourself.
@@ -3592,7 +3600,8 @@ public class Activity extends ContextThemeWrapper
* your own activity; the only changes you can make are to the extras
* inside of it.
* @param options Additional options for how the Activity should be started.
- * May be null if there are no options.
+ * See {@link android.content.Context#startActivity(Intent, Bundle)
+ * Context.startActivity(Intent, Bundle)} for more details.
*
* @return Returns a boolean indicating whether there was another Activity
* to start: true if there was a next activity to start, false if there
@@ -3644,7 +3653,8 @@ public class Activity extends ContextThemeWrapper
* @param intent The intent to start.
* @param requestCode Reply request code. < 0 if reply is not requested.
* @param options Additional options for how the Activity should be started.
- * May be null if there are no options.
+ * See {@link android.content.Context#startActivity(Intent, Bundle)
+ * Context.startActivity(Intent, Bundle)} for more details.
*
* @throws android.content.ActivityNotFoundException
*
@@ -3694,7 +3704,8 @@ public class Activity extends ContextThemeWrapper
* @param intent The intent to start.
* @param requestCode Reply request code. < 0 if reply is not requested.
* @param options Additional options for how the Activity should be started.
- * May be null if there are no options.
+ * See {@link android.content.Context#startActivity(Intent, Bundle)
+ * Context.startActivity(Intent, Bundle)} for more details.
*
* @throws android.content.ActivityNotFoundException
*
@@ -3744,6 +3755,14 @@ public class Activity extends ContextThemeWrapper
* Call immediately after one of the flavors of {@link #startActivity(Intent)}
* or {@link #finish} to specify an explicit transition animation to
* perform next.
+ *
+ * <p>As of {@link android.os.Build.VERSION_CODES#JELLY_BEAN} an alternative
+ * to using this with starting activities is to supply the desired animation
+ * information through a {@link ActivityOptions} bundle to
+ * {@link #startActivity(Intent, Bundle) or a related function. This allows
+ * you to specify a custom animation even when starting an activity from
+ * outside the context of the current top activity.
+ *
* @param enterAnim A resource ID of the animation resource to use for
* the incoming activity. Use 0 for no animation.
* @param exitAnim A resource ID of the animation resource to use for
@@ -4065,7 +4084,7 @@ public class Activity extends ContextThemeWrapper
ActivityManagerNative.getDefault().getIntentSender(
ActivityManager.INTENT_SENDER_ACTIVITY_RESULT, packageName,
mParent == null ? mToken : mParent.mToken,
- mEmbeddedID, requestCode, new Intent[] { data }, null, flags);
+ mEmbeddedID, requestCode, new Intent[] { data }, null, flags, null);
return target != null ? new PendingIntent(target) : null;
} catch (RemoteException e) {
// Empty
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 732d211233ea..a3cc352f75d5 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -835,9 +835,11 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
requestResolvedTypes = null;
}
int fl = data.readInt();
+ Bundle options = data.readInt() != 0
+ ? Bundle.CREATOR.createFromParcel(data) : null;
IIntentSender res = getIntentSender(type, packageName, token,
resultWho, requestCode, requestIntents,
- requestResolvedTypes, fl);
+ requestResolvedTypes, fl, options);
reply.writeNoException();
reply.writeStrongBinder(res != null ? res.asBinder() : null);
return true;
@@ -2607,8 +2609,8 @@ class ActivityManagerProxy implements IActivityManager
}
public IIntentSender getIntentSender(int type,
String packageName, IBinder token, String resultWho,
- int requestCode, Intent[] intents, String[] resolvedTypes, int flags)
- throws RemoteException {
+ int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
+ Bundle options) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
@@ -2625,6 +2627,12 @@ class ActivityManagerProxy implements IActivityManager
data.writeInt(0);
}
data.writeInt(flags);
+ if (options != null) {
+ data.writeInt(1);
+ options.writeToParcel(data, 0);
+ } else {
+ data.writeInt(0);
+ }
mRemote.transact(GET_INTENT_SENDER_TRANSACTION, data, reply, 0);
reply.readException();
IIntentSender res = IIntentSender.Stub.asInterface(
diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java
new file mode 100644
index 000000000000..03bc338b28ef
--- /dev/null
+++ b/core/java/android/app/ActivityOptions.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.app;
+
+import android.content.Context;
+import android.os.Bundle;
+
+/**
+ * Helper class for building an options Bundle that can be used with
+ * {@link android.content.Context#startActivity(android.content.Intent, android.os.Bundle)
+ * Context.startActivity(Intent, Bundle)} and related methods.
+ */
+public class ActivityOptions {
+ /**
+ * The package name that created the options.
+ * @hide
+ */
+ public static final String KEY_PACKAGE_NAME = "android:packageName";
+
+ /**
+ * Custom enter animation resource ID.
+ * @hide
+ */
+ public static final String KEY_ANIM_ENTER_RES_ID = "android:animEnterRes";
+
+ /**
+ * Custom exit animation resource ID.
+ * @hide
+ */
+ public static final String KEY_ANIM_EXIT_RES_ID = "android:animExitRes";
+
+ private String mPackageName;
+ private boolean mIsCustomAnimation;
+ private int mCustomEnterResId;
+ private int mCustomExitResId;
+
+ /**
+ * Create an ActivityOptions specifying a custom animation to run when
+ * the activity is displayed.
+ *
+ * @param context Who is defining this. This is the application that the
+ * animation resources will be loaded from.
+ * @param enterResId A resource ID of the animation resource to use for
+ * the incoming activity. Use 0 for no animation.
+ * @param exitResId A resource ID of the animation resource to use for
+ * the outgoing activity. Use 0 for no animation.
+ * @return Returns a new ActivityOptions object that you can use to
+ * supply these options as the options Bundle when starting an activity.
+ */
+ public static ActivityOptions makeCustomAnimation(Context context,
+ int enterResId, int exitResId) {
+ ActivityOptions opts = new ActivityOptions();
+ opts.mPackageName = context.getPackageName();
+ opts.mIsCustomAnimation = true;
+ opts.mCustomEnterResId = enterResId;
+ opts.mCustomExitResId = exitResId;
+ return opts;
+ }
+
+ private ActivityOptions() {
+ }
+
+ /** @hide */
+ public ActivityOptions(Bundle opts) {
+ mPackageName = opts.getString(KEY_PACKAGE_NAME);
+ if (opts.containsKey(KEY_ANIM_ENTER_RES_ID)) {
+ mIsCustomAnimation = true;
+ mCustomEnterResId = opts.getInt(KEY_ANIM_ENTER_RES_ID, 0);
+ mCustomExitResId = opts.getInt(KEY_ANIM_EXIT_RES_ID, 0);
+ }
+ }
+
+ /** @hide */
+ public String getPackageName() {
+ return mPackageName;
+ }
+
+ /** @hide */
+ public boolean isCustomAnimation() {
+ return mIsCustomAnimation;
+ }
+
+ /** @hide */
+ public int getCustomEnterResId() {
+ return mCustomEnterResId;
+ }
+
+ /** @hide */
+ public int getCustomExitResId() {
+ return mCustomExitResId;
+ }
+
+ /**
+ * Join the values in <var>otherOptions</var> in to this one. Any values
+ * defined in <var>otherOptions</var> replace those in the base options.
+ */
+ public void join(ActivityOptions otherOptions) {
+ if (otherOptions.mPackageName != null) {
+ mPackageName = otherOptions.mPackageName;
+ }
+ if (otherOptions.mIsCustomAnimation) {
+ mIsCustomAnimation = true;
+ mCustomEnterResId = otherOptions.mCustomEnterResId;
+ mCustomExitResId = otherOptions.mCustomExitResId;
+ }
+ }
+
+ /**
+ * Returns the created options as a Bundle, which can be passed to
+ * {@link android.content.Context#startActivity(android.content.Intent, android.os.Bundle)
+ * Context.startActivity(Intent, Bundle)} and related methods.
+ * Note that the returned Bundle is still owned by the ActivityOptions
+ * object; you must not modify it, but can supply it to the startActivity
+ * methods that take an options Bundle.
+ */
+ public Bundle toBundle() {
+ Bundle b = new Bundle();
+ if (mPackageName != null) {
+ b.putString(KEY_PACKAGE_NAME, mPackageName);
+ }
+ if (mIsCustomAnimation) {
+ b.putInt(KEY_ANIM_ENTER_RES_ID, mCustomEnterResId);
+ b.putInt(KEY_ANIM_EXIT_RES_ID, mCustomExitResId);
+ }
+ return b;
+ }
+}
diff --git a/core/java/android/app/Fragment.java b/core/java/android/app/Fragment.java
index dadc4e5ff593..c493f0fb9284 100644
--- a/core/java/android/app/Fragment.java
+++ b/core/java/android/app/Fragment.java
@@ -965,6 +965,8 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene
/**
* Call {@link Activity#startActivity(Intent)} on the fragment's
* containing Activity.
+ *
+ * @param intent The intent to start.
*/
public void startActivity(Intent intent) {
startActivity(intent, null);
@@ -973,6 +975,11 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene
/**
* Call {@link Activity#startActivity(Intent, Bundle)} on the fragment's
* containing Activity.
+ *
+ * @param intent The intent to start.
+ * @param options Additional options for how the Activity should be started.
+ * See {@link android.content.Context#startActivity(Intent, Bundle)
+ * Context.startActivity(Intent, Bundle)} for more details.
*/
public void startActivity(Intent intent, Bundle options) {
if (mActivity == null) {
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 9306bd2a1416..31066b5bb584 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -169,7 +169,7 @@ public interface IActivityManager extends IInterface {
public IIntentSender getIntentSender(int type,
String packageName, IBinder token, String resultWho,
int requestCode, Intent[] intents, String[] resolvedTypes,
- int flags) throws RemoteException;
+ int flags, Bundle options) throws RemoteException;
public void cancelIntentSender(IIntentSender sender) throws RemoteException;
public boolean clearApplicationUserData(final String packageName,
final IPackageDataObserver observer, int userId) throws RemoteException;
diff --git a/core/java/android/app/PendingIntent.java b/core/java/android/app/PendingIntent.java
index 57192c3c45e3..aa366b6af9a7 100644
--- a/core/java/android/app/PendingIntent.java
+++ b/core/java/android/app/PendingIntent.java
@@ -188,6 +188,35 @@ public final class PendingIntent implements Parcelable {
*/
public static PendingIntent getActivity(Context context, int requestCode,
Intent intent, int flags) {
+ return getActivity(context, requestCode, intent, flags, null);
+ }
+
+ /**
+ * Retrieve a PendingIntent that will start a new activity, like calling
+ * {@link Context#startActivity(Intent) Context.startActivity(Intent)}.
+ * Note that the activity will be started outside of the context of an
+ * existing activity, so you must use the {@link Intent#FLAG_ACTIVITY_NEW_TASK
+ * Intent.FLAG_ACTIVITY_NEW_TASK} launch flag in the Intent.
+ *
+ * @param context The Context in which this PendingIntent should start
+ * the activity.
+ * @param requestCode Private request code for the sender (currently
+ * not used).
+ * @param intent Intent of the activity to be launched.
+ * @param flags May be {@link #FLAG_ONE_SHOT}, {@link #FLAG_NO_CREATE},
+ * {@link #FLAG_CANCEL_CURRENT}, {@link #FLAG_UPDATE_CURRENT},
+ * or any of the flags as supported by
+ * {@link Intent#fillIn Intent.fillIn()} to control which unspecified parts
+ * of the intent that can be supplied when the actual send happens.
+ * @param options Additional options for how the Activity should be started.
+ * May be null if there are no options.
+ *
+ * @return Returns an existing or new PendingIntent matching the given
+ * parameters. May return null only if {@link #FLAG_NO_CREATE} has been
+ * supplied.
+ */
+ public static PendingIntent getActivity(Context context, int requestCode,
+ Intent intent, int flags, Bundle options) {
String packageName = context.getPackageName();
String resolvedType = intent != null ? intent.resolveTypeIfNeeded(
context.getContentResolver()) : null;
@@ -197,7 +226,8 @@ public final class PendingIntent implements Parcelable {
ActivityManagerNative.getDefault().getIntentSender(
ActivityManager.INTENT_SENDER_ACTIVITY, packageName,
null, null, requestCode, new Intent[] { intent },
- resolvedType != null ? new String[] { resolvedType } : null, flags);
+ resolvedType != null ? new String[] { resolvedType } : null,
+ flags, options);
return target != null ? new PendingIntent(target) : null;
} catch (RemoteException e) {
}
@@ -247,6 +277,52 @@ public final class PendingIntent implements Parcelable {
*/
public static PendingIntent getActivities(Context context, int requestCode,
Intent[] intents, int flags) {
+ return getActivities(context, requestCode, intents, flags, null);
+ }
+
+ /**
+ * Like {@link #getActivity(Context, int, Intent, int)}, but allows an
+ * array of Intents to be supplied. The first Intent in the array is
+ * taken as the primary key for the PendingIntent, like the single Intent
+ * given to {@link #getActivity(Context, int, Intent, int)}. Upon sending
+ * the resulting PendingIntent, all of the Intents are started in the same
+ * way as they would be by passing them to {@link Context#startActivities(Intent[])}.
+ *
+ * <p class="note">
+ * The <em>first</em> intent in the array will be started outside of the context of an
+ * existing activity, so you must use the {@link Intent#FLAG_ACTIVITY_NEW_TASK
+ * Intent.FLAG_ACTIVITY_NEW_TASK} launch flag in the Intent. (Activities after
+ * the first in the array are started in the context of the previous activity
+ * in the array, so FLAG_ACTIVITY_NEW_TASK is not needed nor desired for them.)
+ * </p>
+ *
+ * <p class="note">
+ * The <em>last</em> intent in the array represents the key for the
+ * PendingIntent. In other words, it is the significant element for matching
+ * (as done with the single intent given to {@link #getActivity(Context, int, Intent, int)},
+ * its content will be the subject of replacement by
+ * {@link #send(Context, int, Intent)} and {@link #FLAG_UPDATE_CURRENT}, etc.
+ * This is because it is the most specific of the supplied intents, and the
+ * UI the user actually sees when the intents are started.
+ * </p>
+ *
+ * @param context The Context in which this PendingIntent should start
+ * the activity.
+ * @param requestCode Private request code for the sender (currently
+ * not used).
+ * @param intents Array of Intents of the activities to be launched.
+ * @param flags May be {@link #FLAG_ONE_SHOT}, {@link #FLAG_NO_CREATE},
+ * {@link #FLAG_CANCEL_CURRENT}, {@link #FLAG_UPDATE_CURRENT},
+ * or any of the flags as supported by
+ * {@link Intent#fillIn Intent.fillIn()} to control which unspecified parts
+ * of the intent that can be supplied when the actual send happens.
+ *
+ * @return Returns an existing or new PendingIntent matching the given
+ * parameters. May return null only if {@link #FLAG_NO_CREATE} has been
+ * supplied.
+ */
+ public static PendingIntent getActivities(Context context, int requestCode,
+ Intent[] intents, int flags, Bundle options) {
String packageName = context.getPackageName();
String[] resolvedTypes = new String[intents.length];
for (int i=0; i<intents.length; i++) {
@@ -257,7 +333,7 @@ public final class PendingIntent implements Parcelable {
IIntentSender target =
ActivityManagerNative.getDefault().getIntentSender(
ActivityManager.INTENT_SENDER_ACTIVITY, packageName,
- null, null, requestCode, intents, resolvedTypes, flags);
+ null, null, requestCode, intents, resolvedTypes, flags, options);
return target != null ? new PendingIntent(target) : null;
} catch (RemoteException e) {
}
@@ -294,7 +370,8 @@ public final class PendingIntent implements Parcelable {
ActivityManagerNative.getDefault().getIntentSender(
ActivityManager.INTENT_SENDER_BROADCAST, packageName,
null, null, requestCode, new Intent[] { intent },
- resolvedType != null ? new String[] { resolvedType } : null, flags);
+ resolvedType != null ? new String[] { resolvedType } : null,
+ flags, null);
return target != null ? new PendingIntent(target) : null;
} catch (RemoteException e) {
}
@@ -332,7 +409,8 @@ public final class PendingIntent implements Parcelable {
ActivityManagerNative.getDefault().getIntentSender(
ActivityManager.INTENT_SENDER_SERVICE, packageName,
null, null, requestCode, new Intent[] { intent },
- resolvedType != null ? new String[] { resolvedType } : null, flags);
+ resolvedType != null ? new String[] { resolvedType } : null,
+ flags, null);
return target != null ? new PendingIntent(target) : null;
} catch (RemoteException e) {
}
diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java
index ec67d8c1fe82..05ef1947400f 100644
--- a/core/java/android/content/ContentProvider.java
+++ b/core/java/android/content/ContentProvider.java
@@ -270,19 +270,24 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
return CancellationSignal.createTransport();
}
- private boolean hasReadPermission(Uri uri) {
+ private void enforceReadPermission(Uri uri) throws SecurityException {
final Context context = getContext();
final int pid = Binder.getCallingPid();
final int uid = Binder.getCallingUid();
+ String missingPerm = null;
if (uid == mMyUid) {
- return true;
+ return;
+ }
- } else if (mExported) {
+ if (mExported) {
final String componentPerm = getReadPermission();
- if (componentPerm != null
- && (context.checkPermission(componentPerm, pid, uid) == PERMISSION_GRANTED)) {
- return true;
+ if (componentPerm != null) {
+ if (context.checkPermission(componentPerm, pid, uid) == PERMISSION_GRANTED) {
+ return;
+ } else {
+ missingPerm = componentPerm;
+ }
}
// track if unprotected read is allowed; any denied
@@ -296,11 +301,12 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
final String pathPerm = pp.getReadPermission();
if (pathPerm != null && pp.match(path)) {
if (context.checkPermission(pathPerm, pid, uid) == PERMISSION_GRANTED) {
- return true;
+ return;
} else {
// any denied <path-permission> means we lose
// default <provider> access.
allowDefaultRead = false;
+ missingPerm = pathPerm;
}
}
}
@@ -308,44 +314,41 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
// if we passed <path-permission> checks above, and no default
// <provider> permission, then allow access.
- if (allowDefaultRead) return true;
+ if (allowDefaultRead) return;
}
// last chance, check against any uri grants
if (context.checkUriPermission(uri, pid, uid, Intent.FLAG_GRANT_READ_URI_PERMISSION)
== PERMISSION_GRANTED) {
- return true;
- }
-
- return false;
- }
-
- private void enforceReadPermission(Uri uri) {
- if (hasReadPermission(uri)) {
return;
}
- String msg = "Permission Denial: reading "
- + ContentProvider.this.getClass().getName()
- + " uri " + uri + " from pid=" + Binder.getCallingPid()
- + ", uid=" + Binder.getCallingUid()
- + " requires " + getReadPermission();
- throw new SecurityException(msg);
+ final String failReason = mExported
+ ? " requires " + missingPerm + ", or grantUriPermission()"
+ : " requires the provider be exported, or grantUriPermission()";
+ throw new SecurityException("Permission Denial: reading "
+ + ContentProvider.this.getClass().getName() + " uri " + uri + " from pid=" + pid
+ + ", uid=" + uid + failReason);
}
- private boolean hasWritePermission(Uri uri) {
+ private void enforceWritePermission(Uri uri) throws SecurityException {
final Context context = getContext();
final int pid = Binder.getCallingPid();
final int uid = Binder.getCallingUid();
+ String missingPerm = null;
if (uid == mMyUid) {
- return true;
+ return;
+ }
- } else if (mExported) {
+ if (mExported) {
final String componentPerm = getWritePermission();
- if (componentPerm != null
- && (context.checkPermission(componentPerm, pid, uid) == PERMISSION_GRANTED)) {
- return true;
+ if (componentPerm != null) {
+ if (context.checkPermission(componentPerm, pid, uid) == PERMISSION_GRANTED) {
+ return;
+ } else {
+ missingPerm = componentPerm;
+ }
}
// track if unprotected write is allowed; any denied
@@ -359,11 +362,12 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
final String pathPerm = pp.getWritePermission();
if (pathPerm != null && pp.match(path)) {
if (context.checkPermission(pathPerm, pid, uid) == PERMISSION_GRANTED) {
- return true;
+ return;
} else {
// any denied <path-permission> means we lose
// default <provider> access.
allowDefaultWrite = false;
+ missingPerm = pathPerm;
}
}
}
@@ -371,33 +375,24 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
// if we passed <path-permission> checks above, and no default
// <provider> permission, then allow access.
- if (allowDefaultWrite) return true;
+ if (allowDefaultWrite) return;
}
// last chance, check against any uri grants
if (context.checkUriPermission(uri, pid, uid, Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
== PERMISSION_GRANTED) {
- return true;
- }
-
- return false;
- }
-
- private void enforceWritePermission(Uri uri) {
- if (hasWritePermission(uri)) {
return;
}
-
- String msg = "Permission Denial: writing "
- + ContentProvider.this.getClass().getName()
- + " uri " + uri + " from pid=" + Binder.getCallingPid()
- + ", uid=" + Binder.getCallingUid()
- + " requires " + getWritePermission();
- throw new SecurityException(msg);
+
+ final String failReason = mExported
+ ? " requires " + missingPerm + ", or grantUriPermission()"
+ : " requires the provider be exported, or grantUriPermission()";
+ throw new SecurityException("Permission Denial: writing "
+ + ContentProvider.this.getClass().getName() + " uri " + uri + " from pid=" + pid
+ + ", uid=" + uid + failReason);
}
}
-
/**
* Retrieves the Context this provider is running in. Only available once
* {@link #onCreate} has been called -- this will return null in the
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 19a5bc0103fd..741a6e90b556 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -846,7 +846,9 @@ public abstract class Context {
*
* @param intent The description of the activity to start.
* @param options Additional options for how the Activity should be started.
- * May be null if there are no options.
+ * May be null if there are no options. See {@link android.app.ActivityOptions}
+ * for how to build the Bundle supplied here; there are no supported definitions
+ * for building it manually.
*
* @throws ActivityNotFoundException
*
@@ -884,7 +886,8 @@ public abstract class Context {
*
* @param intents An array of Intents to be started.
* @param options Additional options for how the Activity should be started.
- * May be null if there are no options.
+ * See {@link android.content.Context#startActivity(Intent, Bundle)
+ * Context.startActivity(Intent, Bundle)} for more details.
*
* @throws ActivityNotFoundException
*
@@ -930,7 +933,10 @@ public abstract class Context {
* <var>flagsMask</var>
* @param extraFlags Always set to 0.
* @param options Additional options for how the Activity should be started.
- * May be null if there are no options.
+ * See {@link android.content.Context#startActivity(Intent, Bundle)
+ * Context.startActivity(Intent, Bundle)} for more details. If options
+ * have also been supplied by the IntentSender, options given here will
+ * override any that conflict with those given by the IntentSender.
*
* @see #startActivity(Intent, Bundle)
* @see #startIntentSender(IntentSender, Intent, int, int, int)
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index 95b6feebd93e..9bd1940d0cad 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -370,4 +370,7 @@ interface IPackageManager {
boolean isFirstBoot();
List<UserInfo> getUsers();
+
+ void setPermissionEnforcement(String permission, int enforcement);
+ int getPermissionEnforcement(String permission);
}
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 544bd9c6bb3c..55426b819cb1 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -1090,6 +1090,11 @@ public abstract class PackageManager {
public static final String EXTRA_VERIFICATION_INSTALL_FLAGS
= "android.content.pm.extra.VERIFICATION_INSTALL_FLAGS";
+ /** {@hide} */
+ public static final int ENFORCEMENT_DEFAULT = 0;
+ /** {@hide} */
+ public static final int ENFORCEMENT_YES = 1;
+
/**
* Retrieve overall information about an application package that is
* installed on the system.
diff --git a/core/java/android/net/Downloads.java b/core/java/android/net/Downloads.java
deleted file mode 100644
index ed6d10335b18..000000000000
--- a/core/java/android/net/Downloads.java
+++ /dev/null
@@ -1,644 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net;
-
-import android.content.ContentResolver;
-import android.content.ContentUris;
-import android.content.ContentValues;
-import android.content.Context;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.ParcelFileDescriptor;
-import android.os.SystemClock;
-import android.provider.BaseColumns;
-import android.util.Log;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.File;
-import java.io.InputStream;
-
-/**
- * The Download Manager
- *
- * @hide
- */
-public final class Downloads {
-
-
- /**
- * Download status codes
- */
-
- /**
- * This download hasn't started yet
- */
- public static final int STATUS_PENDING = 190;
-
- /**
- * This download has started
- */
- public static final int STATUS_RUNNING = 192;
-
- /**
- * This download has successfully completed.
- * Warning: there might be other status values that indicate success
- * in the future.
- * Use isSucccess() to capture the entire category.
- */
- public static final int STATUS_SUCCESS = 200;
-
- /**
- * This download can't be performed because the content type cannot be
- * handled.
- */
- public static final int STATUS_NOT_ACCEPTABLE = 406;
-
- /**
- * This download has completed with an error.
- * Warning: there will be other status values that indicate errors in
- * the future. Use isStatusError() to capture the entire category.
- */
- public static final int STATUS_UNKNOWN_ERROR = 491;
-
- /**
- * This download couldn't be completed because of an HTTP
- * redirect response that the download manager couldn't
- * handle.
- */
- public static final int STATUS_UNHANDLED_REDIRECT = 493;
-
- /**
- * This download couldn't be completed due to insufficient storage
- * space. Typically, this is because the SD card is full.
- */
- public static final int STATUS_INSUFFICIENT_SPACE_ERROR = 498;
-
- /**
- * This download couldn't be completed because no external storage
- * device was found. Typically, this is because the SD card is not
- * mounted.
- */
- public static final int STATUS_DEVICE_NOT_FOUND_ERROR = 499;
-
- /**
- * Returns whether the status is a success (i.e. 2xx).
- */
- public static boolean isStatusSuccess(int status) {
- return (status >= 200 && status < 300);
- }
-
- /**
- * Returns whether the status is an error (i.e. 4xx or 5xx).
- */
- public static boolean isStatusError(int status) {
- return (status >= 400 && status < 600);
- }
-
- /**
- * Download destinations
- */
-
- /**
- * This download will be saved to the external storage. This is the
- * default behavior, and should be used for any file that the user
- * can freely access, copy, delete. Even with that destination,
- * unencrypted DRM files are saved in secure internal storage.
- * Downloads to the external destination only write files for which
- * there is a registered handler. The resulting files are accessible
- * by filename to all applications.
- */
- public static final int DOWNLOAD_DESTINATION_EXTERNAL = 1;
-
- /**
- * This download will be saved to the download manager's private
- * partition. This is the behavior used by applications that want to
- * download private files that are used and deleted soon after they
- * get downloaded. All file types are allowed, and only the initiating
- * application can access the file (indirectly through a content
- * provider). This requires the
- * android.permission.ACCESS_DOWNLOAD_MANAGER_ADVANCED permission.
- */
- public static final int DOWNLOAD_DESTINATION_CACHE = 2;
-
- /**
- * This download will be saved to the download manager's private
- * partition and will be purged as necessary to make space. This is
- * for private files (similar to CACHE_PARTITION) that aren't deleted
- * immediately after they are used, and are kept around by the download
- * manager as long as space is available.
- */
- public static final int DOWNLOAD_DESTINATION_CACHE_PURGEABLE = 3;
-
-
- /**
- * An invalid download id
- */
- public static final long DOWNLOAD_ID_INVALID = -1;
-
-
- /**
- * Broadcast Action: this is sent by the download manager to the app
- * that had initiated a download when that download completes. The
- * download's content: uri is specified in the intent's data.
- */
- public static final String ACTION_DOWNLOAD_COMPLETED =
- "android.intent.action.DOWNLOAD_COMPLETED";
-
- /**
- * If extras are specified when requesting a download they will be provided in the intent that
- * is sent to the specified class and package when a download has finished.
- * <P>Type: TEXT</P>
- * <P>Owner can Init</P>
- */
- public static final String COLUMN_NOTIFICATION_EXTRAS = "notificationextras";
-
-
- /**
- * Status class for a download
- */
- public static final class StatusInfo {
- public boolean completed = false;
- /** The filename of the active download. */
- public String filename = null;
- /** An opaque id for the download */
- public long id = DOWNLOAD_ID_INVALID;
- /** An opaque status code for the download */
- public int statusCode = -1;
- /** Approximate number of bytes downloaded so far, for debugging purposes. */
- public long bytesSoFar = -1;
-
- /**
- * Returns whether the download is completed
- * @return a boolean whether the download is complete.
- */
- public boolean isComplete() {
- return android.provider.Downloads.Impl.isStatusCompleted(statusCode);
- }
-
- /**
- * Returns whether the download is successful
- * @return a boolean whether the download is successful.
- */
- public boolean isSuccessful() {
- return android.provider.Downloads.Impl.isStatusSuccess(statusCode);
- }
- }
-
- /**
- * Class to access initiate and query download by server uri
- */
- public static final class ByUri extends DownloadBase {
- /** @hide */
- private ByUri() {}
-
- /**
- * Query where clause by app data.
- * @hide
- */
- private static final String QUERY_WHERE_APP_DATA_CLAUSE =
- android.provider.Downloads.Impl.COLUMN_APP_DATA + "=?";
-
- /**
- * Gets a Cursor pointing to the download(s) of the current system update.
- * @hide
- */
- private static final Cursor getCurrentOtaDownloads(Context context, String url) {
- return context.getContentResolver().query(
- android.provider.Downloads.Impl.CONTENT_URI,
- DOWNLOADS_PROJECTION,
- QUERY_WHERE_APP_DATA_CLAUSE,
- new String[] {url},
- null);
- }
-
- /**
- * Returns a StatusInfo with the result of trying to download the
- * given URL. Returns null if no attempts have been made.
- */
- public static final StatusInfo getStatus(
- Context context,
- String url,
- long redownload_threshold) {
- StatusInfo result = null;
- boolean hasFailedDownload = false;
- long failedDownloadModificationTime = 0;
- Cursor c = getCurrentOtaDownloads(context, url);
- try {
- while (c != null && c.moveToNext()) {
- if (result == null) {
- result = new StatusInfo();
- }
- int status = getStatusOfDownload(c, redownload_threshold);
- if (status == STATUS_DOWNLOADING_UPDATE ||
- status == STATUS_DOWNLOADED_UPDATE) {
- result.completed = (status == STATUS_DOWNLOADED_UPDATE);
- result.filename = c.getString(DOWNLOADS_COLUMN_FILENAME);
- result.id = c.getLong(DOWNLOADS_COLUMN_ID);
- result.statusCode = c.getInt(DOWNLOADS_COLUMN_STATUS);
- result.bytesSoFar = c.getLong(DOWNLOADS_COLUMN_CURRENT_BYTES);
- return result;
- }
-
- long modTime = c.getLong(DOWNLOADS_COLUMN_LAST_MODIFICATION);
- if (hasFailedDownload &&
- modTime < failedDownloadModificationTime) {
- // older than the one already in result; skip it.
- continue;
- }
-
- hasFailedDownload = true;
- failedDownloadModificationTime = modTime;
- result.statusCode = c.getInt(DOWNLOADS_COLUMN_STATUS);
- result.bytesSoFar = c.getLong(DOWNLOADS_COLUMN_CURRENT_BYTES);
- }
- } finally {
- if (c != null) {
- c.close();
- }
- }
- return result;
- }
-
- /**
- * Query where clause for general querying.
- */
- private static final String QUERY_WHERE_CLAUSE =
- android.provider.Downloads.Impl.COLUMN_NOTIFICATION_PACKAGE + "=? AND " +
- android.provider.Downloads.Impl.COLUMN_NOTIFICATION_CLASS + "=?";
-
- /**
- * Delete all the downloads for a package/class pair.
- */
- public static final void removeAllDownloadsByPackage(
- Context context,
- String notification_package,
- String notification_class) {
- context.getContentResolver().delete(
- android.provider.Downloads.Impl.CONTENT_URI,
- QUERY_WHERE_CLAUSE,
- new String[] { notification_package, notification_class });
- }
-
- /**
- * The column for the id in the Cursor returned by
- * getProgressCursor()
- */
- public static final int getProgressColumnId() {
- return 0;
- }
-
- /**
- * The column for the current byte count in the Cursor returned by
- * getProgressCursor()
- */
- public static final int getProgressColumnCurrentBytes() {
- return 1;
- }
-
- /**
- * The column for the total byte count in the Cursor returned by
- * getProgressCursor()
- */
- public static final int getProgressColumnTotalBytes() {
- return 2;
- }
-
- /** @hide */
- private static final String[] PROJECTION = {
- BaseColumns._ID,
- android.provider.Downloads.Impl.COLUMN_CURRENT_BYTES,
- android.provider.Downloads.Impl.COLUMN_TOTAL_BYTES
- };
-
- /**
- * Returns a Cursor representing the progress of the download identified by the ID.
- */
- public static final Cursor getProgressCursor(Context context, long id) {
- Uri downloadUri = Uri.withAppendedPath(android.provider.Downloads.Impl.CONTENT_URI,
- String.valueOf(id));
- return context.getContentResolver().query(downloadUri, PROJECTION, null, null, null);
- }
- }
-
- /**
- * Class to access downloads by opaque download id
- */
- public static final class ById extends DownloadBase {
- /** @hide */
- private ById() {}
-
- /**
- * Get the mime tupe of the download specified by the download id
- */
- public static String getMimeTypeForId(Context context, long downloadId) {
- ContentResolver cr = context.getContentResolver();
-
- String mimeType = null;
- Cursor downloadCursor = null;
-
- try {
- Uri downloadUri = getDownloadUri(downloadId);
-
- downloadCursor = cr.query(
- downloadUri, new String[]{android.provider.Downloads.Impl.COLUMN_MIME_TYPE},
- null, null, null);
- if (downloadCursor.moveToNext()) {
- mimeType = downloadCursor.getString(0);
- }
- } finally {
- if (downloadCursor != null) downloadCursor.close();
- }
- return mimeType;
- }
-
- /**
- * Delete a download by Id
- */
- public static void deleteDownload(Context context, long downloadId) {
- ContentResolver cr = context.getContentResolver();
-
- String mimeType = null;
-
- Uri downloadUri = getDownloadUri(downloadId);
-
- cr.delete(downloadUri, null, null);
- }
-
- /**
- * Open a filedescriptor to a particular download
- */
- public static ParcelFileDescriptor openDownload(
- Context context, long downloadId, String mode)
- throws FileNotFoundException
- {
- ContentResolver cr = context.getContentResolver();
-
- String mimeType = null;
-
- Uri downloadUri = getDownloadUri(downloadId);
-
- return cr.openFileDescriptor(downloadUri, mode);
- }
-
- /**
- * Open a stream to a particular download
- */
- public static InputStream openDownloadStream(Context context, long downloadId)
- throws FileNotFoundException, IOException
- {
- ContentResolver cr = context.getContentResolver();
-
- String mimeType = null;
-
- Uri downloadUri = getDownloadUri(downloadId);
-
- return cr.openInputStream(downloadUri);
- }
-
- private static Uri getDownloadUri(long downloadId) {
- return Uri.parse(android.provider.Downloads.Impl.CONTENT_URI + "/" + downloadId);
- }
-
- /**
- * Returns a StatusInfo with the result of trying to download the
- * given URL. Returns null if no attempts have been made.
- */
- public static final StatusInfo getStatus(
- Context context,
- long downloadId) {
- StatusInfo result = null;
- boolean hasFailedDownload = false;
- long failedDownloadModificationTime = 0;
-
- Uri downloadUri = getDownloadUri(downloadId);
-
- ContentResolver cr = context.getContentResolver();
-
- Cursor c = cr.query(downloadUri, DOWNLOADS_PROJECTION, null /* selection */,
- null /* selection args */, null /* sort order */);
- try {
- if (c == null || !c.moveToNext()) {
- return result;
- }
-
- if (result == null) {
- result = new StatusInfo();
- }
- int status = getStatusOfDownload(c,0);
- if (status == STATUS_DOWNLOADING_UPDATE ||
- status == STATUS_DOWNLOADED_UPDATE) {
- result.completed = (status == STATUS_DOWNLOADED_UPDATE);
- result.filename = c.getString(DOWNLOADS_COLUMN_FILENAME);
- result.id = c.getLong(DOWNLOADS_COLUMN_ID);
- result.statusCode = c.getInt(DOWNLOADS_COLUMN_STATUS);
- result.bytesSoFar = c.getLong(DOWNLOADS_COLUMN_CURRENT_BYTES);
- return result;
- }
-
- long modTime = c.getLong(DOWNLOADS_COLUMN_LAST_MODIFICATION);
-
- result.statusCode = c.getInt(DOWNLOADS_COLUMN_STATUS);
- result.bytesSoFar = c.getLong(DOWNLOADS_COLUMN_CURRENT_BYTES);
- } finally {
- if (c != null) {
- c.close();
- }
- }
- return result;
- }
- }
-
-
- /**
- * Base class with common functionality for the various download classes
- */
- public static class DownloadBase {
- /** @hide */
- DownloadBase() {}
-
- /**
- * Initiate a download where the download will be tracked by its URI.
- */
- public static long startDownloadByUri(
- Context context,
- String url,
- String cookieData,
- boolean showDownload,
- int downloadDestination,
- boolean allowRoaming,
- boolean skipIntegrityCheck,
- String title,
- String notification_package,
- String notification_class,
- String notification_extras) {
- ContentResolver cr = context.getContentResolver();
-
- // Tell download manager to start downloading update.
- ContentValues values = new ContentValues();
- values.put(android.provider.Downloads.Impl.COLUMN_URI, url);
- values.put(android.provider.Downloads.Impl.COLUMN_COOKIE_DATA, cookieData);
- values.put(android.provider.Downloads.Impl.COLUMN_VISIBILITY,
- showDownload ? android.provider.Downloads.Impl.VISIBILITY_VISIBLE
- : android.provider.Downloads.Impl.VISIBILITY_HIDDEN);
- if (title != null) {
- values.put(android.provider.Downloads.Impl.COLUMN_TITLE, title);
- }
- values.put(android.provider.Downloads.Impl.COLUMN_APP_DATA, url);
-
-
- // NOTE: destination should be seperated from whether the download
- // can happen when roaming
- int destination = android.provider.Downloads.Impl.DESTINATION_EXTERNAL;
- switch (downloadDestination) {
- case DOWNLOAD_DESTINATION_EXTERNAL:
- destination = android.provider.Downloads.Impl.DESTINATION_EXTERNAL;
- break;
- case DOWNLOAD_DESTINATION_CACHE:
- if (allowRoaming) {
- destination = android.provider.Downloads.Impl.DESTINATION_CACHE_PARTITION;
- } else {
- destination =
- android.provider.Downloads.Impl.DESTINATION_CACHE_PARTITION_NOROAMING;
- }
- break;
- case DOWNLOAD_DESTINATION_CACHE_PURGEABLE:
- destination =
- android.provider.Downloads.Impl.DESTINATION_CACHE_PARTITION_PURGEABLE;
- break;
- }
- values.put(android.provider.Downloads.Impl.COLUMN_DESTINATION, destination);
- values.put(android.provider.Downloads.Impl.COLUMN_NO_INTEGRITY,
- skipIntegrityCheck); // Don't check ETag
- if (notification_package != null && notification_class != null) {
- values.put(android.provider.Downloads.Impl.COLUMN_NOTIFICATION_PACKAGE,
- notification_package);
- values.put(android.provider.Downloads.Impl.COLUMN_NOTIFICATION_CLASS,
- notification_class);
-
- if (notification_extras != null) {
- values.put(android.provider.Downloads.Impl.COLUMN_NOTIFICATION_EXTRAS,
- notification_extras);
- }
- }
-
- Uri downloadUri = cr.insert(android.provider.Downloads.Impl.CONTENT_URI, values);
-
- long downloadId = DOWNLOAD_ID_INVALID;
- if (downloadUri != null) {
- downloadId = Long.parseLong(downloadUri.getLastPathSegment());
- }
- return downloadId;
- }
- }
-
- /** @hide */
- private static final int STATUS_INVALID = 0;
- /** @hide */
- private static final int STATUS_DOWNLOADING_UPDATE = 3;
- /** @hide */
- private static final int STATUS_DOWNLOADED_UPDATE = 4;
-
- /**
- * Column projection for the query to the download manager. This must match
- * with the constants DOWNLOADS_COLUMN_*.
- * @hide
- */
- private static final String[] DOWNLOADS_PROJECTION = {
- BaseColumns._ID,
- android.provider.Downloads.Impl.COLUMN_APP_DATA,
- android.provider.Downloads.Impl.COLUMN_STATUS,
- android.provider.Downloads.Impl._DATA,
- android.provider.Downloads.Impl.COLUMN_LAST_MODIFICATION,
- android.provider.Downloads.Impl.COLUMN_CURRENT_BYTES,
- };
-
- /**
- * The column index for the ID.
- * @hide
- */
- private static final int DOWNLOADS_COLUMN_ID = 0;
- /**
- * The column index for the URI.
- * @hide
- */
- private static final int DOWNLOADS_COLUMN_URI = 1;
- /**
- * The column index for the status code.
- * @hide
- */
- private static final int DOWNLOADS_COLUMN_STATUS = 2;
- /**
- * The column index for the filename.
- * @hide
- */
- private static final int DOWNLOADS_COLUMN_FILENAME = 3;
- /**
- * The column index for the last modification time.
- * @hide
- */
- private static final int DOWNLOADS_COLUMN_LAST_MODIFICATION = 4;
- /**
- * The column index for the number of bytes downloaded so far.
- * @hide
- */
- private static final int DOWNLOADS_COLUMN_CURRENT_BYTES = 5;
-
- /**
- * Gets the status of a download.
- *
- * @param c A Cursor pointing to a download. The URL column is assumed to be valid.
- * @return The status of the download.
- * @hide
- */
- private static final int getStatusOfDownload( Cursor c, long redownload_threshold) {
- int status = c.getInt(DOWNLOADS_COLUMN_STATUS);
- long realtime = SystemClock.elapsedRealtime();
-
- // TODO(dougz): special handling of 503, 404? (eg, special
- // explanatory messages to user)
-
- if (!android.provider.Downloads.Impl.isStatusCompleted(status)) {
- // Check if it's stuck
- long modified = c.getLong(DOWNLOADS_COLUMN_LAST_MODIFICATION);
- long now = System.currentTimeMillis();
- if (now < modified || now - modified > redownload_threshold) {
- return STATUS_INVALID;
- }
-
- return STATUS_DOWNLOADING_UPDATE;
- }
-
- if (android.provider.Downloads.Impl.isStatusError(status)) {
- return STATUS_INVALID;
- }
-
- String filename = c.getString(DOWNLOADS_COLUMN_FILENAME);
- if (filename == null) {
- return STATUS_INVALID;
- }
-
- return STATUS_DOWNLOADED_UPDATE;
- }
-
-
- /**
- * @hide
- */
- private Downloads() {}
-}
diff --git a/core/java/android/net/NetworkPolicy.java b/core/java/android/net/NetworkPolicy.java
index 5b94784ad518..c1f58a391e17 100644
--- a/core/java/android/net/NetworkPolicy.java
+++ b/core/java/android/net/NetworkPolicy.java
@@ -42,18 +42,20 @@ public class NetworkPolicy implements Parcelable, Comparable<NetworkPolicy> {
public long lastWarningSnooze;
public long lastLimitSnooze;
public boolean metered;
+ public boolean inferred;
private static final long DEFAULT_MTU = 1500;
+ @Deprecated
public NetworkPolicy(NetworkTemplate template, int cycleDay, String cycleTimezone,
long warningBytes, long limitBytes, boolean metered) {
this(template, cycleDay, cycleTimezone, warningBytes, limitBytes, SNOOZE_NEVER,
- SNOOZE_NEVER, metered);
+ SNOOZE_NEVER, metered, false);
}
public NetworkPolicy(NetworkTemplate template, int cycleDay, String cycleTimezone,
long warningBytes, long limitBytes, long lastWarningSnooze, long lastLimitSnooze,
- boolean metered) {
+ boolean metered, boolean inferred) {
this.template = checkNotNull(template, "missing NetworkTemplate");
this.cycleDay = cycleDay;
this.cycleTimezone = checkNotNull(cycleTimezone, "missing cycleTimezone");
@@ -62,6 +64,7 @@ public class NetworkPolicy implements Parcelable, Comparable<NetworkPolicy> {
this.lastWarningSnooze = lastWarningSnooze;
this.lastLimitSnooze = lastLimitSnooze;
this.metered = metered;
+ this.inferred = inferred;
}
public NetworkPolicy(Parcel in) {
@@ -73,6 +76,7 @@ public class NetworkPolicy implements Parcelable, Comparable<NetworkPolicy> {
lastWarningSnooze = in.readLong();
lastLimitSnooze = in.readLong();
metered = in.readInt() != 0;
+ inferred = in.readInt() != 0;
}
@Override
@@ -85,6 +89,7 @@ public class NetworkPolicy implements Parcelable, Comparable<NetworkPolicy> {
dest.writeLong(lastWarningSnooze);
dest.writeLong(lastLimitSnooze);
dest.writeInt(metered ? 1 : 0);
+ dest.writeInt(inferred ? 1 : 0);
}
@Override
@@ -134,7 +139,7 @@ public class NetworkPolicy implements Parcelable, Comparable<NetworkPolicy> {
@Override
public int hashCode() {
return Objects.hashCode(template, cycleDay, cycleTimezone, warningBytes, limitBytes,
- lastWarningSnooze, lastLimitSnooze, metered);
+ lastWarningSnooze, lastLimitSnooze, metered, inferred);
}
@Override
@@ -145,6 +150,7 @@ public class NetworkPolicy implements Parcelable, Comparable<NetworkPolicy> {
&& limitBytes == other.limitBytes
&& lastWarningSnooze == other.lastWarningSnooze
&& lastLimitSnooze == other.lastLimitSnooze && metered == other.metered
+ && inferred == other.inferred
&& Objects.equal(cycleTimezone, other.cycleTimezone)
&& Objects.equal(template, other.template);
}
@@ -156,7 +162,7 @@ public class NetworkPolicy implements Parcelable, Comparable<NetworkPolicy> {
return "NetworkPolicy[" + template + "]: cycleDay=" + cycleDay + ", cycleTimezone="
+ cycleTimezone + ", warningBytes=" + warningBytes + ", limitBytes=" + limitBytes
+ ", lastWarningSnooze=" + lastWarningSnooze + ", lastLimitSnooze="
- + lastLimitSnooze + ", metered=" + metered;
+ + lastLimitSnooze + ", metered=" + metered + ", inferred=" + inferred;
}
public static final Creator<NetworkPolicy> CREATOR = new Creator<NetworkPolicy>() {
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java
index 6139296ba049..770bf1c47ee9 100644
--- a/core/java/android/os/Process.java
+++ b/core/java/android/os/Process.java
@@ -98,6 +98,12 @@ public class Process {
public static final int SDCARD_RW_GID = 1015;
/**
+ * Defines the UID/GID for the group that controls VPN services.
+ * @hide
+ */
+ public static final int VPN_UID = 1016;
+
+ /**
* Defines the UID/GID for the NFC service process.
* @hide
*/
diff --git a/core/java/android/provider/Downloads.java b/core/java/android/provider/Downloads.java
index ba4804d10ecb..bd6170be19f8 100644
--- a/core/java/android/provider/Downloads.java
+++ b/core/java/android/provider/Downloads.java
@@ -17,6 +17,7 @@
package android.provider;
import android.app.DownloadManager;
+import android.content.Context;
import android.net.NetworkPolicyManager;
import android.net.Uri;
@@ -742,4 +743,19 @@ public final class Downloads {
public static final String INSERT_KEY_PREFIX = "http_header_";
}
}
+
+ /**
+ * Query where clause for general querying.
+ */
+ private static final String QUERY_WHERE_CLAUSE = Impl.COLUMN_NOTIFICATION_PACKAGE + "=? AND "
+ + Impl.COLUMN_NOTIFICATION_CLASS + "=?";
+
+ /**
+ * Delete all the downloads for a package/class pair.
+ */
+ public static final void removeAllDownloadsByPackage(
+ Context context, String notification_package, String notification_class) {
+ context.getContentResolver().delete(Impl.CONTENT_URI, QUERY_WHERE_CLAUSE,
+ new String[] { notification_package, notification_class });
+ }
}
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index d08a61f8132c..b98257cecadd 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -704,7 +704,7 @@ public abstract class HardwareRenderer {
return null;
}
- private void printConfig(EGLConfig config) {
+ private static void printConfig(EGLConfig config) {
int[] value = new int[1];
Log.d(LOG_TAG, "EGL configuration " + config + ":");
@@ -990,10 +990,11 @@ public abstract class HardwareRenderer {
}
if (invalidateNeeded) {
- if (mRedrawClip.isEmpty() || view.getParent() == null) {
- view.invalidate();
+ if (mRedrawClip.isEmpty()) {
+ attachInfo.mViewRootImpl.invalidate();
} else {
- view.getParent().invalidateChild(view, mRedrawClip);
+ attachInfo.mViewRootImpl.invalidateChildInParent(
+ null, mRedrawClip);
}
mRedrawClip.setEmpty();
}
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 6d1f207a4dcd..6c195c4b0170 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -698,14 +698,14 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
private static final int[] VISIBILITY_FLAGS = {VISIBLE, INVISIBLE, GONE};
/**
- * This view is enabled. Intrepretation varies by subclass.
+ * This view is enabled. Interpretation varies by subclass.
* Use with ENABLED_MASK when calling setFlags.
* {@hide}
*/
static final int ENABLED = 0x00000000;
/**
- * This view is disabled. Intrepretation varies by subclass.
+ * This view is disabled. Interpretation varies by subclass.
* Use with ENABLED_MASK when calling setFlags.
* {@hide}
*/
@@ -955,50 +955,6 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
static final int PARENT_SAVE_DISABLED_MASK = 0x20000000;
/**
- * Horizontal direction of this view is from Left to Right.
- * Use with {@link #setLayoutDirection}.
- */
- public static final int LAYOUT_DIRECTION_LTR = 0x00000000;
-
- /**
- * Horizontal direction of this view is from Right to Left.
- * Use with {@link #setLayoutDirection}.
- */
- public static final int LAYOUT_DIRECTION_RTL = 0x40000000;
-
- /**
- * Horizontal direction of this view is inherited from its parent.
- * Use with {@link #setLayoutDirection}.
- */
- public static final int LAYOUT_DIRECTION_INHERIT = 0x80000000;
-
- /**
- * Horizontal direction of this view is from deduced from the default language
- * script for the locale. Use with {@link #setLayoutDirection}.
- */
- public static final int LAYOUT_DIRECTION_LOCALE = 0xC0000000;
-
- /**
- * Mask for use with setFlags indicating bits used for horizontalDirection.
- * {@hide}
- */
- static final int LAYOUT_DIRECTION_MASK = 0xC0000000;
-
- /*
- * Array of horizontal direction flags for mapping attribute "horizontalDirection" to correct
- * flag value.
- * {@hide}
- */
- private static final int[] LAYOUT_DIRECTION_FLAGS = {LAYOUT_DIRECTION_LTR,
- LAYOUT_DIRECTION_RTL, LAYOUT_DIRECTION_INHERIT, LAYOUT_DIRECTION_LOCALE};
-
- /**
- * Default horizontalDirection.
- * {@hide}
- */
- private static final int LAYOUT_DIRECTION_DEFAULT = LAYOUT_DIRECTION_INHERIT;
-
- /**
* View flag indicating whether {@link #addFocusables(ArrayList, int, int)}
* should add all focusable Views regardless if they are focusable in touch mode.
*/
@@ -1503,7 +1459,7 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
* apps.
* @hide
*/
- public static final boolean USE_DISPLAY_LIST_PROPERTIES = false;
+ public static final boolean USE_DISPLAY_LIST_PROPERTIES = true;
/**
* Map used to store views' tags.
@@ -1748,19 +1704,73 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
static final int DRAG_HOVERED = 0x00000002;
/**
- * Indicates whether the view layout direction has been resolved and drawn to the
+ * Horizontal layout direction of this view is from Left to Right.
+ * Use with {@link #setLayoutDirection}.
+ */
+ public static final int LAYOUT_DIRECTION_LTR = 0x00000001;
+
+ /**
+ * Horizontal layout direction of this view is from Right to Left.
+ * Use with {@link #setLayoutDirection}.
+ */
+ public static final int LAYOUT_DIRECTION_RTL = 0x00000002;
+
+ /**
+ * Horizontal layout direction of this view is inherited from its parent.
+ * Use with {@link #setLayoutDirection}.
+ */
+ public static final int LAYOUT_DIRECTION_INHERIT = 0x00000004;
+
+ /**
+ * Horizontal layout direction of this view is from deduced from the default language
+ * script for the locale. Use with {@link #setLayoutDirection}.
+ */
+ public static final int LAYOUT_DIRECTION_LOCALE = 0x00000008;
+
+ /**
+ * Bit shift to get the horizontal layout direction. (bits after DRAG_HOVERED)
+ * @hide
+ */
+ static final int LAYOUT_DIRECTION_MASK_SHIFT = 2;
+
+ /**
+ * Mask for use with private flags indicating bits used for horizontal layout direction.
+ * @hide
+ */
+ static final int LAYOUT_DIRECTION_MASK = 0x0000000F << LAYOUT_DIRECTION_MASK_SHIFT;
+
+ /**
+ * Indicates whether the view horizontal layout direction has been resolved and drawn to the
* right-to-left direction.
- *
* @hide
*/
- static final int LAYOUT_DIRECTION_RESOLVED_RTL = 0x00000004;
+ static final int LAYOUT_DIRECTION_RESOLVED_RTL = 0x00000010 << LAYOUT_DIRECTION_MASK_SHIFT;
/**
- * Indicates whether the view layout direction has been resolved.
- *
+ * Indicates whether the view horizontal layout direction has been resolved.
* @hide
*/
- static final int LAYOUT_DIRECTION_RESOLVED = 0x00000008;
+ static final int LAYOUT_DIRECTION_RESOLVED = 0x00000020 << LAYOUT_DIRECTION_MASK_SHIFT;
+
+ /**
+ * Mask for use with private flags indicating bits used for resolved horizontal layout direction.
+ * @hide
+ */
+ static final int LAYOUT_DIRECTION_RESOLVED_MASK = 0x00000030 << LAYOUT_DIRECTION_MASK_SHIFT;
+
+ /*
+ * Array of horizontal layout direction flags for mapping attribute "layoutDirection" to correct
+ * flag value.
+ * @hide
+ */
+ private static final int[] LAYOUT_DIRECTION_FLAGS = {LAYOUT_DIRECTION_LTR,
+ LAYOUT_DIRECTION_RTL, LAYOUT_DIRECTION_INHERIT, LAYOUT_DIRECTION_LOCALE};
+
+ /**
+ * Default horizontal layout direction.
+ * @hide
+ */
+ private static final int LAYOUT_DIRECTION_DEFAULT = LAYOUT_DIRECTION_INHERIT;
/**
@@ -1770,7 +1780,7 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
*
* @hide
*/
- static final int HAS_TRANSIENT_STATE = 0x00000010;
+ static final int HAS_TRANSIENT_STATE = 0x00000100;
/* End of masks for mPrivateFlags2 */
@@ -2739,7 +2749,8 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
public View(Context context) {
mContext = context;
mResources = context != null ? context.getResources() : null;
- mViewFlags = SOUND_EFFECTS_ENABLED | HAPTIC_FEEDBACK_ENABLED | LAYOUT_DIRECTION_INHERIT;
+ mViewFlags = SOUND_EFFECTS_ENABLED | HAPTIC_FEEDBACK_ENABLED;
+ mPrivateFlags2 |= (LAYOUT_DIRECTION_DEFAULT << LAYOUT_DIRECTION_MASK_SHIFT);
mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
setOverScrollMode(OVER_SCROLL_IF_CONTENT_SCROLLS);
mUserPaddingStart = -1;
@@ -2949,17 +2960,13 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
}
break;
case com.android.internal.R.styleable.View_layoutDirection:
- // Clear any HORIZONTAL_DIRECTION flag already set
- viewFlagValues &= ~LAYOUT_DIRECTION_MASK;
- // Set the HORIZONTAL_DIRECTION flags depending on the value of the attribute
+ // Clear any layout direction flags (included resolved bits) already set
+ mPrivateFlags2 &= ~(LAYOUT_DIRECTION_MASK | LAYOUT_DIRECTION_RESOLVED_MASK);
+ // Set the layout direction flags depending on the value of the attribute
final int layoutDirection = a.getInt(attr, -1);
- if (layoutDirection != -1) {
- viewFlagValues |= LAYOUT_DIRECTION_FLAGS[layoutDirection];
- } else {
- // Set to default (LAYOUT_DIRECTION_INHERIT)
- viewFlagValues |= LAYOUT_DIRECTION_DEFAULT;
- }
- viewFlagMasks |= LAYOUT_DIRECTION_MASK;
+ final int value = (layoutDirection != -1) ?
+ LAYOUT_DIRECTION_FLAGS[layoutDirection] : LAYOUT_DIRECTION_DEFAULT;
+ mPrivateFlags2 |= (value << LAYOUT_DIRECTION_MASK_SHIFT);
break;
case com.android.internal.R.styleable.View_drawingCacheQuality:
final int cacheQuality = a.getInt(attr, 0);
@@ -4882,7 +4889,7 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
@ViewDebug.IntToString(from = LAYOUT_DIRECTION_LOCALE, to = "LOCALE")
})
public int getLayoutDirection() {
- return mViewFlags & LAYOUT_DIRECTION_MASK;
+ return (mPrivateFlags2 & LAYOUT_DIRECTION_MASK) >> LAYOUT_DIRECTION_MASK_SHIFT;
}
/**
@@ -4899,9 +4906,14 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
@RemotableViewMethod
public void setLayoutDirection(int layoutDirection) {
if (getLayoutDirection() != layoutDirection) {
+ // Reset the current layout direction
+ mPrivateFlags2 &= ~LAYOUT_DIRECTION_MASK;
+ // Reset the current resolved layout direction
resetResolvedLayoutDirection();
- // Setting the flag will also request a layout.
- setFlags(layoutDirection, LAYOUT_DIRECTION_MASK);
+ // Set the new layout direction (filtered) and ask for a layout pass
+ mPrivateFlags2 |=
+ ((layoutDirection << LAYOUT_DIRECTION_MASK_SHIFT) & LAYOUT_DIRECTION_MASK);
+ requestLayout();
}
}
@@ -4909,11 +4921,11 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
* Returns the resolved layout direction for this view.
*
* @return {@link #LAYOUT_DIRECTION_RTL} if the layout direction is RTL or returns
- * {@link #LAYOUT_DIRECTION_LTR} id the layout direction is not RTL.
+ * {@link #LAYOUT_DIRECTION_LTR} if the layout direction is not RTL.
*/
@ViewDebug.ExportedProperty(category = "layout", mapping = {
- @ViewDebug.IntToString(from = LAYOUT_DIRECTION_LTR, to = "RESOLVED_DIRECTION_LTR"),
- @ViewDebug.IntToString(from = LAYOUT_DIRECTION_RTL, to = "RESOLVED_DIRECTION_RTL")
+ @ViewDebug.IntToString(from = LAYOUT_DIRECTION_LTR, to = "RESOLVED_DIRECTION_LTR"),
+ @ViewDebug.IntToString(from = LAYOUT_DIRECTION_RTL, to = "RESOLVED_DIRECTION_RTL")
})
public int getResolvedLayoutDirection() {
resolveLayoutDirectionIfNeeded();
@@ -4922,8 +4934,8 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
}
/**
- * <p>Indicates whether or not this view's layout is right-to-left. This is resolved from
- * layout attribute and/or the inherited value from the parent.</p>
+ * Indicates whether or not this view's layout is right-to-left. This is resolved from
+ * layout attribute and/or the inherited value from the parent
*
* @return true if the layout is right-to-left.
*/
@@ -6940,10 +6952,6 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
mParent.recomputeViewAttributes(this);
}
}
-
- if ((changed & LAYOUT_DIRECTION_MASK) != 0) {
- requestLayout();
- }
}
/**
@@ -9834,7 +9842,7 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
if ((mPrivateFlags2 & LAYOUT_DIRECTION_RESOLVED) == LAYOUT_DIRECTION_RESOLVED) return;
// Clear any previous layout direction resolution
- mPrivateFlags2 &= ~LAYOUT_DIRECTION_RESOLVED_RTL;
+ mPrivateFlags2 &= ~LAYOUT_DIRECTION_RESOLVED_MASK;
// Set resolved depending on layout direction
switch (getLayoutDirection()) {
@@ -9966,8 +9974,8 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
* when reset is done.
*/
public void resetResolvedLayoutDirection() {
- // Reset the current View resolution
- mPrivateFlags2 &= ~LAYOUT_DIRECTION_RESOLVED;
+ // Reset the current resolved bits
+ mPrivateFlags2 &= ~LAYOUT_DIRECTION_RESOLVED_MASK;
onResolvedLayoutDirectionReset();
// Reset also the text direction
resetResolvedTextDirection();
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 42426b98ffd8..b8fbf1787164 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -2679,15 +2679,6 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
return child.draw(canvas, this, drawingTime);
}
- @Override
- public void requestLayout() {
- if (mChildrenCount > 0 && getAccessibilityNodeProvider() != null) {
- throw new IllegalStateException("Views with AccessibilityNodeProvider"
- + " can't have children.");
- }
- super.requestLayout();
- }
-
/**
*
* @param enabled True if children should be drawn with layers, false otherwise.
@@ -3109,11 +3100,6 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
private void addViewInner(View child, int index, LayoutParams params,
boolean preventRequestLayout) {
- if (getAccessibilityNodeProvider() != null) {
- throw new IllegalStateException("Views with AccessibilityNodeProvider"
- + " can't have children.");
- }
-
if (mTransition != null) {
// Don't prevent other add transitions from completing, but cancel remove
// transitions to let them complete the process before we add to the container
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 04ad649bc2b9..4eb70ab17a70 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -841,7 +841,9 @@ public final class ViewRootImpl implements ViewParent,
localDirty.union(dirty.left, dirty.top, dirty.right, dirty.bottom);
// Intersect with the bounds of the window to skip
// updates that lie outside of the visible region
- localDirty.intersect(0, 0, mWidth, mHeight);
+ final float appScale = mAttachInfo.mApplicationScale;
+ localDirty.intersect(0, 0,
+ (int) (mWidth * appScale + 0.5f), (int) (mHeight * appScale + 0.5f));
if (!mWillDrawSoon) {
scheduleTraversals();
diff --git a/core/java/android/webkit/BrowserFrame.java b/core/java/android/webkit/BrowserFrame.java
index dbcea71ef180..72af251fe05a 100644
--- a/core/java/android/webkit/BrowserFrame.java
+++ b/core/java/android/webkit/BrowserFrame.java
@@ -448,7 +448,7 @@ class BrowserFrame extends Handler {
// loadType is not used yet
if (isMainFrame) {
mCommitted = true;
- mWebViewCore.getWebView().mViewManager.postResetStateAll();
+ mWebViewCore.getWebViewClassic().mViewManager.postResetStateAll();
}
}
@@ -910,7 +910,7 @@ class BrowserFrame extends Handler {
* Close this frame and window.
*/
private void closeWindow(WebViewCore w) {
- mCallbackProxy.onCloseWindow(w.getWebView());
+ mCallbackProxy.onCloseWindow(w.getWebViewClassic());
}
// XXX: Must match PolicyAction in FrameLoaderTypes.h in webcore
diff --git a/core/java/android/webkit/HTML5Audio.java b/core/java/android/webkit/HTML5Audio.java
index 8e1f57322864..689884f7aba9 100644
--- a/core/java/android/webkit/HTML5Audio.java
+++ b/core/java/android/webkit/HTML5Audio.java
@@ -183,7 +183,7 @@ class HTML5Audio extends Handler
resetMediaPlayer();
mContext = webViewCore.getContext();
mIsPrivateBrowsingEnabledGetter = new IsPrivateBrowsingEnabledGetter(
- webViewCore.getContext().getMainLooper(), webViewCore.getWebView());
+ webViewCore.getContext().getMainLooper(), webViewCore.getWebViewClassic());
}
private void resetMediaPlayer() {
diff --git a/core/java/android/webkit/HTML5VideoViewProxy.java b/core/java/android/webkit/HTML5VideoViewProxy.java
index 1644b0671ad2..5fa4badda334 100644
--- a/core/java/android/webkit/HTML5VideoViewProxy.java
+++ b/core/java/android/webkit/HTML5VideoViewProxy.java
@@ -146,6 +146,12 @@ class HTML5VideoViewProxy extends Handler
// Save the inline video info and inherit it in the full screen
int savePosition = 0;
if (mHTML5VideoView != null) {
+ // We don't allow enter full screen mode while the previous
+ // full screen video hasn't finished yet.
+ if (!mHTML5VideoView.fullScreenExited() && mHTML5VideoView.isFullScreenMode()) {
+ Log.w(LOGTAG, "Try to reenter the full screen mode");
+ return;
+ }
// If we are playing the same video, then it is better to
// save the current position.
if (layerId == mHTML5VideoView.getVideoLayerId()) {
@@ -718,7 +724,7 @@ class HTML5VideoViewProxy extends Handler
* @return a new HTML5VideoViewProxy object.
*/
public static HTML5VideoViewProxy getInstance(WebViewCore webViewCore, int nativePtr) {
- return new HTML5VideoViewProxy(webViewCore.getWebView(), nativePtr);
+ return new HTML5VideoViewProxy(webViewCore.getWebViewClassic(), nativePtr);
}
/* package */ WebViewClassic getWebView() {
diff --git a/core/java/android/webkit/WebSettingsClassic.java b/core/java/android/webkit/WebSettingsClassic.java
index 6850eea538ff..7e385701837a 100644
--- a/core/java/android/webkit/WebSettingsClassic.java
+++ b/core/java/android/webkit/WebSettingsClassic.java
@@ -1638,7 +1638,7 @@ public class WebSettingsClassic extends WebSettings {
*/
public void setProperty(String key, String value) {
if (mWebView.nativeSetProperty(key, value)) {
- mWebView.contentInvalidateAll();
+ mWebView.invalidate();
}
}
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 5e094161a848..dd373de6cf6f 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -21,6 +21,7 @@ import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.Canvas;
+import android.graphics.Paint;
import android.graphics.Picture;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
@@ -1980,4 +1981,10 @@ public class WebView extends AbsoluteLayout
public void setBackgroundColor(int color) {
mProvider.getViewDelegate().setBackgroundColor(color);
}
+
+ @Override
+ public void setLayerType(int layerType, Paint paint) {
+ super.setLayerType(layerType, paint);
+ mProvider.getViewDelegate().setLayerType(layerType, paint);
+ }
}
diff --git a/core/java/android/webkit/WebViewClassic.java b/core/java/android/webkit/WebViewClassic.java
index e5434cec3356..13a2c94e7832 100644
--- a/core/java/android/webkit/WebViewClassic.java
+++ b/core/java/android/webkit/WebViewClassic.java
@@ -5638,6 +5638,7 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
addAccessibilityApisToJavaScript();
mTouchEventQueue.reset();
+ updateHwAccelerated();
}
@Override
@@ -5657,6 +5658,7 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
}
removeAccessibilityApisFromJavaScript();
+ updateHwAccelerated();
}
@Override
@@ -6221,6 +6223,7 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
ted.mReprocess = mDeferTouchProcess;
ted.mNativeLayer = mCurrentScrollingLayerId;
ted.mNativeLayerRect.set(mScrollingLayerRect);
+ ted.mMotionEvent = MotionEvent.obtain(ev);
ted.mSequence = mTouchEventQueue.nextTouchSequence();
mTouchEventQueue.preQueueTouchEventData(ted);
mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted);
@@ -7296,10 +7299,6 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
}
}
- void sendPluginDrawMsg() {
- mWebViewCore.sendMessage(EventHub.PLUGIN_SURFACE_READY);
- }
-
/*
* Return true if the rect (e.g. plugin) is fully visible and maximized
* inside the WebView.
@@ -9359,6 +9358,30 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
nativeDiscardAllTextures();
}
+ @Override
+ public void setLayerType(int layerType, Paint paint) {
+ updateHwAccelerated();
+ }
+
+ private void updateHwAccelerated() {
+ if (mNativeClass == 0) {
+ return;
+ }
+ boolean hwAccelerated = false;
+ if (mWebView.isHardwareAccelerated()
+ && mWebView.getLayerType() != View.LAYER_TYPE_SOFTWARE) {
+ hwAccelerated = true;
+ }
+ int result = nativeSetHwAccelerated(mNativeClass, hwAccelerated);
+ if (mWebViewCore == null || mBlockWebkitViewMessages) {
+ return;
+ }
+ if (result == 1) {
+ // Sync layers
+ mWebViewCore.layersDraw();
+ }
+ }
+
/**
* Begin collecting per-tile profiling data
*
@@ -9480,4 +9503,6 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
private static native boolean nativeIsBaseFirst(int instance);
private static native void nativeMapLayerRect(int instance, int layerId,
Rect rect);
+ // Returns 1 if a layer sync is needed, else 0
+ private static native int nativeSetHwAccelerated(int instance, boolean hwAccelerated);
}
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index d784b08390fd..a36ce06988eb 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -71,9 +71,8 @@ public final class WebViewCore {
* WebViewCore always executes in the same thread as the native webkit.
*/
- // The WebView that corresponds to this WebViewCore.
- // TODO: rename this field (and its getter) to mWebViewClassic or mWebViewImpl.
- private WebViewClassic mWebView;
+ // The WebViewClassic that corresponds to this WebViewCore.
+ private WebViewClassic mWebViewClassic;
// Proxy for handling callbacks from native code
private final CallbackProxy mCallbackProxy;
// Settings object for maintaining all settings
@@ -149,7 +148,7 @@ public final class WebViewCore {
Map<String, Object> javascriptInterfaces) {
// No need to assign this in the WebCore thread.
mCallbackProxy = proxy;
- mWebView = w;
+ mWebViewClassic = w;
mJavascriptInterfaces = javascriptInterfaces;
// This context object is used to initialize the WebViewCore during
// subwindow creation.
@@ -182,7 +181,7 @@ public final class WebViewCore {
// ready.
mEventHub = new EventHub();
// Create a WebSettings object for maintaining all settings
- mSettings = new WebSettingsClassic(mContext, mWebView);
+ mSettings = new WebSettingsClassic(mContext, mWebViewClassic);
// The WebIconDatabase needs to be initialized within the UI thread so
// just request the instance here.
WebIconDatabase.getInstance();
@@ -235,8 +234,8 @@ public final class WebViewCore {
// Send a message back to WebView to tell it that we have set up the
// WebCore thread.
- if (mWebView != null) {
- Message.obtain(mWebView.mPrivateHandler,
+ if (mWebViewClassic != null) {
+ Message.obtain(mWebViewClassic.mPrivateHandler,
WebViewClassic.WEBCORE_INITIALIZED_MSG_ID,
mNativeClass, 0).sendToTarget();
}
@@ -331,8 +330,8 @@ public final class WebViewCore {
* @param nodePointer The node which just blurred.
*/
private void formDidBlur(int nodePointer) {
- if (mWebView == null) return;
- Message.obtain(mWebView.mPrivateHandler, WebViewClassic.FORM_DID_BLUR,
+ if (mWebViewClassic == null) return;
+ Message.obtain(mWebViewClassic.mPrivateHandler, WebViewClassic.FORM_DID_BLUR,
nodePointer, 0).sendToTarget();
}
@@ -340,8 +339,8 @@ public final class WebViewCore {
* Called by JNI when the focus node changed.
*/
private void focusNodeChanged(int nodePointer, WebKitHitTest hitTest) {
- if (mWebView == null) return;
- mWebView.mPrivateHandler.obtainMessage(WebViewClassic.FOCUS_NODE_CHANGED,
+ if (mWebViewClassic == null) return;
+ mWebViewClassic.mPrivateHandler.obtainMessage(WebViewClassic.FOCUS_NODE_CHANGED,
nodePointer, 0, hitTest).sendToTarget();
}
@@ -349,8 +348,8 @@ public final class WebViewCore {
* Called by JNI to advance focus to the next view.
*/
private void chromeTakeFocus(int webkitDirection) {
- if (mWebView == null) return;
- Message m = mWebView.mPrivateHandler.obtainMessage(
+ if (mWebViewClassic == null) return;
+ Message m = mWebViewClassic.mPrivateHandler.obtainMessage(
WebViewClassic.TAKE_FOCUS);
m.arg1 = mapDirection(webkitDirection);
m.sendToTarget();
@@ -561,8 +560,8 @@ public final class WebViewCore {
* Notify the webview that we want to display the video layer fullscreen.
*/
protected void enterFullscreenForVideoLayer(int layerId, String url) {
- if (mWebView == null) return;
- Message message = Message.obtain(mWebView.mPrivateHandler,
+ if (mWebViewClassic == null) return;
+ Message message = Message.obtain(mWebViewClassic.mPrivateHandler,
WebViewClassic.ENTER_FULLSCREEN_VIDEO, layerId, 0);
message.obj = url;
message.sendToTarget();
@@ -573,8 +572,8 @@ public final class WebViewCore {
* This is called through JNI by webcore.
*/
protected void exitFullscreenVideo() {
- if (mWebView == null) return;
- Message message = Message.obtain(mWebView.mPrivateHandler,
+ if (mWebViewClassic == null) return;
+ Message message = Message.obtain(mWebViewClassic.mPrivateHandler,
WebViewClassic.EXIT_FULLSCREEN_VIDEO);
message.sendToTarget();
}
@@ -1256,7 +1255,7 @@ public final class WebViewCore {
return;
}
- if (mWebView == null || mNativeClass == 0) {
+ if (mWebViewClassic == null || mNativeClass == 0) {
if (DebugFlags.WEB_VIEW_CORE) {
Log.w(LOGTAG, "Rejecting message " + msg.what
+ " because we are destroyed");
@@ -1294,7 +1293,7 @@ public final class WebViewCore {
mBrowserFrame = null;
mSettings.onDestroyed();
mNativeClass = 0;
- mWebView = null;
+ mWebViewClassic = null;
}
break;
@@ -1537,7 +1536,7 @@ public final class WebViewCore {
yArray, count, ted.mActionIndex,
ted.mMetaState);
Message.obtain(
- mWebView.mPrivateHandler,
+ mWebViewClassic.mPrivateHandler,
WebViewClassic.PREVENT_TOUCH_ID,
ted.mAction,
ted.mNativeResult ? 1 : 0,
@@ -1607,7 +1606,7 @@ public final class WebViewCore {
String modifiedSelectionString =
nativeModifySelection(mNativeClass, msg.arg1,
msg.arg2);
- mWebView.mPrivateHandler.obtainMessage(
+ mWebViewClassic.mPrivateHandler.obtainMessage(
WebViewClassic.SELECTION_STRING_CHANGED,
modifiedSelectionString).sendToTarget();
break;
@@ -1653,7 +1652,7 @@ public final class WebViewCore {
(WebViewClassic.SaveWebArchiveMessage)msg.obj;
saveMessage.mResultFile =
saveWebArchive(saveMessage.mBasename, saveMessage.mAutoname);
- mWebView.mPrivateHandler.obtainMessage(
+ mWebViewClassic.mPrivateHandler.obtainMessage(
WebViewClassic.SAVE_WEBARCHIVE_FINISHED, saveMessage).sendToTarget();
break;
@@ -1666,7 +1665,7 @@ public final class WebViewCore {
case SPLIT_PICTURE_SET:
nativeSplitContent(mNativeClass, msg.arg1);
- mWebView.mPrivateHandler.obtainMessage(
+ mWebViewClassic.mPrivateHandler.obtainMessage(
WebViewClassic.REPLACE_BASE_CONTENT, msg.arg1, 0);
mSplitPictureIsScheduled = false;
break;
@@ -1714,7 +1713,7 @@ public final class WebViewCore {
d.mNativeLayer, d.mNativeLayerRect);
}
WebKitHitTest hit = performHitTest(d.mX, d.mY, d.mSlop, true);
- mWebView.mPrivateHandler.obtainMessage(
+ mWebViewClassic.mPrivateHandler.obtainMessage(
WebViewClassic.HIT_TEST_RESULT, hit)
.sendToTarget();
break;
@@ -1725,8 +1724,8 @@ public final class WebViewCore {
case AUTOFILL_FORM:
nativeAutoFillForm(mNativeClass, msg.arg1);
- mWebView.mPrivateHandler.obtainMessage(WebViewClassic.AUTOFILL_COMPLETE, null)
- .sendToTarget();
+ mWebViewClassic.mPrivateHandler.obtainMessage(
+ WebViewClassic.AUTOFILL_COMPLETE, null).sendToTarget();
break;
case EXECUTE_JS:
@@ -1734,7 +1733,8 @@ public final class WebViewCore {
if (DebugFlags.WEB_VIEW_CORE) {
Log.d(LOGTAG, "Executing JS : " + msg.obj);
}
- mBrowserFrame.stringByEvaluatingJavaScriptFromString((String) msg.obj);
+ mBrowserFrame.stringByEvaluatingJavaScriptFromString(
+ (String) msg.obj);
}
break;
case SCROLL_LAYER:
@@ -1756,7 +1756,8 @@ public final class WebViewCore {
handles[0], handles[1], handles[2],
handles[3]);
if (copiedText != null) {
- mWebView.mPrivateHandler.obtainMessage(WebViewClassic.COPY_TO_CLIPBOARD, copiedText)
+ mWebViewClassic.mPrivateHandler.obtainMessage(
+ WebViewClassic.COPY_TO_CLIPBOARD, copiedText)
.sendToTarget();
}
break;
@@ -2028,7 +2029,7 @@ public final class WebViewCore {
if (keyCode >= KeyEvent.KEYCODE_DPAD_UP
&& keyCode <= KeyEvent.KEYCODE_DPAD_RIGHT) {
if (canTakeFocusDirection != 0 && isDown) {
- Message m = mWebView.mPrivateHandler.obtainMessage(
+ Message m = mWebViewClassic.mPrivateHandler.obtainMessage(
WebViewClassic.TAKE_FOCUS);
m.arg1 = canTakeFocusDirection;
m.sendToTarget();
@@ -2101,7 +2102,8 @@ public final class WebViewCore {
width = mViewportWidth;
} else {
// For mobile web site.
- width = Math.round(mWebView.getViewWidth() / mWebView.getDefaultZoomScale());
+ width = Math.round(mWebViewClassic.getViewWidth() /
+ mWebViewClassic.getDefaultZoomScale());
}
}
return width;
@@ -2193,8 +2195,8 @@ public final class WebViewCore {
// If anything more complex than position has been touched, let's do a full draw
webkitDraw();
}
- mWebView.mPrivateHandler.removeMessages(WebViewClassic.INVAL_RECT_MSG_ID);
- mWebView.mPrivateHandler.sendMessageAtFrontOfQueue(mWebView.mPrivateHandler
+ mWebViewClassic.mPrivateHandler.removeMessages(WebViewClassic.INVAL_RECT_MSG_ID);
+ mWebViewClassic.mPrivateHandler.sendMessageAtFrontOfQueue(mWebViewClassic.mPrivateHandler
.obtainMessage(WebViewClassic.INVAL_RECT_MSG_ID));
}
@@ -2234,7 +2236,7 @@ public final class WebViewCore {
draw.mBaseLayer = nativeRecordContent(mNativeClass, draw.mInvalRegion,
draw.mContentSize);
if (draw.mBaseLayer == 0) {
- if (mWebView != null && !mWebView.isPaused()) {
+ if (mWebViewClassic != null && !mWebViewClassic.isPaused()) {
if (DebugFlags.WEB_VIEW_CORE) Log.v(LOGTAG, "webkitDraw abort, resending draw message");
mEventHub.sendMessageDelayed(Message.obtain(null, EventHub.WEBKIT_DRAW), 10);
} else {
@@ -2247,7 +2249,7 @@ public final class WebViewCore {
}
private void webkitDraw(DrawData draw) {
- if (mWebView != null) {
+ if (mWebViewClassic != null) {
draw.mFocusSizeChanged = nativeFocusBoundsChanged(mNativeClass);
draw.mViewSize = new Point(mCurrentViewWidth, mCurrentViewHeight);
if (mSettings.getUseWideViewPort()) {
@@ -2266,7 +2268,7 @@ public final class WebViewCore {
mFirstLayoutForNonStandardLoad = false;
}
if (DebugFlags.WEB_VIEW_CORE) Log.v(LOGTAG, "webkitDraw NEW_PICTURE_MSG_ID");
- Message.obtain(mWebView.mPrivateHandler,
+ Message.obtain(mWebViewClassic.mPrivateHandler,
WebViewClassic.NEW_PICTURE_MSG_ID, draw).sendToTarget();
}
}
@@ -2356,7 +2358,7 @@ public final class WebViewCore {
// called from JNI or WebView thread
/* package */ void contentDraw() {
synchronized (this) {
- if (mWebView == null || mBrowserFrame == null) {
+ if (mWebViewClassic == null || mBrowserFrame == null) {
// We were destroyed
return;
}
@@ -2394,8 +2396,8 @@ public final class WebViewCore {
mRestoredY = y;
return;
}
- if (mWebView != null) {
- Message msg = Message.obtain(mWebView.mPrivateHandler,
+ if (mWebViewClassic != null) {
+ Message msg = Message.obtain(mWebViewClassic.mPrivateHandler,
WebViewClassic.SCROLL_TO_MSG_ID, animate ? 1 : 0,
onlyIfImeIsShowing ? 1 : 0, new Point(x, y));
if (mDrawIsScheduled) {
@@ -2417,8 +2419,8 @@ public final class WebViewCore {
in WebView since it (and its thread) know the current scale factor.
*/
private void sendViewInvalidate(int left, int top, int right, int bottom) {
- if (mWebView != null) {
- Message.obtain(mWebView.mPrivateHandler,
+ if (mWebViewClassic != null) {
+ Message.obtain(mWebViewClassic.mPrivateHandler,
WebViewClassic.INVAL_RECT_MSG_ID,
new Rect(left, top, right, bottom)).sendToTarget();
}
@@ -2433,10 +2435,20 @@ public final class WebViewCore {
mRepaintScheduled = false;
}
- // Gets the WebView corresponding to this WebViewCore. Note that the
- // WebView object must only be used on the UI thread.
- /* package */ WebViewClassic getWebView() {
- return mWebView;
+ // Gets the WebViewClassic corresponding to this WebViewCore. Note that the
+ // WebViewClassic object must only be used on the UI thread.
+ /* package */ WebViewClassic getWebViewClassic() {
+ return mWebViewClassic;
+ }
+
+ // Called by JNI
+ private WebView getWebView() {
+ return mWebViewClassic.getWebView();
+ }
+
+ // Called by JNI
+ private void sendPluginDrawMsg() {
+ sendMessage(EventHub.PLUGIN_SURFACE_READY);
}
private native void setViewportSettingsFromNative(int nativeClass);
@@ -2449,7 +2461,7 @@ public final class WebViewCore {
mBrowserFrame.didFirstLayout();
- if (mWebView == null) return;
+ if (mWebViewClassic == null) return;
boolean updateViewState = standardLoad || mIsRestored;
setupViewport(updateViewState);
@@ -2457,11 +2469,11 @@ public final class WebViewCore {
// be called after the WebView updates its state. If updateRestoreState
// is false, start to draw now as it is ready.
if (!updateViewState) {
- mWebView.mViewManager.postReadyToDrawAll();
+ mWebViewClassic.mViewManager.postReadyToDrawAll();
}
// remove the touch highlight when moving to a new page
- mWebView.mPrivateHandler.sendEmptyMessage(
+ mWebViewClassic.mPrivateHandler.sendEmptyMessage(
WebViewClassic.HIT_TEST_RESULT);
// reset the scroll position, the restored offset and scales
@@ -2477,7 +2489,7 @@ public final class WebViewCore {
}
private void setupViewport(boolean updateViewState) {
- if (mWebView == null || mSettings == null) {
+ if (mWebViewClassic == null || mSettings == null) {
// We've been destroyed or are being destroyed, return early
return;
}
@@ -2525,8 +2537,8 @@ public final class WebViewCore {
adjust = (float) mContext.getResources().getDisplayMetrics().densityDpi
/ mViewportDensityDpi;
}
- if (adjust != mWebView.getDefaultZoomScale()) {
- Message.obtain(mWebView.mPrivateHandler,
+ if (adjust != mWebViewClassic.getDefaultZoomScale()) {
+ Message.obtain(mWebViewClassic.mPrivateHandler,
WebViewClassic.UPDATE_ZOOM_DENSITY, adjust).sendToTarget();
}
int defaultScale = (int) (adjust * 100);
@@ -2577,7 +2589,7 @@ public final class WebViewCore {
// for non-mobile site, we don't need minPrefWidth, set it as 0
viewState.mScrollX = 0;
viewState.mShouldStartScrolledRight = false;
- Message.obtain(mWebView.mPrivateHandler,
+ Message.obtain(mWebViewClassic.mPrivateHandler,
WebViewClassic.UPDATE_ZOOM_RANGE, viewState).sendToTarget();
return;
}
@@ -2591,7 +2603,7 @@ public final class WebViewCore {
// this may happen when WebView just starts. This is not perfect as
// we call WebView method from WebCore thread. But not perfect
// reference is better than no reference.
- webViewWidth = mWebView.getViewWidth();
+ webViewWidth = mWebViewClassic.getViewWidth();
viewportWidth = (int) (webViewWidth / adjust);
if (viewportWidth == 0) {
if (DebugFlags.WEB_VIEW_CORE) {
@@ -2640,17 +2652,17 @@ public final class WebViewCore {
}
}
- if (mWebView.mHeightCanMeasure) {
+ if (mWebViewClassic.mHeightCanMeasure) {
// Trick to ensure that the Picture has the exact height for the
// content by forcing to layout with 0 height after the page is
// ready, which is indicated by didFirstLayout. This is essential to
// get rid of the white space in the GMail which uses WebView for
// message view.
- mWebView.mLastHeightSent = 0;
+ mWebViewClassic.mLastHeightSent = 0;
// Send a negative scale to indicate that WebCore should reuse
// the current scale
WebViewClassic.ViewSizeData data = new WebViewClassic.ViewSizeData();
- data.mWidth = mWebView.mLastWidthSent;
+ data.mWidth = mWebViewClassic.mLastWidthSent;
data.mHeight = 0;
// if mHeightCanMeasure is true, getUseWideViewPort() can't be
// true. It is safe to use mWidth for mTextWrapWidth.
@@ -2671,7 +2683,7 @@ public final class WebViewCore {
if (viewportWidth == 0) {
// Trick to ensure VIEW_SIZE_CHANGED will be sent from WebView
// to WebViewCore
- mWebView.mLastWidthSent = 0;
+ mWebViewClassic.mLastWidthSent = 0;
} else {
WebViewClassic.ViewSizeData data = new WebViewClassic.ViewSizeData();
// mViewScale as 0 means it is in zoom overview mode. So we don't
@@ -2699,7 +2711,7 @@ public final class WebViewCore {
if (mSettings.isNarrowColumnLayout()) {
// In case of automatic text reflow in fixed view port mode.
mInitialViewState.mTextWrapScale =
- mWebView.computeReadingLevelScale(data.mScale);
+ mWebViewClassic.computeReadingLevelScale(data.mScale);
}
} else {
// Scale is given such as when page is restored, use it.
@@ -2720,7 +2732,7 @@ public final class WebViewCore {
// are calling a WebView method from the WebCore thread. But this is preferable
// to syncing an incorrect height.
data.mHeight = mCurrentViewHeight == 0 ?
- Math.round(mWebView.getViewHeight() / data.mScale)
+ Math.round(mWebViewClassic.getViewHeight() / data.mScale)
: Math.round((float) mCurrentViewHeight * data.mWidth / viewportWidth);
data.mTextWrapWidth = Math.round(webViewWidth
/ mInitialViewState.mTextWrapScale);
@@ -2749,8 +2761,8 @@ public final class WebViewCore {
// called by JNI
private void needTouchEvents(boolean need) {
- if (mWebView != null) {
- Message.obtain(mWebView.mPrivateHandler,
+ if (mWebViewClassic != null) {
+ Message.obtain(mWebViewClassic.mPrivateHandler,
WebViewClassic.WEBCORE_NEED_TOUCH_EVENTS, need ? 1 : 0, 0)
.sendToTarget();
}
@@ -2759,8 +2771,8 @@ public final class WebViewCore {
// called by JNI
private void updateTextfield(int ptr, boolean changeToPassword,
String text, int textGeneration) {
- if (mWebView != null) {
- Message msg = Message.obtain(mWebView.mPrivateHandler,
+ if (mWebViewClassic != null) {
+ Message msg = Message.obtain(mWebViewClassic.mPrivateHandler,
WebViewClassic.UPDATE_TEXTFIELD_TEXT_MSG_ID, ptr,
textGeneration, text);
msg.getData().putBoolean("password", changeToPassword);
@@ -2771,8 +2783,8 @@ public final class WebViewCore {
// called by JNI
private void updateTextSelection(int pointer, int start, int end,
int textGeneration, int selectionPtr) {
- if (mWebView != null) {
- Message.obtain(mWebView.mPrivateHandler,
+ if (mWebViewClassic != null) {
+ Message.obtain(mWebViewClassic.mPrivateHandler,
WebViewClassic.UPDATE_TEXT_SELECTION_MSG_ID, pointer, textGeneration,
new TextSelectionData(start, end, selectionPtr)).sendToTarget();
}
@@ -2781,10 +2793,10 @@ public final class WebViewCore {
// called by JNI
private void updateTextSizeAndScroll(int pointer, int width, int height,
int scrollX, int scrollY) {
- if (mWebView != null) {
+ if (mWebViewClassic != null) {
Rect rect = new Rect(-scrollX, -scrollY, width - scrollX,
height - scrollY);
- Message.obtain(mWebView.mPrivateHandler,
+ Message.obtain(mWebViewClassic.mPrivateHandler,
WebViewClassic.EDIT_TEXT_SIZE_CHANGED, pointer, 0, rect)
.sendToTarget();
}
@@ -2792,20 +2804,20 @@ public final class WebViewCore {
// called by JNI
private void clearTextEntry() {
- if (mWebView == null) return;
- Message.obtain(mWebView.mPrivateHandler,
+ if (mWebViewClassic == null) return;
+ Message.obtain(mWebViewClassic.mPrivateHandler,
WebViewClassic.CLEAR_TEXT_ENTRY).sendToTarget();
}
// called by JNI
private void initEditField(int start, int end, int selectionPtr,
TextFieldInitData initData) {
- if (mWebView == null) {
+ if (mWebViewClassic == null) {
return;
}
- Message.obtain(mWebView.mPrivateHandler,
+ Message.obtain(mWebViewClassic.mPrivateHandler,
WebViewClassic.INIT_EDIT_FIELD, initData).sendToTarget();
- Message.obtain(mWebView.mPrivateHandler,
+ Message.obtain(mWebViewClassic.mPrivateHandler,
WebViewClassic.REQUEST_KEYBOARD_WITH_SELECTION_MSG_ID,
initData.mFieldPointer, 0,
new TextSelectionData(start, end, selectionPtr))
@@ -2815,10 +2827,10 @@ public final class WebViewCore {
// called by JNI
private void updateMatchCount(int matchIndex, int matchCount,
String findText) {
- if (mWebView == null) {
+ if (mWebViewClassic == null) {
return;
}
- Message.obtain(mWebView.mPrivateHandler,
+ Message.obtain(mWebViewClassic.mPrivateHandler,
WebViewClassic.UPDATE_MATCH_COUNT, matchIndex, matchCount,
findText).sendToTarget();
}
@@ -2842,32 +2854,32 @@ public final class WebViewCore {
// called by JNI
private void requestListBox(String[] array, int[] enabledArray,
int[] selectedArray) {
- if (mWebView != null) {
- mWebView.requestListBox(array, enabledArray, selectedArray);
+ if (mWebViewClassic != null) {
+ mWebViewClassic.requestListBox(array, enabledArray, selectedArray);
}
}
// called by JNI
private void requestListBox(String[] array, int[] enabledArray,
int selection) {
- if (mWebView != null) {
- mWebView.requestListBox(array, enabledArray, selection);
+ if (mWebViewClassic != null) {
+ mWebViewClassic.requestListBox(array, enabledArray, selection);
}
}
// called by JNI
private void requestKeyboard(boolean showKeyboard) {
- if (mWebView != null) {
- Message.obtain(mWebView.mPrivateHandler,
+ if (mWebViewClassic != null) {
+ Message.obtain(mWebViewClassic.mPrivateHandler,
WebViewClassic.REQUEST_KEYBOARD, showKeyboard ? 1 : 0, 0)
.sendToTarget();
}
}
private void setWebTextViewAutoFillable(int queryId, String preview) {
- if (mWebView != null) {
- Message.obtain(mWebView.mPrivateHandler, WebViewClassic.SET_AUTOFILLABLE,
+ if (mWebViewClassic != null) {
+ Message.obtain(mWebViewClassic.mPrivateHandler, WebViewClassic.SET_AUTOFILLABLE,
new AutoFillData(queryId, preview))
.sendToTarget();
}
@@ -2879,8 +2891,9 @@ public final class WebViewCore {
// called by JNI
private void keepScreenOn(boolean screenOn) {
- if (mWebView != null) {
- Message message = mWebView.mPrivateHandler.obtainMessage(WebViewClassic.SCREEN_ON);
+ if (mWebViewClassic != null) {
+ Message message = mWebViewClassic.mPrivateHandler.obtainMessage(
+ WebViewClassic.SCREEN_ON);
message.arg1 = screenOn ? 1 : 0;
message.sendToTarget();
}
@@ -2889,7 +2902,7 @@ public final class WebViewCore {
// called by JNI
private Class<?> getPluginClass(String libName, String clsName) {
- if (mWebView == null) {
+ if (mWebViewClassic == null) {
return null;
}
@@ -2916,11 +2929,12 @@ public final class WebViewCore {
// called by JNI. PluginWidget function to launch a full-screen view using a
// View object provided by the plugin class.
private void showFullScreenPlugin(ViewManager.ChildView childView, int orientation, int npp) {
- if (mWebView == null) {
+ if (mWebViewClassic == null) {
return;
}
- Message message = mWebView.mPrivateHandler.obtainMessage(WebViewClassic.SHOW_FULLSCREEN);
+ Message message = mWebViewClassic.mPrivateHandler.obtainMessage(
+ WebViewClassic.SHOW_FULLSCREEN);
message.obj = childView.mView;
message.arg1 = orientation;
message.arg2 = npp;
@@ -2929,15 +2943,15 @@ public final class WebViewCore {
// called by JNI
private void hideFullScreenPlugin() {
- if (mWebView == null) {
+ if (mWebViewClassic == null) {
return;
}
- mWebView.mPrivateHandler.obtainMessage(WebViewClassic.HIDE_FULLSCREEN)
+ mWebViewClassic.mPrivateHandler.obtainMessage(WebViewClassic.HIDE_FULLSCREEN)
.sendToTarget();
}
private ViewManager.ChildView createSurface(View pluginView) {
- if (mWebView == null) {
+ if (mWebViewClassic == null) {
return null;
}
@@ -2952,7 +2966,7 @@ public final class WebViewCore {
if(pluginView instanceof SurfaceView)
((SurfaceView)pluginView).setZOrderOnTop(true);
- ViewManager.ChildView view = mWebView.mViewManager.createView();
+ ViewManager.ChildView view = mWebViewClassic.mViewManager.createView();
view.mView = pluginView;
return view;
}
@@ -2992,7 +3006,7 @@ public final class WebViewCore {
private void showRect(int left, int top, int width, int height,
int contentWidth, int contentHeight, float xPercentInDoc,
float xPercentInView, float yPercentInDoc, float yPercentInView) {
- if (mWebView != null) {
+ if (mWebViewClassic != null) {
ShowRectData data = new ShowRectData();
data.mLeft = left;
data.mTop = top;
@@ -3004,26 +3018,26 @@ public final class WebViewCore {
data.mXPercentInView = xPercentInView;
data.mYPercentInDoc = yPercentInDoc;
data.mYPercentInView = yPercentInView;
- Message.obtain(mWebView.mPrivateHandler, WebViewClassic.SHOW_RECT_MSG_ID,
+ Message.obtain(mWebViewClassic.mPrivateHandler, WebViewClassic.SHOW_RECT_MSG_ID,
data).sendToTarget();
}
}
// called by JNI
private void centerFitRect(int x, int y, int width, int height) {
- if (mWebView == null) {
+ if (mWebViewClassic == null) {
return;
}
- mWebView.mPrivateHandler.obtainMessage(WebViewClassic.CENTER_FIT_RECT,
+ mWebViewClassic.mPrivateHandler.obtainMessage(WebViewClassic.CENTER_FIT_RECT,
new Rect(x, y, x + width, y + height)).sendToTarget();
}
// called by JNI
private void setScrollbarModes(int hMode, int vMode) {
- if (mWebView == null) {
+ if (mWebViewClassic == null) {
return;
}
- mWebView.mPrivateHandler.obtainMessage(WebViewClassic.SET_SCROLLBAR_MODES,
+ mWebViewClassic.mPrivateHandler.obtainMessage(WebViewClassic.SET_SCROLLBAR_MODES,
hMode, vMode).sendToTarget();
}
diff --git a/core/java/android/webkit/WebViewProvider.java b/core/java/android/webkit/WebViewProvider.java
index 9016fbceeac2..7d47e14183b8 100644
--- a/core/java/android/webkit/WebViewProvider.java
+++ b/core/java/android/webkit/WebViewProvider.java
@@ -19,6 +19,7 @@ package android.webkit;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.Canvas;
+import android.graphics.Paint;
import android.graphics.Picture;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
@@ -337,6 +338,8 @@ public interface WebViewProvider {
public boolean requestChildRectangleOnScreen(View child, Rect rect, boolean immediate);
public void setBackgroundColor(int color);
+
+ public void setLayerType(int layerType, Paint paint);
}
interface ScrollDelegate {
diff --git a/core/java/android/widget/DatePicker.java b/core/java/android/widget/DatePicker.java
index fd939802a577..c5066b672861 100644
--- a/core/java/android/widget/DatePicker.java
+++ b/core/java/android/widget/DatePicker.java
@@ -29,8 +29,8 @@ import android.util.AttributeSet;
import android.util.Log;
import android.util.SparseArray;
import android.view.LayoutInflater;
+import android.view.View;
import android.view.accessibility.AccessibilityEvent;
-import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
@@ -280,9 +280,7 @@ public class DatePicker extends FrameLayout {
reorderSpinners();
// set content descriptions
- if (AccessibilityManager.getInstance(mContext).isEnabled()) {
- setContentDescriptions();
- }
+ setContentDescriptions();
}
/**
@@ -717,20 +715,27 @@ public class DatePicker extends FrameLayout {
private void setContentDescriptions() {
// Day
- String text = mContext.getString(R.string.date_picker_increment_day_button);
- mDaySpinner.findViewById(R.id.increment).setContentDescription(text);
- text = mContext.getString(R.string.date_picker_decrement_day_button);
- mDaySpinner.findViewById(R.id.decrement).setContentDescription(text);
+ trySetContentDescription(mDaySpinner, R.id.increment,
+ R.string.date_picker_increment_day_button);
+ trySetContentDescription(mDaySpinner, R.id.decrement,
+ R.string.date_picker_decrement_day_button);
// Month
- text = mContext.getString(R.string.date_picker_increment_month_button);
- mMonthSpinner.findViewById(R.id.increment).setContentDescription(text);
- text = mContext.getString(R.string.date_picker_decrement_month_button);
- mMonthSpinner.findViewById(R.id.decrement).setContentDescription(text);
+ trySetContentDescription(mMonthSpinner, R.id.increment,
+ R.string.date_picker_increment_month_button);
+ trySetContentDescription(mMonthSpinner, R.id.decrement,
+ R.string.date_picker_decrement_month_button);
// Year
- text = mContext.getString(R.string.date_picker_increment_year_button);
- mYearSpinner.findViewById(R.id.increment).setContentDescription(text);
- text = mContext.getString(R.string.date_picker_decrement_year_button);
- mYearSpinner.findViewById(R.id.decrement).setContentDescription(text);
+ trySetContentDescription(mYearSpinner, R.id.increment,
+ R.string.date_picker_increment_year_button);
+ trySetContentDescription(mYearSpinner, R.id.decrement,
+ R.string.date_picker_decrement_year_button);
+ }
+
+ private void trySetContentDescription(View root, int viewId, int contDescResId) {
+ View target = root.findViewById(viewId);
+ if (target != null) {
+ target.setContentDescription(mContext.getString(contDescResId));
+ }
}
private void updateInputState() {
diff --git a/core/java/android/widget/HorizontalScrollView.java b/core/java/android/widget/HorizontalScrollView.java
index 0db6ef25fe76..4e13ea14152f 100644
--- a/core/java/android/widget/HorizontalScrollView.java
+++ b/core/java/android/widget/HorizontalScrollView.java
@@ -715,6 +715,7 @@ public class HorizontalScrollView extends FrameLayout {
} else {
super.scrollTo(scrollX, scrollY);
}
+
awakenScrollBars();
}
@@ -1204,10 +1205,9 @@ public class HorizontalScrollView extends FrameLayout {
}
}
- awakenScrollBars();
-
- // Keep on drawing until the animation has finished.
- postInvalidate();
+ if (!awakenScrollBars()) {
+ invalidate();
+ }
}
}
@@ -1414,7 +1414,7 @@ public class HorizontalScrollView extends FrameLayout {
/**
* Return true if child is a descendant of parent, (or equal to the parent).
*/
- private boolean isViewDescendantOf(View child, View parent) {
+ private static boolean isViewDescendantOf(View child, View parent) {
if (child == parent) {
return true;
}
@@ -1524,7 +1524,7 @@ public class HorizontalScrollView extends FrameLayout {
}
}
- private int clamp(int n, int my, int child) {
+ private static int clamp(int n, int my, int child) {
if (my >= child || n < 0) {
return 0;
}
diff --git a/core/java/android/widget/NumberPicker.java b/core/java/android/widget/NumberPicker.java
index 3335da0bd672..4e56cd6a46ee 100644
--- a/core/java/android/widget/NumberPicker.java
+++ b/core/java/android/widget/NumberPicker.java
@@ -16,10 +16,6 @@
package android.widget;
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.AnimatorSet;
-import android.animation.ObjectAnimator;
import android.annotation.Widget;
import android.content.Context;
import android.content.res.ColorStateList;
@@ -48,22 +44,41 @@ import android.view.ViewConfiguration;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.accessibility.AccessibilityNodeProvider;
import android.view.animation.DecelerateInterpolator;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import com.android.internal.R;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
/**
* A widget that enables the user to select a number form a predefined range.
- * The widget presents an input field and up and down buttons for selecting the
- * current value. Pressing/long-pressing the up and down buttons increments and
- * decrements the current value respectively. Touching the input field shows a
- * scroll wheel, which when touched allows direct edit
- * of the current value. Sliding gestures up or down hide the buttons and the
- * input filed, show and rotate the scroll wheel. Flinging is
- * also supported. The widget enables mapping from positions to strings such
- * that, instead of the position index, the corresponding string is displayed.
+ * There are two flavors of this widget and which one is presented to the user
+ * depends on the current theme.
+ * <ul>
+ * <li>
+ * If the current theme is derived from {@link android.R.style#Theme} the widget
+ * presents the current value as an editable input field with an increment button
+ * above and a decrement button below. Long pressing the buttons allows for a quick
+ * change of the current value. Tapping on the input field allows to type in
+ * a desired value.
+ * </li>
+ * <li>
+ * If the current theme is derived from {@link android.R.style#Theme_Holo} or
+ * {@link android.R.style#Theme_Holo_Light} the widget presents the current
+ * value as an editable input field with a lesser value above and a greater
+ * value below. Tapping on the lesser or greater value selects it by animating
+ * the number axis up or down to make the chosen value current. Flinging up
+ * or down allows for multiple increments or decrements of the current value.
+ * Long pressing on the lesser and greater values also allows for a quick change
+ * of the current value. Tapping on the current value allows to type in a
+ * desired value.
+ * </li>
+ * </ul>
* <p>
* For an example of using this widget, see {@link android.widget.TimePicker}.
* </p>
@@ -74,7 +89,7 @@ public class NumberPicker extends LinearLayout {
/**
* The number of items show in the selector wheel.
*/
- public static final int SELECTOR_WHEEL_ITEM_COUNT = 5;
+ private static final int SELECTOR_WHEEL_ITEM_COUNT = 3;
/**
* The default update interval during long press.
@@ -84,7 +99,7 @@ public class NumberPicker extends LinearLayout {
/**
* The index of the middle selector item.
*/
- private static final int SELECTOR_MIDDLE_ITEM_INDEX = 2;
+ private static final int SELECTOR_MIDDLE_ITEM_INDEX = SELECTOR_WHEEL_ITEM_COUNT / 2;
/**
* The coefficient by which to adjust (divide) the max fling velocity.
@@ -97,19 +112,12 @@ public class NumberPicker extends LinearLayout {
private static final int SELECTOR_ADJUSTMENT_DURATION_MILLIS = 800;
/**
- * The duration of scrolling to the next/previous value while changing
- * the current value by one, i.e. increment or decrement.
+ * The duration of scrolling to the next/previous value while changing the
+ * current value by one, i.e. increment or decrement.
*/
private static final int CHANGE_CURRENT_BY_ONE_SCROLL_DURATION = 300;
/**
- * The the delay for showing the input controls after a single tap on the
- * input text.
- */
- private static final int SHOW_INPUT_CONTROLS_DELAY_MILLIS = ViewConfiguration
- .getDoubleTapTimeout();
-
- /**
* The strength of fading in the top and bottom while drawing the selector.
*/
private static final float TOP_AND_BOTTOM_FADING_EDGE_STRENGTH = 0.9f;
@@ -120,56 +128,31 @@ public class NumberPicker extends LinearLayout {
private static final int UNSCALED_DEFAULT_SELECTION_DIVIDER_HEIGHT = 2;
/**
- * In this state the selector wheel is not shown.
- */
- private static final int SELECTOR_WHEEL_STATE_NONE = 0;
-
- /**
- * In this state the selector wheel is small.
- */
- private static final int SELECTOR_WHEEL_STATE_SMALL = 1;
-
- /**
- * In this state the selector wheel is large.
- */
- private static final int SELECTOR_WHEEL_STATE_LARGE = 2;
-
- /**
- * The alpha of the selector wheel when it is bright.
- */
- private static final int SELECTOR_WHEEL_BRIGHT_ALPHA = 255;
-
- /**
- * The alpha of the selector wheel when it is dimmed.
+ * The default unscaled distance between the selection dividers.
*/
- private static final int SELECTOR_WHEEL_DIM_ALPHA = 60;
+ private static final int UNSCALED_DEFAULT_SELECTION_DIVIDERS_DISTANCE = 48;
/**
- * The alpha for the increment/decrement button when it is transparent.
+ * The default unscaled minimal distance for a swipe to be considered a fling.
*/
- private static final int BUTTON_ALPHA_TRANSPARENT = 0;
+ private static final int UNSCALED_DEFAULT_MIN_FLING_DISTANCE = 150;
/**
- * The alpha for the increment/decrement button when it is opaque.
+ * Coefficient for adjusting touch scroll distance.
*/
- private static final int BUTTON_ALPHA_OPAQUE = 1;
+ private static final float TOUCH_SCROLL_DECELERATION_COEFFICIENT = 2.5f;
/**
- * The property for setting the selector paint.
+ * The resource id for the default layout.
*/
- private static final String PROPERTY_SELECTOR_PAINT_ALPHA = "selectorPaintAlpha";
-
- /**
- * The property for setting the increment/decrement button alpha.
- */
- private static final String PROPERTY_BUTTON_ALPHA = "alpha";
+ private static final int DEFAULT_LAYOUT_RESOURCE_ID = R.layout.number_picker;
/**
* The numbers accepted by the input text's {@link Filter}
*/
private static final char[] DIGIT_CHARACTERS = new char[] {
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'
- };
+ };
/**
* Constant for unspecified size.
@@ -215,6 +198,11 @@ public class NumberPicker extends LinearLayout {
private final EditText mInputText;
/**
+ * The distance between the two selection dividers.
+ */
+ private final int mSelectionDividersDistance;
+
+ /**
* The min height of this widget.
*/
private final int mMinHeight;
@@ -245,6 +233,11 @@ public class NumberPicker extends LinearLayout {
private final int mTextSize;
/**
+ * The minimal distance for a swipe to be considered a fling.
+ */
+ private final int mMinFlingDistance;
+
+ /**
* The height of the gap between text elements if the selector wheel.
*/
private int mSelectorTextGapHeight;
@@ -297,10 +290,7 @@ public class NumberPicker extends LinearLayout {
/**
* The selector indices whose value are show by the selector.
*/
- private final int[] mSelectorIndices = new int[] {
- Integer.MIN_VALUE, Integer.MIN_VALUE, Integer.MIN_VALUE, Integer.MIN_VALUE,
- Integer.MIN_VALUE
- };
+ private final int[] mSelectorIndices = new int[SELECTOR_WHEEL_ITEM_COUNT];
/**
* The {@link Paint} for drawing the selector.
@@ -343,25 +333,15 @@ public class NumberPicker extends LinearLayout {
private SetSelectionCommand mSetSelectionCommand;
/**
- * Handle to the reusable command for adjusting the scroller.
- */
- private AdjustScrollerCommand mAdjustScrollerCommand;
-
- /**
* Handle to the reusable command for changing the current value from long
* press by one.
*/
private ChangeCurrentByOneFromLongPressCommand mChangeCurrentByOneFromLongPressCommand;
/**
- * {@link Animator} for showing the up/down arrows.
- */
- private final AnimatorSet mShowInputControlsAnimator;
-
- /**
- * {@link Animator} for dimming the selector wheel.
+ * Command for beginning an edit of the current value via IME on long press.
*/
- private final Animator mDimSelectorWheelAnimator;
+ private BeginSoftInputOnLongPressCommand mBeginSoftInputOnLongPressCommand;
/**
* The Y position of the last down event.
@@ -369,24 +349,14 @@ public class NumberPicker extends LinearLayout {
private float mLastDownEventY;
/**
- * The Y position of the last motion event.
+ * The time of the last down event.
*/
- private float mLastMotionEventY;
+ private long mLastDownEventTime;
/**
- * Flag if to check for double tap and potentially start edit.
+ * The Y position of the last down or move event.
*/
- private boolean mCheckBeginEditOnUpEvent;
-
- /**
- * Flag if to adjust the selector wheel on next up event.
- */
- private boolean mAdjustScrollerOnUpEvent;
-
- /**
- * The state of the selector wheel.
- */
- private int mSelectorWheelState;
+ private float mLastDownOrMoveEventY;
/**
* Determines speed during touch scrolling.
@@ -419,9 +389,9 @@ public class NumberPicker extends LinearLayout {
private final int mSolidColor;
/**
- * Flag indicating if this widget supports flinging.
+ * Flag whether this widget has a selector wheel.
*/
- private final boolean mFlingable;
+ private final boolean mHasSelectorWheel;
/**
* Divider for showing item to be selected while scrolling
@@ -434,29 +404,40 @@ public class NumberPicker extends LinearLayout {
private final int mSelectionDividerHeight;
/**
- * Reusable {@link Rect} instance.
+ * The current scroll state of the number picker.
*/
- private final Rect mTempRect = new Rect();
+ private int mScrollState = OnScrollListener.SCROLL_STATE_IDLE;
/**
- * The current scroll state of the number picker.
+ * Flag whether to ignore move events - we ignore such when we show in IME
+ * to prevent the content from scrolling.
*/
- private int mScrollState = OnScrollListener.SCROLL_STATE_IDLE;
+ private boolean mIngonreMoveEvents;
/**
- * The duration of the animation for showing the input controls.
+ * Flag whether to show soft input on tap.
*/
- private final long mShowInputControlsAnimimationDuration;
+ private boolean mShowSoftInputOnTap;
/**
- * Flag whether the scoll wheel and the fading edges have been initialized.
+ * The top of the top selection divider.
*/
- private boolean mScrollWheelAndFadingEdgesInitialized;
+ private int mTopSelectionDividerTop;
/**
- * The time of the last up event.
+ * The bottom of the bottom selection divider.
*/
- private long mLastUpEventTimeMillis;
+ private int mBottomSelectionDividerBottom;
+
+ /**
+ * The virtual id of the last hovered child.
+ */
+ private int mLastHoveredChildVirtualViewId;
+
+ /**
+ * Provider to report to clients the semantic structure of this widget.
+ */
+ private AccessibilityNodeProviderImpl mAccessibilityNodeProvider;
/**
* Interface to listen for changes of the current value.
@@ -484,7 +465,7 @@ public class NumberPicker extends LinearLayout {
public static int SCROLL_STATE_IDLE = 0;
/**
- * The user is scrolling using touch, and their finger is still on the screen.
+ * The user is scrolling using touch, and his finger is still on the screen.
*/
public static int SCROLL_STATE_TOUCH_SCROLL = 1;
@@ -549,58 +530,78 @@ public class NumberPicker extends LinearLayout {
super(context, attrs, defStyle);
// process style attributes
- TypedArray attributesArray = context.obtainStyledAttributes(attrs,
- R.styleable.NumberPicker, defStyle, 0);
+ TypedArray attributesArray = context.obtainStyledAttributes(
+ attrs, R.styleable.NumberPicker, defStyle, 0);
+ final int layoutResId = attributesArray.getResourceId(
+ R.styleable.NumberPicker_internalLayout, DEFAULT_LAYOUT_RESOURCE_ID);
+
+ mHasSelectorWheel = (layoutResId != DEFAULT_LAYOUT_RESOURCE_ID);
+
mSolidColor = attributesArray.getColor(R.styleable.NumberPicker_solidColor, 0);
- mFlingable = attributesArray.getBoolean(R.styleable.NumberPicker_flingable, true);
+
mSelectionDivider = attributesArray.getDrawable(R.styleable.NumberPicker_selectionDivider);
- int defSelectionDividerHeight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
- UNSCALED_DEFAULT_SELECTION_DIVIDER_HEIGHT,
+
+ final int defSelectionDividerHeight = (int) TypedValue.applyDimension(
+ TypedValue.COMPLEX_UNIT_DIP, UNSCALED_DEFAULT_SELECTION_DIVIDER_HEIGHT,
getResources().getDisplayMetrics());
mSelectionDividerHeight = attributesArray.getDimensionPixelSize(
R.styleable.NumberPicker_selectionDividerHeight, defSelectionDividerHeight);
+
+ final int defSelectionDividerDistance = (int) TypedValue.applyDimension(
+ TypedValue.COMPLEX_UNIT_DIP, UNSCALED_DEFAULT_SELECTION_DIVIDERS_DISTANCE,
+ getResources().getDisplayMetrics());
+ mSelectionDividersDistance = attributesArray.getDimensionPixelSize(
+ R.styleable.NumberPicker_selectionDividersDistance, defSelectionDividerDistance);
+
+ final int defMinFlingDistance = (int) TypedValue.applyDimension(
+ TypedValue.COMPLEX_UNIT_DIP, UNSCALED_DEFAULT_MIN_FLING_DISTANCE,
+ getResources().getDisplayMetrics());
+ mMinFlingDistance = attributesArray.getDimensionPixelSize(
+ R.styleable.NumberPicker_minFlingDistance, defMinFlingDistance);
+
mMinHeight = attributesArray.getDimensionPixelSize(
R.styleable.NumberPicker_internalMinHeight, SIZE_UNSPECIFIED);
+
mMaxHeight = attributesArray.getDimensionPixelSize(
R.styleable.NumberPicker_internalMaxHeight, SIZE_UNSPECIFIED);
if (mMinHeight != SIZE_UNSPECIFIED && mMaxHeight != SIZE_UNSPECIFIED
&& mMinHeight > mMaxHeight) {
throw new IllegalArgumentException("minHeight > maxHeight");
}
- mMinWidth = attributesArray.getDimensionPixelSize(R.styleable.NumberPicker_internalMinWidth,
- SIZE_UNSPECIFIED);
- mMaxWidth = attributesArray.getDimensionPixelSize(R.styleable.NumberPicker_internalMaxWidth,
- SIZE_UNSPECIFIED);
+
+ mMinWidth = attributesArray.getDimensionPixelSize(
+ R.styleable.NumberPicker_internalMinWidth, SIZE_UNSPECIFIED);
+
+ mMaxWidth = attributesArray.getDimensionPixelSize(
+ R.styleable.NumberPicker_internalMaxWidth, SIZE_UNSPECIFIED);
if (mMinWidth != SIZE_UNSPECIFIED && mMaxWidth != SIZE_UNSPECIFIED
&& mMinWidth > mMaxWidth) {
throw new IllegalArgumentException("minWidth > maxWidth");
}
+
mComputeMaxWidth = (mMaxWidth == Integer.MAX_VALUE);
- attributesArray.recycle();
- mShowInputControlsAnimimationDuration = getResources().getInteger(
- R.integer.config_longAnimTime);
+ attributesArray.recycle();
// By default Linearlayout that we extend is not drawn. This is
// its draw() method is not called but dispatchDraw() is called
// directly (see ViewGroup.drawChild()). However, this class uses
// the fading edge effect implemented by View and we need our
// draw() method to be called. Therefore, we declare we will draw.
- setWillNotDraw(false);
- setSelectorWheelState(SELECTOR_WHEEL_STATE_NONE);
+ setWillNotDraw(!mHasSelectorWheel);
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
- inflater.inflate(R.layout.number_picker, this, true);
+ inflater.inflate(layoutResId, this, true);
OnClickListener onClickListener = new OnClickListener() {
public void onClick(View v) {
hideSoftInput();
mInputText.clearFocus();
if (v.getId() == R.id.increment) {
- changeCurrentByOne(true);
+ changeValueByOne(true);
} else {
- changeCurrentByOne(false);
+ changeValueByOne(false);
}
}
};
@@ -610,23 +611,31 @@ public class NumberPicker extends LinearLayout {
hideSoftInput();
mInputText.clearFocus();
if (v.getId() == R.id.increment) {
- postChangeCurrentByOneFromLongPress(true);
+ postChangeCurrentByOneFromLongPress(true, 0);
} else {
- postChangeCurrentByOneFromLongPress(false);
+ postChangeCurrentByOneFromLongPress(false, 0);
}
return true;
}
};
// increment button
- mIncrementButton = (ImageButton) findViewById(R.id.increment);
- mIncrementButton.setOnClickListener(onClickListener);
- mIncrementButton.setOnLongClickListener(onLongClickListener);
+ if (!mHasSelectorWheel) {
+ mIncrementButton = (ImageButton) findViewById(R.id.increment);
+ mIncrementButton.setOnClickListener(onClickListener);
+ mIncrementButton.setOnLongClickListener(onLongClickListener);
+ } else {
+ mIncrementButton = null;
+ }
// decrement button
- mDecrementButton = (ImageButton) findViewById(R.id.decrement);
- mDecrementButton.setOnClickListener(onClickListener);
- mDecrementButton.setOnLongClickListener(onLongClickListener);
+ if (!mHasSelectorWheel) {
+ mDecrementButton = (ImageButton) findViewById(R.id.decrement);
+ mDecrementButton.setOnClickListener(onClickListener);
+ mDecrementButton.setOnLongClickListener(onLongClickListener);
+ } else {
+ mDecrementButton = null;
+ }
// input text
mInputText = (EditText) findViewById(R.id.numberpicker_input);
@@ -648,7 +657,6 @@ public class NumberPicker extends LinearLayout {
mInputText.setImeOptions(EditorInfo.IME_ACTION_DONE);
// initialize constants
- mTouchSlop = ViewConfiguration.getTapTimeout();
ViewConfiguration configuration = ViewConfiguration.get(context);
mTouchSlop = configuration.getScaledTouchSlop();
mMinimumFlingVelocity = configuration.getScaledMinimumFlingVelocity();
@@ -667,69 +675,22 @@ public class NumberPicker extends LinearLayout {
paint.setColor(color);
mSelectorWheelPaint = paint;
- // create the animator for showing the input controls
- mDimSelectorWheelAnimator = ObjectAnimator.ofInt(this, PROPERTY_SELECTOR_PAINT_ALPHA,
- SELECTOR_WHEEL_BRIGHT_ALPHA, SELECTOR_WHEEL_DIM_ALPHA);
- final ObjectAnimator showIncrementButton = ObjectAnimator.ofFloat(mIncrementButton,
- PROPERTY_BUTTON_ALPHA, BUTTON_ALPHA_TRANSPARENT, BUTTON_ALPHA_OPAQUE);
- final ObjectAnimator showDecrementButton = ObjectAnimator.ofFloat(mDecrementButton,
- PROPERTY_BUTTON_ALPHA, BUTTON_ALPHA_TRANSPARENT, BUTTON_ALPHA_OPAQUE);
- mShowInputControlsAnimator = new AnimatorSet();
- mShowInputControlsAnimator.playTogether(mDimSelectorWheelAnimator, showIncrementButton,
- showDecrementButton);
- mShowInputControlsAnimator.addListener(new AnimatorListenerAdapter() {
- private boolean mCanceled = false;
-
- @Override
- public void onAnimationEnd(Animator animation) {
- if (!mCanceled) {
- // if canceled => we still want the wheel drawn
- setSelectorWheelState(SELECTOR_WHEEL_STATE_SMALL);
- }
- mCanceled = false;
- }
-
- @Override
- public void onAnimationCancel(Animator animation) {
- if (mShowInputControlsAnimator.isRunning()) {
- mCanceled = true;
- }
- }
- });
-
// create the fling and adjust scrollers
mFlingScroller = new Scroller(getContext(), null, true);
mAdjustScroller = new Scroller(getContext(), new DecelerateInterpolator(2.5f));
updateInputTextView();
- updateIncrementAndDecrementButtonsVisibilityState();
-
- if (mFlingable) {
- if (isInEditMode()) {
- setSelectorWheelState(SELECTOR_WHEEL_STATE_SMALL);
- } else {
- // Start with shown selector wheel and hidden controls. When made
- // visible hide the selector and fade-in the controls to suggest
- // fling interaction.
- setSelectorWheelState(SELECTOR_WHEEL_STATE_LARGE);
- hideInputControls();
- }
- }
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+ if (!mHasSelectorWheel) {
+ super.onLayout(changed, left, top, right, bottom);
+ return;
+ }
final int msrdWdth = getMeasuredWidth();
final int msrdHght = getMeasuredHeight();
- // Increment button at the top.
- final int inctBtnMsrdWdth = mIncrementButton.getMeasuredWidth();
- final int incrBtnLeft = (msrdWdth - inctBtnMsrdWdth) / 2;
- final int incrBtnTop = 0;
- final int incrBtnRight = incrBtnLeft + inctBtnMsrdWdth;
- final int incrBtnBottom = incrBtnTop + mIncrementButton.getMeasuredHeight();
- mIncrementButton.layout(incrBtnLeft, incrBtnTop, incrBtnRight, incrBtnBottom);
-
// Input text centered horizontally.
final int inptTxtMsrdWdth = mInputText.getMeasuredWidth();
final int inptTxtMsrdHght = mInputText.getMeasuredHeight();
@@ -739,24 +700,23 @@ public class NumberPicker extends LinearLayout {
final int inptTxtBottom = inptTxtTop + inptTxtMsrdHght;
mInputText.layout(inptTxtLeft, inptTxtTop, inptTxtRight, inptTxtBottom);
- // Decrement button at the top.
- final int decrBtnMsrdWdth = mIncrementButton.getMeasuredWidth();
- final int decrBtnLeft = (msrdWdth - decrBtnMsrdWdth) / 2;
- final int decrBtnTop = msrdHght - mDecrementButton.getMeasuredHeight();
- final int decrBtnRight = decrBtnLeft + decrBtnMsrdWdth;
- final int decrBtnBottom = msrdHght;
- mDecrementButton.layout(decrBtnLeft, decrBtnTop, decrBtnRight, decrBtnBottom);
-
- if (!mScrollWheelAndFadingEdgesInitialized) {
- mScrollWheelAndFadingEdgesInitialized = true;
+ if (changed) {
// need to do all this when we know our size
initializeSelectorWheel();
initializeFadingEdges();
+ mTopSelectionDividerTop = (getHeight() - mSelectionDividersDistance) / 2
+ - mSelectionDividerHeight;
+ mBottomSelectionDividerBottom = mTopSelectionDividerTop + 2 * mSelectionDividerHeight
+ + mSelectionDividersDistance;
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ if (!mHasSelectorWheel) {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ return;
+ }
// Try greedily to fit the max width and height.
final int newWidthMeasureSpec = makeMeasureSpec(widthMeasureSpec, mMaxWidth);
final int newHeightMeasureSpec = makeMeasureSpec(heightMeasureSpec, mMaxHeight);
@@ -769,120 +729,143 @@ public class NumberPicker extends LinearLayout {
setMeasuredDimension(widthSize, heightSize);
}
+ /**
+ * Move to the final position of a scroller. Ensures to force finish the scroller
+ * and if it is not at its final position a scroll of the selector wheel is
+ * performed to fast forward to the final position.
+ *
+ * @param scroller The scroller to whose final position to get.
+ * @return True of the a move was performed, i.e. the scroller was not in final position.
+ */
+ private boolean moveToFinalScrollerPosition(Scroller scroller) {
+ scroller.forceFinished(true);
+ int amountToScroll = scroller.getFinalY() - scroller.getCurrY();
+ int futureScrollOffset = (mCurrentScrollOffset + amountToScroll) % mSelectorElementHeight;
+ int overshootAdjustment = mInitialScrollOffset - futureScrollOffset;
+ if (overshootAdjustment != 0) {
+ if (Math.abs(overshootAdjustment) > mSelectorElementHeight / 2) {
+ if (overshootAdjustment > 0) {
+ overshootAdjustment -= mSelectorElementHeight;
+ } else {
+ overshootAdjustment += mSelectorElementHeight;
+ }
+ }
+ amountToScroll += overshootAdjustment;
+ scrollBy(0, amountToScroll);
+ return true;
+ }
+ return false;
+ }
+
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
- if (!isEnabled() || !mFlingable) {
+ if (!mHasSelectorWheel || !isEnabled()) {
return false;
}
- switch (event.getActionMasked()) {
- case MotionEvent.ACTION_DOWN:
- mLastMotionEventY = mLastDownEventY = event.getY();
+ final int action = event.getActionMasked();
+ switch (action) {
+ case MotionEvent.ACTION_DOWN: {
removeAllCallbacks();
- mShowInputControlsAnimator.cancel();
- mDimSelectorWheelAnimator.cancel();
- mCheckBeginEditOnUpEvent = false;
- mAdjustScrollerOnUpEvent = true;
- if (mSelectorWheelState == SELECTOR_WHEEL_STATE_LARGE) {
- mSelectorWheelPaint.setAlpha(SELECTOR_WHEEL_BRIGHT_ALPHA);
- boolean scrollersFinished = mFlingScroller.isFinished()
- && mAdjustScroller.isFinished();
- if (!scrollersFinished) {
- mFlingScroller.forceFinished(true);
- mAdjustScroller.forceFinished(true);
- onScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
- }
- mCheckBeginEditOnUpEvent = scrollersFinished;
- mAdjustScrollerOnUpEvent = true;
+ mInputText.setVisibility(View.INVISIBLE);
+ mLastDownOrMoveEventY = mLastDownEventY = event.getY();
+ mLastDownEventTime = event.getEventTime();
+ mIngonreMoveEvents = false;
+ mShowSoftInputOnTap = false;
+ if (!mFlingScroller.isFinished()) {
+ mFlingScroller.forceFinished(true);
+ mAdjustScroller.forceFinished(true);
+ onScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
+ } else if (!mAdjustScroller.isFinished()) {
+ mFlingScroller.forceFinished(true);
+ mAdjustScroller.forceFinished(true);
+ } else if (mLastDownEventY < mTopSelectionDividerTop) {
hideSoftInput();
- hideInputControls();
- return true;
- }
- if (isEventInVisibleViewHitRect(event, mIncrementButton)
- || isEventInVisibleViewHitRect(event, mDecrementButton)) {
- return false;
- }
- mAdjustScrollerOnUpEvent = false;
- setSelectorWheelState(SELECTOR_WHEEL_STATE_LARGE);
- hideSoftInput();
- hideInputControls();
- return true;
- case MotionEvent.ACTION_MOVE:
- float currentMoveY = event.getY();
- int deltaDownY = (int) Math.abs(currentMoveY - mLastDownEventY);
- if (deltaDownY > mTouchSlop) {
- mCheckBeginEditOnUpEvent = false;
- onScrollStateChange(OnScrollListener.SCROLL_STATE_TOUCH_SCROLL);
- setSelectorWheelState(SELECTOR_WHEEL_STATE_LARGE);
+ postChangeCurrentByOneFromLongPress(
+ false, ViewConfiguration.getLongPressTimeout());
+ } else if (mLastDownEventY > mBottomSelectionDividerBottom) {
hideSoftInput();
- hideInputControls();
- return true;
+ postChangeCurrentByOneFromLongPress(
+ true, ViewConfiguration.getLongPressTimeout());
+ } else {
+ mShowSoftInputOnTap = true;
+ postBeginSoftInputOnLongPressCommand();
}
- break;
+ return true;
+ }
}
return false;
}
@Override
- public boolean onTouchEvent(MotionEvent ev) {
- if (!isEnabled()) {
+ public boolean onTouchEvent(MotionEvent event) {
+ if (!isEnabled() || !mHasSelectorWheel) {
return false;
}
if (mVelocityTracker == null) {
mVelocityTracker = VelocityTracker.obtain();
}
- mVelocityTracker.addMovement(ev);
- int action = ev.getActionMasked();
+ mVelocityTracker.addMovement(event);
+ int action = event.getActionMasked();
switch (action) {
- case MotionEvent.ACTION_MOVE:
- float currentMoveY = ev.getY();
- if (mCheckBeginEditOnUpEvent
- || mScrollState != OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) {
+ case MotionEvent.ACTION_MOVE: {
+ if (mIngonreMoveEvents) {
+ break;
+ }
+ float currentMoveY = event.getY();
+ if (mScrollState != OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) {
int deltaDownY = (int) Math.abs(currentMoveY - mLastDownEventY);
if (deltaDownY > mTouchSlop) {
- mCheckBeginEditOnUpEvent = false;
+ removeAllCallbacks();
onScrollStateChange(OnScrollListener.SCROLL_STATE_TOUCH_SCROLL);
}
+ } else {
+ int deltaMoveY = (int) ((currentMoveY - mLastDownOrMoveEventY)
+ / TOUCH_SCROLL_DECELERATION_COEFFICIENT);
+ scrollBy(0, deltaMoveY);
+ invalidate();
}
- int deltaMoveY = (int) (currentMoveY - mLastMotionEventY);
- scrollBy(0, deltaMoveY);
- invalidate();
- mLastMotionEventY = currentMoveY;
- break;
- case MotionEvent.ACTION_UP:
- if (mCheckBeginEditOnUpEvent) {
- mCheckBeginEditOnUpEvent = false;
- final long deltaTapTimeMillis = ev.getEventTime() - mLastUpEventTimeMillis;
- if (deltaTapTimeMillis < ViewConfiguration.getDoubleTapTimeout()) {
- setSelectorWheelState(SELECTOR_WHEEL_STATE_SMALL);
- showInputControls(mShowInputControlsAnimimationDuration);
- mInputText.requestFocus();
- InputMethodManager inputMethodManager = InputMethodManager.peekInstance();
- if (inputMethodManager != null) {
- inputMethodManager.showSoftInput(mInputText, 0);
- }
- mLastUpEventTimeMillis = ev.getEventTime();
- return true;
- }
- }
+ mLastDownOrMoveEventY = currentMoveY;
+ } break;
+ case MotionEvent.ACTION_UP: {
+ removeBeginSoftInputCommand();
+ removeChangeCurrentByOneFromLongPress();
VelocityTracker velocityTracker = mVelocityTracker;
velocityTracker.computeCurrentVelocity(1000, mMaximumFlingVelocity);
int initialVelocity = (int) velocityTracker.getYVelocity();
if (Math.abs(initialVelocity) > mMinimumFlingVelocity) {
- fling(initialVelocity);
+ int deltaMove = (int) (event.getY() - mLastDownEventY);
+ int absDeltaMoveY = Math.abs(deltaMove);
+ if (absDeltaMoveY > mMinFlingDistance) {
+ fling(initialVelocity);
+ } else {
+ changeValueByOne(deltaMove < 0);
+ }
onScrollStateChange(OnScrollListener.SCROLL_STATE_FLING);
} else {
- if (mAdjustScrollerOnUpEvent) {
- if (mFlingScroller.isFinished() && mAdjustScroller.isFinished()) {
- postAdjustScrollerCommand(0);
+ int eventY = (int) event.getY();
+ int deltaMoveY = (int) Math.abs(eventY - mLastDownEventY);
+ long deltaTime = event.getEventTime() - mLastDownEventTime;
+ if (deltaMoveY <= mTouchSlop && deltaTime < ViewConfiguration.getTapTimeout()) {
+ if (mShowSoftInputOnTap) {
+ mShowSoftInputOnTap = false;
+ showSoftInput();
+ } else {
+ int selectorIndexOffset = (eventY / mSelectorElementHeight)
+ - SELECTOR_MIDDLE_ITEM_INDEX;
+ if (selectorIndexOffset > 0) {
+ changeValueByOne(true);
+ } else if (selectorIndexOffset < 0) {
+ changeValueByOne(false);
+ }
}
} else {
- postAdjustScrollerCommand(SHOW_INPUT_CONTROLS_DELAY_MILLIS);
+ ensureScrollWheelAdjusted();
}
+ onScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
}
mVelocityTracker.recycle();
mVelocityTracker = null;
- mLastUpEventTimeMillis = ev.getEventTime();
- break;
+ } break;
}
return true;
}
@@ -891,12 +874,6 @@ public class NumberPicker extends LinearLayout {
public boolean dispatchTouchEvent(MotionEvent event) {
final int action = event.getActionMasked();
switch (action) {
- case MotionEvent.ACTION_MOVE:
- if (mSelectorWheelState == SELECTOR_WHEEL_STATE_LARGE) {
- removeAllCallbacks();
- forceCompleteChangeCurrentByOneViaScroll();
- }
- break;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
removeAllCallbacks();
@@ -907,27 +884,75 @@ public class NumberPicker extends LinearLayout {
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
- int keyCode = event.getKeyCode();
- if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER || keyCode == KeyEvent.KEYCODE_ENTER) {
- removeAllCallbacks();
+ final int keyCode = event.getKeyCode();
+ switch (keyCode) {
+ case KeyEvent.KEYCODE_DPAD_CENTER:
+ case KeyEvent.KEYCODE_ENTER:
+ removeAllCallbacks();
+ break;
}
return super.dispatchKeyEvent(event);
}
@Override
public boolean dispatchTrackballEvent(MotionEvent event) {
- int action = event.getActionMasked();
- if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) {
- removeAllCallbacks();
+ final int action = event.getActionMasked();
+ switch (action) {
+ case MotionEvent.ACTION_CANCEL:
+ case MotionEvent.ACTION_UP:
+ removeAllCallbacks();
+ break;
}
return super.dispatchTrackballEvent(event);
}
@Override
- public void computeScroll() {
- if (mSelectorWheelState == SELECTOR_WHEEL_STATE_NONE) {
- return;
+ protected boolean dispatchHoverEvent(MotionEvent event) {
+ if (!mHasSelectorWheel) {
+ return super.dispatchHoverEvent(event);
+ }
+ if (AccessibilityManager.getInstance(mContext).isEnabled()) {
+ final int eventY = (int) event.getY();
+ final int hoveredVirtualViewId;
+ if (eventY < mTopSelectionDividerTop) {
+ hoveredVirtualViewId = AccessibilityNodeProviderImpl.VIRTUAL_VIEW_ID_DECREMENT;
+ } else if (eventY > mBottomSelectionDividerBottom) {
+ hoveredVirtualViewId = AccessibilityNodeProviderImpl.VIRTUAL_VIEW_ID_INCREMENT;
+ } else {
+ hoveredVirtualViewId = AccessibilityNodeProviderImpl.VIRTUAL_VIEW_ID_INPUT;
+ }
+ final int action = event.getActionMasked();
+ AccessibilityNodeProviderImpl provider =
+ (AccessibilityNodeProviderImpl) getAccessibilityNodeProvider();
+ switch (action) {
+ case MotionEvent.ACTION_HOVER_ENTER: {
+ provider.sendAccessibilityEventForVirtualView(hoveredVirtualViewId,
+ AccessibilityEvent.TYPE_VIEW_HOVER_ENTER);
+ mLastHoveredChildVirtualViewId = hoveredVirtualViewId;
+ } break;
+ case MotionEvent.ACTION_HOVER_MOVE: {
+ if (mLastHoveredChildVirtualViewId != hoveredVirtualViewId
+ && mLastHoveredChildVirtualViewId != View.NO_ID) {
+ provider.sendAccessibilityEventForVirtualView(
+ mLastHoveredChildVirtualViewId,
+ AccessibilityEvent.TYPE_VIEW_HOVER_EXIT);
+ provider.sendAccessibilityEventForVirtualView(hoveredVirtualViewId,
+ AccessibilityEvent.TYPE_VIEW_HOVER_ENTER);
+ mLastHoveredChildVirtualViewId = hoveredVirtualViewId;
+ }
+ } break;
+ case MotionEvent.ACTION_HOVER_EXIT: {
+ provider.sendAccessibilityEventForVirtualView(hoveredVirtualViewId,
+ AccessibilityEvent.TYPE_VIEW_HOVER_EXIT);
+ mLastHoveredChildVirtualViewId = View.NO_ID;
+ } break;
+ }
}
+ return false;
+ }
+
+ @Override
+ public void computeScroll() {
Scroller scroller = mFlingScroller;
if (scroller.isFinished()) {
scroller = mAdjustScroller;
@@ -952,16 +977,17 @@ public class NumberPicker extends LinearLayout {
@Override
public void setEnabled(boolean enabled) {
super.setEnabled(enabled);
- mIncrementButton.setEnabled(enabled);
- mDecrementButton.setEnabled(enabled);
+ if (!mHasSelectorWheel) {
+ mIncrementButton.setEnabled(enabled);
+ }
+ if (!mHasSelectorWheel) {
+ mDecrementButton.setEnabled(enabled);
+ }
mInputText.setEnabled(enabled);
}
@Override
public void scrollBy(int x, int y) {
- if (mSelectorWheelState == SELECTOR_WHEEL_STATE_NONE) {
- return;
- }
int[] selectorIndices = mSelectorIndices;
if (!mWrapSelectorWheel && y > 0
&& selectorIndices[SELECTOR_MIDDLE_ITEM_INDEX] <= mMinValue) {
@@ -977,7 +1003,7 @@ public class NumberPicker extends LinearLayout {
while (mCurrentScrollOffset - mInitialScrollOffset > mSelectorTextGapHeight) {
mCurrentScrollOffset -= mSelectorElementHeight;
decrementSelectorIndices(selectorIndices);
- changeCurrent(selectorIndices[SELECTOR_MIDDLE_ITEM_INDEX]);
+ setValueInternal(selectorIndices[SELECTOR_MIDDLE_ITEM_INDEX], true);
if (!mWrapSelectorWheel && selectorIndices[SELECTOR_MIDDLE_ITEM_INDEX] <= mMinValue) {
mCurrentScrollOffset = mInitialScrollOffset;
}
@@ -985,7 +1011,7 @@ public class NumberPicker extends LinearLayout {
while (mCurrentScrollOffset - mInitialScrollOffset < -mSelectorTextGapHeight) {
mCurrentScrollOffset += mSelectorElementHeight;
incrementSelectorIndices(selectorIndices);
- changeCurrent(selectorIndices[SELECTOR_MIDDLE_ITEM_INDEX]);
+ setValueInternal(selectorIndices[SELECTOR_MIDDLE_ITEM_INDEX], true);
if (!mWrapSelectorWheel && selectorIndices[SELECTOR_MIDDLE_ITEM_INDEX] >= mMaxValue) {
mCurrentScrollOffset = mInitialScrollOffset;
}
@@ -1024,8 +1050,7 @@ public class NumberPicker extends LinearLayout {
*
* @param formatter The formatter object. If formatter is <code>null</code>,
* {@link String#valueOf(int)} will be used.
- *
- * @see #setDisplayedValues(String[])
+ *@see #setDisplayedValues(String[])
*/
public void setFormatter(Formatter formatter) {
if (formatter == mFormatter) {
@@ -1068,26 +1093,35 @@ public class NumberPicker extends LinearLayout {
if (mValue == value) {
return;
}
- if (value < mMinValue) {
- value = mWrapSelectorWheel ? mMaxValue : mMinValue;
- }
- if (value > mMaxValue) {
- value = mWrapSelectorWheel ? mMinValue : mMaxValue;
- }
- mValue = value;
+ setValueInternal(value, false);
initializeSelectorWheelIndices();
- updateInputTextView();
- updateIncrementAndDecrementButtonsVisibilityState();
invalidate();
}
/**
- * Hides the soft input of it is active for the input text.
+ * Shows the soft input for its input text.
+ */
+ private void showSoftInput() {
+ InputMethodManager inputMethodManager = InputMethodManager.peekInstance();
+ if (inputMethodManager != null) {
+ if (mHasSelectorWheel) {
+ mInputText.setVisibility(View.VISIBLE);
+ }
+ mInputText.requestFocus();
+ inputMethodManager.showSoftInput(mInputText, 0);
+ }
+ }
+
+ /**
+ * Hides the soft input if it is active for the input text.
*/
private void hideSoftInput() {
InputMethodManager inputMethodManager = InputMethodManager.peekInstance();
if (inputMethodManager != null && inputMethodManager.isActive(mInputText)) {
inputMethodManager.hideSoftInputFromWindow(getWindowToken(), 0);
+ if (mHasSelectorWheel) {
+ mInputText.setVisibility(View.INVISIBLE);
+ }
}
}
@@ -1151,23 +1185,22 @@ public class NumberPicker extends LinearLayout {
* wrap around the {@link NumberPicker#getMinValue()} and
* {@link NumberPicker#getMaxValue()} values.
* <p>
- * By default if the range (max - min) is more than five (the number of
- * items shown on the selector wheel) the selector wheel wrapping is
- * enabled.
+ * By default if the range (max - min) is more than the number of items shown
+ * on the selector wheel the selector wheel wrapping is enabled.
* </p>
* <p>
- * <strong>Note:</strong> If the number of items, i.e. the range
- * ({@link #getMaxValue()} - {@link #getMinValue()}) is less than
- * {@link #SELECTOR_WHEEL_ITEM_COUNT}, the selector wheel will not
- * wrap. Hence, in such a case calling this method is a NOP.
+ * <strong>Note:</strong> If the number of items, i.e. the range (
+ * {@link #getMaxValue()} - {@link #getMinValue()}) is less than
+ * the number of items shown on the selector wheel, the selector wheel will
+ * not wrap. Hence, in such a case calling this method is a NOP.
* </p>
+ *
* @param wrapSelectorWheel Whether to wrap.
*/
public void setWrapSelectorWheel(boolean wrapSelectorWheel) {
final boolean wrappingAllowed = (mMaxValue - mMinValue) >= mSelectorIndices.length;
if ((!wrapSelectorWheel || wrappingAllowed) && wrapSelectorWheel != mWrapSelectorWheel) {
mWrapSelectorWheel = wrapSelectorWheel;
- updateIncrementAndDecrementButtonsVisibilityState();
}
}
@@ -1224,6 +1257,7 @@ public class NumberPicker extends LinearLayout {
initializeSelectorWheelIndices();
updateInputTextView();
tryComputeMaxWidth();
+ invalidate();
}
/**
@@ -1256,6 +1290,7 @@ public class NumberPicker extends LinearLayout {
initializeSelectorWheelIndices();
updateInputTextView();
tryComputeMaxWidth();
+ invalidate();
}
/**
@@ -1300,102 +1335,49 @@ public class NumberPicker extends LinearLayout {
}
@Override
- protected void onAttachedToWindow() {
- super.onAttachedToWindow();
- // make sure we show the controls only the very
- // first time the user sees this widget
- if (mFlingable && !isInEditMode()) {
- // animate a bit slower the very first time
- showInputControls(mShowInputControlsAnimimationDuration * 2);
- }
- }
-
- @Override
protected void onDetachedFromWindow() {
removeAllCallbacks();
}
@Override
- protected void dispatchDraw(Canvas canvas) {
- // There is a good reason for doing this. See comments in draw().
- }
-
- @Override
- public void draw(Canvas canvas) {
- // Dispatch draw to our children only if we are not currently running
- // the animation for simultaneously dimming the scroll wheel and
- // showing in the buttons. This class takes advantage of the View
- // implementation of fading edges effect to draw the selector wheel.
- // However, in View.draw(), the fading is applied after all the children
- // have been drawn and we do not want this fading to be applied to the
- // buttons. Therefore, we draw our children after we have completed
- // drawing ourselves.
- super.draw(canvas);
-
- // Draw our children if we are not showing the selector wheel of fading
- // it out
- if (mShowInputControlsAnimator.isRunning()
- || mSelectorWheelState != SELECTOR_WHEEL_STATE_LARGE) {
- long drawTime = getDrawingTime();
- for (int i = 0, count = getChildCount(); i < count; i++) {
- View child = getChildAt(i);
- if (!child.isShown()) {
- continue;
- }
- drawChild(canvas, getChildAt(i), drawTime);
- }
- }
- }
-
- @Override
protected void onDraw(Canvas canvas) {
- if (mSelectorWheelState == SELECTOR_WHEEL_STATE_NONE) {
+ if (!mHasSelectorWheel) {
+ super.onDraw(canvas);
return;
}
-
float x = (mRight - mLeft) / 2;
float y = mCurrentScrollOffset;
- final int restoreCount = canvas.save();
-
- if (mSelectorWheelState == SELECTOR_WHEEL_STATE_SMALL) {
- Rect clipBounds = canvas.getClipBounds();
- clipBounds.inset(0, mSelectorElementHeight);
- canvas.clipRect(clipBounds);
- }
-
// draw the selector wheel
int[] selectorIndices = mSelectorIndices;
for (int i = 0; i < selectorIndices.length; i++) {
int selectorIndex = selectorIndices[i];
String scrollSelectorValue = mSelectorIndexToStringCache.get(selectorIndex);
- // Do not draw the middle item if input is visible since the input is shown only
- // if the wheel is static and it covers the middle item. Otherwise, if the user
- // starts editing the text via the IME he may see a dimmed version of the old
- // value intermixed with the new one.
+ // Do not draw the middle item if input is visible since the input
+ // is shown only if the wheel is static and it covers the middle
+ // item. Otherwise, if the user starts editing the text via the
+ // IME he may see a dimmed version of the old value intermixed
+ // with the new one.
if (i != SELECTOR_MIDDLE_ITEM_INDEX || mInputText.getVisibility() != VISIBLE) {
canvas.drawText(scrollSelectorValue, x, y, mSelectorWheelPaint);
}
y += mSelectorElementHeight;
}
- // draw the selection dividers (only if scrolling and drawable specified)
+ // draw the selection dividers
if (mSelectionDivider != null) {
// draw the top divider
- int topOfTopDivider =
- (getHeight() - mSelectorElementHeight - mSelectionDividerHeight) / 2;
+ int topOfTopDivider = mTopSelectionDividerTop;
int bottomOfTopDivider = topOfTopDivider + mSelectionDividerHeight;
mSelectionDivider.setBounds(0, topOfTopDivider, mRight, bottomOfTopDivider);
mSelectionDivider.draw(canvas);
// draw the bottom divider
- int topOfBottomDivider = topOfTopDivider + mSelectorElementHeight;
- int bottomOfBottomDivider = bottomOfTopDivider + mSelectorElementHeight;
+ int bottomOfBottomDivider = mBottomSelectionDividerBottom;
+ int topOfBottomDivider = bottomOfBottomDivider - mSelectionDividerHeight;
mSelectionDivider.setBounds(0, topOfBottomDivider, mRight, bottomOfBottomDivider);
mSelectionDivider.draw(canvas);
}
-
- canvas.restoreToCount(restoreCount);
}
@Override
@@ -1408,12 +1390,20 @@ public class NumberPicker extends LinearLayout {
public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
super.onInitializeAccessibilityEvent(event);
event.setClassName(NumberPicker.class.getName());
+ event.setScrollable(true);
+ event.setScrollY((mMinValue + mValue) * mSelectorElementHeight);
+ event.setMaxScrollY((mMaxValue - mMinValue) * mSelectorElementHeight);
}
@Override
- public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
- super.onInitializeAccessibilityNodeInfo(info);
- info.setClassName(NumberPicker.class.getName());
+ public AccessibilityNodeProvider getAccessibilityNodeProvider() {
+ if (!mHasSelectorWheel) {
+ return super.getAccessibilityNodeProvider();
+ }
+ if (mAccessibilityNodeProvider == null) {
+ mAccessibilityNodeProvider = new AccessibilityNodeProviderImpl();
+ }
+ return mAccessibilityNodeProvider;
}
/**
@@ -1442,17 +1432,17 @@ public class NumberPicker extends LinearLayout {
}
/**
- * Utility to reconcile a desired size and state, with constraints imposed by
- * a MeasureSpec. Tries to respect the min size, unless a different size is
- * imposed by the constraints.
+ * Utility to reconcile a desired size and state, with constraints imposed
+ * by a MeasureSpec. Tries to respect the min size, unless a different size
+ * is imposed by the constraints.
*
* @param minSize The minimal desired size.
* @param measuredSize The currently measured size.
* @param measureSpec The current measure spec.
* @return The resolved size and state.
*/
- private int resolveSizeAndStateRespectingMinSize(int minSize, int measuredSize,
- int measureSpec) {
+ private int resolveSizeAndStateRespectingMinSize(
+ int minSize, int measuredSize, int measureSpec) {
if (minSize != SIZE_UNSPECIFIED) {
final int desiredWidth = Math.max(minSize, measuredSize);
return resolveSizeAndState(desiredWidth, measureSpec, 0);
@@ -1462,8 +1452,8 @@ public class NumberPicker extends LinearLayout {
}
/**
- * Resets the selector indices and clear the cached
- * string representation of these indices.
+ * Resets the selector indices and clear the cached string representation of
+ * these indices.
*/
private void initializeSelectorWheelIndices() {
mSelectorIndexToStringCache.clear();
@@ -1480,39 +1470,44 @@ public class NumberPicker extends LinearLayout {
}
/**
- * Sets the current value of this NumberPicker, and sets mPrevious to the
- * previous value. If current is greater than mEnd less than mStart, the
- * value of mCurrent is wrapped around. Subclasses can override this to
- * change the wrapping behavior
+ * Sets the current value of this NumberPicker.
*
- * @param current the new value of the NumberPicker
+ * @param current The new value of the NumberPicker.
+ * @param notifyChange Whether to notify if the current value changed.
*/
- private void changeCurrent(int current) {
+ private void setValueInternal(int current, boolean notifyChange) {
if (mValue == current) {
return;
}
// Wrap around the values if we go past the start or end
if (mWrapSelectorWheel) {
current = getWrappedSelectorIndex(current);
+ } else {
+ current = Math.max(current, mMinValue);
+ current = Math.min(current, mMaxValue);
}
int previous = mValue;
- setValue(current);
- notifyChange(previous, current);
+ mValue = current;
+ updateInputTextView();
+ if (notifyChange) {
+ notifyChange(previous, current);
+ }
}
/**
* Changes the current value by one which is increment or
* decrement based on the passes argument.
+ * decrement the current value.
*
* @param increment True to increment, false to decrement.
*/
- private void changeCurrentByOne(boolean increment) {
- if (mFlingable) {
- mDimSelectorWheelAnimator.cancel();
+ private void changeValueByOne(boolean increment) {
+ if (mHasSelectorWheel) {
mInputText.setVisibility(View.INVISIBLE);
- mSelectorWheelPaint.setAlpha(SELECTOR_WHEEL_BRIGHT_ALPHA);
+ if (!moveToFinalScrollerPosition(mFlingScroller)) {
+ moveToFinalScrollerPosition(mAdjustScroller);
+ }
mPreviousScrollerY = 0;
- forceCompleteChangeCurrentByOneViaScroll();
if (increment) {
mFlingScroller.startScroll(0, 0, 0, -mSelectorElementHeight,
CHANGE_CURRENT_BY_ONE_SCROLL_DURATION);
@@ -1523,81 +1518,26 @@ public class NumberPicker extends LinearLayout {
invalidate();
} else {
if (increment) {
- changeCurrent(mValue + 1);
+ setValueInternal(mValue + 1, true);
} else {
- changeCurrent(mValue - 1);
+ setValueInternal(mValue - 1, true);
}
}
}
- /**
- * Ensures that if we are in the process of changing the current value
- * by one via scrolling the scroller gets to its final state and the
- * value is updated.
- */
- private void forceCompleteChangeCurrentByOneViaScroll() {
- Scroller scroller = mFlingScroller;
- if (!scroller.isFinished()) {
- final int yBeforeAbort = scroller.getCurrY();
- scroller.abortAnimation();
- final int yDelta = scroller.getCurrY() - yBeforeAbort;
- scrollBy(0, yDelta);
- }
- }
-
- /**
- * Sets the <code>alpha</code> of the {@link Paint} for drawing the selector
- * wheel.
- */
- @SuppressWarnings("unused")
- // Called via reflection
- private void setSelectorPaintAlpha(int alpha) {
- mSelectorWheelPaint.setAlpha(alpha);
- invalidate();
- }
-
- /**
- * @return If the <code>event</code> is in the visible <code>view</code>.
- */
- private boolean isEventInVisibleViewHitRect(MotionEvent event, View view) {
- if (view.getVisibility() == VISIBLE) {
- view.getHitRect(mTempRect);
- return mTempRect.contains((int) event.getX(), (int) event.getY());
- }
- return false;
- }
-
- /**
- * Sets the <code>selectorWheelState</code>.
- */
- private void setSelectorWheelState(int selectorWheelState) {
- mSelectorWheelState = selectorWheelState;
- if (selectorWheelState == SELECTOR_WHEEL_STATE_LARGE) {
- mSelectorWheelPaint.setAlpha(SELECTOR_WHEEL_BRIGHT_ALPHA);
- }
-
- if (mFlingable && selectorWheelState == SELECTOR_WHEEL_STATE_LARGE
- && AccessibilityManager.getInstance(mContext).isEnabled()) {
- AccessibilityManager.getInstance(mContext).interrupt();
- String text = mContext.getString(R.string.number_picker_increment_scroll_action);
- mInputText.setContentDescription(text);
- mInputText.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED);
- mInputText.setContentDescription(null);
- }
- }
-
private void initializeSelectorWheel() {
initializeSelectorWheelIndices();
int[] selectorIndices = mSelectorIndices;
int totalTextHeight = selectorIndices.length * mTextSize;
float totalTextGapHeight = (mBottom - mTop) - totalTextHeight;
- float textGapCount = selectorIndices.length - 1;
+ float textGapCount = selectorIndices.length;
mSelectorTextGapHeight = (int) (totalTextGapHeight / textGapCount + 0.5f);
mSelectorElementHeight = mTextSize + mSelectorTextGapHeight;
- // Ensure that the middle item is positioned the same as the text in mInputText
+ // Ensure that the middle item is positioned the same as the text in
+ // mInputText
int editTextTextPosition = mInputText.getBaseline() + mInputText.getTop();
- mInitialScrollOffset = editTextTextPosition -
- (mSelectorElementHeight * SELECTOR_MIDDLE_ITEM_INDEX);
+ mInitialScrollOffset = editTextTextPosition
+ - (mSelectorElementHeight * SELECTOR_MIDDLE_ITEM_INDEX);
mCurrentScrollOffset = mInitialScrollOffset;
updateInputTextView();
}
@@ -1612,16 +1552,14 @@ public class NumberPicker extends LinearLayout {
*/
private void onScrollerFinished(Scroller scroller) {
if (scroller == mFlingScroller) {
- if (mSelectorWheelState == SELECTOR_WHEEL_STATE_LARGE) {
- postAdjustScrollerCommand(0);
- onScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
- } else {
+ if (!ensureScrollWheelAdjusted()) {
updateInputTextView();
- fadeSelectorWheel(mShowInputControlsAnimimationDuration);
}
+ onScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
} else {
- updateInputTextView();
- showInputControls(mShowInputControlsAnimimationDuration);
+ if (mScrollState != OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) {
+ updateInputTextView();
+ }
}
}
@@ -1654,56 +1592,6 @@ public class NumberPicker extends LinearLayout {
}
/**
- * Hides the input controls which is the up/down arrows and the text field.
- */
- private void hideInputControls() {
- mShowInputControlsAnimator.cancel();
- mIncrementButton.setVisibility(INVISIBLE);
- mDecrementButton.setVisibility(INVISIBLE);
- mInputText.setVisibility(INVISIBLE);
- }
-
- /**
- * Show the input controls by making them visible and animating the alpha
- * property up/down arrows.
- *
- * @param animationDuration The duration of the animation.
- */
- private void showInputControls(long animationDuration) {
- updateIncrementAndDecrementButtonsVisibilityState();
- mInputText.setVisibility(VISIBLE);
- mShowInputControlsAnimator.setDuration(animationDuration);
- mShowInputControlsAnimator.start();
- }
-
- /**
- * Fade the selector wheel via an animation.
- *
- * @param animationDuration The duration of the animation.
- */
- private void fadeSelectorWheel(long animationDuration) {
- mInputText.setVisibility(VISIBLE);
- mDimSelectorWheelAnimator.setDuration(animationDuration);
- mDimSelectorWheelAnimator.start();
- }
-
- /**
- * Updates the visibility state of the increment and decrement buttons.
- */
- private void updateIncrementAndDecrementButtonsVisibilityState() {
- if (mWrapSelectorWheel || mValue < mMaxValue) {
- mIncrementButton.setVisibility(VISIBLE);
- } else {
- mIncrementButton.setVisibility(INVISIBLE);
- }
- if (mWrapSelectorWheel || mValue > mMinValue) {
- mDecrementButton.setVisibility(VISIBLE);
- } else {
- mDecrementButton.setVisibility(INVISIBLE);
- }
- }
-
- /**
* @return The wrapped index <code>selectorIndex</code> value.
*/
private int getWrappedSelectorIndex(int selectorIndex) {
@@ -1749,8 +1637,7 @@ public class NumberPicker extends LinearLayout {
/**
* Ensures we have a cached string representation of the given <code>
- * selectorIndex</code>
- * to avoid multiple instantiations of the same string.
+ * selectorIndex</code> to avoid multiple instantiations of the same string.
*/
private void ensureCachedScrollSelectorValue(int selectorIndex) {
SparseArray<String> cache = mSelectorIndexToStringCache;
@@ -1783,7 +1670,7 @@ public class NumberPicker extends LinearLayout {
} else {
// Check the new value and ensure it's in range
int current = getSelectedPos(str.toString());
- changeCurrent(current);
+ setValueInternal(current, true);
}
}
@@ -1792,25 +1679,23 @@ public class NumberPicker extends LinearLayout {
* the string corresponding to the index specified by the current value will
* be returned. Otherwise, the formatter specified in {@link #setFormatter}
* will be used to format the number.
+ *
+ * @return Whether the text was updated.
*/
- private void updateInputTextView() {
+ private boolean updateInputTextView() {
/*
* If we don't have displayed values then use the current number else
* find the correct value in the displayed values for the current
* number.
*/
- if (mDisplayedValues == null) {
- mInputText.setText(formatNumber(mValue));
- } else {
- mInputText.setText(mDisplayedValues[mValue - mMinValue]);
+ String text = (mDisplayedValues == null) ? formatNumber(mValue)
+ : mDisplayedValues[mValue - mMinValue];
+ if (!TextUtils.isEmpty(text) && !text.equals(mInputText.getText().toString())) {
+ mInputText.setText(text);
+ return true;
}
- mInputText.setSelection(mInputText.getText().length());
- if (mFlingable && AccessibilityManager.getInstance(mContext).isEnabled()) {
- String text = mContext.getString(R.string.number_picker_increment_scroll_mode,
- mInputText.getText());
- mInputText.setContentDescription(text);
- }
+ return false;
}
/**
@@ -1828,14 +1713,45 @@ public class NumberPicker extends LinearLayout {
*
* @param increment Whether to increment or decrement the value.
*/
- private void postChangeCurrentByOneFromLongPress(boolean increment) {
- mInputText.clearFocus();
- removeAllCallbacks();
+ private void postChangeCurrentByOneFromLongPress(boolean increment, long delayMillis) {
if (mChangeCurrentByOneFromLongPressCommand == null) {
mChangeCurrentByOneFromLongPressCommand = new ChangeCurrentByOneFromLongPressCommand();
+ } else {
+ removeCallbacks(mChangeCurrentByOneFromLongPressCommand);
+ }
+ mChangeCurrentByOneFromLongPressCommand.setStep(increment);
+ postDelayed(mChangeCurrentByOneFromLongPressCommand, delayMillis);
+ }
+
+ /**
+ * Removes the command for changing the current value by one.
+ */
+ private void removeChangeCurrentByOneFromLongPress() {
+ if (mChangeCurrentByOneFromLongPressCommand != null) {
+ removeCallbacks(mChangeCurrentByOneFromLongPressCommand);
+ }
+ }
+
+ /**
+ * Posts a command for beginning an edit of the current value via IME on
+ * long press.
+ */
+ private void postBeginSoftInputOnLongPressCommand() {
+ if (mBeginSoftInputOnLongPressCommand == null) {
+ mBeginSoftInputOnLongPressCommand = new BeginSoftInputOnLongPressCommand();
+ } else {
+ removeCallbacks(mBeginSoftInputOnLongPressCommand);
+ }
+ postDelayed(mBeginSoftInputOnLongPressCommand, ViewConfiguration.getLongPressTimeout());
+ }
+
+ /**
+ * Removes the command for beginning an edit of the current value via IME.
+ */
+ private void removeBeginSoftInputCommand() {
+ if (mBeginSoftInputOnLongPressCommand != null) {
+ removeCallbacks(mBeginSoftInputOnLongPressCommand);
}
- mChangeCurrentByOneFromLongPressCommand.setIncrement(increment);
- post(mChangeCurrentByOneFromLongPressCommand);
}
/**
@@ -1845,12 +1761,12 @@ public class NumberPicker extends LinearLayout {
if (mChangeCurrentByOneFromLongPressCommand != null) {
removeCallbacks(mChangeCurrentByOneFromLongPressCommand);
}
- if (mAdjustScrollerCommand != null) {
- removeCallbacks(mAdjustScrollerCommand);
- }
if (mSetSelectionCommand != null) {
removeCallbacks(mSetSelectionCommand);
}
+ if (mBeginSoftInputOnLongPressCommand != null) {
+ removeCallbacks(mBeginSoftInputOnLongPressCommand);
+ }
}
/**
@@ -1888,8 +1804,7 @@ public class NumberPicker extends LinearLayout {
/**
* Posts an {@link SetSelectionCommand} from the given <code>selectionStart
- * </code> to
- * <code>selectionEnd</code>.
+ * </code> to <code>selectionEnd</code>.
*/
private void postSetSelectionCommand(int selectionStart, int selectionEnd) {
if (mSetSelectionCommand == null) {
@@ -1903,20 +1818,6 @@ public class NumberPicker extends LinearLayout {
}
/**
- * Posts an {@link AdjustScrollerCommand} within the given <code>
- * delayMillis</code>
- * .
- */
- private void postAdjustScrollerCommand(int delayMillis) {
- if (mAdjustScrollerCommand == null) {
- mAdjustScrollerCommand = new AdjustScrollerCommand();
- } else {
- removeCallbacks(mAdjustScrollerCommand);
- }
- postDelayed(mAdjustScrollerCommand, delayMillis);
- }
-
- /**
* Filter for accepting only valid indices or prefixes of the string
* representation of valid indices.
*/
@@ -1934,8 +1835,8 @@ public class NumberPicker extends LinearLayout {
}
@Override
- public CharSequence filter(CharSequence source, int start, int end, Spanned dest,
- int dstart, int dend) {
+ public CharSequence filter(
+ CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
if (mDisplayedValues == null) {
CharSequence filtered = super.filter(source, start, end, dest, dstart, dend);
if (filtered == null) {
@@ -1981,6 +1882,27 @@ public class NumberPicker extends LinearLayout {
}
/**
+ * Ensures that the scroll wheel is adjusted i.e. there is no offset and the
+ * middle element is in the middle of the widget.
+ *
+ * @return Whether an adjustment has been made.
+ */
+ private boolean ensureScrollWheelAdjusted() {
+ // adjust to the closest value
+ int deltaY = mInitialScrollOffset - mCurrentScrollOffset;
+ if (deltaY != 0) {
+ mPreviousScrollerY = 0;
+ if (Math.abs(deltaY) > mSelectorElementHeight / 2) {
+ deltaY += (deltaY > 0) ? -mSelectorElementHeight : mSelectorElementHeight;
+ }
+ mAdjustScroller.startScroll(0, 0, 0, deltaY, SELECTOR_ADJUSTMENT_DURATION_MILLIS);
+ invalidate();
+ return true;
+ }
+ return false;
+ }
+
+ /**
* Command for setting the input text selection.
*/
class SetSelectionCommand implements Runnable {
@@ -1994,39 +1916,18 @@ public class NumberPicker extends LinearLayout {
}
/**
- * Command for adjusting the scroller to show in its center the closest of
- * the displayed items.
- */
- class AdjustScrollerCommand implements Runnable {
- public void run() {
- mPreviousScrollerY = 0;
- if (mInitialScrollOffset == mCurrentScrollOffset) {
- updateInputTextView();
- showInputControls(mShowInputControlsAnimimationDuration);
- return;
- }
- // adjust to the closest value
- int deltaY = mInitialScrollOffset - mCurrentScrollOffset;
- if (Math.abs(deltaY) > mSelectorElementHeight / 2) {
- deltaY += (deltaY > 0) ? -mSelectorElementHeight : mSelectorElementHeight;
- }
- mAdjustScroller.startScroll(0, 0, 0, deltaY, SELECTOR_ADJUSTMENT_DURATION_MILLIS);
- invalidate();
- }
- }
-
- /**
* Command for changing the current value from a long press by one.
*/
class ChangeCurrentByOneFromLongPressCommand implements Runnable {
private boolean mIncrement;
- private void setIncrement(boolean increment) {
+ private void setStep(boolean increment) {
mIncrement = increment;
}
+ @Override
public void run() {
- changeCurrentByOne(mIncrement);
+ changeValueByOne(mIncrement);
postDelayed(this, mLongPressUpdateInterval);
}
}
@@ -2048,4 +1949,248 @@ public class NumberPicker extends LinearLayout {
}
}
}
+
+ /**
+ * Command for beginning soft input on long press.
+ */
+ class BeginSoftInputOnLongPressCommand implements Runnable {
+
+ @Override
+ public void run() {
+ showSoftInput();
+ mIngonreMoveEvents = true;
+ }
+ }
+
+ class AccessibilityNodeProviderImpl extends AccessibilityNodeProvider {
+ private static final int VIRTUAL_VIEW_ID_INCREMENT = 1;
+
+ private static final int VIRTUAL_VIEW_ID_INPUT = 2;
+
+ private static final int VIRTUAL_VIEW_ID_DECREMENT = 3;
+
+ private final Rect mTempRect = new Rect();
+
+ private final int[] mTempArray = new int[2];
+
+ @Override
+ public AccessibilityNodeInfo createAccessibilityNodeInfo(int virtualViewId) {
+ switch (virtualViewId) {
+ case View.NO_ID:
+ return createAccessibilityNodeInfoForNumberPicker( mScrollX, mScrollY,
+ mScrollX + (mRight - mLeft), mScrollY + (mBottom - mTop));
+ case VIRTUAL_VIEW_ID_DECREMENT:
+ return createAccessibilityNodeInfoForVirtualButton(VIRTUAL_VIEW_ID_DECREMENT,
+ getVirtualDecrementButtonText(), mScrollX, mScrollY,
+ mScrollX + (mRight - mLeft),
+ mTopSelectionDividerTop + mSelectionDividerHeight);
+ case VIRTUAL_VIEW_ID_INPUT:
+ return createAccessibiltyNodeInfoForInputText();
+ case VIRTUAL_VIEW_ID_INCREMENT:
+ return createAccessibilityNodeInfoForVirtualButton(VIRTUAL_VIEW_ID_INCREMENT,
+ getVirtualIncrementButtonText(), mScrollX,
+ mBottomSelectionDividerBottom - mSelectionDividerHeight,
+ mScrollX + (mRight - mLeft), mScrollY + (mBottom - mTop));
+ }
+ return super.createAccessibilityNodeInfo(virtualViewId);
+ }
+
+ @Override
+ public List<AccessibilityNodeInfo> findAccessibilityNodeInfosByText(String searched,
+ int virtualViewId) {
+ if (TextUtils.isEmpty(searched)) {
+ return Collections.emptyList();
+ }
+ String searchedLowerCase = searched.toLowerCase();
+ List<AccessibilityNodeInfo> result = new ArrayList<AccessibilityNodeInfo>();
+ switch (virtualViewId) {
+ case View.NO_ID: {
+ findAccessibilityNodeInfosByTextInChild(searchedLowerCase,
+ VIRTUAL_VIEW_ID_DECREMENT, result);
+ findAccessibilityNodeInfosByTextInChild(searchedLowerCase,
+ VIRTUAL_VIEW_ID_INPUT, result);
+ findAccessibilityNodeInfosByTextInChild(searchedLowerCase,
+ VIRTUAL_VIEW_ID_INCREMENT, result);
+ return result;
+ }
+ case VIRTUAL_VIEW_ID_DECREMENT:
+ case VIRTUAL_VIEW_ID_INCREMENT:
+ case VIRTUAL_VIEW_ID_INPUT: {
+ findAccessibilityNodeInfosByTextInChild(searchedLowerCase, virtualViewId,
+ result);
+ return result;
+ }
+ }
+ return super.findAccessibilityNodeInfosByText(searched, virtualViewId);
+ }
+
+ @Override
+ public boolean performAccessibilityAction(int action, int virtualViewId) {
+ switch (virtualViewId) {
+ case VIRTUAL_VIEW_ID_INPUT: {
+ switch (action) {
+ case AccessibilityNodeInfo.ACTION_FOCUS: {
+ if (!mInputText.isFocused()) {
+ return mInputText.requestFocus();
+ }
+ } break;
+ case AccessibilityNodeInfo.ACTION_CLEAR_FOCUS: {
+ if (mInputText.isFocused()) {
+ mInputText.clearFocus();
+ return true;
+ }
+ } break;
+ }
+ } break;
+ }
+ return super.performAccessibilityAction(action, virtualViewId);
+ }
+
+ public void sendAccessibilityEventForVirtualView(int virtualViewId, int eventType) {
+ switch (virtualViewId) {
+ case VIRTUAL_VIEW_ID_DECREMENT: {
+ sendAccessibilityEventForVirtualButton(virtualViewId, eventType,
+ getVirtualDecrementButtonText());
+ } break;
+ case VIRTUAL_VIEW_ID_INPUT: {
+ sendAccessibilityEventForVirtualText(eventType);
+ } break;
+ case VIRTUAL_VIEW_ID_INCREMENT: {
+ sendAccessibilityEventForVirtualButton(virtualViewId, eventType,
+ getVirtualIncrementButtonText());
+ } break;
+ }
+ }
+
+ private void sendAccessibilityEventForVirtualText(int eventType) {
+ AccessibilityEvent event = AccessibilityEvent.obtain(eventType);
+ mInputText.onInitializeAccessibilityEvent(event);
+ mInputText.onPopulateAccessibilityEvent(event);
+ event.setSource(NumberPicker.this, VIRTUAL_VIEW_ID_INPUT);
+ requestSendAccessibilityEvent(NumberPicker.this, event);
+ }
+
+ private void sendAccessibilityEventForVirtualButton(int virtualViewId, int eventType,
+ String text) {
+ AccessibilityEvent event = AccessibilityEvent.obtain(eventType);
+ event.setClassName(Button.class.getName());
+ event.setPackageName(mContext.getPackageName());
+ event.getText().add(text);
+ event.setEnabled(NumberPicker.this.isEnabled());
+ event.setSource(NumberPicker.this, virtualViewId);
+ requestSendAccessibilityEvent(NumberPicker.this, event);
+ }
+
+ private void findAccessibilityNodeInfosByTextInChild(String searchedLowerCase,
+ int virtualViewId, List<AccessibilityNodeInfo> outResult) {
+ switch (virtualViewId) {
+ case VIRTUAL_VIEW_ID_DECREMENT: {
+ String text = getVirtualDecrementButtonText();
+ if (!TextUtils.isEmpty(text)
+ && text.toString().toLowerCase().contains(searchedLowerCase)) {
+ outResult.add(createAccessibilityNodeInfo(VIRTUAL_VIEW_ID_DECREMENT));
+ }
+ } return;
+ case VIRTUAL_VIEW_ID_INPUT: {
+ CharSequence text = mInputText.getText();
+ if (!TextUtils.isEmpty(text) &&
+ text.toString().toLowerCase().contains(searchedLowerCase)) {
+ outResult.add(createAccessibilityNodeInfo(VIRTUAL_VIEW_ID_INPUT));
+ return;
+ }
+ CharSequence contentDesc = mInputText.getText();
+ if (!TextUtils.isEmpty(contentDesc) &&
+ contentDesc.toString().toLowerCase().contains(searchedLowerCase)) {
+ outResult.add(createAccessibilityNodeInfo(VIRTUAL_VIEW_ID_INPUT));
+ return;
+ }
+ } break;
+ case VIRTUAL_VIEW_ID_INCREMENT: {
+ String text = getVirtualIncrementButtonText();
+ if (!TextUtils.isEmpty(text)
+ && text.toString().toLowerCase().contains(searchedLowerCase)) {
+ outResult.add(createAccessibilityNodeInfo(VIRTUAL_VIEW_ID_INCREMENT));
+ }
+ } return;
+ }
+ }
+
+ private AccessibilityNodeInfo createAccessibiltyNodeInfoForInputText() {
+ AccessibilityNodeInfo info = mInputText.createAccessibilityNodeInfo();
+ info.setLongClickable(true);
+ info.setSource(NumberPicker.this, VIRTUAL_VIEW_ID_INPUT);
+ return info;
+ }
+
+ private AccessibilityNodeInfo createAccessibilityNodeInfoForVirtualButton(int virtualViewId,
+ String text, int left, int top, int right, int bottom) {
+ AccessibilityNodeInfo info = AccessibilityNodeInfo.obtain();
+ info.setClassName(Button.class.getName());
+ info.setPackageName(mContext.getPackageName());
+ info.setSource(NumberPicker.this, virtualViewId);
+ info.setParent(NumberPicker.this);
+ info.addChild(NumberPicker.this, VIRTUAL_VIEW_ID_DECREMENT);
+ info.addChild(NumberPicker.this, VIRTUAL_VIEW_ID_INPUT);
+ info.addChild(NumberPicker.this, VIRTUAL_VIEW_ID_INCREMENT);
+ info.setText(text);
+ info.setClickable(true);
+ info.setLongClickable(true);
+ info.setEnabled(NumberPicker.this.isEnabled());
+ Rect boundsInParent = mTempRect;
+ boundsInParent.set(left, top, right, bottom);
+ info.setBoundsInParent(boundsInParent);
+ Rect boundsInScreen = boundsInParent;
+ int[] locationOnScreen = mTempArray;
+ getLocationOnScreen(locationOnScreen);
+ boundsInScreen.offsetTo(0, 0);
+ boundsInScreen.offset(locationOnScreen[0], locationOnScreen[1]);
+ info.setBoundsInScreen(boundsInScreen);
+ return info;
+ }
+
+ private AccessibilityNodeInfo createAccessibilityNodeInfoForNumberPicker(int left, int top,
+ int right, int bottom) {
+ AccessibilityNodeInfo info = AccessibilityNodeInfo.obtain();
+ info.setClassName(Button.class.getName());
+ info.setPackageName(mContext.getPackageName());
+ info.setSource(NumberPicker.this);
+ info.setParent((View) getParent());
+ info.setEnabled(NumberPicker.this.isEnabled());
+ info.setScrollable(true);
+ Rect boundsInParent = mTempRect;
+ boundsInParent.set(left, top, right, bottom);
+ info.setBoundsInParent(boundsInParent);
+ Rect boundsInScreen = boundsInParent;
+ int[] locationOnScreen = mTempArray;
+ getLocationOnScreen(locationOnScreen);
+ boundsInScreen.offsetTo(0, 0);
+ boundsInScreen.offset(locationOnScreen[0], locationOnScreen[1]);
+ info.setBoundsInScreen(boundsInScreen);
+ return info;
+ }
+
+ private String getVirtualDecrementButtonText() {
+ int value = mValue - 1;
+ if (mWrapSelectorWheel) {
+ value = getWrappedSelectorIndex(value);
+ }
+ if (value >= mMinValue) {
+ return (mDisplayedValues == null) ? formatNumber(value)
+ : mDisplayedValues[value - mMinValue];
+ }
+ return null;
+ }
+
+ private String getVirtualIncrementButtonText() {
+ int value = mValue + 1;
+ if (mWrapSelectorWheel) {
+ value = getWrappedSelectorIndex(value);
+ }
+ if (value <= mMaxValue) {
+ return (mDisplayedValues == null) ? formatNumber(value)
+ : mDisplayedValues[value - mMinValue];
+ }
+ return null;
+ }
+ }
}
diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java
index 25dd438c4693..e0e3e93d99a8 100644
--- a/core/java/android/widget/ScrollView.java
+++ b/core/java/android/widget/ScrollView.java
@@ -642,8 +642,7 @@ public class ScrollView extends FrameLayout {
break;
case MotionEvent.ACTION_POINTER_DOWN: {
final int index = ev.getActionIndex();
- final float y = ev.getY(index);
- mLastMotionY = y;
+ mLastMotionY = ev.getY(index);
mActivePointerId = ev.getPointerId(index);
break;
}
@@ -715,6 +714,7 @@ public class ScrollView extends FrameLayout {
} else {
super.scrollTo(scrollX, scrollY);
}
+
awakenScrollBars();
}
@@ -749,42 +749,6 @@ public class ScrollView extends FrameLayout {
/**
* <p>
- * Finds the next focusable component that fits in this View's bounds
- * (excluding fading edges) pretending that this View's top is located at
- * the parameter top.
- * </p>
- *
- * @param topFocus look for a candidate at the top of the bounds if topFocus is true,
- * or at the bottom of the bounds if topFocus is false
- * @param top the top offset of the bounds in which a focusable must be
- * found (the fading edge is assumed to start at this position)
- * @param preferredFocusable the View that has highest priority and will be
- * returned if it is within my bounds (null is valid)
- * @return the next focusable component in the bounds or null if none can be found
- */
- private View findFocusableViewInMyBounds(final boolean topFocus,
- final int top, View preferredFocusable) {
- /*
- * The fading edge's transparent side should be considered for focus
- * since it's mostly visible, so we divide the actual fading edge length
- * by 2.
- */
- final int fadingEdgeLength = getVerticalFadingEdgeLength() / 2;
- final int topWithoutFadingEdge = top + fadingEdgeLength;
- final int bottomWithoutFadingEdge = top + getHeight() - fadingEdgeLength;
-
- if ((preferredFocusable != null)
- && (preferredFocusable.getTop() < bottomWithoutFadingEdge)
- && (preferredFocusable.getBottom() > topWithoutFadingEdge)) {
- return preferredFocusable;
- }
-
- return findFocusableViewInBounds(topFocus, topWithoutFadingEdge,
- bottomWithoutFadingEdge);
- }
-
- /**
- * <p>
* Finds the next focusable component that fits in the specified bounds.
* </p>
*
@@ -1208,10 +1172,10 @@ public class ScrollView extends FrameLayout {
}
}
- awakenScrollBars();
-
- // Keep on drawing until the animation has finished.
- postInvalidate();
+ if (!awakenScrollBars()) {
+ // Keep on drawing until the animation has finished.
+ invalidate();
+ }
} else {
if (mFlingStrictSpan != null) {
mFlingStrictSpan.finish();
@@ -1438,7 +1402,7 @@ public class ScrollView extends FrameLayout {
/**
* Return true if child is a descendant of parent, (or equal to the parent).
*/
- private boolean isViewDescendantOf(View child, View parent) {
+ private static boolean isViewDescendantOf(View child, View parent) {
if (child == parent) {
return true;
}
@@ -1462,8 +1426,6 @@ public class ScrollView extends FrameLayout {
mScroller.fling(mScrollX, mScrollY, 0, velocityY, 0, 0, 0,
Math.max(0, bottom - height), 0, height/2);
- final boolean movingDown = velocityY > 0;
-
if (mFlingStrictSpan == null) {
mFlingStrictSpan = StrictMode.enterCriticalSpan("ScrollView-fling");
}
@@ -1554,7 +1516,7 @@ public class ScrollView extends FrameLayout {
}
}
- private int clamp(int n, int my, int child) {
+ private static int clamp(int n, int my, int child) {
if (my >= child || n < 0) {
/* my >= child is this case:
* |--------------- me ---------------|
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 9941c951a953..3c63b17ede3e 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -11680,7 +11680,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
highlight = null;
}
- if (canHaveDisplayList() && canvas.isHardwareAccelerated()) {
+ if (false /* TEMP patch for bugs 6198276 & 6193544 */ && canHaveDisplayList() && canvas.isHardwareAccelerated()) {
drawHardwareAccelerated(canvas, layout, highlight, cursorOffsetVertical);
} else {
layout.draw(canvas, highlight, mHighlightPaint, cursorOffsetVertical);
diff --git a/core/java/android/widget/TimePicker.java b/core/java/android/widget/TimePicker.java
index 7eff1aa04bd2..bc88b622eaf4 100644
--- a/core/java/android/widget/TimePicker.java
+++ b/core/java/android/widget/TimePicker.java
@@ -532,21 +532,28 @@ public class TimePicker extends FrameLayout {
private void setContentDescriptions() {
// Minute
- String text = mContext.getString(R.string.time_picker_increment_minute_button);
- mMinuteSpinner.findViewById(R.id.increment).setContentDescription(text);
- text = mContext.getString(R.string.time_picker_decrement_minute_button);
- mMinuteSpinner.findViewById(R.id.decrement).setContentDescription(text);
+ trySetContentDescription(mMinuteSpinner, R.id.increment,
+ R.string.time_picker_increment_minute_button);
+ trySetContentDescription(mMinuteSpinner, R.id.decrement,
+ R.string.time_picker_decrement_minute_button);
// Hour
- text = mContext.getString(R.string.time_picker_increment_hour_button);
- mHourSpinner.findViewById(R.id.increment).setContentDescription(text);
- text = mContext.getString(R.string.time_picker_decrement_hour_button);
- mHourSpinner.findViewById(R.id.decrement).setContentDescription(text);
+ trySetContentDescription(mHourSpinner, R.id.increment,
+ R.string.time_picker_increment_hour_button);
+ trySetContentDescription(mHourSpinner, R.id.decrement,
+ R.string.time_picker_decrement_hour_button);
// AM/PM
if (mAmPmSpinner != null) {
- text = mContext.getString(R.string.time_picker_increment_set_pm_button);
- mAmPmSpinner.findViewById(R.id.increment).setContentDescription(text);
- text = mContext.getString(R.string.time_picker_decrement_set_am_button);
- mAmPmSpinner.findViewById(R.id.decrement).setContentDescription(text);
+ trySetContentDescription(mAmPmSpinner, R.id.increment,
+ R.string.time_picker_increment_set_pm_button);
+ trySetContentDescription(mAmPmSpinner, R.id.decrement,
+ R.string.time_picker_decrement_set_am_button);
+ }
+ }
+
+ private void trySetContentDescription(View root, int viewId, int contDescResId) {
+ View target = root.findViewById(viewId);
+ if (target != null) {
+ target.setContentDescription(mContext.getString(contDescResId));
}
}
diff --git a/core/java/com/android/internal/view/menu/MenuItemImpl.java b/core/java/com/android/internal/view/menu/MenuItemImpl.java
index 04147ab99e4a..2564921c909f 100644
--- a/core/java/com/android/internal/view/menu/MenuItemImpl.java
+++ b/core/java/com/android/internal/view/menu/MenuItemImpl.java
@@ -382,7 +382,10 @@ public final class MenuItemImpl implements MenuItem {
}
if (mIconResId != NO_ICON) {
- return mMenu.getResources().getDrawable(mIconResId);
+ Drawable icon = mMenu.getResources().getDrawable(mIconResId);
+ mIconResId = NO_ICON;
+ mIconDrawable = icon;
+ return icon;
}
return null;
diff --git a/core/java/com/android/internal/widget/multiwaveview/MultiWaveView.java b/core/java/com/android/internal/widget/multiwaveview/MultiWaveView.java
index d51ced11d96b..f2b6e45c67a5 100644
--- a/core/java/com/android/internal/widget/multiwaveview/MultiWaveView.java
+++ b/core/java/com/android/internal/widget/multiwaveview/MultiWaveView.java
@@ -164,9 +164,10 @@ public class MultiWaveView extends View {
mFeedbackCount = a.getInt(R.styleable.MultiWaveView_feedbackCount,
mFeedbackCount);
mHandleDrawable = new TargetDrawable(res,
- a.getDrawable(R.styleable.MultiWaveView_handleDrawable));
+ a.peekValue(R.styleable.MultiWaveView_handleDrawable).resourceId);
mTapRadius = mHandleDrawable.getWidth()/2;
- mOuterRing = new TargetDrawable(res, a.getDrawable(R.styleable.MultiWaveView_waveDrawable));
+ mOuterRing = new TargetDrawable(res,
+ a.peekValue(R.styleable.MultiWaveView_waveDrawable).resourceId);
// Read chevron animation drawables
final int chevrons[] = { R.styleable.MultiWaveView_leftChevronDrawable,
@@ -174,11 +175,12 @@ public class MultiWaveView extends View {
R.styleable.MultiWaveView_topChevronDrawable,
R.styleable.MultiWaveView_bottomChevronDrawable
};
+
for (int chevron : chevrons) {
- Drawable chevronDrawable = a.getDrawable(chevron);
+ TypedValue typedValue = a.peekValue(chevron);
for (int i = 0; i < mFeedbackCount; i++) {
mChevronDrawables.add(
- chevronDrawable != null ? new TargetDrawable(res, chevronDrawable) : null);
+ typedValue != null ? new TargetDrawable(res, typedValue.resourceId) : null);
}
}
@@ -519,8 +521,8 @@ public class MultiWaveView extends View {
int count = array.length();
ArrayList<TargetDrawable> targetDrawables = new ArrayList<TargetDrawable>(count);
for (int i = 0; i < count; i++) {
- Drawable drawable = array.getDrawable(i);
- targetDrawables.add(new TargetDrawable(res, drawable));
+ TypedValue value = array.peekValue(i);
+ targetDrawables.add(new TargetDrawable(res, value != null ? value.resourceId : 0));
}
array.recycle();
mTargetResourceId = resourceId;
@@ -679,7 +681,7 @@ public class MultiWaveView extends View {
if (DEBUG && mDragging) Log.v(TAG, "** Handle RELEASE");
switchToState(STATE_FINISH, event.getX(), event.getY());
}
-
+
private void handleCancel(MotionEvent event) {
if (DEBUG && mDragging) Log.v(TAG, "** Handle CANCEL");
mActiveTarget = -1; // Drop the active target if canceled.
@@ -723,7 +725,7 @@ public class MultiWaveView extends View {
float dx = limitX - target.getX();
float dy = limitY - target.getY();
float dist2 = dx*dx + dy*dy;
- if (target.isValid() && dist2 < hitRadius2 && dist2 < best) {
+ if (target.isEnabled() && dist2 < hitRadius2 && dist2 < best) {
activeTarget = i;
best = dist2;
}
@@ -968,4 +970,34 @@ public class MultiWaveView extends View {
array.recycle();
return targetContentDescriptions;
}
+
+ public int getResourceIdForTarget(int index) {
+ final TargetDrawable drawable = mTargetDrawables.get(index);
+ return drawable == null ? 0 : drawable.getResourceId();
+ }
+
+ public void setEnableTarget(int resourceId, boolean enabled) {
+ for (int i = 0; i < mTargetDrawables.size(); i++) {
+ final TargetDrawable target = mTargetDrawables.get(i);
+ if (target.getResourceId() == resourceId) {
+ target.setEnabled(enabled);
+ break; // should never be more than one match
+ }
+ }
+ }
+
+ /**
+ * Gets the position of a target in the array that matches the given resource.
+ * @param resourceId
+ * @return the index or -1 if not found
+ */
+ public int getTargetPosition(int resourceId) {
+ for (int i = 0; i < mTargetDrawables.size(); i++) {
+ final TargetDrawable target = mTargetDrawables.get(i);
+ if (target.getResourceId() == resourceId) {
+ return i; // should never be more than one match
+ }
+ }
+ return -1;
+ }
}
diff --git a/core/java/com/android/internal/widget/multiwaveview/TargetDrawable.java b/core/java/com/android/internal/widget/multiwaveview/TargetDrawable.java
index aa9fa451b068..ec2c94592379 100644
--- a/core/java/com/android/internal/widget/multiwaveview/TargetDrawable.java
+++ b/core/java/com/android/internal/widget/multiwaveview/TargetDrawable.java
@@ -40,6 +40,8 @@ public class TargetDrawable {
private float mScaleY = 1.0f;
private float mAlpha = 1.0f;
private Drawable mDrawable;
+ private boolean mEnabled = true;
+ private int mResourceId;
/* package */ static class DrawableWithAlpha extends Drawable {
private float mAlpha = 1.0f;
@@ -72,10 +74,8 @@ public class TargetDrawable {
}
public TargetDrawable(Resources res, int resId) {
- this(res, resId == 0 ? null : res.getDrawable(resId));
- }
-
- public TargetDrawable(Resources res, Drawable drawable) {
+ mResourceId = resId;
+ Drawable drawable = resId == 0 ? null : res.getDrawable(resId);
// Mutate the drawable so we can animate shared drawable properties.
mDrawable = drawable != null ? drawable.mutate() : null;
resizeDrawables();
@@ -122,8 +122,8 @@ public class TargetDrawable {
*
* @return
*/
- public boolean isValid() {
- return mDrawable != null;
+ public boolean isEnabled() {
+ return mDrawable != null && mEnabled;
}
/**
@@ -205,7 +205,7 @@ public class TargetDrawable {
}
public void draw(Canvas canvas) {
- if (mDrawable == null) {
+ if (mDrawable == null || !mEnabled) {
return;
}
canvas.save(Canvas.MATRIX_SAVE_FLAG);
@@ -216,4 +216,12 @@ public class TargetDrawable {
mDrawable.draw(canvas);
canvas.restore();
}
+
+ public void setEnabled(boolean enabled) {
+ mEnabled = enabled;
+ }
+
+ public int getResourceId() {
+ return mResourceId;
+ }
}
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index 92b07b349472..5650d685e0d9 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -211,6 +211,7 @@ LOCAL_SHARED_LIBRARIES := \
libicuuc \
libicui18n \
libmedia \
+ libmedia_native \
libwpa_client \
libjpeg \
libusbhost \
diff --git a/core/jni/android/graphics/BitmapFactory.cpp b/core/jni/android/graphics/BitmapFactory.cpp
index c9eb640a7635..dcd1d28a7bfb 100644
--- a/core/jni/android/graphics/BitmapFactory.cpp
+++ b/core/jni/android/graphics/BitmapFactory.cpp
@@ -90,8 +90,54 @@ static bool optionsJustBounds(JNIEnv* env, jobject options) {
return options != NULL && env->GetBooleanField(options, gOptions_justBoundsFieldID);
}
+static void scaleNinePatchChunk(android::Res_png_9patch* chunk, float scale) {
+ chunk->paddingLeft = int(chunk->paddingLeft * scale + 0.5f);
+ chunk->paddingTop = int(chunk->paddingTop * scale + 0.5f);
+ chunk->paddingRight = int(chunk->paddingRight * scale + 0.5f);
+ chunk->paddingBottom = int(chunk->paddingBottom * scale + 0.5f);
+
+ for (int i = 0; i < chunk->numXDivs; i++) {
+ chunk->xDivs[i] = int(chunk->xDivs[i] * scale + 0.5f);
+ if (i > 0 && chunk->xDivs[i] == chunk->xDivs[i - 1]) {
+ chunk->xDivs[i]++;
+ }
+ }
+
+ for (int i = 0; i < chunk->numYDivs; i++) {
+ chunk->yDivs[i] = int(chunk->yDivs[i] * scale + 0.5f);
+ if (i > 0 && chunk->yDivs[i] == chunk->yDivs[i - 1]) {
+ chunk->yDivs[i]++;
+ }
+ }
+}
+
+static jbyteArray nativeScaleNinePatch(JNIEnv* env, jobject, jbyteArray chunkObject, jfloat scale,
+ jobject padding) {
+
+ jbyte* array = env->GetByteArrayElements(chunkObject, 0);
+ if (array != NULL) {
+ size_t chunkSize = env->GetArrayLength(chunkObject);
+ void* storage = alloca(chunkSize);
+ android::Res_png_9patch* chunk = static_cast<android::Res_png_9patch*>(storage);
+ memcpy(chunk, array, chunkSize);
+ android::Res_png_9patch::deserialize(chunk);
+
+ scaleNinePatchChunk(chunk, scale);
+ memcpy(array, chunk, chunkSize);
+
+ if (padding) {
+ GraphicsJNI::set_jrect(env, padding, chunk->paddingLeft, chunk->paddingTop,
+ chunk->paddingRight, chunk->paddingBottom);
+ }
+
+ env->ReleaseByteArrayElements(chunkObject, array, 0);
+ }
+ return chunkObject;
+}
+
static SkPixelRef* installPixelRef(SkBitmap* bitmap, SkStream* stream,
- int sampleSize, bool ditherImage) {
+ int sampleSize, bool ditherImage) {
+
SkImageRef* pr;
// only use ashmem for large images, since mmaps come at a price
if (bitmap->getSize() >= 32 * 1024) {
@@ -109,22 +155,29 @@ static SkPixelRef* installPixelRef(SkBitmap* bitmap, SkStream* stream,
// i.e. dynamically allocated, since its lifetime may exceed the current stack
// frame.
static jobject doDecode(JNIEnv* env, SkStream* stream, jobject padding,
- jobject options, bool allowPurgeable,
- bool forcePurgeable = false) {
+ jobject options, bool allowPurgeable, bool forcePurgeable = false,
+ bool applyScale = false, float scale = 1.0f) {
+
int sampleSize = 1;
+
SkImageDecoder::Mode mode = SkImageDecoder::kDecodePixels_Mode;
SkBitmap::Config prefConfig = SkBitmap::kARGB_8888_Config;
+
bool doDither = true;
bool isMutable = false;
- bool isPurgeable = forcePurgeable || (allowPurgeable && optionsPurgeable(env, options));
+ bool willScale = applyScale && scale != 1.0f;
+ bool isPurgeable = !willScale &&
+ (forcePurgeable || (allowPurgeable && optionsPurgeable(env, options)));
bool preferQualityOverSpeed = false;
+
jobject javaBitmap = NULL;
- if (NULL != options) {
+ if (options != NULL) {
sampleSize = env->GetIntField(options, gOptions_sampleSizeFieldID);
if (optionsJustBounds(env, options)) {
mode = SkImageDecoder::kDecodeBounds_Mode;
}
+
// initialize these, in case we fail later on
env->SetIntField(options, gOptions_widthFieldID, -1);
env->SetIntField(options, gOptions_heightFieldID, -1);
@@ -139,8 +192,12 @@ static jobject doDecode(JNIEnv* env, SkStream* stream, jobject padding,
javaBitmap = env->GetObjectField(options, gOptions_bitmapFieldID);
}
+ if (willScale && javaBitmap != NULL) {
+ return nullObjectReturn("Cannot pre-scale a reused bitmap");
+ }
+
SkImageDecoder* decoder = SkImageDecoder::Factory(stream);
- if (NULL == decoder) {
+ if (decoder == NULL) {
return nullObjectReturn("SkImageDecoder::Factory returned null");
}
@@ -148,35 +205,35 @@ static jobject doDecode(JNIEnv* env, SkStream* stream, jobject padding,
decoder->setDitherImage(doDither);
decoder->setPreferQualityOverSpeed(preferQualityOverSpeed);
- NinePatchPeeker peeker(decoder);
- JavaPixelAllocator javaAllocator(env);
- SkBitmap* bitmap;
+ NinePatchPeeker peeker(decoder);
+ JavaPixelAllocator javaAllocator(env);
+
+ SkBitmap* bitmap;
if (javaBitmap == NULL) {
bitmap = new SkBitmap;
} else {
if (sampleSize != 1) {
return nullObjectReturn("SkImageDecoder: Cannot reuse bitmap with sampleSize != 1");
}
- bitmap = (SkBitmap *) env->GetIntField(javaBitmap, gBitmap_nativeBitmapFieldID);
+ bitmap = (SkBitmap*) env->GetIntField(javaBitmap, gBitmap_nativeBitmapFieldID);
// config of supplied bitmap overrules config set in options
prefConfig = bitmap->getConfig();
}
- Res_png_9patch dummy9Patch;
- SkAutoTDelete<SkImageDecoder> add(decoder);
- SkAutoTDelete<SkBitmap> adb(bitmap, (javaBitmap == NULL));
+ SkAutoTDelete<SkImageDecoder> add(decoder);
+ SkAutoTDelete<SkBitmap> adb(bitmap, javaBitmap == NULL);
decoder->setPeeker(&peeker);
if (!isPurgeable) {
decoder->setAllocator(&javaAllocator);
}
- AutoDecoderCancel adc(options, decoder);
+ AutoDecoderCancel adc(options, decoder);
// To fix the race condition in case "requestCancelDecode"
// happens earlier than AutoDecoderCancel object is added
// to the gAutoDecoderCancelMutex linked list.
- if (NULL != options && env->GetBooleanField(options, gOptions_mCancelID)) {
+ if (options != NULL && env->GetBooleanField(options, gOptions_mCancelID)) {
return nullObjectReturn("gOptions_mCancelID");
}
@@ -184,38 +241,57 @@ static jobject doDecode(JNIEnv* env, SkStream* stream, jobject padding,
if (isPurgeable) {
decodeMode = SkImageDecoder::kDecodeBounds_Mode;
}
- if (!decoder->decode(stream, bitmap, prefConfig, decodeMode, javaBitmap != NULL)) {
+
+ SkBitmap* decoded;
+ if (willScale) {
+ decoded = new SkBitmap;
+ } else {
+ decoded = bitmap;
+ }
+ SkAutoTDelete<SkBitmap> adb2(willScale ? decoded : NULL);
+
+ if (!decoder->decode(stream, decoded, prefConfig, decodeMode, javaBitmap != NULL)) {
return nullObjectReturn("decoder->decode returned false");
}
+ int scaledWidth = decoded->width();
+ int scaledHeight = decoded->height();
+
+ if (willScale && mode != SkImageDecoder::kDecodeBounds_Mode) {
+ scaledWidth = int(scaledWidth * scale + 0.5f);
+ scaledHeight = int(scaledHeight * scale + 0.5f);
+ }
+
// update options (if any)
- if (NULL != options) {
- env->SetIntField(options, gOptions_widthFieldID, bitmap->width());
- env->SetIntField(options, gOptions_heightFieldID, bitmap->height());
- // TODO: set the mimeType field with the data from the codec.
- // but how to reuse a set of strings, rather than allocating new one
- // each time?
+ if (options != NULL) {
+ env->SetIntField(options, gOptions_widthFieldID, scaledWidth);
+ env->SetIntField(options, gOptions_heightFieldID, scaledHeight);
env->SetObjectField(options, gOptions_mimeFieldID,
- getMimeTypeString(env, decoder->getFormat()));
+ getMimeTypeString(env, decoder->getFormat()));
}
// if we're in justBounds mode, return now (skip the java bitmap)
- if (SkImageDecoder::kDecodeBounds_Mode == mode) {
+ if (mode == SkImageDecoder::kDecodeBounds_Mode) {
return NULL;
}
jbyteArray ninePatchChunk = NULL;
if (peeker.fPatchIsValid) {
+ if (willScale) {
+ scaleNinePatchChunk(peeker.fPatch, scale);
+ }
+
size_t ninePatchArraySize = peeker.fPatch->serializedSize();
ninePatchChunk = env->NewByteArray(ninePatchArraySize);
- if (NULL == ninePatchChunk) {
+ if (ninePatchChunk == NULL) {
return nullObjectReturn("ninePatchChunk == null");
}
- jbyte* array = (jbyte*)env->GetPrimitiveArrayCritical(ninePatchChunk,
- NULL);
- if (NULL == array) {
+
+ jbyte* array = (jbyte*) env->GetPrimitiveArrayCritical(ninePatchChunk, NULL);
+ if (array == NULL) {
return nullObjectReturn("primitive array == null");
}
+
peeker.fPatch->serialize(array);
env->ReleasePrimitiveArrayCritical(ninePatchChunk, array, 0);
}
@@ -223,13 +299,32 @@ static jobject doDecode(JNIEnv* env, SkStream* stream, jobject padding,
// detach bitmap from its autodeleter, since we want to own it now
adb.detach();
+ if (willScale) {
+ // This is weird so let me explain: we could use the scale parameter
+ // directly, but for historical reasons this is how the corresponding
+ // Dalvik code has always behaved. We simply recreate the behavior here.
+ // The result is slightly different from simply using scale because of
+ // the 0.5f rounding bias applied when computing the target image size
+ const float sx = scaledWidth / float(decoded->width());
+ const float sy = scaledHeight / float(decoded->height());
+
+ bitmap->setConfig(decoded->getConfig(), scaledWidth, scaledHeight);
+ bitmap->allocPixels(&javaAllocator, NULL);
+ bitmap->eraseColor(0);
+
+ SkPaint paint;
+ paint.setFilterBitmap(true);
+
+ SkCanvas canvas(*bitmap);
+ canvas.scale(sx, sy);
+ canvas.drawBitmap(*decoded, 0.0f, 0.0f, &paint);
+ }
+
if (padding) {
if (peeker.fPatchIsValid) {
GraphicsJNI::set_jrect(env, padding,
- peeker.fPatch->paddingLeft,
- peeker.fPatch->paddingTop,
- peeker.fPatch->paddingRight,
- peeker.fPatch->paddingBottom);
+ peeker.fPatch->paddingLeft, peeker.fPatch->paddingTop,
+ peeker.fPatch->paddingRight, peeker.fPatch->paddingBottom);
} else {
GraphicsJNI::set_jrect(env, padding, -1, -1, -1, -1);
}
@@ -258,22 +353,26 @@ static jobject doDecode(JNIEnv* env, SkStream* stream, jobject padding,
isMutable, ninePatchChunk);
}
-static jobject nativeDecodeStream(JNIEnv* env, jobject clazz,
- jobject is, // InputStream
- jbyteArray storage, // byte[]
- jobject padding,
- jobject options) { // BitmapFactory$Options
+static jobject nativeDecodeStreamScaled(JNIEnv* env, jobject clazz, jobject is, jbyteArray storage,
+ jobject padding, jobject options, jboolean applyScale, jfloat scale) {
+
jobject bitmap = NULL;
SkStream* stream = CreateJavaInputStreamAdaptor(env, is, storage, 0);
if (stream) {
// for now we don't allow purgeable with java inputstreams
- bitmap = doDecode(env, stream, padding, options, false);
+ bitmap = doDecode(env, stream, padding, options, false, false, applyScale, scale);
stream->unref();
}
return bitmap;
}
+static jobject nativeDecodeStream(JNIEnv* env, jobject clazz, jobject is, jbyteArray storage,
+ jobject padding, jobject options) {
+
+ return nativeDecodeStreamScaled(env, clazz, is, storage, padding, options, false, 1.0f);
+}
+
static ssize_t getFDSize(int fd) {
off64_t curr = ::lseek64(fd, 0, SEEK_CUR);
if (curr < 0) {
@@ -284,10 +383,9 @@ static ssize_t getFDSize(int fd) {
return size;
}
-static jobject nativeDecodeFileDescriptor(JNIEnv* env, jobject clazz,
- jobject fileDescriptor,
- jobject padding,
- jobject bitmapFactoryOptions) {
+static jobject nativeDecodeFileDescriptor(JNIEnv* env, jobject clazz, jobject fileDescriptor,
+ jobject padding, jobject bitmapFactoryOptions) {
+
NPE_CHECK_RETURN_ZERO(env, fileDescriptor);
jint descriptor = jniGetFDFromFileDescriptor(env, fileDescriptor);
@@ -349,10 +447,9 @@ static SkStream* copyAssetToStream(Asset* asset) {
return stream;
}
-static jobject nativeDecodeAsset(JNIEnv* env, jobject clazz,
- jint native_asset, // Asset
- jobject padding, // Rect
- jobject options) { // BitmapFactory$Options
+static jobject nativeDecodeAssetScaled(JNIEnv* env, jobject clazz, jint native_asset,
+ jobject padding, jobject options, jboolean applyScale, jfloat scale) {
+
SkStream* stream;
Asset* asset = reinterpret_cast<Asset*>(native_asset);
bool forcePurgeable = optionsPurgeable(env, options);
@@ -360,7 +457,7 @@ static jobject nativeDecodeAsset(JNIEnv* env, jobject clazz,
// if we could "ref/reopen" the asset, we may not need to copy it here
// and we could assume optionsShareable, since assets are always RO
stream = copyAssetToStream(asset);
- if (NULL == stream) {
+ if (stream == NULL) {
return NULL;
}
} else {
@@ -369,18 +466,24 @@ static jobject nativeDecodeAsset(JNIEnv* env, jobject clazz,
stream = new AssetStreamAdaptor(asset);
}
SkAutoUnref aur(stream);
- return doDecode(env, stream, padding, options, true, forcePurgeable);
+ return doDecode(env, stream, padding, options, true, forcePurgeable, applyScale, scale);
+}
+
+static jobject nativeDecodeAsset(JNIEnv* env, jobject clazz, jint native_asset,
+ jobject padding, jobject options) {
+
+ return nativeDecodeAssetScaled(env, clazz, native_asset, padding, options, false, 1.0f);
}
static jobject nativeDecodeByteArray(JNIEnv* env, jobject, jbyteArray byteArray,
- int offset, int length, jobject options) {
+ int offset, int length, jobject options) {
+
/* If optionsShareable() we could decide to just wrap the java array and
share it, but that means adding a globalref to the java array object
and managing its lifetime. For now we just always copy the array's data
if optionsPurgeable(), unless we're just decoding bounds.
*/
- bool purgeable = optionsPurgeable(env, options)
- && !optionsJustBounds(env, options);
+ bool purgeable = optionsPurgeable(env, options) && !optionsJustBounds(env, options);
AutoJavaByteArray ar(env, byteArray);
SkStream* stream = new SkMemoryStream(ar.ptr() + offset, length, purgeable);
SkAutoUnref aur(stream);
@@ -391,48 +494,6 @@ static void nativeRequestCancel(JNIEnv*, jobject joptions) {
(void)AutoDecoderCancel::RequestCancel(joptions);
}
-static jbyteArray nativeScaleNinePatch(JNIEnv* env, jobject, jbyteArray chunkObject, jfloat scale,
- jobject padding) {
-
- jbyte* array = env->GetByteArrayElements(chunkObject, 0);
- if (array != NULL) {
- size_t chunkSize = env->GetArrayLength(chunkObject);
- void* storage = alloca(chunkSize);
- android::Res_png_9patch* chunk = static_cast<android::Res_png_9patch*>(storage);
- memcpy(chunk, array, chunkSize);
- android::Res_png_9patch::deserialize(chunk);
-
- chunk->paddingLeft = int(chunk->paddingLeft * scale + 0.5f);
- chunk->paddingTop = int(chunk->paddingTop * scale + 0.5f);
- chunk->paddingRight = int(chunk->paddingRight * scale + 0.5f);
- chunk->paddingBottom = int(chunk->paddingBottom * scale + 0.5f);
-
- for (int i = 0; i < chunk->numXDivs; i++) {
- chunk->xDivs[i] = int(chunk->xDivs[i] * scale + 0.5f);
- if (i > 0 && chunk->xDivs[i] == chunk->xDivs[i - 1]) {
- chunk->xDivs[i]++;
- }
- }
-
- for (int i = 0; i < chunk->numYDivs; i++) {
- chunk->yDivs[i] = int(chunk->yDivs[i] * scale + 0.5f);
- if (i > 0 && chunk->yDivs[i] == chunk->yDivs[i - 1]) {
- chunk->yDivs[i]++;
- }
- }
-
- memcpy(array, chunk, chunkSize);
-
- if (padding) {
- GraphicsJNI::set_jrect(env, padding, chunk->paddingLeft, chunk->paddingTop,
- chunk->paddingRight, chunk->paddingBottom);
- }
-
- env->ReleaseByteArrayElements(chunkObject, array, 0);
- }
- return chunkObject;
-}
-
static jboolean nativeIsSeekable(JNIEnv* env, jobject, jobject fileDescriptor) {
jint descriptor = jniGetFDFromFileDescriptor(env, fileDescriptor);
return ::lseek64(descriptor, 0, SEEK_CUR) != -1 ? JNI_TRUE : JNI_FALSE;
@@ -445,6 +506,10 @@ static JNINativeMethod gMethods[] = {
"(Ljava/io/InputStream;[BLandroid/graphics/Rect;Landroid/graphics/BitmapFactory$Options;)Landroid/graphics/Bitmap;",
(void*)nativeDecodeStream
},
+ { "nativeDecodeStream",
+ "(Ljava/io/InputStream;[BLandroid/graphics/Rect;Landroid/graphics/BitmapFactory$Options;ZF)Landroid/graphics/Bitmap;",
+ (void*)nativeDecodeStreamScaled
+ },
{ "nativeDecodeFileDescriptor",
"(Ljava/io/FileDescriptor;Landroid/graphics/Rect;Landroid/graphics/BitmapFactory$Options;)Landroid/graphics/Bitmap;",
@@ -456,6 +521,11 @@ static JNINativeMethod gMethods[] = {
(void*)nativeDecodeAsset
},
+ { "nativeDecodeAsset",
+ "(ILandroid/graphics/Rect;Landroid/graphics/BitmapFactory$Options;ZF)Landroid/graphics/Bitmap;",
+ (void*)nativeDecodeAssetScaled
+ },
+
{ "nativeDecodeByteArray",
"([BIILandroid/graphics/BitmapFactory$Options;)Landroid/graphics/Bitmap;",
(void*)nativeDecodeByteArray
diff --git a/core/res/res/drawable-hdpi/ic_facial_backup.png b/core/res/res/drawable-hdpi/ic_facial_backup.png
new file mode 100644
index 000000000000..295610910dda
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_facial_backup.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/intro_bg.png b/core/res/res/drawable-hdpi/intro_bg.png
new file mode 100644
index 000000000000..a758e7dd1b89
--- /dev/null
+++ b/core/res/res/drawable-hdpi/intro_bg.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_down_disabled_focused_holo_dark.png b/core/res/res/drawable-hdpi/numberpicker_down_disabled_focused_holo_dark.png
deleted file mode 100644
index 9584649d7d40..000000000000
--- a/core/res/res/drawable-hdpi/numberpicker_down_disabled_focused_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_down_disabled_focused_holo_light.png b/core/res/res/drawable-hdpi/numberpicker_down_disabled_focused_holo_light.png
deleted file mode 100644
index 5c37873b68aa..000000000000
--- a/core/res/res/drawable-hdpi/numberpicker_down_disabled_focused_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_down_disabled_holo_dark.png b/core/res/res/drawable-hdpi/numberpicker_down_disabled_holo_dark.png
deleted file mode 100644
index b5faf6fe67d4..000000000000
--- a/core/res/res/drawable-hdpi/numberpicker_down_disabled_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_down_disabled_holo_light.png b/core/res/res/drawable-hdpi/numberpicker_down_disabled_holo_light.png
deleted file mode 100644
index 041412b100d2..000000000000
--- a/core/res/res/drawable-hdpi/numberpicker_down_disabled_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_down_focused_holo_dark.png b/core/res/res/drawable-hdpi/numberpicker_down_focused_holo_dark.png
deleted file mode 100644
index 5717beebcf23..000000000000
--- a/core/res/res/drawable-hdpi/numberpicker_down_focused_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_down_focused_holo_light.png b/core/res/res/drawable-hdpi/numberpicker_down_focused_holo_light.png
deleted file mode 100644
index e874330d3868..000000000000
--- a/core/res/res/drawable-hdpi/numberpicker_down_focused_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_down_longpressed_holo_dark.png b/core/res/res/drawable-hdpi/numberpicker_down_longpressed_holo_dark.png
deleted file mode 100644
index 96a6c8a2dd91..000000000000
--- a/core/res/res/drawable-hdpi/numberpicker_down_longpressed_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_down_longpressed_holo_light.png b/core/res/res/drawable-hdpi/numberpicker_down_longpressed_holo_light.png
deleted file mode 100644
index 96a6c8a2dd91..000000000000
--- a/core/res/res/drawable-hdpi/numberpicker_down_longpressed_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_down_normal_holo_dark.png b/core/res/res/drawable-hdpi/numberpicker_down_normal_holo_dark.png
deleted file mode 100644
index 4631d85cf15e..000000000000
--- a/core/res/res/drawable-hdpi/numberpicker_down_normal_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_down_normal_holo_light.png b/core/res/res/drawable-hdpi/numberpicker_down_normal_holo_light.png
deleted file mode 100644
index 39c7af4145ff..000000000000
--- a/core/res/res/drawable-hdpi/numberpicker_down_normal_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_down_pressed_holo_dark.png b/core/res/res/drawable-hdpi/numberpicker_down_pressed_holo_dark.png
deleted file mode 100644
index 9c23a18ed917..000000000000
--- a/core/res/res/drawable-hdpi/numberpicker_down_pressed_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_down_pressed_holo_light.png b/core/res/res/drawable-hdpi/numberpicker_down_pressed_holo_light.png
deleted file mode 100644
index 9c23a18ed917..000000000000
--- a/core/res/res/drawable-hdpi/numberpicker_down_pressed_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_up_disabled_focused_holo_dark.png b/core/res/res/drawable-hdpi/numberpicker_up_disabled_focused_holo_dark.png
deleted file mode 100644
index 159913ced5ce..000000000000
--- a/core/res/res/drawable-hdpi/numberpicker_up_disabled_focused_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_up_disabled_focused_holo_light.png b/core/res/res/drawable-hdpi/numberpicker_up_disabled_focused_holo_light.png
deleted file mode 100644
index cfee4b79d2bf..000000000000
--- a/core/res/res/drawable-hdpi/numberpicker_up_disabled_focused_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_up_disabled_holo_dark.png b/core/res/res/drawable-hdpi/numberpicker_up_disabled_holo_dark.png
deleted file mode 100644
index e5f04309615c..000000000000
--- a/core/res/res/drawable-hdpi/numberpicker_up_disabled_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_up_disabled_holo_light.png b/core/res/res/drawable-hdpi/numberpicker_up_disabled_holo_light.png
deleted file mode 100644
index 7e4ec4a61057..000000000000
--- a/core/res/res/drawable-hdpi/numberpicker_up_disabled_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_up_focused_holo_dark.png b/core/res/res/drawable-hdpi/numberpicker_up_focused_holo_dark.png
deleted file mode 100644
index b06017e0f8b6..000000000000
--- a/core/res/res/drawable-hdpi/numberpicker_up_focused_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_up_focused_holo_light.png b/core/res/res/drawable-hdpi/numberpicker_up_focused_holo_light.png
deleted file mode 100644
index a1000f8951f7..000000000000
--- a/core/res/res/drawable-hdpi/numberpicker_up_focused_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_up_longpressed_holo_dark.png b/core/res/res/drawable-hdpi/numberpicker_up_longpressed_holo_dark.png
deleted file mode 100644
index b3d6706a408c..000000000000
--- a/core/res/res/drawable-hdpi/numberpicker_up_longpressed_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_up_longpressed_holo_light.png b/core/res/res/drawable-hdpi/numberpicker_up_longpressed_holo_light.png
deleted file mode 100644
index b3d6706a408c..000000000000
--- a/core/res/res/drawable-hdpi/numberpicker_up_longpressed_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_up_normal_holo_dark.png b/core/res/res/drawable-hdpi/numberpicker_up_normal_holo_dark.png
deleted file mode 100644
index 9ee35c7db9d8..000000000000
--- a/core/res/res/drawable-hdpi/numberpicker_up_normal_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_up_normal_holo_light.png b/core/res/res/drawable-hdpi/numberpicker_up_normal_holo_light.png
deleted file mode 100644
index 4da4fa76f996..000000000000
--- a/core/res/res/drawable-hdpi/numberpicker_up_normal_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_up_pressed_holo_dark.png b/core/res/res/drawable-hdpi/numberpicker_up_pressed_holo_dark.png
deleted file mode 100644
index 358a13fca7ac..000000000000
--- a/core/res/res/drawable-hdpi/numberpicker_up_pressed_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_up_pressed_holo_light.png b/core/res/res/drawable-hdpi/numberpicker_up_pressed_holo_light.png
deleted file mode 100644
index 358a13fca7ac..000000000000
--- a/core/res/res/drawable-hdpi/numberpicker_up_pressed_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_facial_backup.png b/core/res/res/drawable-mdpi/ic_facial_backup.png
new file mode 100644
index 000000000000..6ed1327a626a
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_facial_backup.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/intro_bg.png b/core/res/res/drawable-mdpi/intro_bg.png
new file mode 100644
index 000000000000..540da311dcc1
--- /dev/null
+++ b/core/res/res/drawable-mdpi/intro_bg.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_down_disabled_focused_holo_dark.png b/core/res/res/drawable-mdpi/numberpicker_down_disabled_focused_holo_dark.png
deleted file mode 100644
index 50f6e98accd9..000000000000
--- a/core/res/res/drawable-mdpi/numberpicker_down_disabled_focused_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_down_disabled_focused_holo_light.png b/core/res/res/drawable-mdpi/numberpicker_down_disabled_focused_holo_light.png
deleted file mode 100644
index 67434f6277c5..000000000000
--- a/core/res/res/drawable-mdpi/numberpicker_down_disabled_focused_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_down_disabled_holo_dark.png b/core/res/res/drawable-mdpi/numberpicker_down_disabled_holo_dark.png
deleted file mode 100644
index 9c2b83383865..000000000000
--- a/core/res/res/drawable-mdpi/numberpicker_down_disabled_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_down_disabled_holo_light.png b/core/res/res/drawable-mdpi/numberpicker_down_disabled_holo_light.png
deleted file mode 100644
index dcf2fb7cf71b..000000000000
--- a/core/res/res/drawable-mdpi/numberpicker_down_disabled_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_down_focused_holo_dark.png b/core/res/res/drawable-mdpi/numberpicker_down_focused_holo_dark.png
deleted file mode 100644
index b63c510dcde0..000000000000
--- a/core/res/res/drawable-mdpi/numberpicker_down_focused_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_down_focused_holo_light.png b/core/res/res/drawable-mdpi/numberpicker_down_focused_holo_light.png
deleted file mode 100644
index 55312a1b3573..000000000000
--- a/core/res/res/drawable-mdpi/numberpicker_down_focused_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_down_longpressed_holo_dark.png b/core/res/res/drawable-mdpi/numberpicker_down_longpressed_holo_dark.png
deleted file mode 100644
index 48e300c26472..000000000000
--- a/core/res/res/drawable-mdpi/numberpicker_down_longpressed_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_down_longpressed_holo_light.png b/core/res/res/drawable-mdpi/numberpicker_down_longpressed_holo_light.png
deleted file mode 100644
index 48e300c26472..000000000000
--- a/core/res/res/drawable-mdpi/numberpicker_down_longpressed_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_down_normal_holo_dark.png b/core/res/res/drawable-mdpi/numberpicker_down_normal_holo_dark.png
deleted file mode 100644
index 1558d3d95893..000000000000
--- a/core/res/res/drawable-mdpi/numberpicker_down_normal_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_down_normal_holo_light.png b/core/res/res/drawable-mdpi/numberpicker_down_normal_holo_light.png
deleted file mode 100644
index 6b6e7e1f50ee..000000000000
--- a/core/res/res/drawable-mdpi/numberpicker_down_normal_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_down_pressed_holo_dark.png b/core/res/res/drawable-mdpi/numberpicker_down_pressed_holo_dark.png
deleted file mode 100644
index eb16f8dde140..000000000000
--- a/core/res/res/drawable-mdpi/numberpicker_down_pressed_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_down_pressed_holo_light.png b/core/res/res/drawable-mdpi/numberpicker_down_pressed_holo_light.png
deleted file mode 100644
index eb16f8dde140..000000000000
--- a/core/res/res/drawable-mdpi/numberpicker_down_pressed_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_up_disabled_focused_holo_dark.png b/core/res/res/drawable-mdpi/numberpicker_up_disabled_focused_holo_dark.png
deleted file mode 100644
index 58a3b64322ac..000000000000
--- a/core/res/res/drawable-mdpi/numberpicker_up_disabled_focused_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_up_disabled_focused_holo_light.png b/core/res/res/drawable-mdpi/numberpicker_up_disabled_focused_holo_light.png
deleted file mode 100644
index 382943b08ac7..000000000000
--- a/core/res/res/drawable-mdpi/numberpicker_up_disabled_focused_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_up_disabled_holo_dark.png b/core/res/res/drawable-mdpi/numberpicker_up_disabled_holo_dark.png
deleted file mode 100644
index cf856a19261b..000000000000
--- a/core/res/res/drawable-mdpi/numberpicker_up_disabled_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_up_disabled_holo_light.png b/core/res/res/drawable-mdpi/numberpicker_up_disabled_holo_light.png
deleted file mode 100644
index 6665953aeb3d..000000000000
--- a/core/res/res/drawable-mdpi/numberpicker_up_disabled_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_up_focused_holo_dark.png b/core/res/res/drawable-mdpi/numberpicker_up_focused_holo_dark.png
deleted file mode 100644
index d63d797e51a2..000000000000
--- a/core/res/res/drawable-mdpi/numberpicker_up_focused_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_up_focused_holo_light.png b/core/res/res/drawable-mdpi/numberpicker_up_focused_holo_light.png
deleted file mode 100644
index 22b6dbd4d0af..000000000000
--- a/core/res/res/drawable-mdpi/numberpicker_up_focused_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_up_longpressed_holo_dark.png b/core/res/res/drawable-mdpi/numberpicker_up_longpressed_holo_dark.png
deleted file mode 100644
index 4bcce9871f23..000000000000
--- a/core/res/res/drawable-mdpi/numberpicker_up_longpressed_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_up_longpressed_holo_light.png b/core/res/res/drawable-mdpi/numberpicker_up_longpressed_holo_light.png
deleted file mode 100644
index 4bcce9871f23..000000000000
--- a/core/res/res/drawable-mdpi/numberpicker_up_longpressed_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_up_normal_holo_dark.png b/core/res/res/drawable-mdpi/numberpicker_up_normal_holo_dark.png
deleted file mode 100644
index 12ba823e1fe3..000000000000
--- a/core/res/res/drawable-mdpi/numberpicker_up_normal_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_up_normal_holo_light.png b/core/res/res/drawable-mdpi/numberpicker_up_normal_holo_light.png
deleted file mode 100644
index d841f5a6c555..000000000000
--- a/core/res/res/drawable-mdpi/numberpicker_up_normal_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_up_pressed_holo_dark.png b/core/res/res/drawable-mdpi/numberpicker_up_pressed_holo_dark.png
deleted file mode 100644
index bc5e3faef985..000000000000
--- a/core/res/res/drawable-mdpi/numberpicker_up_pressed_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_up_pressed_holo_light.png b/core/res/res/drawable-mdpi/numberpicker_up_pressed_holo_light.png
deleted file mode 100644
index bc5e3faef985..000000000000
--- a/core/res/res/drawable-mdpi/numberpicker_up_pressed_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_facial_backup.png b/core/res/res/drawable-xhdpi/ic_facial_backup.png
new file mode 100644
index 000000000000..942cf239fff9
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_facial_backup.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/intro_bg.png b/core/res/res/drawable-xhdpi/intro_bg.png
new file mode 100644
index 000000000000..00466c539e8a
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/intro_bg.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_down_disabled_focused_holo_dark.png b/core/res/res/drawable-xhdpi/numberpicker_down_disabled_focused_holo_dark.png
deleted file mode 100644
index 111f57eb772d..000000000000
--- a/core/res/res/drawable-xhdpi/numberpicker_down_disabled_focused_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_down_disabled_focused_holo_light.png b/core/res/res/drawable-xhdpi/numberpicker_down_disabled_focused_holo_light.png
deleted file mode 100644
index d0ef05b8a5d2..000000000000
--- a/core/res/res/drawable-xhdpi/numberpicker_down_disabled_focused_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_down_disabled_holo_dark.png b/core/res/res/drawable-xhdpi/numberpicker_down_disabled_holo_dark.png
deleted file mode 100644
index ff2194168af6..000000000000
--- a/core/res/res/drawable-xhdpi/numberpicker_down_disabled_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_down_disabled_holo_light.png b/core/res/res/drawable-xhdpi/numberpicker_down_disabled_holo_light.png
deleted file mode 100644
index 3e9bddad90c8..000000000000
--- a/core/res/res/drawable-xhdpi/numberpicker_down_disabled_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_down_focused_holo_dark.png b/core/res/res/drawable-xhdpi/numberpicker_down_focused_holo_dark.png
deleted file mode 100644
index 0462fca48902..000000000000
--- a/core/res/res/drawable-xhdpi/numberpicker_down_focused_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_down_focused_holo_light.png b/core/res/res/drawable-xhdpi/numberpicker_down_focused_holo_light.png
deleted file mode 100644
index a488e8e6b62e..000000000000
--- a/core/res/res/drawable-xhdpi/numberpicker_down_focused_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_down_longpressed_holo_dark.png b/core/res/res/drawable-xhdpi/numberpicker_down_longpressed_holo_dark.png
deleted file mode 100644
index f61b07651914..000000000000
--- a/core/res/res/drawable-xhdpi/numberpicker_down_longpressed_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_down_longpressed_holo_light.png b/core/res/res/drawable-xhdpi/numberpicker_down_longpressed_holo_light.png
deleted file mode 100644
index f61b07651914..000000000000
--- a/core/res/res/drawable-xhdpi/numberpicker_down_longpressed_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_down_normal_holo_dark.png b/core/res/res/drawable-xhdpi/numberpicker_down_normal_holo_dark.png
deleted file mode 100644
index 211944e53f7a..000000000000
--- a/core/res/res/drawable-xhdpi/numberpicker_down_normal_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_down_normal_holo_light.png b/core/res/res/drawable-xhdpi/numberpicker_down_normal_holo_light.png
deleted file mode 100644
index 12bc11ae0ca7..000000000000
--- a/core/res/res/drawable-xhdpi/numberpicker_down_normal_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_down_pressed_holo_dark.png b/core/res/res/drawable-xhdpi/numberpicker_down_pressed_holo_dark.png
deleted file mode 100644
index 635184cec76e..000000000000
--- a/core/res/res/drawable-xhdpi/numberpicker_down_pressed_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_down_pressed_holo_light.png b/core/res/res/drawable-xhdpi/numberpicker_down_pressed_holo_light.png
deleted file mode 100644
index 635184cec76e..000000000000
--- a/core/res/res/drawable-xhdpi/numberpicker_down_pressed_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_up_disabled_focused_holo_dark.png b/core/res/res/drawable-xhdpi/numberpicker_up_disabled_focused_holo_dark.png
deleted file mode 100644
index 470e569413b4..000000000000
--- a/core/res/res/drawable-xhdpi/numberpicker_up_disabled_focused_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_up_disabled_focused_holo_light.png b/core/res/res/drawable-xhdpi/numberpicker_up_disabled_focused_holo_light.png
deleted file mode 100644
index 16df74df151a..000000000000
--- a/core/res/res/drawable-xhdpi/numberpicker_up_disabled_focused_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_up_disabled_holo_dark.png b/core/res/res/drawable-xhdpi/numberpicker_up_disabled_holo_dark.png
deleted file mode 100644
index edd4c04ed558..000000000000
--- a/core/res/res/drawable-xhdpi/numberpicker_up_disabled_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_up_disabled_holo_light.png b/core/res/res/drawable-xhdpi/numberpicker_up_disabled_holo_light.png
deleted file mode 100644
index d8f459a70fe6..000000000000
--- a/core/res/res/drawable-xhdpi/numberpicker_up_disabled_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_up_focused_holo_dark.png b/core/res/res/drawable-xhdpi/numberpicker_up_focused_holo_dark.png
deleted file mode 100644
index 08bf2411a2b4..000000000000
--- a/core/res/res/drawable-xhdpi/numberpicker_up_focused_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_up_focused_holo_light.png b/core/res/res/drawable-xhdpi/numberpicker_up_focused_holo_light.png
deleted file mode 100644
index b2c40f19247e..000000000000
--- a/core/res/res/drawable-xhdpi/numberpicker_up_focused_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_up_longpressed_holo_dark.png b/core/res/res/drawable-xhdpi/numberpicker_up_longpressed_holo_dark.png
deleted file mode 100644
index f4f73317b3fb..000000000000
--- a/core/res/res/drawable-xhdpi/numberpicker_up_longpressed_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_up_longpressed_holo_light.png b/core/res/res/drawable-xhdpi/numberpicker_up_longpressed_holo_light.png
deleted file mode 100644
index f4f73317b3fb..000000000000
--- a/core/res/res/drawable-xhdpi/numberpicker_up_longpressed_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_up_normal_holo_dark.png b/core/res/res/drawable-xhdpi/numberpicker_up_normal_holo_dark.png
deleted file mode 100644
index 83650b163981..000000000000
--- a/core/res/res/drawable-xhdpi/numberpicker_up_normal_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_up_normal_holo_light.png b/core/res/res/drawable-xhdpi/numberpicker_up_normal_holo_light.png
deleted file mode 100644
index 78085d3d11d5..000000000000
--- a/core/res/res/drawable-xhdpi/numberpicker_up_normal_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_up_pressed_holo_dark.png b/core/res/res/drawable-xhdpi/numberpicker_up_pressed_holo_dark.png
deleted file mode 100644
index b8f68499dbac..000000000000
--- a/core/res/res/drawable-xhdpi/numberpicker_up_pressed_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_up_pressed_holo_light.png b/core/res/res/drawable-xhdpi/numberpicker_up_pressed_holo_light.png
deleted file mode 100644
index b8f68499dbac..000000000000
--- a/core/res/res/drawable-xhdpi/numberpicker_up_pressed_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable/numberpicker_down_btn_holo_dark.xml b/core/res/res/drawable/numberpicker_down_btn_holo_dark.xml
deleted file mode 100644
index dd6332db5685..000000000000
--- a/core/res/res/drawable/numberpicker_down_btn_holo_dark.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-
- <item android:state_pressed="false"
- android:state_enabled="true"
- android:state_focused="false"
- android:drawable="@drawable/numberpicker_down_normal_holo_dark" />
-
- <item android:state_pressed="true"
- android:state_enabled="true"
- android:drawable="@drawable/numberpicker_down_pressed_holo_dark" />
-
- <item android:state_pressed="false"
- android:state_enabled="true"
- android:state_focused="true"
- android:drawable="@drawable/numberpicker_down_focused_holo_dark" />
-
- <item android:state_pressed="false"
- android:state_enabled="false"
- android:state_focused="false"
- android:drawable="@drawable/numberpicker_down_disabled_holo_dark" />
-
- <item android:state_pressed="false"
- android:state_enabled="false"
- android:state_focused="true"
- android:drawable="@drawable/numberpicker_down_disabled_focused_holo_dark" />
-
-</selector>
diff --git a/core/res/res/drawable/numberpicker_down_btn_holo_light.xml b/core/res/res/drawable/numberpicker_down_btn_holo_light.xml
deleted file mode 100644
index 565fd868bfb2..000000000000
--- a/core/res/res/drawable/numberpicker_down_btn_holo_light.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-
- <item android:state_pressed="false"
- android:state_enabled="true"
- android:state_focused="false"
- android:drawable="@drawable/numberpicker_down_normal_holo_light" />
-
- <item android:state_pressed="true"
- android:state_enabled="true"
- android:drawable="@drawable/numberpicker_down_pressed_holo_light" />
-
- <item android:state_pressed="false"
- android:state_enabled="true"
- android:state_focused="true"
- android:drawable="@drawable/numberpicker_down_focused_holo_light" />
-
- <item android:state_pressed="false"
- android:state_enabled="false"
- android:state_focused="false"
- android:drawable="@drawable/numberpicker_down_disabled_holo_light" />
-
- <item android:state_pressed="false"
- android:state_enabled="false"
- android:state_focused="true"
- android:drawable="@drawable/numberpicker_down_disabled_focused_holo_light" />
-
-</selector>
diff --git a/core/res/res/drawable/numberpicker_up_btn_holo_dark.xml b/core/res/res/drawable/numberpicker_up_btn_holo_dark.xml
deleted file mode 100644
index 7af3ee42df3c..000000000000
--- a/core/res/res/drawable/numberpicker_up_btn_holo_dark.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-
- <item android:state_pressed="false"
- android:state_enabled="true"
- android:state_focused="false"
- android:drawable="@drawable/numberpicker_up_normal_holo_dark" />
-
- <item android:state_pressed="true"
- android:state_enabled="true"
- android:drawable="@drawable/numberpicker_up_pressed_holo_dark" />
-
- <item android:state_pressed="false"
- android:state_enabled="true"
- android:state_focused="true"
- android:drawable="@drawable/numberpicker_up_focused_holo_dark" />
-
- <item android:state_pressed="false"
- android:state_enabled="false"
- android:state_focused="false"
- android:drawable="@drawable/numberpicker_up_disabled_holo_dark" />
-
- <item android:state_pressed="false"
- android:state_enabled="false"
- android:state_focused="true"
- android:drawable="@drawable/numberpicker_up_disabled_focused_holo_dark" />
-
-</selector>
diff --git a/core/res/res/drawable/numberpicker_up_btn_holo_light.xml b/core/res/res/drawable/numberpicker_up_btn_holo_light.xml
deleted file mode 100644
index cbcbb07704ee..000000000000
--- a/core/res/res/drawable/numberpicker_up_btn_holo_light.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-
- <item android:state_pressed="false"
- android:state_enabled="true"
- android:state_focused="false"
- android:drawable="@drawable/numberpicker_up_normal_holo_light" />
-
- <item android:state_pressed="true"
- android:state_enabled="true"
- android:drawable="@drawable/numberpicker_up_pressed_holo_light" />
-
- <item android:state_pressed="false"
- android:state_enabled="true"
- android:state_focused="true"
- android:drawable="@drawable/numberpicker_up_focused_holo_light" />
-
- <item android:state_pressed="false"
- android:state_enabled="false"
- android:state_focused="false"
- android:drawable="@drawable/numberpicker_up_focused_holo_light" />
-
- <item android:state_pressed="false"
- android:state_enabled="false"
- android:state_focused="true"
- android:drawable="@drawable/numberpicker_up_disabled_focused_holo_light" />
-
-</selector>
diff --git a/core/res/res/layout-sw600dp/keyguard_screen_password_landscape.xml b/core/res/res/layout-sw600dp/keyguard_screen_password_landscape.xml
index 43d0a2c5b31f..2495b6771458 100644
--- a/core/res/res/layout-sw600dp/keyguard_screen_password_landscape.xml
+++ b/core/res/res/layout-sw600dp/keyguard_screen_password_landscape.xml
@@ -153,13 +153,32 @@
</LinearLayout>
<!-- Area to overlay FaceLock -->
- <View android:id="@+id/faceLockAreaView"
+ <RelativeLayout
+ android:id="@+id/faceLockAreaView"
android:visibility="invisible"
android:layout_width="512dip"
android:layout_height="512dip"
android:layout_centerInParent="true"
- android:background="@color/facelock_color_background"
- />
+ android:background="@drawable/intro_bg">
+
+ <View
+ android:id="@+id/spotlightMask"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="@color/facelock_spotlight_mask"
+ />
+
+ <ImageView
+ android:id="@+id/cancel_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:padding="5dip"
+ android:layout_alignParentTop="true"
+ android:layout_alignParentRight="true"
+ android:src="@drawable/ic_facial_backup"
+ />
+
+ </RelativeLayout>
</RelativeLayout>
diff --git a/core/res/res/layout-sw600dp/keyguard_screen_password_portrait.xml b/core/res/res/layout-sw600dp/keyguard_screen_password_portrait.xml
index 8c02888b0e9b..fb62eb68d76b 100644
--- a/core/res/res/layout-sw600dp/keyguard_screen_password_portrait.xml
+++ b/core/res/res/layout-sw600dp/keyguard_screen_password_portrait.xml
@@ -156,13 +156,32 @@
</LinearLayout>
<!-- Area to overlay FaceLock -->
- <View android:id="@+id/faceLockAreaView"
+ <RelativeLayout
+ android:id="@+id/faceLockAreaView"
android:visibility="invisible"
android:layout_width="512dip"
android:layout_height="512dip"
android:layout_centerInParent="true"
- android:background="@color/facelock_color_background"
- />
+ android:background="@drawable/intro_bg">
+
+ <View
+ android:id="@+id/spotlightMask"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="@color/facelock_spotlight_mask"
+ />
+
+ <ImageView
+ android:id="@+id/cancel_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:padding="5dip"
+ android:layout_alignParentTop="true"
+ android:layout_alignParentRight="true"
+ android:src="@drawable/ic_facial_backup"
+ />
+
+ </RelativeLayout>
</RelativeLayout>
diff --git a/core/res/res/layout-sw600dp/keyguard_screen_unlock_landscape.xml b/core/res/res/layout-sw600dp/keyguard_screen_unlock_landscape.xml
index 802ef822f9c3..53ecbac2935a 100644
--- a/core/res/res/layout-sw600dp/keyguard_screen_unlock_landscape.xml
+++ b/core/res/res/layout-sw600dp/keyguard_screen_unlock_landscape.xml
@@ -124,13 +124,32 @@
</RelativeLayout>
<!-- Area to overlay FaceLock -->
- <View android:id="@+id/faceLockAreaView"
+ <RelativeLayout
+ android:id="@+id/faceLockAreaView"
android:visibility="invisible"
android:layout_width="512dip"
android:layout_height="512dip"
android:layout_centerInParent="true"
- android:background="@color/facelock_color_background"
- />
+ android:background="@drawable/intro_bg">
+
+ <View
+ android:id="@+id/spotlightMask"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="@color/facelock_spotlight_mask"
+ />
+
+ <ImageView
+ android:id="@+id/cancel_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:padding="5dip"
+ android:layout_alignParentTop="true"
+ android:layout_alignParentRight="true"
+ android:src="@drawable/ic_facial_backup"
+ />
+
+ </RelativeLayout>
</RelativeLayout>
diff --git a/core/res/res/layout-sw600dp/keyguard_screen_unlock_portrait.xml b/core/res/res/layout-sw600dp/keyguard_screen_unlock_portrait.xml
index 40f24929f9ba..577668fe0da0 100644
--- a/core/res/res/layout-sw600dp/keyguard_screen_unlock_portrait.xml
+++ b/core/res/res/layout-sw600dp/keyguard_screen_unlock_portrait.xml
@@ -119,13 +119,32 @@
</RelativeLayout>
<!-- Area to overlay FaceLock -->
- <View android:id="@+id/faceLockAreaView"
+ <RelativeLayout
+ android:id="@+id/faceLockAreaView"
android:visibility="invisible"
android:layout_width="512dip"
android:layout_height="512dip"
android:layout_centerInParent="true"
- android:background="@color/facelock_color_background"
- />
+ android:background="@drawable/intro_bg">
+
+ <View
+ android:id="@+id/spotlightMask"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="@color/facelock_spotlight_mask"
+ />
+
+ <ImageView
+ android:id="@+id/cancel_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:padding="5dip"
+ android:layout_alignParentTop="true"
+ android:layout_alignParentRight="true"
+ android:src="@drawable/ic_facial_backup"
+ />
+
+ </RelativeLayout>
</RelativeLayout>
diff --git a/core/res/res/layout/keyguard_screen_password_landscape.xml b/core/res/res/layout/keyguard_screen_password_landscape.xml
index 66d7fd79044c..3bea16ce45b6 100644
--- a/core/res/res/layout/keyguard_screen_password_landscape.xml
+++ b/core/res/res/layout/keyguard_screen_password_landscape.xml
@@ -208,7 +208,8 @@
/>
<!-- Area to overlay FaceLock -->
- <TextView android:id="@+id/faceLockAreaView"
+ <RelativeLayout
+ android:id="@+id/faceLockAreaView"
android:visibility="invisible"
android:layout_row="0"
android:layout_column="2"
@@ -217,7 +218,25 @@
android:layout_gravity="fill"
android:layout_width="0dip"
android:layout_height="0dip"
- android:background="@color/facelock_color_background"
- />
+ android:background="@drawable/intro_bg">
+
+ <View
+ android:id="@+id/spotlightMask"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="@color/facelock_spotlight_mask"
+ />
+
+ <ImageView
+ android:id="@+id/cancel_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:padding="5dip"
+ android:layout_alignParentTop="true"
+ android:layout_alignParentRight="true"
+ android:src="@drawable/ic_facial_backup"
+ />
+
+ </RelativeLayout>
</GridLayout>
diff --git a/core/res/res/layout/keyguard_screen_password_portrait.xml b/core/res/res/layout/keyguard_screen_password_portrait.xml
index 426b2f7f139e..6b409aa21678 100644
--- a/core/res/res/layout/keyguard_screen_password_portrait.xml
+++ b/core/res/res/layout/keyguard_screen_password_portrait.xml
@@ -199,7 +199,8 @@
/>
<!-- Area to overlay FaceLock -->
- <TextView android:id="@+id/faceLockAreaView"
+ <RelativeLayout
+ android:id="@+id/faceLockAreaView"
android:visibility="invisible"
android:layout_row="3"
android:layout_column="0"
@@ -208,7 +209,25 @@
android:layout_gravity="fill"
android:layout_width="0dip"
android:layout_height="0dip"
- android:background="@color/facelock_color_background"
- />
+ android:background="@drawable/intro_bg">
+
+ <View
+ android:id="@+id/spotlightMask"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="@color/facelock_spotlight_mask"
+ />
+
+ <ImageView
+ android:id="@+id/cancel_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:padding="5dip"
+ android:layout_alignParentTop="true"
+ android:layout_alignParentRight="true"
+ android:src="@drawable/ic_facial_backup"
+ />
+
+ </RelativeLayout>
</GridLayout>
diff --git a/core/res/res/layout/keyguard_screen_unlock_landscape.xml b/core/res/res/layout/keyguard_screen_unlock_landscape.xml
index 103865706fff..7f9aaa048f88 100644
--- a/core/res/res/layout/keyguard_screen_unlock_landscape.xml
+++ b/core/res/res/layout/keyguard_screen_unlock_landscape.xml
@@ -161,7 +161,8 @@
/>
<!-- Area to overlay FaceLock -->
- <TextView android:id="@+id/faceLockAreaView"
+ <RelativeLayout
+ android:id="@+id/faceLockAreaView"
android:visibility="invisible"
android:layout_row="0"
android:layout_column="1"
@@ -171,7 +172,25 @@
android:layout_marginLeft="8dip"
android:layout_width="0dip"
android:layout_height="0dip"
- android:background="@color/facelock_color_background"
- />
+ android:background="@drawable/intro_bg">
+
+ <View
+ android:id="@+id/spotlightMask"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="@color/facelock_spotlight_mask"
+ />
+
+ <ImageView
+ android:id="@+id/cancel_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:padding="5dip"
+ android:layout_alignParentTop="true"
+ android:layout_alignParentRight="true"
+ android:src="@drawable/ic_facial_backup"
+ />
+
+ </RelativeLayout>
</GridLayout>
diff --git a/core/res/res/layout/keyguard_screen_unlock_portrait.xml b/core/res/res/layout/keyguard_screen_unlock_portrait.xml
index 336faa19b182..9a2e02455306 100644
--- a/core/res/res/layout/keyguard_screen_unlock_portrait.xml
+++ b/core/res/res/layout/keyguard_screen_unlock_portrait.xml
@@ -170,7 +170,8 @@
/>
<!-- Area to overlay FaceLock -->
- <TextView android:id="@+id/faceLockAreaView"
+ <RelativeLayout
+ android:id="@+id/faceLockAreaView"
android:visibility="invisible"
android:layout_row="4"
android:layout_column="0"
@@ -181,7 +182,25 @@
android:layout_marginBottom="8dip"
android:layout_width="0dip"
android:layout_height="0dip"
- android:background="@color/facelock_color_background"
- />
+ android:background="@drawable/intro_bg">
+
+ <View
+ android:id="@+id/spotlightMask"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="@color/facelock_spotlight_mask"
+ />
+
+ <ImageView
+ android:id="@+id/cancel_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:padding="5dip"
+ android:layout_alignParentTop="true"
+ android:layout_alignParentRight="true"
+ android:src="@drawable/ic_facial_backup"
+ />
+
+ </RelativeLayout>
</GridLayout>
diff --git a/core/res/res/layout/number_picker.xml b/core/res/res/layout/number_picker.xml
index 2967696d56ae..b7e7ae146730 100644
--- a/core/res/res/layout/number_picker.xml
+++ b/core/res/res/layout/number_picker.xml
@@ -22,19 +22,26 @@
<ImageButton android:id="@+id/increment"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
- style="?android:attr/numberPickerUpButtonStyle"
+ android:background="@android:drawable/numberpicker_up_btn"
+ android:paddingTop="22dip"
+ android:paddingBottom="22dip"
android:contentDescription="@string/number_picker_increment_button" />
- <view class="android.widget.NumberPicker$CustomEditText"
+ <EditText
android:id="@+id/numberpicker_input"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
- style="?android:attr/numberPickerInputTextStyle" />
+ android:textAppearance="@style/TextAppearance.Large.Inverse.NumberPickerInputText"
+ android:gravity="center"
+ android:singleLine="true"
+ android:background="@drawable/numberpicker_input" />
<ImageButton android:id="@+id/decrement"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
- style="?android:attr/numberPickerDownButtonStyle"
+ android:background="@android:drawable/numberpicker_down_btn"
+ android:paddingTop="22dip"
+ android:paddingBottom="22dip"
android:contentDescription="@string/number_picker_decrement_button" />
</merge>
diff --git a/core/res/res/layout/number_picker_with_selector_wheel.xml b/core/res/res/layout/number_picker_with_selector_wheel.xml
new file mode 100644
index 000000000000..c8fa0f7b2180
--- /dev/null
+++ b/core/res/res/layout/number_picker_with_selector_wheel.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2012, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<merge xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <view class="android.widget.NumberPicker$CustomEditText"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:id="@+id/numberpicker_input"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center"
+ android:singleLine="true"
+ android:background="@null" />
+
+</merge>
diff --git a/core/res/res/layout/preference_child_holo.xml b/core/res/res/layout/preference_child_holo.xml
index 3c6a12edc391..41678628be16 100644
--- a/core/res/res/layout/preference_child_holo.xml
+++ b/core/res/res/layout/preference_child_holo.xml
@@ -60,7 +60,7 @@
android:layout_alignLeft="@android:id/title"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="?android:attr/textColorSecondary"
- android:maxLines="4" />
+ android:maxLines="10" />
</RelativeLayout>
diff --git a/core/res/res/layout/preference_holo.xml b/core/res/res/layout/preference_holo.xml
index 48f483df9e72..e57421995bd8 100644
--- a/core/res/res/layout/preference_holo.xml
+++ b/core/res/res/layout/preference_holo.xml
@@ -63,7 +63,7 @@
android:layout_alignLeft="@android:id/title"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="?android:attr/textColorSecondary"
- android:maxLines="4" />
+ android:maxLines="10" />
</RelativeLayout>
diff --git a/core/res/res/layout/preference_information_holo.xml b/core/res/res/layout/preference_information_holo.xml
index e29ed03913c4..5e03cfb7c214 100644
--- a/core/res/res/layout/preference_information_holo.xml
+++ b/core/res/res/layout/preference_information_holo.xml
@@ -61,7 +61,7 @@
android:layout_alignLeft="@android:id/title"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="?android:attr/textColorSecondary"
- android:maxLines="2" />
+ android:maxLines="10" />
</RelativeLayout>
diff --git a/core/res/res/values-af-rZA/arrays.xml b/core/res/res/values-af-rZA/donottranslate-maps.xml
index 5bff0f489ca3..5bff0f489ca3 100644
--- a/core/res/res/values-af-rZA/arrays.xml
+++ b/core/res/res/values-af-rZA/donottranslate-maps.xml
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 0141016d6aed..f020f5db57e4 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -335,18 +335,12 @@
<string name="permlab_writeContacts" msgid="644616215860933284">"skryf kontakdata"</string>
<string name="permdesc_writeContacts" product="tablet" msgid="988969759110632978">"Laat die program toe om die kontakdata (adresse) wat op jou tablet gestoor is, te verander. Kwaadwillige programme kan dit dalk gebruik om jou kontakdata uit te vee of te verander."</string>
<string name="permdesc_writeContacts" product="default" msgid="5075164818647934067">"Laat die program toe om die kontakdata (adresse) wat op jou foon gestoor is, te verander. Kwaadwillige programme kan dit dalk gebruik om jou kontakdata uit te vee of te verander."</string>
- <!-- no translation found for permlab_readCallLog (3478133184624102739) -->
- <skip />
- <!-- no translation found for permdesc_readCallLog (3995157599976515002) -->
- <skip />
- <!-- no translation found for permdesc_readCallLog (3452017559804750758) -->
- <skip />
- <!-- no translation found for permlab_writeCallLog (8552045664743499354) -->
- <skip />
- <!-- no translation found for permdesc_writeCallLog (6661806062274119245) -->
- <skip />
- <!-- no translation found for permdesc_writeCallLog (683941736352787842) -->
- <skip />
+ <string name="permlab_readCallLog" msgid="3478133184624102739">"lees oproeprekord"</string>
+ <string name="permdesc_readCallLog" product="tablet" msgid="3995157599976515002">"Laat die program toe om jou tablet se oproeprekord, insluitende data oor inkomende en uitgaande oproepe, te lees. Kwaadwillige programme kan dit gebruik om jou data na ander mense te stuur."</string>
+ <string name="permdesc_readCallLog" product="default" msgid="3452017559804750758">"Laat die program toe om jou foon se oproeprekord, insluitende data oor inkomende en uitgaande oproepe, te lees. Kwaadwillige programme kan dit gebruik om jou data na ander mense te stuur."</string>
+ <string name="permlab_writeCallLog" msgid="8552045664743499354">"skryf oproeprekord"</string>
+ <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Laat die program toe om jou tablet se oproeprekord, insluitende data oor inkomende en uitgaande oproepe, te verander. Kwaadwillige programme kan dit gebruik om jou oproeprekord uit te vee of te verander."</string>
+ <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Laat die program toe om jou foon se oproeprekord, insluitende data oor inkomende en uitgaande oproepe, te verander. Kwaadwillige programme kan dit gebruik om jou oproeprekord uit te vee of te verander."</string>
<string name="permlab_readProfile" msgid="6824681438529842282">"lees jou profieldata"</string>
<string name="permdesc_readProfile" product="default" msgid="94520753797630679">"Laat die program toe om persoonlike profielinligting te lees wat op jou toestel gestoor is, soos jou naam en kontakbesonderhede. Dit beteken dat die program jou kan identifiseer en jou profielinligting aan ander mense kan stuur."</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"skryf na jou profieldata"</string>
@@ -511,8 +505,8 @@
<string name="permdesc_readDictionary" msgid="8977815988329283705">"Laat die program toe om enige private woorde, name en frases te lees wat die gebruiker in die gebruikerwoordeboek gestoor het."</string>
<string name="permlab_writeDictionary" msgid="2296383164914812772">"skryf na gebruikergedefinieerde woordeboek"</string>
<string name="permdesc_writeDictionary" msgid="8185385716255065291">"Laat die program toe om nuwe woorde in die gebruikerwoordeboek te skryf."</string>
- <string name="permlab_sdcardRead" product="nosdcard" msgid="4086221374639183281">"Lees USB-geheue se inhoud"</string>
- <string name="permlab_sdcardRead" product="default" msgid="8537875151845139539">"Lees SD-kaart se inhoud"</string>
+ <string name="permlab_sdcardRead" product="nosdcard" msgid="4086221374639183281">"lees USB-geheue se inhoud"</string>
+ <string name="permlab_sdcardRead" product="default" msgid="8537875151845139539">"lees SD-kaart se inhoud"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="1055302898999352339">"Laat die program toe om die USB-geheue se inhoud te lees."</string>
<string name="permdesc_sdcardRead" product="default" msgid="7947792373570683542">"Laat die program toe om die SD-kaart se inhoud te lees."</string>
<string name="permlab_sdcardWrite" product="nosdcard" msgid="85430876310764752">"verander/vee uit USB-berging se inhoud"</string>
diff --git a/core/res/res/values-am-rET/arrays.xml b/core/res/res/values-am-rET/donottranslate-maps.xml
index 67e8b08ab275..67e8b08ab275 100644
--- a/core/res/res/values-am-rET/arrays.xml
+++ b/core/res/res/values-am-rET/donottranslate-maps.xml
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index f9e0a8a8742b..f1379f75d10e 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -336,11 +336,11 @@
<string name="permdesc_writeContacts" product="tablet" msgid="988969759110632978">"በጡባዊ ተኮህ ላይ የተከማቹ የእውቂያ(አድራሻ) ውሂብ ለመቀየር ለመተግበሪያው ይፈቅዳሉ፡፡ የእውቅያ ውሂብህን ለመደምሰስ ወይም ለመቀየር ተንኮል አዘል መተግበሪያዎች ሊጠቀሙት ይችላሉ፡፡"</string>
<string name="permdesc_writeContacts" product="default" msgid="5075164818647934067">"በስልክህ ላይ የተከማቹ የእውቂያ(አድራሻ) ውሂብ ለመቀየር ለመተግበሪያው ይፈቅዳሉ፡፡ የእውቅያ ውሂብህን ለመደምሰስ ወይም ለመቀየር ተንኮል አዘል መተግበሪያዎች ሊጠቀሙት ይችላሉ፡፡"</string>
<string name="permlab_readCallLog" msgid="3478133184624102739">"የጥሪ ምዝግብ ማስታወሻን አንብብ"</string>
- <string name="permdesc_readCallLog" product="tablet" msgid="3995157599976515002">"ስለ ገቢ እና ወጪ ጥሪዎችን ውሂብ ጨምሮ፣ የጡባዊ ተኮህን ምዝግብ ማስታወሻ እንዲያነብ ለመተግበሪያው ይፈቅዳል፡፡ ይሄንን ተንኮል አዘል መተግበሪያዎች ለሌሎች ሰዎች ውሂብህን ለመላክ ሊጠቀሙበት ይችላሉ፡፡"</string>
- <string name="permdesc_readCallLog" product="default" msgid="3452017559804750758">"ስለ ገቢ እና ወጪ ጥሪዎችን ውሂብ ጨምሮ፣ የስልክ ጥሪህን ምዝግብ ማስታወሻ እንዲያነብ ለመተግበሪያው ይፈቅዳል፡፡ ይሄንን ተንኮል አዘል መተግበሪያዎች ለሌሎች ሰዎች ውሂብህን ለመላክ ሊጠቀሙበት ይችላሉ፡፡"</string>
+ <string name="permdesc_readCallLog" product="tablet" msgid="3995157599976515002">"ስለ ገቢ እና ወጪ ጥሪዎችን ውሂብ ጨምሮ፣ የጡባዊ ተኮህን ምዝግብ ማስታወሻ እንዲያነብ ለመተግበሪያው ይፈቅዳል። ይሄንን ተንኮል አዘል መተግበሪያዎች ለሌሎች ሰዎች ውሂብህን ለመላክ ሊጠቀሙበት ይችላሉ።"</string>
+ <string name="permdesc_readCallLog" product="default" msgid="3452017559804750758">"ስለ ገቢ እና ወጪ ጥሪዎችን ውሂብ ጨምሮ፣ የስልክ ጥሪህን ምዝግብ ማስታወሻ እንዲያነብ ለመተግበሪያው ይፈቅዳል። ይሄንን ተንኮል አዘል መተግበሪያዎች ለሌሎች ሰዎች ውሂብህን ለመላክ ሊጠቀሙበት ይችላሉ።"</string>
<string name="permlab_writeCallLog" msgid="8552045664743499354">"የጥሪ ምዝግብ ማስታወሻን ፃፍ"</string>
- <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"ስለ ገቢ እና ወጪ ጥሪዎችን ውሂብ ጨምሮ፣ የጡባዊተኮህን ምዝግብ ማስታወሻ ለመቀየር ለመተግበሪያው ይፈቅዳል፡፡ ይሄንን ተንኮል አዘል መተግበሪያዎች የስልክህን ምዝግብ ማስታወሻ ለመሰረዝ ወይም ለመለወጥ ሊጠቀሙበት ይችላሉ፡፡"</string>
- <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"ስለ ገቢ እና ወጪ ጥሪዎችን ውሂብ ጨምሮ፣ የስልክህን ምዝግብ ማስታወሻ ለመቀየር ለመተግበሪያው ይፈቅዳል፡፡ ይሄንን ተንኮል አዘል መተግበሪያዎች የስልክህን ምዝግብ ማስታወሻ ለመሰረዝ ወይም ለመለወጥ ሊጠቀሙበት ይችላሉ፡፡"</string>
+ <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"ስለ ገቢ እና ወጪ ጥሪዎችን ውሂብ ጨምሮ፣ የጡባዊተኮህን ምዝግብ ማስታወሻ ለመቀየር ለመተግበሪያው ይፈቅዳል። ይሄንን ተንኮል አዘል መተግበሪያዎች የስልክህን ምዝግብ ማስታወሻ ለመሰረዝ ወይም ለመለወጥ ሊጠቀሙበት ይችላሉ።"</string>
+ <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"ስለ ገቢ እና ወጪ ጥሪዎችን ውሂብ ጨምሮ፣ የስልክህን ምዝግብ ማስታወሻ ለመቀየር ለመተግበሪያው ይፈቅዳል። ይሄንን ተንኮል አዘል መተግበሪያዎች የስልክህን ምዝግብ ማስታወሻ ለመሰረዝ ወይም ለመለወጥ ሊጠቀሙበት ይችላሉ።"</string>
<string name="permlab_readProfile" msgid="6824681438529842282">"የመገለጫ ውሂብዎን ያንብቡ"</string>
<string name="permdesc_readProfile" product="default" msgid="94520753797630679">"ልክ እንደ አንተ ስም እና የዕውቂያ መረጃ ፣ ባንተ መሳሪያ ወስጥ የተከማቹ የግል መገለጫ መረጃ ለማንበብ ለመተግበሪያው ይፈቅዳሉ፡፡ይሄም ማለት ሌሎች መተግበሪያዎች ሊለዩህ ይችላሉ እና ለሌሎች የመገለጫ መረጃህን ይልካሉ፡፡"</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"የአርስዎ መገለጫ ውሂብ ላይ ይፃፉ"</string>
@@ -507,8 +507,8 @@
<string name="permdesc_writeDictionary" msgid="8185385716255065291">"በተጠቃሚ መዝገበ ቃላት ውስጥ አዲስ ቃል እንዲጽፍ ለመተግበሪያው ይፈቅዳሉ፡፡"</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="4086221374639183281">"የUSB ካርድ ይዘቶችን አንብብ"</string>
<string name="permlab_sdcardRead" product="default" msgid="8537875151845139539">"የSD ካርድ ይዘቶችን አንብብ"</string>
- <string name="permdesc_sdcardRead" product="nosdcard" msgid="1055302898999352339">"መተግበሪያው ከUSB ካርድ ላይ ያሉ ይዘቶችን እንዲያነብ ይፈቅድለታል፡፡"</string>
- <string name="permdesc_sdcardRead" product="default" msgid="7947792373570683542">"መተግበሪያው ከSD ካርድ ላይ ያሉ ይዘቶችን እንዲያነብ ይፈቅድለታል፡፡"</string>
+ <string name="permdesc_sdcardRead" product="nosdcard" msgid="1055302898999352339">"መተግበሪያው ከUSB ካርድ ላይ ያሉ ይዘቶችን እንዲያነብ ይፈቅድለታል።"</string>
+ <string name="permdesc_sdcardRead" product="default" msgid="7947792373570683542">"መተግበሪያው ከSD ካርድ ላይ ያሉ ይዘቶችን እንዲያነብ ይፈቅድለታል።"</string>
<string name="permlab_sdcardWrite" product="nosdcard" msgid="85430876310764752">"የUSB ማከማቻ ይዘቶችን ቀይር/ሰርዝ"</string>
<string name="permlab_sdcardWrite" product="default" msgid="8079403759001777291">"የSD ካርድ ይዘትንቀይር/ሰርዝ"</string>
<string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"ወደ USB ማህደረ ትውስታው ለመፃፍ ለመተግበሪያው ይፈቅዳሉ፡፡"</string>
diff --git a/core/res/res/values-ar-rEG/arrays.xml b/core/res/res/values-ar-rEG/donottranslate-maps.xml
index 1180cb31697e..1180cb31697e 100644
--- a/core/res/res/values-ar-rEG/arrays.xml
+++ b/core/res/res/values-ar-rEG/donottranslate-maps.xml
diff --git a/core/res/res/values-ar-rIL/arrays.xml b/core/res/res/values-ar-rIL/donottranslate-maps.xml
index 87c1231cf5dd..87c1231cf5dd 100644
--- a/core/res/res/values-ar-rIL/arrays.xml
+++ b/core/res/res/values-ar-rIL/donottranslate-maps.xml
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index a8868be7892e..a156e64ce372 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -335,18 +335,12 @@
<string name="permlab_writeContacts" msgid="644616215860933284">"كتابة بيانات جهة الاتصال"</string>
<string name="permdesc_writeContacts" product="tablet" msgid="988969759110632978">"للسماح للتطبيق بتعديل بيانات (عنوان) جهة الاتصال المخزّنة على الجهاز اللوحي. يمكن أن تستخدم التطبيقات الضارة ذلك لمسح بيانات جهات الاتصال أو تعديلها."</string>
<string name="permdesc_writeContacts" product="default" msgid="5075164818647934067">"للسماح للتطبيق بتعديل بيانات (عنوان) جهة الاتصال المخزّنة على هاتفك. يمكن أن تستخدم التطبيقات الضارة ذلك لمسح بيانات جهات الاتصال أو تعديلها."</string>
- <!-- no translation found for permlab_readCallLog (3478133184624102739) -->
- <skip />
- <!-- no translation found for permdesc_readCallLog (3995157599976515002) -->
- <skip />
- <!-- no translation found for permdesc_readCallLog (3452017559804750758) -->
- <skip />
- <!-- no translation found for permlab_writeCallLog (8552045664743499354) -->
- <skip />
- <!-- no translation found for permdesc_writeCallLog (6661806062274119245) -->
- <skip />
- <!-- no translation found for permdesc_writeCallLog (683941736352787842) -->
- <skip />
+ <string name="permlab_readCallLog" msgid="3478133184624102739">"قراءة سجل المكالمات"</string>
+ <string name="permdesc_readCallLog" product="tablet" msgid="3995157599976515002">"للسماح للتطبيق بقراءة سجل المكالمات، بما في ذلك البيانات عن المكالمات الواردة والصادرة. وربما تستخدم التطبيقات الضارة هذا لإرسال بياناتك إلى أشخاص آخرين."</string>
+ <string name="permdesc_readCallLog" product="default" msgid="3452017559804750758">"للسماح للتطبيق بقراءة سجل مكالمات الهاتف، بما في ذلك البيانات عن المكالمات الواردة والصادرة. وربما تستخدم التطبيقات الضارة هذا لإرسال بياناتك إلى أشخاص آخرين."</string>
+ <string name="permlab_writeCallLog" msgid="8552045664743499354">"كتابة سجل المكالمات"</string>
+ <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"للسماح للتطبيق بتعديل سجل مكالمات الجهاز اللوحي، بما في ذلك البيانات عن المكالمات الواردة والصادرة. وربما تستخدم التطبيقات الضارة هذا لمسح سجل المكالمات أو تعديله."</string>
+ <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"للسماح للتطبيق بتعديل سجل مكالمات الهاتف، بما في ذلك البيانات عن المكالمات الواردة والصادرة. وربما تستخدم التطبيقات الضارة هذا لمحو سجل المكالمات أو تعديله."</string>
<string name="permlab_readProfile" msgid="6824681438529842282">"قراءة بيانات ملفك الشخصي"</string>
<string name="permdesc_readProfile" product="default" msgid="94520753797630679">"للسماح للتطبيق بقراءة معلومات الملف الشخصي الشخصية المخزنة على الجهاز، مثل اسمك ومعلومات جهات الاتصال. يعني ذلك أنه يمكن للتطبيق التعرف عليك وإرسال معلومات ملفك الشخصي إلى الآخرين."</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"الكتابة إلى بيانات ملفك الشخصي"</string>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index cfeb360d4b12..017876457521 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -335,18 +335,12 @@
<string name="permlab_writeContacts" msgid="644616215860933284">"запісваць кантактныя дадзеныя"</string>
<string name="permdesc_writeContacts" product="tablet" msgid="988969759110632978">"Дазваляе прыкладанням змяняць кантакты (адрасы), якія захоўваюцца на планшэце. Шкоднасныя прыкладанні могуць выкарыстоўваць гэтую магчымасць для выдалення або змены кантактных дадзеных."</string>
<string name="permdesc_writeContacts" product="default" msgid="5075164818647934067">"Дазваляе прыкладанням змяняць кантакты (адрасы), якія захоўваюцца на вашым тэлефоне. Шкоднасныя прыкладанні могуць выкарыстоўваць гэту магчымасць для выдалення або змены кантактных дадзеных."</string>
- <!-- no translation found for permlab_readCallLog (3478133184624102739) -->
- <skip />
- <!-- no translation found for permdesc_readCallLog (3995157599976515002) -->
- <skip />
- <!-- no translation found for permdesc_readCallLog (3452017559804750758) -->
- <skip />
- <!-- no translation found for permlab_writeCallLog (8552045664743499354) -->
- <skip />
- <!-- no translation found for permdesc_writeCallLog (6661806062274119245) -->
- <skip />
- <!-- no translation found for permdesc_writeCallLog (683941736352787842) -->
- <skip />
+ <string name="permlab_readCallLog" msgid="3478133184624102739">"чытанне гiсторыi выклікаў"</string>
+ <string name="permdesc_readCallLog" product="tablet" msgid="3995157599976515002">"Дазваляе прыкладанню чытаць гiсторыю выклiкаў планшэту, у тым лiку дадзеныя пра ўваходныя і зыходныя выклiкi. Шкоднасныя прыкладаннi могуць выкарыстоўваць гэта, каб адпраўляць вашы дадзеныя іншым людзям."</string>
+ <string name="permdesc_readCallLog" product="default" msgid="3452017559804750758">"Дазваляе прыкладанню чытаць гiсторыю выклiкаў, у тым лiку ўваходныя і зыходныя выклiкi. Шкоднасныя праграмы могуць выкарыстоўваць гэта, каб адпраўляць вашы дадзеныя іншым людзям."</string>
+ <string name="permlab_writeCallLog" msgid="8552045664743499354">"запіс гiсторыi выклікаў"</string>
+ <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Дазваляе прыкладанню змяняць гiсторыю выклiкаў планшэта, у тым лiку дадзеныя пра ўваходныя i зыходныя выклiкi. Шкоднасныя прыкладаннi могуць выкарыстоўваць гэта, каб выдаляць або змяняць гiсторыю выклікаў."</string>
+ <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Дазваляе прыкладанням змяняць гiсторыю выклiкаў тэлефону, у тым лiку дадзеныя пра ўваходныя і зыходныя выклiкi. Шкоднасныя прыкладаннi могуць выкарыстоўваць гэта, каб выдаляць або змяняць гiсторыю выклікаў."</string>
<string name="permlab_readProfile" msgid="6824681438529842282">"чытаць дадзеныя вашага профілю"</string>
<string name="permdesc_readProfile" product="default" msgid="94520753797630679">"Дазваляе прыкладанням счытваць асабістую інфармацыю ў профілях, якая захоўваецца на вашай прыладзе, напрыклад, ваша імя і кантактную інфармацыю. Гэта азначае, што прыкладанне можа ідэнтыфікаваць вас і адправіць інфармацыю вашага профілю трэцім асобам."</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"увядзіце дадзеныя вашага профілю"</string>
diff --git a/core/res/res/values-bg-rBG/arrays.xml b/core/res/res/values-bg-rBG/donottranslate-maps.xml
index 3cfcbfde237b..3cfcbfde237b 100644
--- a/core/res/res/values-bg-rBG/arrays.xml
+++ b/core/res/res/values-bg-rBG/donottranslate-maps.xml
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 2d74ffde4580..479e118d462d 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -335,18 +335,12 @@
<string name="permlab_writeContacts" msgid="644616215860933284">"запис на данни за контактите"</string>
<string name="permdesc_writeContacts" product="tablet" msgid="988969759110632978">"Разрешава на приложението да променя данните за контактите (за адрес), съхранени в таблета ви. Злонамерените приложения могат да използват това, за да изтрият или променят тези данни."</string>
<string name="permdesc_writeContacts" product="default" msgid="5075164818647934067">"Разрешава на приложението да променя данните за контактите (за адрес), съхранени в телефона ви. Злонамерените приложения могат да използват това, за да изтрият или променят тези данни."</string>
- <!-- no translation found for permlab_readCallLog (3478133184624102739) -->
- <skip />
- <!-- no translation found for permdesc_readCallLog (3995157599976515002) -->
- <skip />
- <!-- no translation found for permdesc_readCallLog (3452017559804750758) -->
- <skip />
- <!-- no translation found for permlab_writeCallLog (8552045664743499354) -->
- <skip />
- <!-- no translation found for permdesc_writeCallLog (6661806062274119245) -->
- <skip />
- <!-- no translation found for permdesc_writeCallLog (683941736352787842) -->
- <skip />
+ <string name="permlab_readCallLog" msgid="3478133184624102739">"четене на списъка с обаждания"</string>
+ <string name="permdesc_readCallLog" product="tablet" msgid="3995157599976515002">"Разрешава на приложението да чете списъка с обаждания на таблета ви, включително данните за входящите и изходящите обаждания. Злонамерените приложения могат да използват това, за да изпращат информацията ви на други хора."</string>
+ <string name="permdesc_readCallLog" product="default" msgid="3452017559804750758">"Разрешава на приложението да чете списъка с обаждания на телефона ви, включително данните за входящите и изходящите обаждания. Злонамерените приложения могат да използват това, за да изпращат информацията ви на други хора."</string>
+ <string name="permlab_writeCallLog" msgid="8552045664743499354">"запис на списъка с обаждания"</string>
+ <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Разрешава на приложението да променя списъка с обаждания на таблета ви, включително данните за входящите и изходящите обаждания. Злонамерените приложения могат да използват това, за да изтрият или променят този списък."</string>
+ <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Разрешава на приложението да променя списъка с обаждания на телефона ви, включително данните за входящите и изходящите обаждания. Злонамерените приложения могат да използват това, за да изтрият или променят този списък."</string>
<string name="permlab_readProfile" msgid="6824681438529842282">"четене на данните в профила ви"</string>
<string name="permdesc_readProfile" product="default" msgid="94520753797630679">"Разрешава на приложението да чете информацията от личния потребителски профил, съхранена на устройството ви, например вашето име и данни за връзка. Това означава, че приложението може да ви идентифицира и да изпраща информацията за потребителския ви профил на други хора."</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"запис в потр. ви профил"</string>
diff --git a/core/res/res/values-ca-rES/arrays.xml b/core/res/res/values-ca-rES/donottranslate-maps.xml
index 7f5667cb966e..7f5667cb966e 100644
--- a/core/res/res/values-ca-rES/arrays.xml
+++ b/core/res/res/values-ca-rES/donottranslate-maps.xml
diff --git a/core/res/res/values-cs-rCZ/arrays.xml b/core/res/res/values-cs-rCZ/donottranslate-maps.xml
index 484c9b34dcfd..484c9b34dcfd 100644
--- a/core/res/res/values-cs-rCZ/arrays.xml
+++ b/core/res/res/values-cs-rCZ/donottranslate-maps.xml
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 08f4dc99cdf8..8125ee318030 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -335,18 +335,12 @@
<string name="permlab_writeContacts" msgid="644616215860933284">"zapisovat data kontaktů"</string>
<string name="permdesc_writeContacts" product="tablet" msgid="988969759110632978">"Umožňuje aplikaci upravit kontaktní údaje (adresy) uložené v tabletu. Škodlivé aplikace mohou toto oprávnění použít k vymazání nebo úpravě kontaktních údajů."</string>
<string name="permdesc_writeContacts" product="default" msgid="5075164818647934067">"Umožňuje aplikaci upravit kontaktní údaje uložené v telefonu (adresu). Škodlivé aplikace mohou toto oprávnění použít k vymazání nebo úpravě kontaktních údajů."</string>
- <!-- no translation found for permlab_readCallLog (3478133184624102739) -->
- <skip />
- <!-- no translation found for permdesc_readCallLog (3995157599976515002) -->
- <skip />
- <!-- no translation found for permdesc_readCallLog (3452017559804750758) -->
- <skip />
- <!-- no translation found for permlab_writeCallLog (8552045664743499354) -->
- <skip />
- <!-- no translation found for permdesc_writeCallLog (6661806062274119245) -->
- <skip />
- <!-- no translation found for permdesc_writeCallLog (683941736352787842) -->
- <skip />
+ <string name="permlab_readCallLog" msgid="3478133184624102739">"číst seznam hovorů"</string>
+ <string name="permdesc_readCallLog" product="tablet" msgid="3995157599976515002">"Umožňuje aplikaci číst seznam hovorů vašeho tabletu, včetně dat o příchozích a odchozích hovorech. Škodlivé aplikace mohou tato data posílat jiným osobám."</string>
+ <string name="permdesc_readCallLog" product="default" msgid="3452017559804750758">"Umožňuje aplikaci číst seznam hovorů vašeho telefonu, včetně dat o příchozích a odchozích hovorech. Škodlivé aplikace mohou tato data posílat jiným osobám."</string>
+ <string name="permlab_writeCallLog" msgid="8552045664743499354">"zapisovat seznam hovorů"</string>
+ <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Umožňuje aplikaci upravovat seznam hovorů vašeho tabletu, včetně dat o příchozích a odchozích hovorech. Škodlivé aplikace to mohou zneužít k vymazání nebo změnám seznamu hovorů."</string>
+ <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Umožňuje aplikaci upravovat seznam hovorů vašeho telefonu, včetně dat o příchozích a odchozích hovorech. Škodlivé aplikace to mohou zneužít k vymazání nebo změnám seznamu hovorů."</string>
<string name="permlab_readProfile" msgid="6824681438529842282">"čtení údajů o vašem profilu"</string>
<string name="permdesc_readProfile" product="default" msgid="94520753797630679">"Umožňuje aplikaci číst údaje v osobním profilu uložené v zařízení, například jméno nebo kontaktní údaje. Znamená to, že vás ostatní aplikace mohou identifikovat a odeslat údaje z profilu dalším aplikacím."</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"zapisovat do údajů o profilu"</string>
diff --git a/core/res/res/values-da-rDK/arrays.xml b/core/res/res/values-da-rDK/donottranslate-maps.xml
index 4d0abd033ea0..4d0abd033ea0 100644
--- a/core/res/res/values-da-rDK/arrays.xml
+++ b/core/res/res/values-da-rDK/donottranslate-maps.xml
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index ed51692154dd..b139e5e577df 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -335,18 +335,12 @@
<string name="permlab_writeContacts" msgid="644616215860933284">"skriv kontaktdata"</string>
<string name="permdesc_writeContacts" product="tablet" msgid="988969759110632978">"Tillader, at appen kan ændre data for kontaktpersoner (adresser), der er gemt på din tablet. Ondsindede apps kan bruge dette til at slette eller ændre dine kontaktoplysninger."</string>
<string name="permdesc_writeContacts" product="default" msgid="5075164818647934067">"Tillader, at appen kan ændre kontaktdata (adresser), der er gemt på din telefon. Ondsindede apps kan bruge dette til at slette eller ændre kontaktdata."</string>
- <!-- no translation found for permlab_readCallLog (3478133184624102739) -->
- <skip />
- <!-- no translation found for permdesc_readCallLog (3995157599976515002) -->
- <skip />
- <!-- no translation found for permdesc_readCallLog (3452017559804750758) -->
- <skip />
- <!-- no translation found for permlab_writeCallLog (8552045664743499354) -->
- <skip />
- <!-- no translation found for permdesc_writeCallLog (6661806062274119245) -->
- <skip />
- <!-- no translation found for permdesc_writeCallLog (683941736352787842) -->
- <skip />
+ <string name="permlab_readCallLog" msgid="3478133184624102739">"læs opkaldsliste"</string>
+ <string name="permdesc_readCallLog" product="tablet" msgid="3995157599976515002">"Tillader, at appen læser din tablets opkaldsliste, herunder data om indgående og udgående opkald. Ondsindede apps kan bruge dette til at sende dine data til andre personer."</string>
+ <string name="permdesc_readCallLog" product="default" msgid="3452017559804750758">"Tillader, at appen læser telefonens opkaldsliste, herunder data om indgående og udgående opkald. Ondsindede apps kan bruge dette til at sende dine data til andre personer."</string>
+ <string name="permlab_writeCallLog" msgid="8552045664743499354">"skriv opkaldsliste"</string>
+ <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Tillader, at appen ændrer din tablets opkaldsliste, herunder data om indgående og udgående opkald. Ondsindede apps kan bruge dette til at slette eller ændre din opkaldsliste."</string>
+ <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Tillader, at appen ændrer telefonens opkaldsliste, herunder data om indgående og udgående opkald. Ondsindede apps kan bruge dette til at slette eller ændre din opkaldsliste."</string>
<string name="permlab_readProfile" msgid="6824681438529842282">"læse dine profildata"</string>
<string name="permdesc_readProfile" product="default" msgid="94520753797630679">"Tillader, at appen kan læse personlige profiloplysninger, der er gemt på din enhed, f.eks. dit navn og dine kontaktoplysninger. Det betyder, at appen kan identificere dig og sende dine profiloplysninger til andre."</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"skrive til dine profildata"</string>
@@ -513,8 +507,8 @@
<string name="permdesc_writeDictionary" msgid="8185385716255065291">"Tillader, at appen kan skrive nye ord i brugerordbogen."</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="4086221374639183281">"læse USB-lagerets indhold"</string>
<string name="permlab_sdcardRead" product="default" msgid="8537875151845139539">"læse indholdet af SD-kortet"</string>
- <string name="permdesc_sdcardRead" product="nosdcard" msgid="1055302898999352339">"Tillader, at app\'en læser indhold på USB-lager."</string>
- <string name="permdesc_sdcardRead" product="default" msgid="7947792373570683542">"Tillader, at app\'en læser indholdet af SD-kortet."</string>
+ <string name="permdesc_sdcardRead" product="nosdcard" msgid="1055302898999352339">"Tillader, at appen læser indhold på USB-lageret."</string>
+ <string name="permdesc_sdcardRead" product="default" msgid="7947792373570683542">"Tillader, at appen læser indholdet af SD-kortet."</string>
<string name="permlab_sdcardWrite" product="nosdcard" msgid="85430876310764752">"rette/slette i USB-lager"</string>
<string name="permlab_sdcardWrite" product="default" msgid="8079403759001777291">"ret/slet indholdet på SD-kortet"</string>
<string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"Lader appen skrive til USB."</string>
diff --git a/core/res/res/values-de-rAT/arrays.xml b/core/res/res/values-de-rAT/donottranslate-maps.xml
index e8855cf652e1..e8855cf652e1 100644
--- a/core/res/res/values-de-rAT/arrays.xml
+++ b/core/res/res/values-de-rAT/donottranslate-maps.xml
diff --git a/core/res/res/values-de-rCH/arrays.xml b/core/res/res/values-de-rCH/donottranslate-maps.xml
index f2982e9f54d9..f2982e9f54d9 100644
--- a/core/res/res/values-de-rCH/arrays.xml
+++ b/core/res/res/values-de-rCH/donottranslate-maps.xml
diff --git a/core/res/res/values-de-rDE/arrays.xml b/core/res/res/values-de-rDE/donottranslate-maps.xml
index 3680fd33f21c..3680fd33f21c 100644
--- a/core/res/res/values-de-rDE/arrays.xml
+++ b/core/res/res/values-de-rDE/donottranslate-maps.xml
diff --git a/core/res/res/values-de-rLI/arrays.xml b/core/res/res/values-de-rLI/donottranslate-maps.xml
index 0481b764b798..0481b764b798 100644
--- a/core/res/res/values-de-rLI/arrays.xml
+++ b/core/res/res/values-de-rLI/donottranslate-maps.xml
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index f9ae61bb7ed4..baf3e40e8a82 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -335,18 +335,12 @@
<string name="permlab_writeContacts" msgid="644616215860933284">"Kontaktdaten schreiben"</string>
<string name="permdesc_writeContacts" product="tablet" msgid="988969759110632978">"Ermöglicht der App, die auf Ihrem Tablet gespeicherten Kontaktdaten (Adressen) zu ändern. Schädliche Apps können so Ihre Kontaktdaten löschen oder ändern."</string>
<string name="permdesc_writeContacts" product="default" msgid="5075164818647934067">"Ermöglicht der App, die auf Ihrem Telefon gespeicherten Kontaktdaten (Adressen) zu ändern. Schädliche Apps können so Ihre Kontaktdaten löschen oder ändern."</string>
- <!-- no translation found for permlab_readCallLog (3478133184624102739) -->
- <skip />
- <!-- no translation found for permdesc_readCallLog (3995157599976515002) -->
- <skip />
- <!-- no translation found for permdesc_readCallLog (3452017559804750758) -->
- <skip />
- <!-- no translation found for permlab_writeCallLog (8552045664743499354) -->
- <skip />
- <!-- no translation found for permdesc_writeCallLog (6661806062274119245) -->
- <skip />
- <!-- no translation found for permdesc_writeCallLog (683941736352787842) -->
- <skip />
+ <string name="permlab_readCallLog" msgid="3478133184624102739">"Anrufprotokoll lesen"</string>
+ <string name="permdesc_readCallLog" product="tablet" msgid="3995157599976515002">"Ermöglicht der App, das Anrufprotokoll Ihres Tablets zu lesen, einschließlich der Daten über ein- und ausgehende Anrufe. Schädliche Apps können so Ihre Daten an Dritte senden."</string>
+ <string name="permdesc_readCallLog" product="default" msgid="3452017559804750758">"Ermöglicht der App, das Anrufprotokoll Ihres Telefons zu lesen, einschließlich der Daten über ein- und ausgehende Anrufe. Schädliche Apps können so Ihre Daten an Dritte senden."</string>
+ <string name="permlab_writeCallLog" msgid="8552045664743499354">"Anrufprotokoll bearbeiten"</string>
+ <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Ermöglicht der App, das Anrufprotokoll Ihres Tablets zu ändern, einschließlich der Daten über ein- und ausgehende Anrufe. Schädliche Apps können so Ihr Anrufprotokoll löschen oder ändern."</string>
+ <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Ermöglicht der App, das Anrufprotokoll Ihres Telefons zu ändern, einschließlich der Daten über ein- und ausgehende Anrufe. Schädliche Apps können so Ihr Anrufprotokoll löschen oder ändern."</string>
<string name="permlab_readProfile" msgid="6824681438529842282">"Ihre Profildaten lesen"</string>
<string name="permdesc_readProfile" product="default" msgid="94520753797630679">"Ermöglicht der App, auf Ihrem Gerät gespeicherte persönliche Profilinformationen zu lesen, darunter Ihren Namen und Ihre Kontaktdaten. Die App kann Sie somit identifizieren und Ihre Profilinformationen an andere senden."</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"In Ihre Profildaten schreiben"</string>
@@ -423,8 +417,8 @@
<string name="permdesc_performCdmaProvisioning" msgid="1994193538802314186">"Ermöglicht der App, die CDMA-Bereitstellung zu starten. Schädliche Apps können so die CDMA-Bereitstellung unnötigerweise starten."</string>
<string name="permlab_locationUpdates" msgid="7785408253364335740">"Benachrichtigungen für Standortaktualisierung steuern"</string>
<string name="permdesc_locationUpdates" msgid="1120741557891438876">"Ermöglicht der App, Mobilfunkbenachrichtigungen über Standort-Updates zu aktivieren bzw. zu deaktivieren. Nicht für normale Apps vorgesehen."</string>
- <string name="permlab_checkinProperties" msgid="7855259461268734914">"Auf Check-In-Eigenschaften zugreifen"</string>
- <string name="permdesc_checkinProperties" msgid="4024526968630194128">"Ermöglicht der App Schreib-/Lesezugriff auf vom Check-In-Service hochgeladene Elemente. Nicht für normale Apps vorgesehen."</string>
+ <string name="permlab_checkinProperties" msgid="7855259461268734914">"Auf Check-in-Eigenschaften zugreifen"</string>
+ <string name="permdesc_checkinProperties" msgid="4024526968630194128">"Ermöglicht der App Schreib-/Lesezugriff auf vom Check-in-Service hochgeladene Elemente. Nicht für normale Apps vorgesehen."</string>
<string name="permlab_bindGadget" msgid="776905339015863471">"Widgets auswählen"</string>
<string name="permdesc_bindGadget" msgid="8261326938599049290">"Ermöglicht der App, dem System zu melden, welche Widgets von welcher App verwendet werden können. Mit dieser Berechtigung können Apps anderen Apps Zugriff auf persönliche Daten gewähren. Nicht für normale Apps vorgesehen."</string>
<string name="permlab_modifyPhoneState" msgid="8423923777659292228">"Telefonstatus ändern"</string>
diff --git a/core/res/res/values-el-rGR/arrays.xml b/core/res/res/values-el-rGR/donottranslate-maps.xml
index 0329ca3d55df..0329ca3d55df 100644
--- a/core/res/res/values-el-rGR/arrays.xml
+++ b/core/res/res/values-el-rGR/donottranslate-maps.xml
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 99883fbe13b6..ad840e3523e3 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -335,18 +335,12 @@
<string name="permlab_writeContacts" msgid="644616215860933284">"εγγραφή δεδομένων επαφής"</string>
<string name="permdesc_writeContacts" product="tablet" msgid="988969759110632978">"Επιτρέπει στην εφαρμογή να τροποποιεί τα δεδομένα επαφής (διεύθυνσης) που είναι αποθηκευμένα στο tablet σας. Κακόβουλες εφαρμογές μπορούν να το χρησιμοποιήσουν για να διαγράψουν ή να τροποποιήσουν τα δεδομένα επαφών σας."</string>
<string name="permdesc_writeContacts" product="default" msgid="5075164818647934067">"Επιτρέπει στην εφαρμογή να τροποποιεί τα δεδομένα επαφής (διεύθυνσης) που είναι αποθηκευμένα στο τηλέφωνό σας. Κακόβουλες εφαρμογές μπορούν να το χρησιμοποιήσουν για να διαγράψουν ή να τροποποιήσουν τα δεδομένα επαφών σας."</string>
- <!-- no translation found for permlab_readCallLog (3478133184624102739) -->
- <skip />
- <!-- no translation found for permdesc_readCallLog (3995157599976515002) -->
- <skip />
- <!-- no translation found for permdesc_readCallLog (3452017559804750758) -->
- <skip />
- <!-- no translation found for permlab_writeCallLog (8552045664743499354) -->
- <skip />
- <!-- no translation found for permdesc_writeCallLog (6661806062274119245) -->
- <skip />
- <!-- no translation found for permdesc_writeCallLog (683941736352787842) -->
- <skip />
+ <string name="permlab_readCallLog" msgid="3478133184624102739">"ανάγνωση αρχείου καταγραφής κλήσεων"</string>
+ <string name="permdesc_readCallLog" product="tablet" msgid="3995157599976515002">"Επιτρέπει στην εφαρμογή να διαβάζει το αρχείο καταγραφής κλήσεων του tablet σας, συμπεριλαμβανομένων των δεδομένων σχετικά με τις εισερχόμενες και τις εξερχόμενες κλήσεις. Οι κακόβουλες εφαρμογές μπορεί να το χρησιμοποιήσουν για να στείλουν τα δεδομένα σας σε άλλα άτομα."</string>
+ <string name="permdesc_readCallLog" product="default" msgid="3452017559804750758">"Επιτρέπει στην εφαρμογή να διαβάζει το αρχείο καταγραφής κλήσεων του τηλεφώνου σας, συμπεριλαμβανομένων των δεδομένων σχετικά με τις εισερχόμενες και τις εξερχόμενες κλήσεις. Οι κακόβουλες εφαρμογές μπορεί να το χρησιμοποιήσουν για να στείλουν τα δεδομένα σας σε άλλα άτομα."</string>
+ <string name="permlab_writeCallLog" msgid="8552045664743499354">"εγγραφή αρχείου καταγραφής κλήσεων"</string>
+ <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Επιτρέπει στην εφαρμογή να τροποποιεί το αρχείο καταγραφής κλήσεων του tablet σας, συμπεριλαμβανομένων των δεδομένων σχετικά με τις εισερχόμενες και τις εξερχόμενες κλήσεις. Οι κακόβουλες εφαρμογές μπορεί να το χρησιμοποιήσουν για να διαγράψουν ή να τροποποιήσουν το αρχείο καταγραφής κλήσεων."</string>
+ <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Επιτρέπει στην εφαρμογή να τροποποιεί το αρχείο καταγραφής κλήσεων του τηλεφώνου σας, συμπεριλαμβανομένων των δεδομένων σχετικά με τις εισερχόμενες και τις εξερχόμενες κλήσεις. Οι κακόβουλες εφαρμογές μπορεί να το χρησιμοποιήσουν για να διαγράψουν ή να τροποποιήσουν το αρχείο καταγραφής κλήσεων."</string>
<string name="permlab_readProfile" msgid="6824681438529842282">"ανάγν. δεδ. προφ."</string>
<string name="permdesc_readProfile" product="default" msgid="94520753797630679">"Επιτρέπει στην εφαρμογή την ανάγνωση προσωπικών πληροφοριών προφίλ οι οποίες είναι αποθηκευμένες στη συσκευή σας, όπως το όνομα και τα στοιχεία επικοινωνίας σας. Αυτό σημαίνει ότι η εφαρμογή μπορεί να σας αναγνωρίσει και να στείλει τις πληροφορίες σας προφίλ σε άλλους."</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"εγγρ. σε δεδ. προφίλ"</string>
diff --git a/core/res/res/values-en-rAU/arrays.xml b/core/res/res/values-en-rAU/donottranslate-maps.xml
index 46351e65df39..46351e65df39 100644
--- a/core/res/res/values-en-rAU/arrays.xml
+++ b/core/res/res/values-en-rAU/donottranslate-maps.xml
diff --git a/core/res/res/values-en-rCA/arrays.xml b/core/res/res/values-en-rCA/donottranslate-maps.xml
index 00c7ca421f98..00c7ca421f98 100644
--- a/core/res/res/values-en-rCA/arrays.xml
+++ b/core/res/res/values-en-rCA/donottranslate-maps.xml
diff --git a/core/res/res/values-en-rGB/arrays.xml b/core/res/res/values-en-rGB/donottranslate-maps.xml
index 02a0e0fe85f9..02a0e0fe85f9 100644
--- a/core/res/res/values-en-rGB/arrays.xml
+++ b/core/res/res/values-en-rGB/donottranslate-maps.xml
diff --git a/core/res/res/values-en-rIE/arrays.xml b/core/res/res/values-en-rIE/donottranslate-maps.xml
index 51cc537de006..51cc537de006 100644
--- a/core/res/res/values-en-rIE/arrays.xml
+++ b/core/res/res/values-en-rIE/donottranslate-maps.xml
diff --git a/core/res/res/values-en-rIN/arrays.xml b/core/res/res/values-en-rIN/donottranslate-maps.xml
index d5b2889c59f2..d5b2889c59f2 100644
--- a/core/res/res/values-en-rIN/arrays.xml
+++ b/core/res/res/values-en-rIN/donottranslate-maps.xml
diff --git a/core/res/res/values-en-rNZ/arrays.xml b/core/res/res/values-en-rNZ/donottranslate-maps.xml
index 26f00d94ce1e..26f00d94ce1e 100644
--- a/core/res/res/values-en-rNZ/arrays.xml
+++ b/core/res/res/values-en-rNZ/donottranslate-maps.xml
diff --git a/core/res/res/values-en-rSG/arrays.xml b/core/res/res/values-en-rSG/donottranslate-maps.xml
index ee1e64ba073f..ee1e64ba073f 100644
--- a/core/res/res/values-en-rSG/arrays.xml
+++ b/core/res/res/values-en-rSG/donottranslate-maps.xml
diff --git a/core/res/res/values-en-rZA/arrays.xml b/core/res/res/values-en-rZA/donottranslate-maps.xml
index 259b2b15af5d..259b2b15af5d 100644
--- a/core/res/res/values-en-rZA/arrays.xml
+++ b/core/res/res/values-en-rZA/donottranslate-maps.xml
diff --git a/core/res/res/values-es-rES/arrays.xml b/core/res/res/values-es-rES/donottranslate-maps.xml
index 7f5667cb966e..7f5667cb966e 100644
--- a/core/res/res/values-es-rES/arrays.xml
+++ b/core/res/res/values-es-rES/donottranslate-maps.xml
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 20f18d90485c..8761ca9e996e 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -335,18 +335,12 @@
<string name="permlab_writeContacts" msgid="644616215860933284">"escribir datos de contacto"</string>
<string name="permdesc_writeContacts" product="tablet" msgid="988969759110632978">"Permite que la aplicación modifique la información de contacto (dirección) almacenada en tu tableta. Las aplicaciones maliciosas pueden utilizar este permiso para borrar o modificar tu información de contacto."</string>
<string name="permdesc_writeContacts" product="default" msgid="5075164818647934067">"Permite que la aplicación modifique la información de contacto (dirección) almacenada en tu dispositivo. Las aplicaciones maliciosas pueden utilizar este permiso para borrar o modificar tu información de contacto."</string>
- <!-- no translation found for permlab_readCallLog (3478133184624102739) -->
- <skip />
- <!-- no translation found for permdesc_readCallLog (3995157599976515002) -->
- <skip />
- <!-- no translation found for permdesc_readCallLog (3452017559804750758) -->
- <skip />
- <!-- no translation found for permlab_writeCallLog (8552045664743499354) -->
- <skip />
- <!-- no translation found for permdesc_writeCallLog (6661806062274119245) -->
- <skip />
- <!-- no translation found for permdesc_writeCallLog (683941736352787842) -->
- <skip />
+ <string name="permlab_readCallLog" msgid="3478133184624102739">"leer el registro de llamadas"</string>
+ <string name="permdesc_readCallLog" product="tablet" msgid="3995157599976515002">"Permite que la aplicación lea el registro de llamadas de la tableta, incluidos los datos sobre llamadas entrantes y salientes. Las aplicaciones malintencionadas pueden usar este permiso para enviar tus datos a otros usuarios."</string>
+ <string name="permdesc_readCallLog" product="default" msgid="3452017559804750758">"Permite que la aplicación lea el registro de llamadas del dispositivo, incluidos los datos sobre llamadas entrantes y salientes. Las aplicaciones malintencionadas pueden usar este permiso para enviar tus datos a otros usuarios."</string>
+ <string name="permlab_writeCallLog" msgid="8552045664743499354">"escribir en el registro de llamadas"</string>
+ <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Permite que la aplicación modifique el registro de llamadas de la tableta, incluidos los datos sobre llamadas entrantes y salientes. Las aplicaciones malintencionadas pueden usar este permiso para borrar o modificar el registro de llamadas."</string>
+ <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Permite que la aplicación modifique el registro de llamadas del dispositivo, incluidos los datos sobre llamadas entrantes y salientes. Las aplicaciones malintencionadas pueden usar este permiso para borrar o modificar el registro de llamadas."</string>
<string name="permlab_readProfile" msgid="6824681438529842282">"Leer tus datos de perfil"</string>
<string name="permdesc_readProfile" product="default" msgid="94520753797630679">"Permite que la aplicación lea la información de perfil almacenada en tu dispositivo, como tu nombre e información de contacto. Esto significa que la aplicación puede identificarte y enviar tu información de perfil a otros."</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"Escrib. en datos de tu perfil"</string>
@@ -511,14 +505,10 @@
<string name="permdesc_readDictionary" msgid="8977815988329283705">"Permite que la aplicación lea cualquier palabra, nombre o frase de carácter privado que el usuario haya almacenado en su diccionario."</string>
<string name="permlab_writeDictionary" msgid="2296383164914812772">"agregar al diccionario definido por el usuario"</string>
<string name="permdesc_writeDictionary" msgid="8185385716255065291">"Permite que la aplicación ingrese palabras nuevas en el diccionario del usuario."</string>
- <!-- no translation found for permlab_sdcardRead (4086221374639183281) -->
- <skip />
- <!-- no translation found for permlab_sdcardRead (8537875151845139539) -->
- <skip />
- <!-- no translation found for permdesc_sdcardRead (1055302898999352339) -->
- <skip />
- <!-- no translation found for permdesc_sdcardRead (7947792373570683542) -->
- <skip />
+ <string name="permlab_sdcardRead" product="nosdcard" msgid="4086221374639183281">"Leer almacenamiento USB"</string>
+ <string name="permlab_sdcardRead" product="default" msgid="8537875151845139539">"Leer el contenido de la tarjeta SD"</string>
+ <string name="permdesc_sdcardRead" product="nosdcard" msgid="1055302898999352339">"Permite leer USB."</string>
+ <string name="permdesc_sdcardRead" product="default" msgid="7947792373570683542">"Permite a la aplicación leer el contenido de la tarjeta SD."</string>
<string name="permlab_sdcardWrite" product="nosdcard" msgid="85430876310764752">"modificar o eliminar el contenido del almacenamiento USB"</string>
<string name="permlab_sdcardWrite" product="default" msgid="8079403759001777291">"modificar/eliminar el contenido de la tarjeta SD"</string>
<string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"Permite que la aplicación escriba en el almacenamiento USB."</string>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index 3c8079d3a44a..b68944e29434 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -335,18 +335,12 @@
<string name="permlab_writeContacts" msgid="644616215860933284">"kirjuta kontaktandmeid"</string>
<string name="permdesc_writeContacts" product="tablet" msgid="988969759110632978">"Võimaldab rakendusel muuta tahvelarvutisse salvestatud kontaktandmeid (aadresse). Pahatahtlikud rakendused võivad seda kasutada teie kontaktandmete kustutamiseks või muutmiseks."</string>
<string name="permdesc_writeContacts" product="default" msgid="5075164818647934067">"Võimaldab rakendusel muuta telefoni salvestatud kontaktandmeid (aadresse). Pahatahtlikud rakendused võivad seda kasutada teie kontaktandmete kustutamiseks või muutmiseks."</string>
- <!-- no translation found for permlab_readCallLog (3478133184624102739) -->
- <skip />
- <!-- no translation found for permdesc_readCallLog (3995157599976515002) -->
- <skip />
- <!-- no translation found for permdesc_readCallLog (3452017559804750758) -->
- <skip />
- <!-- no translation found for permlab_writeCallLog (8552045664743499354) -->
- <skip />
- <!-- no translation found for permdesc_writeCallLog (6661806062274119245) -->
- <skip />
- <!-- no translation found for permdesc_writeCallLog (683941736352787842) -->
- <skip />
+ <string name="permlab_readCallLog" msgid="3478133184624102739">"kõnelogi lugemine"</string>
+ <string name="permdesc_readCallLog" product="tablet" msgid="3995157599976515002">"Lubab rakendusel lugeda tahvelarvuti kõnelogi, sh teavet sissetulevate ja väljaminevate kõnede kohta. Pahatahtlikud rakendused võivad saata selle abil teie teavet teistele inimestele."</string>
+ <string name="permdesc_readCallLog" product="default" msgid="3452017559804750758">"Lubab rakendusel lugeda telefoni kõnelogi, sh teavet sissetulevate ja väljaminevate kõnede kohta. Pahatahtlikud rakendused võivad saata selle abil teie teavet teistele inimestele."</string>
+ <string name="permlab_writeCallLog" msgid="8552045664743499354">"kõnelogi kirjutamine"</string>
+ <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Lubab rakendusel muuta tahvelarvuti kõnelogi, sh sissetulevate ja väljaminevate kõnede andmeid. Pahatahtlikud rakendused võivad kasutada seda kõnelogi kustutamiseks või muutmiseks."</string>
+ <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Lubab rakendusel muuta telefoni kõnelogi, sh sissetulevate ja väljaminevate kõnede andmeid. Pahatahtlikud rakendused võivad kasutada seda kõnelogi kustutamiseks või muutmiseks."</string>
<string name="permlab_readProfile" msgid="6824681438529842282">"profiili andmete lugemine"</string>
<string name="permdesc_readProfile" product="default" msgid="94520753797630679">"Võimaldab rakendusel lugeda seadmesse salvestatud isiklikku teavet, näiteks teie nime ja kontaktandmeid. See tähendab, et rakendus saab teid tuvastada ja saata teie profiiliteavet teistele."</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"andmete kirjutamine profiili"</string>
diff --git a/core/res/res/values-fa-rIR/arrays.xml b/core/res/res/values-fa-rIR/donottranslate-maps.xml
index de0f368e2831..de0f368e2831 100644
--- a/core/res/res/values-fa-rIR/arrays.xml
+++ b/core/res/res/values-fa-rIR/donottranslate-maps.xml
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 164d2138481a..5a536e6e0cc2 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -335,18 +335,12 @@
<string name="permlab_writeContacts" msgid="644616215860933284">"نوشتن اطلاعات تماس"</string>
<string name="permdesc_writeContacts" product="tablet" msgid="988969759110632978">"به برنامه اجازه می‎دهد داده‎های مخاطب ذخیره شده در رایانه لوحی را تغییر دهد. برنامه‎های مخرب می‎توانند از آن استفاده کنند تا داده‎های تماس شما را تغییر دهند یا پاک کنند."</string>
<string name="permdesc_writeContacts" product="default" msgid="5075164818647934067">"به برنامه اجازه می‎دهد تا داده‎های مخاطب (آدرس) را که در تلفن ذخیره شده تغییر دهد. برنامه‎های مخرب می‎توانند از این استفاده کنند تا داده‎های تماس شما را پاک کنند یا تغییر دهند."</string>
- <!-- no translation found for permlab_readCallLog (3478133184624102739) -->
- <skip />
- <!-- no translation found for permdesc_readCallLog (3995157599976515002) -->
- <skip />
- <!-- no translation found for permdesc_readCallLog (3452017559804750758) -->
- <skip />
- <!-- no translation found for permlab_writeCallLog (8552045664743499354) -->
- <skip />
- <!-- no translation found for permdesc_writeCallLog (6661806062274119245) -->
- <skip />
- <!-- no translation found for permdesc_writeCallLog (683941736352787842) -->
- <skip />
+ <string name="permlab_readCallLog" msgid="3478133184624102739">"خواندن گزارش تماس"</string>
+ <string name="permdesc_readCallLog" product="tablet" msgid="3995157599976515002">"به برنامه اجازه می‌دهد گزارشات تماس رایانه لوحی شما، از جمله داده‌هایی درمورد تماس‎های ورودی و خروجی را بخواند. برنامه‌های مخرب ممکن است از این ویژگی برای ارسال داده‌های شما به دیگران استفاده کنند."</string>
+ <string name="permdesc_readCallLog" product="default" msgid="3452017559804750758">"به برنامه اجازه می‌دهد گزارشات تماس تلفنی شما، از جمله داده‌هایی درمورد تماس‎های ورودی و خروجی را بخواند. برنامه‌های مخرب ممکن است از این ویژگی برای ارسال داده‌های شما به دیگران استفاده کنند."</string>
+ <string name="permlab_writeCallLog" msgid="8552045664743499354">"نوشتن در گزارش تماس"</string>
+ <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"به برنامه اجازه می‌دهد گزارشات تماس رایانه لوحی شما، از جمله داده‌هایی درمورد تماس‎های ورودی و خروجی را تغییر دهد. برنامه‌های مخرب ممکن است از این ویژگی برای پاک کردن یا تغییر گزارش تماس شما استفاده کنند."</string>
+ <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"به برنامه اجازه می‌دهد گزارشات تماس تلفنی شما، از جمله داده‌هایی درمورد تماس‎های ورودی و خروجی را تغییر دهد. برنامه‌های مخرب ممکن است از این ویژگی برای پاک کردن یا تغییر گزارش تماس شما استفاده کنند."</string>
<string name="permlab_readProfile" msgid="6824681438529842282">"خواندن داده‌های نمایه شما"</string>
<string name="permdesc_readProfile" product="default" msgid="94520753797630679">"به برنامه اجازه می‎دهد اطلاعات نمایه شخصی ذخیره شده در دستگاه شما را بخواند. یعنی برنامه می‎تواند شما را شناسایی کند و اطلاعات نمایه شما را به دیگران ارسال کند."</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"نوشتن در داده‌های نمایه شما"</string>
diff --git a/core/res/res/values-fi-rFI/arrays.xml b/core/res/res/values-fi-rFI/donottranslate-maps.xml
index 2e2395376f61..2e2395376f61 100644
--- a/core/res/res/values-fi-rFI/arrays.xml
+++ b/core/res/res/values-fi-rFI/donottranslate-maps.xml
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 07f6118d849e..b1009a551de4 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -335,18 +335,12 @@
<string name="permlab_writeContacts" msgid="644616215860933284">"kirjoita yhteystietoja"</string>
<string name="permdesc_writeContacts" product="tablet" msgid="988969759110632978">"Antaa sovelluksen muokata tablet-laitteen yhteystietoja (osoitetietoja). Haitalliset sovellukset voivat käyttää tätä yhteystietojen poistamiseen tai muokkaamiseen."</string>
<string name="permdesc_writeContacts" product="default" msgid="5075164818647934067">"Antaa sovelluksen muokata puhelimen yhteystietoja (osoitetietoja). Haitalliset sovellukset voivat käyttää tätä yhteystietojen poistamiseen tai muokkaamiseen."</string>
- <!-- no translation found for permlab_readCallLog (3478133184624102739) -->
- <skip />
- <!-- no translation found for permdesc_readCallLog (3995157599976515002) -->
- <skip />
- <!-- no translation found for permdesc_readCallLog (3452017559804750758) -->
- <skip />
- <!-- no translation found for permlab_writeCallLog (8552045664743499354) -->
- <skip />
- <!-- no translation found for permdesc_writeCallLog (6661806062274119245) -->
- <skip />
- <!-- no translation found for permdesc_writeCallLog (683941736352787842) -->
- <skip />
+ <string name="permlab_readCallLog" msgid="3478133184624102739">"lue puhelulokia"</string>
+ <string name="permdesc_readCallLog" product="tablet" msgid="3995157599976515002">"Antaa sovelluksen lukea tablet-laitteesi puhelulokia, kuten tietoja vastatuista ja soitetuista puheluista. Haitalliset sovellukset voivat lähettää tietojasi muille henkilöille."</string>
+ <string name="permdesc_readCallLog" product="default" msgid="3452017559804750758">"Antaa sovelluksen lukea puhelimesi puhelulokia, kuten tietoja vastatuista ja soitetuista puheluista. Haitalliset sovellukset voivat lähettää tietojasi muille henkilöille."</string>
+ <string name="permlab_writeCallLog" msgid="8552045664743499354">"kirjoita puhelulokiin"</string>
+ <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Antaa sovelluksen muokata tablet-laitteesi puhelulokia, kuten tietoja vastatuista ja soitetuista puheluista. Haitalliset sovellukset voivat poistaa puhelulokisi tai muokata sitä."</string>
+ <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Antaa sovelluksen muokata puhelimesi puhelulokia, kuten tietoja vastatuista ja soitetuista puheluista. Haitalliset sovellukset voivat poistaa puhelulokisi tai muokata sitä."</string>
<string name="permlab_readProfile" msgid="6824681438529842282">"lukea profiilisi tiedot"</string>
<string name="permdesc_readProfile" product="default" msgid="94520753797630679">"Antaa sovelluksen lukea laitteelle tallennettuja henkilökohtaisia tietoja, kuten nimen ja yhteystietoja. Tämä antaa sovelluksen tunnistaa sinut ja lähettää profiilitietojasi muille."</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"kirjoittaa profiilin tietoihin"</string>
diff --git a/core/res/res/values-fr-rBE/arrays.xml b/core/res/res/values-fr-rBE/donottranslate-maps.xml
index 9e93a0922154..9e93a0922154 100644
--- a/core/res/res/values-fr-rBE/arrays.xml
+++ b/core/res/res/values-fr-rBE/donottranslate-maps.xml
diff --git a/core/res/res/values-fr-rCA/arrays.xml b/core/res/res/values-fr-rCA/donottranslate-maps.xml
index 00c7ca421f98..00c7ca421f98 100644
--- a/core/res/res/values-fr-rCA/arrays.xml
+++ b/core/res/res/values-fr-rCA/donottranslate-maps.xml
diff --git a/core/res/res/values-fr-rCH/arrays.xml b/core/res/res/values-fr-rCH/donottranslate-maps.xml
index f2982e9f54d9..f2982e9f54d9 100644
--- a/core/res/res/values-fr-rCH/arrays.xml
+++ b/core/res/res/values-fr-rCH/donottranslate-maps.xml
diff --git a/core/res/res/values-fr-rFR/arrays.xml b/core/res/res/values-fr-rFR/donottranslate-maps.xml
index 504ab0f63a68..504ab0f63a68 100644
--- a/core/res/res/values-fr-rFR/arrays.xml
+++ b/core/res/res/values-fr-rFR/donottranslate-maps.xml
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 88fe7214b831..d044a706af68 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -507,7 +507,7 @@
<string name="permdesc_writeDictionary" msgid="8185385716255065291">"Permet à l\'application d\'enregistrer de nouveaux mots dans le dictionnaire personnel de l\'utilisateur."</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="4086221374639183281">"lire contenu de la mémoire USB"</string>
<string name="permlab_sdcardRead" product="default" msgid="8537875151845139539">"lire le contenu de la carte SD"</string>
- <string name="permdesc_sdcardRead" product="nosdcard" msgid="1055302898999352339">"Permet à l\'appli de lire contenu mémoire USB."</string>
+ <string name="permdesc_sdcardRead" product="nosdcard" msgid="1055302898999352339">"Permet à l\'appli de lire contenu de mémoire USB."</string>
<string name="permdesc_sdcardRead" product="default" msgid="7947792373570683542">"Permet à l\'application de lire le contenu de la carte SD."</string>
<string name="permlab_sdcardWrite" product="nosdcard" msgid="85430876310764752">"Modifier/Supprimer contenu mémoire USB"</string>
<string name="permlab_sdcardWrite" product="default" msgid="8079403759001777291">"modifier/supprimer le contenu de la carte SD"</string>
diff --git a/core/res/res/values-hi-rIN/arrays.xml b/core/res/res/values-hi-rIN/donottranslate-maps.xml
index d5b2889c59f2..d5b2889c59f2 100644
--- a/core/res/res/values-hi-rIN/arrays.xml
+++ b/core/res/res/values-hi-rIN/donottranslate-maps.xml
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 966c70df84de..bd8863fe4d77 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -335,18 +335,12 @@
<string name="permlab_writeContacts" msgid="644616215860933284">"संपर्क डेटा लिखें"</string>
<string name="permdesc_writeContacts" product="tablet" msgid="988969759110632978">"एप्लिकेशन को आपके टेबलेट में संग्रहीत संपर्क (पता) डेटा संशोधित करने देता है. दुर्भावनापूर्ण एप्लिकेशन इसका उपयोग आपके संपर्क डेटा को मिटाने या संशोधित करने में कर सकते हैं."</string>
<string name="permdesc_writeContacts" product="default" msgid="5075164818647934067">"एप्लिकेशन को आपके फ़ोन में संग्रहीत संपर्क (पता) डेटा संशोधित करने देता है. दुर्भावनापूर्ण एप्लिकेशन इसका उपयोग आपके संपर्क डेटा को मिटाने या संशोधित करने में कर सकते हैं."</string>
- <!-- no translation found for permlab_readCallLog (3478133184624102739) -->
- <skip />
- <!-- no translation found for permdesc_readCallLog (3995157599976515002) -->
- <skip />
- <!-- no translation found for permdesc_readCallLog (3452017559804750758) -->
- <skip />
- <!-- no translation found for permlab_writeCallLog (8552045664743499354) -->
- <skip />
- <!-- no translation found for permdesc_writeCallLog (6661806062274119245) -->
- <skip />
- <!-- no translation found for permdesc_writeCallLog (683941736352787842) -->
- <skip />
+ <string name="permlab_readCallLog" msgid="3478133184624102739">"कॉल लॉग पढ़ें"</string>
+ <string name="permdesc_readCallLog" product="tablet" msgid="3995157599976515002">"एप्‍लिकेशन को इनकमिंग और आउटगोइंग कॉल के डेटा सहित, आपके टेबलेट का कॉल लॉग पढ़ने देता है. दुर्भावनापूर्ण एप्‍लिकेशन अन्‍य लोगों को आपका डेटा भेजने के लिए इसका उपयोग कर सकते हैं."</string>
+ <string name="permdesc_readCallLog" product="default" msgid="3452017559804750758">"एप्‍लिकेशन को इनकमिंग और आउटगोइंग कॉल के डेटा सहित, आपके फ़ोन का कॉल लॉग पढ़ने देता है. दुर्भावनापूर्ण एप्‍लिकेशन अन्‍य लोगों को आपका डेटा भेजने के लिए इसका उपयोग कर सकते हैं."</string>
+ <string name="permlab_writeCallLog" msgid="8552045664743499354">"कॉल लॉग लिखें"</string>
+ <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"एप्‍लिकेशन को इनकमिंग और आउटगोइंग कॉल के डेटा सहित, आपके टेबलेट का कॉल लॉग संशोधित करने देता है. दुर्भावनापूर्ण एप्‍लिकेशन आपके कॉल लॉग को मिटाने या संशोधित करने के लिए इसका उपयोग कर सकते हैं."</string>
+ <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"एप्‍लिकेशन को इनकमिंग और आउटगोइंग कॉल के डेटा सहित, आपके फ़ोन का कॉल लॉग संशोधित करने देता है. दुर्भावनापूर्ण एप्‍लिकेशन आपके कॉल लॉग को मिटाने या संशोधित करने के लिए इसका उपयोग कर सकते हैं."</string>
<string name="permlab_readProfile" msgid="6824681438529842282">"अपना प्रोफ़ाइल डेटा पढ़ें"</string>
<string name="permdesc_readProfile" product="default" msgid="94520753797630679">"एप्लिकेशन को आपके उपकरण में संग्रहीत नाम और संपर्क जानकारी जैसी निजी प्रोफ़ाइल जानकारी पढ़ने देता है. इसका अर्थ है कि एप्लिकेशन आपको पहचान सकता है और आपकी प्रोफ़ाइल की जानकारी अन्य लोगों को भेज सकता है."</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"अपने प्रोफ़ाइल डेटा में लि‍खें"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 588de28d8d0f..749012be7606 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -335,18 +335,12 @@
<string name="permlab_writeContacts" msgid="644616215860933284">"pisanje kontaktnih podataka"</string>
<string name="permdesc_writeContacts" product="tablet" msgid="988969759110632978">"Omogućuje aplikaciji da promijeni kontaktne podatke (adrese) pohranjene na tabletnom računalu. Zlonamjerne aplikacije mogu na taj način izbrisati ili promijeniti vaše kontaktne podatke."</string>
<string name="permdesc_writeContacts" product="default" msgid="5075164818647934067">"Omogućuje aplikaciji da promijeni kontaktne podatke (adrese) pohranjene na telefonu. Zlonamjerne aplikacije mogu na taj način izbrisati ili promijeniti vaše kontaktne podatke."</string>
- <!-- no translation found for permlab_readCallLog (3478133184624102739) -->
- <skip />
- <!-- no translation found for permdesc_readCallLog (3995157599976515002) -->
- <skip />
- <!-- no translation found for permdesc_readCallLog (3452017559804750758) -->
- <skip />
- <!-- no translation found for permlab_writeCallLog (8552045664743499354) -->
- <skip />
- <!-- no translation found for permdesc_writeCallLog (6661806062274119245) -->
- <skip />
- <!-- no translation found for permdesc_writeCallLog (683941736352787842) -->
- <skip />
+ <string name="permlab_readCallLog" msgid="3478133184624102739">"čitanje dnevnika poziva"</string>
+ <string name="permdesc_readCallLog" product="tablet" msgid="3995157599976515002">"Aplikaciji omogućuje čitanje dnevnika poziva vašeg tabletnog računala zajedno s podacima o dolaznim i odlaznim pozivima. Zlonamjerne aplikacije to mogu upotrebljavati za slanje vaših podataka drugim osobama."</string>
+ <string name="permdesc_readCallLog" product="default" msgid="3452017559804750758">"Aplikaciji omogućuje čitanje dnevnika poziva vašeg telefona zajedno s podacima o dolaznim i odlaznim pozivima. Zlonamjerne aplikacije to mogu upotrebljavati za slanje vaših podataka drugim osobama."</string>
+ <string name="permlab_writeCallLog" msgid="8552045664743499354">"pisanje u dnevnik poziva"</string>
+ <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Aplikaciji omogućuje izmjenu dnevnika poziva vašeg tabletnog računala zajedno s podacima o dolaznim i odlaznim pozivima. Zlonamjerne aplikacije to mogu upotrebljavati za brisanje ili izmjenu vašeg dnevnika poziva."</string>
+ <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Aplikaciji omogućuje izmjenu dnevnika poziva vašeg telefona zajedno s podacima o dolaznim i odlaznim pozivima. Zlonamjerne aplikacije to mogu upotrebljavati za brisanje ili izmjenu vašeg dnevnika poziva."</string>
<string name="permlab_readProfile" msgid="6824681438529842282">"čitanje podataka vašeg profila"</string>
<string name="permdesc_readProfile" product="default" msgid="94520753797630679">"Omogućuje aplikaciji čitanje osobnih podataka profila pohranjenih na uređaju, kao što su vaše ime ili kontaktni podaci. To znači da vas aplikacija može identificirati i slati informacije s vašeg profila drugima."</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"pisanje u podatke profila"</string>
diff --git a/core/res/res/values-hu-rHU/arrays.xml b/core/res/res/values-hu-rHU/donottranslate-maps.xml
index 833bb24304b1..833bb24304b1 100644
--- a/core/res/res/values-hu-rHU/arrays.xml
+++ b/core/res/res/values-hu-rHU/donottranslate-maps.xml
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 637bdd2d3826..24a70d751ea9 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -335,18 +335,12 @@
<string name="permlab_writeContacts" msgid="644616215860933284">"névjegyadatok írása"</string>
<string name="permdesc_writeContacts" product="tablet" msgid="988969759110632978">"Lehetővé teszi az alkalmazás számára, hogy módosítsa a táblagépen tárolt névjegy- (cím-) adatokat. A rosszindulatú alkalmazások felhasználhatják ezt a névjegyadatok törlésére vagy módosítására."</string>
<string name="permdesc_writeContacts" product="default" msgid="5075164818647934067">"Lehetővé teszi az alkalmazás számára, hogy módosítsa a telefonon tárolt névjegy- (cím-) adatokat. A rosszindulatú alkalmazások felhasználhatják ezt a névjegyadatok törlésére vagy módosítására."</string>
- <!-- no translation found for permlab_readCallLog (3478133184624102739) -->
- <skip />
- <!-- no translation found for permdesc_readCallLog (3995157599976515002) -->
- <skip />
- <!-- no translation found for permdesc_readCallLog (3452017559804750758) -->
- <skip />
- <!-- no translation found for permlab_writeCallLog (8552045664743499354) -->
- <skip />
- <!-- no translation found for permdesc_writeCallLog (6661806062274119245) -->
- <skip />
- <!-- no translation found for permdesc_writeCallLog (683941736352787842) -->
- <skip />
+ <string name="permlab_readCallLog" msgid="3478133184624102739">"Híváslista beolvasása"</string>
+ <string name="permdesc_readCallLog" product="tablet" msgid="3995157599976515002">"Lehetővé teszi, hogy az alkalmazás hozzáférjen a táblagép híváslistájához, beleértve a bejövő és kimenő hívások adatait. A rosszindulatú alkalmazások ezt arra használhatják, hogy az adatait elküldjék másoknak."</string>
+ <string name="permdesc_readCallLog" product="default" msgid="3452017559804750758">"Lehetővé teszi, hogy az alkalmazás hozzáférjen híváslistájához, beleértve a bejövő és kimenő hívások adatait. A rosszindulatú alkalmazások ezt arra használhatják, hogy az adatait elküldjék másoknak."</string>
+ <string name="permlab_writeCallLog" msgid="8552045664743499354">"Híváslista készítése"</string>
+ <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Lehetővé teszi, hogy az alkalmazás módosítsa a táblagép híváslistáját, beleértve a bejövő és kimenő hívások adatait is. A rosszindulatú alkalmazások ezt arra használhatják, hogy híváslistáját töröljék vagy módosítsák."</string>
+ <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Lehetővé teszi, hogy az alkalmazás módosítsa a telefon híváslistáját, beleértve a bejövő és kimenő hívások adatait is. A rosszindulatú alkalmazások ezt arra használhatják, hogy híváslistáját töröljék vagy módosítsák."</string>
<string name="permlab_readProfile" msgid="6824681438529842282">"olvassa el profiladatait"</string>
<string name="permdesc_readProfile" product="default" msgid="94520753797630679">"Lehetővé teszi az alkalmazás számára a készüléken tárolt személyes profiladatok, például a név és elérhetőség olvasását. Ez azt jelenti, hogy más alkalmazások is azonosíthatják Önt, és elküldhetik másoknak a profiladatait."</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"írás a profiladatokba"</string>
diff --git a/core/res/res/values-in-rID/arrays.xml b/core/res/res/values-in-rID/donottranslate-maps.xml
index 512cace1a568..512cace1a568 100644
--- a/core/res/res/values-in-rID/arrays.xml
+++ b/core/res/res/values-in-rID/donottranslate-maps.xml
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index b8b086786ecf..d2b4f048147d 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -335,18 +335,12 @@
<string name="permlab_writeContacts" msgid="644616215860933284">"tuliskan data kenalan"</string>
<string name="permdesc_writeContacts" product="tablet" msgid="988969759110632978">"Mengizinkan apl mengubah data (alamat) kenalan yang tersimpan di tablet. Apl berbahaya dapat menggunakan ini untuk menghapus atau mengubah data kenalan Anda."</string>
<string name="permdesc_writeContacts" product="default" msgid="5075164818647934067">"Mengizinkan apl memodifikasi data (alamat) kenalan yang tersimpan di ponsel Anda. Apl berbahaya dapat menggunakan ini untuk menghapus atau memodifikasi data kenalan Anda."</string>
- <!-- no translation found for permlab_readCallLog (3478133184624102739) -->
- <skip />
- <!-- no translation found for permdesc_readCallLog (3995157599976515002) -->
- <skip />
- <!-- no translation found for permdesc_readCallLog (3452017559804750758) -->
- <skip />
- <!-- no translation found for permlab_writeCallLog (8552045664743499354) -->
- <skip />
- <!-- no translation found for permdesc_writeCallLog (6661806062274119245) -->
- <skip />
- <!-- no translation found for permdesc_writeCallLog (683941736352787842) -->
- <skip />
+ <string name="permlab_readCallLog" msgid="3478133184624102739">"membaca log panggilan"</string>
+ <string name="permdesc_readCallLog" product="tablet" msgid="3995157599976515002">"Memungkinkan apl membaca log panggilan tablet Anda, termasuk data tentang panggilan masuk dan keluar. Apl berbahaya dapat menggunakan ini untuk mengirim data ke orang lain."</string>
+ <string name="permdesc_readCallLog" product="default" msgid="3452017559804750758">"Memungkinkan apl membaca log panggilan ponsel Anda, termasuk data tentang panggilan masuk dan keluar. Apl berbahaya dapat menggunakan ini untuk mengirim data ke orang lain."</string>
+ <string name="permlab_writeCallLog" msgid="8552045664743499354">"menulis log panggilan"</string>
+ <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Memungkinkan apl memodifikasi log panggilan tablet Anda, termasuk data tentang panggilan masuk dan keluar. Apl berbahaya dapat menggunakan ini untuk menghapus atau memodifikasi log panggilan Anda."</string>
+ <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Memungkinkan apl memodifikasi log panggilan ponsel Anda, termasuk data tentang panggilan masuk dan keluar. Apl berbahaya dapat menggunakan ini untuk menghapus atau memodifikasi log panggilan Anda."</string>
<string name="permlab_readProfile" msgid="6824681438529842282">"membaca data profil Anda"</string>
<string name="permdesc_readProfile" product="default" msgid="94520753797630679">"Mengizinkan apl membaca informasi profil pribadi yang tersimpan di perangkat Anda, misalnya nama dan informasi kenalan Anda. Ini artinya apl dapat mengenali dan mengirim informasi profil Anda ke orang lain."</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"menulis ke data profil Anda"</string>
@@ -511,14 +505,10 @@
<string name="permdesc_readDictionary" msgid="8977815988329283705">"Mengizinkan apl membaca kata, nama, dan frasa pribadi apa pun yang mungkin disimpan oleh pengguna di kamus pengguna."</string>
<string name="permlab_writeDictionary" msgid="2296383164914812772">"menulis ke kamus yang dibuat pengguna"</string>
<string name="permdesc_writeDictionary" msgid="8185385716255065291">"Mengizinkan apl menulis kata-kata baru ke dalam kamus pengguna."</string>
- <!-- no translation found for permlab_sdcardRead (4086221374639183281) -->
- <skip />
- <!-- no translation found for permlab_sdcardRead (8537875151845139539) -->
- <skip />
- <!-- no translation found for permdesc_sdcardRead (1055302898999352339) -->
- <skip />
- <!-- no translation found for permdesc_sdcardRead (7947792373570683542) -->
- <skip />
+ <string name="permlab_sdcardRead" product="nosdcard" msgid="4086221374639183281">"membaca konten penyimpanan USB"</string>
+ <string name="permlab_sdcardRead" product="default" msgid="8537875151845139539">"membaca konten kartu SD"</string>
+ <string name="permdesc_sdcardRead" product="nosdcard" msgid="1055302898999352339">"Mengizinkan apl membaca konten penyimpanan USB."</string>
+ <string name="permdesc_sdcardRead" product="default" msgid="7947792373570683542">"Mengizinkan apl membaca konten kartu SD."</string>
<string name="permlab_sdcardWrite" product="nosdcard" msgid="85430876310764752">"ubah/hapus konten penyimpanan USB"</string>
<string name="permlab_sdcardWrite" product="default" msgid="8079403759001777291">"ubah/hapus isi kartu SD"</string>
<string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"Mengizinkan apl menulis ke penyimpanan USB."</string>
diff --git a/core/res/res/values-it-rCH/arrays.xml b/core/res/res/values-it-rCH/donottranslate-maps.xml
index f2982e9f54d9..f2982e9f54d9 100644
--- a/core/res/res/values-it-rCH/arrays.xml
+++ b/core/res/res/values-it-rCH/donottranslate-maps.xml
diff --git a/core/res/res/values-it-rIT/arrays.xml b/core/res/res/values-it-rIT/donottranslate-maps.xml
index 92e5260d3c3d..92e5260d3c3d 100644
--- a/core/res/res/values-it-rIT/arrays.xml
+++ b/core/res/res/values-it-rIT/donottranslate-maps.xml
diff --git a/core/res/res/values-iw-rIL/arrays.xml b/core/res/res/values-iw-rIL/donottranslate-maps.xml
index 87c1231cf5dd..87c1231cf5dd 100644
--- a/core/res/res/values-iw-rIL/arrays.xml
+++ b/core/res/res/values-iw-rIL/donottranslate-maps.xml
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 40a4d015d615..f51f2329b7b3 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -130,7 +130,7 @@
<string name="low_memory" product="tablet" msgid="6494019234102154896">"שטח האחסון של הטבלט מלא. מחק קבצים כדי לפנות מקום."</string>
<string name="low_memory" product="default" msgid="3475999286680000541">"שטח האחסון של הטלפון מלא. מחק חלק מהקבצים כדי לפנות שטח."</string>
<string name="me" msgid="6545696007631404292">"אני"</string>
- <string name="power_dialog" product="tablet" msgid="8545351420865202853">"אפשרויות טבלט"</string>
+ <string name="power_dialog" product="tablet" msgid="8545351420865202853">"אפשרויות טאבלט"</string>
<string name="power_dialog" product="default" msgid="1319919075463988638">"אפשרויות טלפון"</string>
<string name="silent_mode" msgid="7167703389802618663">"מצב שקט"</string>
<string name="turn_on_radio" msgid="3912793092339962371">"הפעל חיבור אלחוטי"</string>
@@ -146,7 +146,7 @@
<string name="shutdown_confirm_question" msgid="2906544768881136183">"האם ברצונך לבצע כיבוי?"</string>
<string name="recent_tasks_title" msgid="3691764623638127888">"נוצרו לאחרונה"</string>
<string name="no_recent_tasks" msgid="8794906658732193473">"אין יישומים אחרונים"</string>
- <string name="global_actions" product="tablet" msgid="408477140088053665">"אפשרויות טבלט"</string>
+ <string name="global_actions" product="tablet" msgid="408477140088053665">"אפשרויות טאבלט"</string>
<string name="global_actions" product="default" msgid="2406416831541615258">"אפשרויות טלפון"</string>
<string name="global_action_lock" msgid="2844945191792119712">"נעילת מסך"</string>
<string name="global_action_power_off" msgid="4471879440839879722">"כיבוי"</string>
@@ -376,7 +376,7 @@
<string name="permdesc_recordAudio" msgid="2387462233976248635">"מאפשר ליישום לגשת לנתיב להקלטת אודיו."</string>
<string name="permlab_camera" msgid="3616391919559751192">"צלם תמונות וסרטונים"</string>
<string name="permdesc_camera" msgid="1507407407002492176">"מאפשר ליישום לצלם תמונות וסרטוני וידאו עם המצלמה. הגדרה זו מאפשרת ליישום לאסוף תמונות שהמצלמה קולטת בכל עת."</string>
- <string name="permlab_brick" product="tablet" msgid="2961292205764488304">"השבת טבלט לצמיתות"</string>
+ <string name="permlab_brick" product="tablet" msgid="2961292205764488304">"השבת טאבלט לצמיתות"</string>
<string name="permlab_brick" product="default" msgid="8337817093326370537">"השבת טלפון לצמיתות"</string>
<string name="permdesc_brick" product="tablet" msgid="4334818808001699530">"מאפשר ליישום להשבית את הטבלט כולו לצמיתות. זו הרשאה מסוכנת מאוד."</string>
<string name="permdesc_brick" product="default" msgid="5788903297627283099">"מאפשר ליישום להשבית את הטלפון כולו לצמיתות. זו הרשאה מסוכנת מאוד."</string>
@@ -412,7 +412,7 @@
<string name="permdesc_callPhone" msgid="6396463004110544744">"מאפשר ליישום להתקשר למספרי טלפון ללא התערבותך. יישומים זדוניים עלולים לגרום לחיובי שיחות בלתי צפויים בחשבון הטלפון שלך. לתשומת לבך, הרשאה זו לא מאפשרת ליישום להתקשר למספרי חירום."</string>
<string name="permlab_callPrivileged" msgid="4198349211108497879">"התקשר ישירות לכל מספר טלפון"</string>
<string name="permdesc_callPrivileged" msgid="1689024901509996810">"מאפשר ליישום להתקשר לכל מספר טלפון שהוא, כולל מספרי חירום, ללא התערבותך. יישומים זדוניים עלולים לבצע שיחות מיותרות ולא חוקיות לשירותי חירום."</string>
- <string name="permlab_performCdmaProvisioning" product="tablet" msgid="4842576994144604821">"הפעל ישירות התקנת טבלט מסוג CDMA"</string>
+ <string name="permlab_performCdmaProvisioning" product="tablet" msgid="4842576994144604821">"הפעל ישירות התקנת טאבלט מסוג CDMA"</string>
<string name="permlab_performCdmaProvisioning" product="default" msgid="5604848095315421425">"הפעל ישירות הגדרה של טלפון CDMA"</string>
<string name="permdesc_performCdmaProvisioning" msgid="1994193538802314186">"מאפשר ליישום להפעיל הקצאת CDMA. יישומים זדוניים עלולים להפעיל הקצאת CDMA ללא צורך."</string>
<string name="permlab_locationUpdates" msgid="7785408253364335740">"שלוט בהתראות על עדכון מיקום"</string>
@@ -429,7 +429,7 @@
<string name="permlab_wakeLock" product="default" msgid="573480187941496130">"מניעת מעבר הטלפון למצב שינה"</string>
<string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"מאפשר ליישום למנוע מהטבלט לעבור למצב שינה."</string>
<string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"מאפשר ליישום למנוע מהטלפון לעבור למצב שינה."</string>
- <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"הפעלה או כיבוי של טבלט"</string>
+ <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"הפעלה או כיבוי של טאבלט"</string>
<string name="permlab_devicePower" product="default" msgid="4928622470980943206">"הפעל או כבה את הטלפון"</string>
<string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"מאפשר ליישום להפעיל או לכבות את הטבלט."</string>
<string name="permdesc_devicePower" product="default" msgid="6037057348463131032">"מאפשר ליישום להפעיל או לכבות את הטלפון."</string>
diff --git a/core/res/res/values-ja-rJP/arrays.xml b/core/res/res/values-ja-rJP/donottranslate-maps.xml
index 74e8a59b17e0..74e8a59b17e0 100644
--- a/core/res/res/values-ja-rJP/arrays.xml
+++ b/core/res/res/values-ja-rJP/donottranslate-maps.xml
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 5b0918203fe9..549c1e208310 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -335,18 +335,12 @@
<string name="permlab_writeContacts" msgid="644616215860933284">"連絡先データの書き込み"</string>
<string name="permdesc_writeContacts" product="tablet" msgid="988969759110632978">"タブレットに保存されている連絡先(アドレス)データの変更をアプリに許可します。この許可を悪意のあるアプリに利用されると、連絡先データが消去または変更される恐れがあります。"</string>
<string name="permdesc_writeContacts" product="default" msgid="5075164818647934067">"携帯端末に保存されている連絡先(アドレス)データの変更をアプリに許可します。この許可を悪意のあるアプリに利用されると、連絡先データが消去または変更される恐れがあります。"</string>
- <!-- no translation found for permlab_readCallLog (3478133184624102739) -->
- <skip />
- <!-- no translation found for permdesc_readCallLog (3995157599976515002) -->
- <skip />
- <!-- no translation found for permdesc_readCallLog (3452017559804750758) -->
- <skip />
- <!-- no translation found for permlab_writeCallLog (8552045664743499354) -->
- <skip />
- <!-- no translation found for permdesc_writeCallLog (6661806062274119245) -->
- <skip />
- <!-- no translation found for permdesc_writeCallLog (683941736352787842) -->
- <skip />
+ <string name="permlab_readCallLog" msgid="3478133184624102739">"通話履歴の読み取り"</string>
+ <string name="permdesc_readCallLog" product="tablet" msgid="3995157599976515002">"タブレットの通話履歴(着信や発信のデータなど)の読み取りをアプリに許可します。この許可を悪意のあるアプリに利用されると、データが他のユーザーに送信される恐れがあります。"</string>
+ <string name="permdesc_readCallLog" product="default" msgid="3452017559804750758">"携帯端末の通話履歴(着信や発信のデータなど)の読み取りをアプリに許可します。この許可を悪意のあるアプリに利用されると、データが他のユーザーに送信される恐れがあります。"</string>
+ <string name="permlab_writeCallLog" msgid="8552045664743499354">"通話履歴の書き込み"</string>
+ <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"タブレットの通話履歴(着信や発信のデータなど)の変更をアプリに許可します。この許可を悪意のあるアプリに利用されると、通話履歴が消去または変更される恐れがあります。"</string>
+ <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"携帯端末の通話履歴(着信や発信のデータなど)の変更をアプリに許可します。この許可を悪意のあるアプリに利用されると、通話履歴が消去または変更される恐れがあります。"</string>
<string name="permlab_readProfile" msgid="6824681438529842282">"プロフィールデータの読み取り"</string>
<string name="permdesc_readProfile" product="default" msgid="94520753797630679">"端末に保存されている個人のプロフィール情報(名前、連絡先情報など)を読み取ることをアプリに許可します。許可すると、アプリではユーザーの身元を特定したりプロフィール情報を第三者に転送したりできるようになります。"</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"プロフィールデータに書き込む"</string>
diff --git a/core/res/res/values-ko-rKR/arrays.xml b/core/res/res/values-ko-rKR/donottranslate-maps.xml
index e245def469e9..e245def469e9 100644
--- a/core/res/res/values-ko-rKR/arrays.xml
+++ b/core/res/res/values-ko-rKR/donottranslate-maps.xml
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index ed3cfc999eec..fc8e7b1e7cb0 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -335,18 +335,12 @@
<string name="permlab_writeContacts" msgid="644616215860933284">"연락처 데이터 작성"</string>
<string name="permdesc_writeContacts" product="tablet" msgid="988969759110632978">"앱이 태블릿에 저장된 모든 연락처(주소) 데이터를 읽을 수 있도록 허용합니다. 이 경우 악성 앱이 연락처 데이터를 지우거나 수정할 수 있습니다."</string>
<string name="permdesc_writeContacts" product="default" msgid="5075164818647934067">"앱이 휴대전화에 저장된 모든 연락처(주소) 데이터를 읽을 수 있도록 허용합니다. 이 경우 악성 앱이 연락처 데이터를 지우거나 수정할 수 있습니다."</string>
- <!-- no translation found for permlab_readCallLog (3478133184624102739) -->
- <skip />
- <!-- no translation found for permdesc_readCallLog (3995157599976515002) -->
- <skip />
- <!-- no translation found for permdesc_readCallLog (3452017559804750758) -->
- <skip />
- <!-- no translation found for permlab_writeCallLog (8552045664743499354) -->
- <skip />
- <!-- no translation found for permdesc_writeCallLog (6661806062274119245) -->
- <skip />
- <!-- no translation found for permdesc_writeCallLog (683941736352787842) -->
- <skip />
+ <string name="permlab_readCallLog" msgid="3478133184624102739">"통화 기록 읽기"</string>
+ <string name="permdesc_readCallLog" product="tablet" msgid="3995157599976515002">"앱에서 수신 및 발신 통화 데이터를 포함하여 태블릿의 통화 기록을 읽을 수 있도록 허용합니다. 이 경우 악성 앱이 데이터를 다른 사용자에게 보낼 수 있습니다."</string>
+ <string name="permdesc_readCallLog" product="default" msgid="3452017559804750758">"앱에서 수신 및 발신 통화 데이터를 포함하여 휴대전화의 통화 기록을 읽을 수 있도록 허용합니다. 이 경우 악성 앱이 데이터를 다른 사용자에게 보낼 수 있습니다."</string>
+ <string name="permlab_writeCallLog" msgid="8552045664743499354">"통화 기록 쓰기"</string>
+ <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"앱에서 수신 및 발신 통화 데이터를 포함하여 태블릿의 통화 기록을 수정할 수 있도록 허용합니다. 이 경우 악성 앱이 통화 기록을 지우거나 수정할 수 있습니다."</string>
+ <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"앱에서 수신 및 발신 통화 데이터를 포함하여 휴대전화의 통화 기록을 수정할 수 있도록 허용합니다. 이 경우 악성 앱이 통화 기록을 지우거나 수정할 수 있습니다."</string>
<string name="permlab_readProfile" msgid="6824681438529842282">"프로필 데이터 읽기"</string>
<string name="permdesc_readProfile" product="default" msgid="94520753797630679">"앱이 기기에 저장된 개인 프로필 정보(예: 사용자 이름, 연락처 정보 등)를 읽을 수 있도록 허용합니다. 이는 앱이 사용자를 확인하고 다른 사용자들에게 해당 프로필 정보를 전송할 수 있다는 것을 의미합니다."</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"프로필 데이터에 쓰기"</string>
@@ -513,7 +507,7 @@
<string name="permdesc_writeDictionary" msgid="8185385716255065291">"앱이 사용자 사전에 새 단어를 입력할 수 있도록 허용합니다."</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="4086221374639183281">"USB 저장소 콘텐츠 읽기"</string>
<string name="permlab_sdcardRead" product="default" msgid="8537875151845139539">"SD 카드 콘텐츠 읽기"</string>
- <string name="permdesc_sdcardRead" product="nosdcard" msgid="1055302898999352339">"앱 USB 콘텐츠 읽기 허용"</string>
+ <string name="permdesc_sdcardRead" product="nosdcard" msgid="1055302898999352339">"앱이 USB 콘텐츠를 읽도록 허용"</string>
<string name="permdesc_sdcardRead" product="default" msgid="7947792373570683542">"앱이 SD 카드의 콘텐츠를 읽을 수 있도록 허용합니다."</string>
<string name="permlab_sdcardWrite" product="nosdcard" msgid="85430876310764752">"USB 저장소 콘텐츠 수정/삭제"</string>
<string name="permlab_sdcardWrite" product="default" msgid="8079403759001777291">"SD 카드 콘텐츠 수정/삭제"</string>
diff --git a/core/res/res/values-lt-rLT/arrays.xml b/core/res/res/values-lt-rLT/donottranslate-maps.xml
index 0d5a3aa8253b..0d5a3aa8253b 100644
--- a/core/res/res/values-lt-rLT/arrays.xml
+++ b/core/res/res/values-lt-rLT/donottranslate-maps.xml
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index e0a1ddf496d2..5e9d3f4930cb 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -335,18 +335,12 @@
<string name="permlab_writeContacts" msgid="644616215860933284">"rašyti adresatų duomenis"</string>
<string name="permdesc_writeContacts" product="tablet" msgid="988969759110632978">"Leidžiama programai keisti planšetiniame kompiuteryje saugomus kontaktinius (adreso) duomenis. Kenkėjiškos programos gali tai naudoti, kad ištrintų ar pakeistų jūsų kontaktinius duomenis."</string>
<string name="permdesc_writeContacts" product="default" msgid="5075164818647934067">"Leidžiama programai keisti telefone saugomus kontaktinius (adreso) duomenis. Kenkėjiškos programos gali tai naudoti, kad ištrintų ar pakeistų jūsų kontaktinius duomenis."</string>
- <!-- no translation found for permlab_readCallLog (3478133184624102739) -->
- <skip />
- <!-- no translation found for permdesc_readCallLog (3995157599976515002) -->
- <skip />
- <!-- no translation found for permdesc_readCallLog (3452017559804750758) -->
- <skip />
- <!-- no translation found for permlab_writeCallLog (8552045664743499354) -->
- <skip />
- <!-- no translation found for permdesc_writeCallLog (6661806062274119245) -->
- <skip />
- <!-- no translation found for permdesc_writeCallLog (683941736352787842) -->
- <skip />
+ <string name="permlab_readCallLog" msgid="3478133184624102739">"skaityti skambučių žurnalą"</string>
+ <string name="permdesc_readCallLog" product="tablet" msgid="3995157599976515002">"Programai leidžiama skaityti planšetinio kompiuterio skambučių žurnalą, įskaitant duomenis apie gaunamus ir siunčiamus skambučius. Kenkėjiškos programos tai gali naudoti, kad išsiųstų jūsų duomenis kitiems žmonėms."</string>
+ <string name="permdesc_readCallLog" product="default" msgid="3452017559804750758">"Programai leidžiama skaityti telefono skambučių žurnalą, įskaitant duomenis apie gaunamus ir siunčiamus skambučius. Kenkėjiškos programos tai gali naudoti, kad išsiųstų jūsų duomenis kitiems žmonėms."</string>
+ <string name="permlab_writeCallLog" msgid="8552045664743499354">"rašyti skambučių žurnalą"</string>
+ <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Programai leidžiama skaityti planšetinio kompiuterio skambučių žurnalą, įskaitant duomenis apie gaunamus ir siunčiamus skambučius. Kenkėjiškos programos tai gali naudoti, kad ištrintų ar keistų jūsų skambučių žurnalą."</string>
+ <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Programai leidžiama skaityti telefono skambučių žurnalą, įskaitant duomenis apie gaunamus ir siunčiamus skambučius. Kenkėjiškos programos tai gali naudoti, kad ištrintų ar keistų jūsų skambučių žurnalą."</string>
<string name="permlab_readProfile" msgid="6824681438529842282">"skaityti profilio duomenis"</string>
<string name="permdesc_readProfile" product="default" msgid="94520753797630679">"Leidžiama programai skaityti asmeninę profilio informaciją, saugomą jūsų įrenginyje, pvz., jūsų vardą, pavardę ir kontaktinę informaciją. Tai reiškia, kad programa gali nustatyti jūsų tapatybę ir siųsti profilio informaciją kitiems."</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"rašyti kaip profilio duomenis"</string>
@@ -511,7 +505,7 @@
<string name="permdesc_readDictionary" msgid="8977815988329283705">"Leidžiama programai skaityti privačius žodžius, vardus ir frazes, kuriuos naudotojas išsaugojo naudotojo žodyne."</string>
<string name="permlab_writeDictionary" msgid="2296383164914812772">"rašyti naudotojo nustatytame žodyne"</string>
<string name="permdesc_writeDictionary" msgid="8185385716255065291">"Leidžiama programai rašyti naujus žodžius į naudotojo žodyną."</string>
- <string name="permlab_sdcardRead" product="nosdcard" msgid="4086221374639183281">"skaityti USB atminties turinį"</string>
+ <string name="permlab_sdcardRead" product="nosdcard" msgid="4086221374639183281">"skaityti USB atmint. turinį"</string>
<string name="permlab_sdcardRead" product="default" msgid="8537875151845139539">"skaityti SD kortelės turinį"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="1055302898999352339">"Leid. progr. skait. USB turin."</string>
<string name="permdesc_sdcardRead" product="default" msgid="7947792373570683542">"Leidžiama programai skaityti SD kortelės turinį."</string>
diff --git a/core/res/res/values-lv-rLV/arrays.xml b/core/res/res/values-lv-rLV/donottranslate-maps.xml
index d9ba7a44afc0..d9ba7a44afc0 100644
--- a/core/res/res/values-lv-rLV/arrays.xml
+++ b/core/res/res/values-lv-rLV/donottranslate-maps.xml
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 6e1bb33fba85..a568c3b5e4b5 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -335,18 +335,12 @@
<string name="permlab_writeContacts" msgid="644616215860933284">"rakstīt kontaktpersonu datus"</string>
<string name="permdesc_writeContacts" product="tablet" msgid="988969759110632978">"Ļauj lietotnei modificēt planšetdatorā saglabātos kontaktpersonu (adrešu) datus. Ļaunprātīgas lietotnes to var izmantot, lai dzēstu vai modificētu kontaktpersonu datus."</string>
<string name="permdesc_writeContacts" product="default" msgid="5075164818647934067">"Ļauj lietotnei modificēt tālrunī saglabātos kontaktpersonu (adrešu) datus. Ļaunprātīgas lietotnes to var izmantot, lai dzēstu vai modificētu kontaktpersonu datus."</string>
- <!-- no translation found for permlab_readCallLog (3478133184624102739) -->
- <skip />
- <!-- no translation found for permdesc_readCallLog (3995157599976515002) -->
- <skip />
- <!-- no translation found for permdesc_readCallLog (3452017559804750758) -->
- <skip />
- <!-- no translation found for permlab_writeCallLog (8552045664743499354) -->
- <skip />
- <!-- no translation found for permdesc_writeCallLog (6661806062274119245) -->
- <skip />
- <!-- no translation found for permdesc_writeCallLog (683941736352787842) -->
- <skip />
+ <string name="permlab_readCallLog" msgid="3478133184624102739">"nolasīt zvanu žurnālu"</string>
+ <string name="permdesc_readCallLog" product="tablet" msgid="3995157599976515002">"Ļauj lietotnei nolasīt planšetdatora zvanu žurnālu, tostarp ienākošo un izejošo zvanu datus. Ļaunprātīgas lietotnes var to izmantot, lai sūtītu jūsu datus citām personām."</string>
+ <string name="permdesc_readCallLog" product="default" msgid="3452017559804750758">"Ļauj lietotnei nolasīt tālruņa zvanu žurnālu, tostarp ienākošo un izejošo zvanu datus. Ļaunprātīgas lietotnes var to izmantot, lai sūtītu jūsu datus citām personām."</string>
+ <string name="permlab_writeCallLog" msgid="8552045664743499354">"rakstīt zvanu žurnālā"</string>
+ <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Ļauj lietotnei pārveidot planšetdatora zvanu žurnālu, tostarp ienākošo un izejošo zvanu datus. Ļaunprātīgas lietotnes var to izmantot, lai dzēstu vai pārveidotu savu zvanu žurnālu."</string>
+ <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Ļauj lietotnei pārveidot tālruņa zvanu žurnālu, tostarp ienākošo un izejošo zvanu datus. Ļaunprātīgas lietotnes var to izmantot, lai dzēstu vai pārveidotu savu zvanu žurnālu."</string>
<string name="permlab_readProfile" msgid="6824681438529842282">"jūsu profila datu lasīšana"</string>
<string name="permdesc_readProfile" product="default" msgid="94520753797630679">"Ļauj lietotnei lasīt ierīcē saglabāto personīgā profila informāciju, piemēram, jūsu vārdu un kontaktinformāciju. Tas nozīmē, ka lietotne var jūs identificēt un sūtīt jūsu profila informāciju citām personām."</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"rakstīšana jūsu profila datos"</string>
diff --git a/core/res/res/values-mcc204/arrays.xml b/core/res/res/values-mcc204/donottranslate-maps.xml
index 7902a13c70d7..7902a13c70d7 100644
--- a/core/res/res/values-mcc204/arrays.xml
+++ b/core/res/res/values-mcc204/donottranslate-maps.xml
diff --git a/core/res/res/values-mcc230/arrays.xml b/core/res/res/values-mcc230/donottranslate-maps.xml
index 71c3ed671d6d..71c3ed671d6d 100644
--- a/core/res/res/values-mcc230/arrays.xml
+++ b/core/res/res/values-mcc230/donottranslate-maps.xml
diff --git a/core/res/res/values-mcc232/arrays.xml b/core/res/res/values-mcc232/donottranslate-maps.xml
index 98458f848aa3..98458f848aa3 100644
--- a/core/res/res/values-mcc232/arrays.xml
+++ b/core/res/res/values-mcc232/donottranslate-maps.xml
diff --git a/core/res/res/values-mcc260/arrays.xml b/core/res/res/values-mcc260/donottranslate-maps.xml
index 03447ab28acc..03447ab28acc 100644
--- a/core/res/res/values-mcc260/arrays.xml
+++ b/core/res/res/values-mcc260/donottranslate-maps.xml
diff --git a/core/res/res/values-mcc262/arrays.xml b/core/res/res/values-mcc262/donottranslate-maps.xml
index 955df7d2eeef..955df7d2eeef 100644
--- a/core/res/res/values-mcc262/arrays.xml
+++ b/core/res/res/values-mcc262/donottranslate-maps.xml
diff --git a/core/res/res/values-ms-rMY/arrays.xml b/core/res/res/values-ms-rMY/donottranslate-maps.xml
index 3a708e6aa87e..3a708e6aa87e 100644
--- a/core/res/res/values-ms-rMY/arrays.xml
+++ b/core/res/res/values-ms-rMY/donottranslate-maps.xml
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index bb2cf626b7aa..363832d93dda 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -335,18 +335,12 @@
<string name="permlab_writeContacts" msgid="644616215860933284">"tulis data kenalan"</string>
<string name="permdesc_writeContacts" product="tablet" msgid="988969759110632978">"Membenarkan apl untuk mengubah suai data kenalan (alamat) yang disimpan pada tablet anda. Apl hasad boleh menggunakannya untuk memadam atau mengubah suai data kenalan anda."</string>
<string name="permdesc_writeContacts" product="default" msgid="5075164818647934067">"Membenarkan apl untuk mengubah suai data kenalan (alamat) yang disimpan pada telefon anda. Apl hasad boleh menggunakannya untuk memadam atau mengubah suai data kenalan anda."</string>
- <!-- no translation found for permlab_readCallLog (3478133184624102739) -->
- <skip />
- <!-- no translation found for permdesc_readCallLog (3995157599976515002) -->
- <skip />
- <!-- no translation found for permdesc_readCallLog (3452017559804750758) -->
- <skip />
- <!-- no translation found for permlab_writeCallLog (8552045664743499354) -->
- <skip />
- <!-- no translation found for permdesc_writeCallLog (6661806062274119245) -->
- <skip />
- <!-- no translation found for permdesc_writeCallLog (683941736352787842) -->
- <skip />
+ <string name="permlab_readCallLog" msgid="3478133184624102739">"baca log panggilan"</string>
+ <string name="permdesc_readCallLog" product="tablet" msgid="3995157599976515002">"Membenarkan apl membaca log panggilan tablet anda, termasuk data tentang panggilan masuk dan keluar. Apl hasad boleh menggunakannya untuk menghantar data anda kepada orang lain."</string>
+ <string name="permdesc_readCallLog" product="default" msgid="3452017559804750758">"Membenarkan apl membaca log panggilan telefon anda, termasuk data tentang panggilan masuk dan keluar. Apl hasad boleh menggunakannya untuk menghantar data anda kepada orang lain."</string>
+ <string name="permlab_writeCallLog" msgid="8552045664743499354">"tulis log panggilan"</string>
+ <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Membenarkan apl untuk mengubah suai panggilan tablet anda, termasuk data tentang panggilan masuk dan keluar. Apl hasad boleh menggunakannya untuk memadam atau mengubah suai log panggilan anda."</string>
+ <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Membenarkan apl untuk mengubah suai panggilan telefon anda, termasuk data tentang panggilan masuk dan keluar. Apl hasad boleh menggunakannya untuk memadam atau mengubah suai log panggilan anda."</string>
<string name="permlab_readProfile" msgid="6824681438529842282">"baca data profil anda"</string>
<string name="permdesc_readProfile" product="default" msgid="94520753797630679">"Membenarkan apl untuk membaca maklumat profil peribadi yang disimpan dalam peranti anda, seperti nama dan maklumat kenalan anda. Ini bermakna apl lain boleh mengenal pasti anda dan menghantar maklumat profil anda kepada orang lain."</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"tulis ke data profil anda"</string>
@@ -511,14 +505,10 @@
<string name="permdesc_readDictionary" msgid="8977815988329283705">"Membenarkan apl membaca sebarang kata-kata peribadi, nama dan frasa yang mungkin telah disimpan oleh pengguna dalam kamus pengguna."</string>
<string name="permlab_writeDictionary" msgid="2296383164914812772">"tulis ke kamus yang ditakrifkan pengguna"</string>
<string name="permdesc_writeDictionary" msgid="8185385716255065291">"Membenarkan apl menulis perkataan baharu ke dalam kamus pengguna."</string>
- <!-- no translation found for permlab_sdcardRead (4086221374639183281) -->
- <skip />
- <!-- no translation found for permlab_sdcardRead (8537875151845139539) -->
- <skip />
- <!-- no translation found for permdesc_sdcardRead (1055302898999352339) -->
- <skip />
- <!-- no translation found for permdesc_sdcardRead (7947792373570683542) -->
- <skip />
+ <string name="permlab_sdcardRead" product="nosdcard" msgid="4086221374639183281">"baca kandungan storan USB"</string>
+ <string name="permlab_sdcardRead" product="default" msgid="8537875151845139539">"baca kandungan kad SD"</string>
+ <string name="permdesc_sdcardRead" product="nosdcard" msgid="1055302898999352339">"Membenarkan apl membaca kandungan storan USB."</string>
+ <string name="permdesc_sdcardRead" product="default" msgid="7947792373570683542">"Membenarkan apl membaca kandungan kad SD."</string>
<string name="permlab_sdcardWrite" product="nosdcard" msgid="85430876310764752">"ubah suai/padam kdgn storn USB"</string>
<string name="permlab_sdcardWrite" product="default" msgid="8079403759001777291">"ubah suai/padamkan kandungan kad SD"</string>
<string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"Membenarkan apl menulis ke storan USB."</string>
diff --git a/core/res/res/values-nb-rNO/arrays.xml b/core/res/res/values-nb-rNO/donottranslate-maps.xml
index 500e8e1edf1d..500e8e1edf1d 100644
--- a/core/res/res/values-nb-rNO/arrays.xml
+++ b/core/res/res/values-nb-rNO/donottranslate-maps.xml
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 66ddfa877c5f..384fdaca9d2c 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -335,18 +335,12 @@
<string name="permlab_writeContacts" msgid="644616215860933284">"skrive kontaktinformasjon"</string>
<string name="permdesc_writeContacts" product="tablet" msgid="988969759110632978">"Lar appen lese alle kontaktdataene (adressene) som er lagret på nettbrettet. Ondsinnede apper kan bruke dette til å slette eller endre kontaktdataene dine."</string>
<string name="permdesc_writeContacts" product="default" msgid="5075164818647934067">"Lar appen lese alle kontaktdataene (adressene) som er lagret på telefonen. Ondsinnede apper kan bruke dette til å slette eller endre kontaktdataene dine."</string>
- <!-- no translation found for permlab_readCallLog (3478133184624102739) -->
- <skip />
- <!-- no translation found for permdesc_readCallLog (3995157599976515002) -->
- <skip />
- <!-- no translation found for permdesc_readCallLog (3452017559804750758) -->
- <skip />
- <!-- no translation found for permlab_writeCallLog (8552045664743499354) -->
- <skip />
- <!-- no translation found for permdesc_writeCallLog (6661806062274119245) -->
- <skip />
- <!-- no translation found for permdesc_writeCallLog (683941736352787842) -->
- <skip />
+ <string name="permlab_readCallLog" msgid="3478133184624102739">"lar appen lese anropsloggen"</string>
+ <string name="permdesc_readCallLog" product="tablet" msgid="3995157599976515002">"Lar appen lese nettbrettets samtalelogg, inkludert data om innkommende og utgående anrop. Skadelige apper kan utnytte denne tillatelsen til å sende dataene dine til andre personer."</string>
+ <string name="permdesc_readCallLog" product="default" msgid="3452017559804750758">"Lar appen lese telefonens samtalelogg, inkludert data om innkommende og utgående anrop. Skadelige apper kan utnytte denne tillatelsen til å sende dataene dine til andre personer."</string>
+ <string name="permlab_writeCallLog" msgid="8552045664743499354">"lar appen endre samtaleloggen"</string>
+ <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Lar appen endre nettbrettets samtalelogg, inkludert data om innkommende og utgående anrop. Skadelige apper kan utnytte denne tillatelsen til å slette eller endre samtaleloggen din."</string>
+ <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Lar appen endre telefonens samtalelogg, inkludert data om innkommende og utgående anrop. Skadelige apper kan utnytte denne tillatelsen til å slette eller endre samtaleloggen din."</string>
<string name="permlab_readProfile" msgid="6824681438529842282">"lese profildataene dine"</string>
<string name="permdesc_readProfile" product="default" msgid="94520753797630679">"Lar appen lese personlige profilinformasjon som er lagret på enheten, som for eksempel navn og kontaktinformasjon. Dette betyr at appen kan identifisere deg og sende profilinformasjonen din til andre."</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"skriv til profildataene dine"</string>
@@ -513,7 +507,7 @@
<string name="permdesc_writeDictionary" msgid="8185385716255065291">"Lar appen skrive nye ord i brukerordlisten."</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="4086221374639183281">"lese innhold på USB-lagr."</string>
<string name="permlab_sdcardRead" product="default" msgid="8537875151845139539">"lese innhold på SD-kortet"</string>
- <string name="permdesc_sdcardRead" product="nosdcard" msgid="1055302898999352339">"Lar appen lese innhold på USB-lagringsenheten."</string>
+ <string name="permdesc_sdcardRead" product="nosdcard" msgid="1055302898999352339">"Lar appen lese innhold på USB-lager."</string>
<string name="permdesc_sdcardRead" product="default" msgid="7947792373570683542">"Lar appen lese innhold på SD-kortet."</string>
<string name="permlab_sdcardWrite" product="nosdcard" msgid="85430876310764752">"endre/slette innh. i USB-lagr."</string>
<string name="permlab_sdcardWrite" product="default" msgid="8079403759001777291">"redigere/slette innhold på minnekort"</string>
diff --git a/core/res/res/values-nl-rBE/arrays.xml b/core/res/res/values-nl-rBE/donottranslate-maps.xml
index 9e93a0922154..9e93a0922154 100644
--- a/core/res/res/values-nl-rBE/arrays.xml
+++ b/core/res/res/values-nl-rBE/donottranslate-maps.xml
diff --git a/core/res/res/values-nl-rNL/arrays.xml b/core/res/res/values-nl-rNL/donottranslate-maps.xml
index fe5422bf953b..fe5422bf953b 100644
--- a/core/res/res/values-nl-rNL/arrays.xml
+++ b/core/res/res/values-nl-rNL/donottranslate-maps.xml
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 7609cc559e8d..030222d01da9 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -335,18 +335,12 @@
<string name="permlab_writeContacts" msgid="644616215860933284">"contactgegevens schrijven"</string>
<string name="permdesc_writeContacts" product="tablet" msgid="988969759110632978">"Hiermee kan de app de op uw tablet opgeslagen contactgegevens (adresgegevens) wijzigen. Schadelijke apps kunnen hiermee uw contactgegevens verwijderen of wijzigen."</string>
<string name="permdesc_writeContacts" product="default" msgid="5075164818647934067">"Hiermee kan de app de op uw telefoon opgeslagen contactgegevens (adresgegevens) wijzigen. Schadelijke apps kunnen hiermee uw contactgegevens verwijderen of wijzigen."</string>
- <!-- no translation found for permlab_readCallLog (3478133184624102739) -->
- <skip />
- <!-- no translation found for permdesc_readCallLog (3995157599976515002) -->
- <skip />
- <!-- no translation found for permdesc_readCallLog (3452017559804750758) -->
- <skip />
- <!-- no translation found for permlab_writeCallLog (8552045664743499354) -->
- <skip />
- <!-- no translation found for permdesc_writeCallLog (6661806062274119245) -->
- <skip />
- <!-- no translation found for permdesc_writeCallLog (683941736352787842) -->
- <skip />
+ <string name="permlab_readCallLog" msgid="3478133184624102739">"oproeplogboek lezen"</string>
+ <string name="permdesc_readCallLog" product="tablet" msgid="3995157599976515002">"Toestaan dat de app het oproeplogboek van uw tablet leest, waaronder gegevens over inkomende en uitgaande oproepen. Schadelijke apps kunnen hiermee uw gegevens naar andere personen verzenden."</string>
+ <string name="permdesc_readCallLog" product="default" msgid="3452017559804750758">"Toestaan dat de app het oproeplogboek van uw telefoon leest, waaronder gegevens over inkomende en uitgaande oproepen. Schadelijke apps kunnen hiermee uw gegevens naar andere personen verzenden."</string>
+ <string name="permlab_writeCallLog" msgid="8552045664743499354">"oproeplogboek schrijven"</string>
+ <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Toestaan dat de app het oproeplogboek van uw tablet aanpast, waaronder gegevens over inkomende en uitgaande oproepen. Schadelijke apps kunnen hiermee uw oproeplogboek wissen of aanpassen."</string>
+ <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Toestaan dat de app het oproeplogboek van uw telefoon aanpast, waaronder gegevens over inkomende en uitgaande oproepen. Schadelijke apps kunnen hiermee uw oproeplogboek wissen of aanpassen."</string>
<string name="permlab_readProfile" msgid="6824681438529842282">"uw profielgegevens lezen"</string>
<string name="permdesc_readProfile" product="default" msgid="94520753797630679">"Hiermee kan de app persoonlijke profielgegevens lezen die op uw apparaat zijn opgeslagen, zoals uw naam en contactgegevens. Dit betekent dat de app u kan identificeren en uw profielgegevens naar anderen kan verzenden."</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"schrijven naar profielgegevens"</string>
@@ -511,14 +505,10 @@
<string name="permdesc_readDictionary" msgid="8977815988329283705">"Hiermee kan de app privéwoorden, namen en woordcombinaties lezen die de gebruiker heeft opgeslagen in het gebruikerswoordenboek."</string>
<string name="permlab_writeDictionary" msgid="2296383164914812772">"schrijven naar door gebruiker gedefinieerd woordenboek"</string>
<string name="permdesc_writeDictionary" msgid="8185385716255065291">"Hiermee kan de app nieuwe woorden schrijven naar het gebruikerswoordenboek."</string>
- <!-- no translation found for permlab_sdcardRead (4086221374639183281) -->
- <skip />
- <!-- no translation found for permlab_sdcardRead (8537875151845139539) -->
- <skip />
- <!-- no translation found for permdesc_sdcardRead (1055302898999352339) -->
- <skip />
- <!-- no translation found for permdesc_sdcardRead (7947792373570683542) -->
- <skip />
+ <string name="permlab_sdcardRead" product="nosdcard" msgid="4086221374639183281">"inhoud van USB-opslag lezen"</string>
+ <string name="permlab_sdcardRead" product="default" msgid="8537875151845139539">"inhoud van SD-kaart lezen"</string>
+ <string name="permdesc_sdcardRead" product="nosdcard" msgid="1055302898999352339">"App kan inhoud van USB lezen."</string>
+ <string name="permdesc_sdcardRead" product="default" msgid="7947792373570683542">"Hiermee kan de app de inhoud van de SD-kaart lezen."</string>
<string name="permlab_sdcardWrite" product="nosdcard" msgid="85430876310764752">"inhoud van USB-opslag aanpassen/verwijderen"</string>
<string name="permlab_sdcardWrite" product="default" msgid="8079403759001777291">"inhoud op de SD-kaart aanpassen/verwijderen"</string>
<string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"Hiermee kan de app schrijven naar de USB-opslag."</string>
diff --git a/core/res/res/values-pl-rPL/arrays.xml b/core/res/res/values-pl-rPL/donottranslate-maps.xml
index 950248c4d545..950248c4d545 100644
--- a/core/res/res/values-pl-rPL/arrays.xml
+++ b/core/res/res/values-pl-rPL/donottranslate-maps.xml
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index b57e27d3b7a0..9e4cbf3bd2eb 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -335,18 +335,12 @@
<string name="permlab_writeContacts" msgid="644616215860933284">"zapisywanie danych kontaktowych"</string>
<string name="permdesc_writeContacts" product="tablet" msgid="988969759110632978">"Pozwala aplikacji na zmianę danych kontaktowych (adresowych) zapisanych w tablecie. Złośliwe aplikacje mogą to wykorzystać w celu usunięcia lub zmodyfikowania Twoich danych kontaktowych."</string>
<string name="permdesc_writeContacts" product="default" msgid="5075164818647934067">"Pozwala aplikacji na zmianę danych kontaktowych (adresowych) zapisanych w telefonie. Złośliwe aplikacje mogą to wykorzystać do usunięcia lub zmodyfikowania Twoich danych kontaktowych."</string>
- <!-- no translation found for permlab_readCallLog (3478133184624102739) -->
- <skip />
- <!-- no translation found for permdesc_readCallLog (3995157599976515002) -->
- <skip />
- <!-- no translation found for permdesc_readCallLog (3452017559804750758) -->
- <skip />
- <!-- no translation found for permlab_writeCallLog (8552045664743499354) -->
- <skip />
- <!-- no translation found for permdesc_writeCallLog (6661806062274119245) -->
- <skip />
- <!-- no translation found for permdesc_writeCallLog (683941736352787842) -->
- <skip />
+ <string name="permlab_readCallLog" msgid="3478133184624102739">"czytanie rejestru połączeń"</string>
+ <string name="permdesc_readCallLog" product="tablet" msgid="3995157599976515002">"Zezwala aplikacji na odczytywanie rejestru połączeń tabletu, w tym danych o połączeniach przychodzących i wychodzących. Złośliwe aplikacje mogą wykorzystywać tę możliwość, by wysyłać dane do innych osób."</string>
+ <string name="permdesc_readCallLog" product="default" msgid="3452017559804750758">"Zezwala aplikacji na odczytywanie rejestru połączeń telefonu, w tym danych o połączeniach przychodzących i wychodzących. Złośliwe aplikacje mogą wykorzystywać tę możliwość, by wysyłać dane do innych osób."</string>
+ <string name="permlab_writeCallLog" msgid="8552045664743499354">"zapisywanie rejestru połączeń"</string>
+ <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Zezwala aplikacji na modyfikowanie rejestru połączeń tabletu, w tym danych o połączeniach przychodzących i wychodzących. Złośliwe aplikacje mogą wykorzystać tę możliwość, by wyczyścić lub zmodyfikować rejestr połączeń."</string>
+ <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Zezwala aplikacji na modyfikowanie rejestru połączeń telefonu, w tym danych o połączeniach przychodzących i wychodzących. Złośliwe aplikacje mogą wykorzystać tę możliwość, by wyczyścić lub zmodyfikować rejestr połączeń."</string>
<string name="permlab_readProfile" msgid="6824681438529842282">"odczyt danych z Twojego profilu"</string>
<string name="permdesc_readProfile" product="default" msgid="94520753797630679">"Pozwala aplikacji na odczyt informacji, takich jak Twoje nazwisko i informacje kontaktowe, z profilu osobistego przechowywanego na urządzeniu. Oznacza to, że inne aplikacje mogą Cię zidentyfikować i przesłać informacje z Twojego profilu do innych osób."</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"zapis danych w Twoim profilu"</string>
@@ -514,7 +508,7 @@
<string name="permlab_sdcardRead" product="nosdcard" msgid="4086221374639183281">"odczyt zawartości pamięci USB"</string>
<string name="permlab_sdcardRead" product="default" msgid="8537875151845139539">"odczyt zawartości karty SD"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="1055302898999352339">"Pozwala aplikacji na odczyt pamięci USB."</string>
- <string name="permdesc_sdcardRead" product="default" msgid="7947792373570683542">"Pozwala aplikacji na odczyt zawartości karty SD."</string>
+ <string name="permdesc_sdcardRead" product="default" msgid="7947792373570683542">"Pozwala aplikacji na odczyt karty SD."</string>
<string name="permlab_sdcardWrite" product="nosdcard" msgid="85430876310764752">"Modyfikowanie/usuwanie z nośnika USB"</string>
<string name="permlab_sdcardWrite" product="default" msgid="8079403759001777291">"modyfikowanie/usuwanie zawartości karty SD"</string>
<string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"Pozwala aplikacji na zapis w pamięci USB."</string>
diff --git a/core/res/res/values-pt-rBR/arrays.xml b/core/res/res/values-pt-rBR/donottranslate-maps.xml
index 389d0c4fc0a7..389d0c4fc0a7 100644
--- a/core/res/res/values-pt-rBR/arrays.xml
+++ b/core/res/res/values-pt-rBR/donottranslate-maps.xml
diff --git a/core/res/res/values-pt-rPT/arrays.xml b/core/res/res/values-pt-rPT/donottranslate-maps.xml
index a1ba15aa9c8a..a1ba15aa9c8a 100644
--- a/core/res/res/values-pt-rPT/arrays.xml
+++ b/core/res/res/values-pt-rPT/donottranslate-maps.xml
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index e53a7c53b004..abe1454af0bb 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -336,11 +336,11 @@
<string name="permdesc_writeContacts" product="tablet" msgid="988969759110632978">"Permite que a aplicação modifique os dados de contacto (endereço) armazenados no tablet. As aplicações maliciosas podem utilizar isto para apagar ou modificar os dados dos seus contactos."</string>
<string name="permdesc_writeContacts" product="default" msgid="5075164818647934067">"Permite que uma aplicação modifique os dados de contacto (endereço) armazenados no telemóvel. As aplicações maliciosas podem utilizar isto para apagar ou modificar os dados dos seus contactos."</string>
<string name="permlab_readCallLog" msgid="3478133184624102739">"ler registo de chamadas"</string>
- <string name="permdesc_readCallLog" product="tablet" msgid="3995157599976515002">"Permite à aplicação ler o registo de chamadas do tablet, incluindo os dados sobre as chamadas recebidas e efetuadas. As aplicações maliciosas podem utilizar isto para enviar os seus dados para outras pessoas."</string>
- <string name="permdesc_readCallLog" product="default" msgid="3452017559804750758">"Permite à aplicação ler o registo de chamadas do telemóvel, incluindo os dados sobre as chamadas recebidas e efetuadas. As aplicações maliciosas podem utilizar isto para enviar os seus dados para outras pessoas."</string>
+ <string name="permdesc_readCallLog" product="tablet" msgid="3995157599976515002">"Permite à aplicação ler o registo de chamadas do tablet, incluindo os dados sobre as chamadas recebidas e efetuadas. As aplicações maliciosas podem utilizar esta funcionalidade para enviar os seus dados para outras pessoas."</string>
+ <string name="permdesc_readCallLog" product="default" msgid="3452017559804750758">"Permite que a aplicação leia o registo de chamadas do telemóvel, incluindo os dados sobre as chamadas recebidas e efetuadas. As aplicações maliciosas podem utilizar esta funcionalidade para enviar os seus dados para outras pessoas."</string>
<string name="permlab_writeCallLog" msgid="8552045664743499354">"escrever registo de chamadas"</string>
- <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Permite à aplicação modificar o registo de chamadas do tablet, incluindo os dados sobre as chamadas recebidas e efetuadas. As aplicações maliciosas podem utilizar isto para apagar ou modificar o registo de chamadas."</string>
- <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Permite à aplicação modificar o registo de chamadas do telemóvel, incluindo os dados sobre as chamadas recebidas e efetuadas. As aplicações maliciosas podem utilizar isto para apagar ou modificar o registo de chamadas."</string>
+ <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Permite à aplicação modificar o registo de chamadas do tablet, incluindo os dados sobre as chamadas recebidas e efetuadas. As aplicações maliciosas podem utilizar esta funcionalidade para apagar ou modificar o registo de chamadas."</string>
+ <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Permite à aplicação modificar o registo de chamadas do telemóvel, incluindo os dados sobre as chamadas recebidas e efetuadas. As aplicações maliciosas podem utilizar esta funcionalidade para apagar ou modificar o seu registo de chamadas."</string>
<string name="permlab_readProfile" msgid="6824681438529842282">"ler os dados do perfil"</string>
<string name="permdesc_readProfile" product="default" msgid="94520753797630679">"Permite que a aplicação leia dados de perfil pessoais armazenados no seu aparelho, como o seu nome e dados de contacto. Isto significa que outras aplicações podem identificá-lo e enviar os seus dados de perfil a terceiros."</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"escrever nos dados do seu perfil"</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index f91b25cc3821..3ae566cf4191 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -505,14 +505,10 @@
<string name="permdesc_readDictionary" msgid="8977815988329283705">"Permite que o aplicativo leia palavras, nomes e frases particulares armazenados pelo usuário no dicionário do usuário."</string>
<string name="permlab_writeDictionary" msgid="2296383164914812772">"gravar no dicionário definido pelo usuário"</string>
<string name="permdesc_writeDictionary" msgid="8185385716255065291">"Permite que o aplicativo grave novas palavras no dicionário do usuário."</string>
- <!-- no translation found for permlab_sdcardRead (4086221374639183281) -->
- <skip />
- <!-- no translation found for permlab_sdcardRead (8537875151845139539) -->
- <skip />
- <!-- no translation found for permdesc_sdcardRead (1055302898999352339) -->
- <skip />
- <!-- no translation found for permdesc_sdcardRead (7947792373570683542) -->
- <skip />
+ <string name="permlab_sdcardRead" product="nosdcard" msgid="4086221374639183281">"ler conteúdo do armaz. USB"</string>
+ <string name="permlab_sdcardRead" product="default" msgid="8537875151845139539">"ler conteúdo do cartão SD"</string>
+ <string name="permdesc_sdcardRead" product="nosdcard" msgid="1055302898999352339">"Permite apl. ler cont. arm USB"</string>
+ <string name="permdesc_sdcardRead" product="default" msgid="7947792373570683542">"Permite que o aplicativo leia o conteúdo do cartão SD."</string>
<string name="permlab_sdcardWrite" product="nosdcard" msgid="85430876310764752">"modificar/excluir cont. USB"</string>
<string name="permlab_sdcardWrite" product="default" msgid="8079403759001777291">"modificar/excluir conteúdo do cartão SD"</string>
<string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"Permite gravar no armaz. USB."</string>
diff --git a/core/res/res/values-rm-rCH/arrays.xml b/core/res/res/values-rm-rCH/donottranslate-maps.xml
index 48e861302476..48e861302476 100644
--- a/core/res/res/values-rm-rCH/arrays.xml
+++ b/core/res/res/values-rm-rCH/donottranslate-maps.xml
diff --git a/core/res/res/values-ro-rRO/arrays.xml b/core/res/res/values-ro-rRO/donottranslate-maps.xml
index c5579d0e4d45..c5579d0e4d45 100644
--- a/core/res/res/values-ro-rRO/arrays.xml
+++ b/core/res/res/values-ro-rRO/donottranslate-maps.xml
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 6d49accd327f..d443d1df961a 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -335,18 +335,12 @@
<string name="permlab_writeContacts" msgid="644616215860933284">"scriere date de contact"</string>
<string name="permdesc_writeContacts" product="tablet" msgid="988969759110632978">"Permite aplicaţiei să modifice datele de contact (adresele) stocate pe tabletă. Aplicaţiile rău intenţionate pot să utilizeze această permisiune pentru a şterge sau a modifica datele dvs. de contact."</string>
<string name="permdesc_writeContacts" product="default" msgid="5075164818647934067">"Permite aplicaţiei să modifice datele de contact (adresele) stocate pe telefon. Aplicaţiile rău intenţionate pot să utilizeze această permisiune pentru a şterge sau pentru a modifica datele dvs. de contact."</string>
- <!-- no translation found for permlab_readCallLog (3478133184624102739) -->
- <skip />
- <!-- no translation found for permdesc_readCallLog (3995157599976515002) -->
- <skip />
- <!-- no translation found for permdesc_readCallLog (3452017559804750758) -->
- <skip />
- <!-- no translation found for permlab_writeCallLog (8552045664743499354) -->
- <skip />
- <!-- no translation found for permdesc_writeCallLog (6661806062274119245) -->
- <skip />
- <!-- no translation found for permdesc_writeCallLog (683941736352787842) -->
- <skip />
+ <string name="permlab_readCallLog" msgid="3478133184624102739">"citeşte jurnalul de apeluri"</string>
+ <string name="permdesc_readCallLog" product="tablet" msgid="3995157599976515002">"Permite aplicaţiei să citească jurnalul de apeluri al tabletei dvs., inclusiv datele despre apelurile primite sau efectuate. Aplicaţiile rău intenţionate pot utiliza această permisiune pentru a trimite datele dvs. altor persoane."</string>
+ <string name="permdesc_readCallLog" product="default" msgid="3452017559804750758">"Permite aplicaţiei să citească jurnalul de apeluri al telefonului dvs., inclusiv datele despre apelurile primite sau efectuate. Aplicaţiile rău intenţionate pot utiliza această permisiune pentru a trimite datele dvs. altor persoane."</string>
+ <string name="permlab_writeCallLog" msgid="8552045664743499354">"scrie jurnalul de apeluri"</string>
+ <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Permite aplicaţiei să modifice jurnalul de apeluri al tabletei dvs., inclusiv datele despre apelurile primite sau efectuate. Aplicaţiile rău intenţionate pot utiliza această permisiune pentru a şterge sau pentru a modifica jurnalul dvs. de apeluri."</string>
+ <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Permite aplicaţiei să modifice jurnalul de apeluri al telefonului dvs., inclusiv datele despre apelurile primite sau efectuate. Aplicaţiile rău intenţionate pot utiliza această permisiune pentru a şterge sau pentru a modifica jurnalul dvs. de apeluri."</string>
<string name="permlab_readProfile" msgid="6824681438529842282">"citire date din profilul dvs."</string>
<string name="permdesc_readProfile" product="default" msgid="94520753797630679">"Permite aplicaţiei să citească informaţii de profil personal stocate pe dispozitiv, cum ar fi numele şi informaţiile de contact, ceea ce înseamnă că aplicaţia vă poate identifica şi poate trimite informaţiile dvs. de profil altor utilizatori."</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"scriere date în profilul dvs."</string>
diff --git a/core/res/res/values-ru-rRU/arrays.xml b/core/res/res/values-ru-rRU/donottranslate-maps.xml
index 733fdc07de1c..733fdc07de1c 100644
--- a/core/res/res/values-ru-rRU/arrays.xml
+++ b/core/res/res/values-ru-rRU/donottranslate-maps.xml
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 662bbbbc421c..5ed4c2e61f4f 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -335,18 +335,12 @@
<string name="permlab_writeContacts" msgid="644616215860933284">"перезаписывать данные контакта"</string>
<string name="permdesc_writeContacts" product="tablet" msgid="988969759110632978">"Приложение сможет изменять адреса, сохраненные на планшетном ПК. Вредоносные программы смогут таким образом удалять и изменять данные ваших контактов."</string>
<string name="permdesc_writeContacts" product="default" msgid="5075164818647934067">"Приложение сможет изменять адреса, сохраненные на телефоне. Вредоносные программы смогут таким образом удалять и изменять данные ваших контактов."</string>
- <!-- no translation found for permlab_readCallLog (3478133184624102739) -->
- <skip />
- <!-- no translation found for permdesc_readCallLog (3995157599976515002) -->
- <skip />
- <!-- no translation found for permdesc_readCallLog (3452017559804750758) -->
- <skip />
- <!-- no translation found for permlab_writeCallLog (8552045664743499354) -->
- <skip />
- <!-- no translation found for permdesc_writeCallLog (6661806062274119245) -->
- <skip />
- <!-- no translation found for permdesc_writeCallLog (683941736352787842) -->
- <skip />
+ <string name="permlab_readCallLog" msgid="3478133184624102739">"чтение журнала вызовов"</string>
+ <string name="permdesc_readCallLog" product="tablet" msgid="3995157599976515002">"Приложение получит доступ к списку вызовов планшетного ПК, включая данные о входящих и исходящих звонках. Вредоносные приложения могут использовать доступ для передачи ваших данных третьим лицам."</string>
+ <string name="permdesc_readCallLog" product="default" msgid="3452017559804750758">"Приложение получит доступ к списку вызовов телефона, включая данные о входящих и исходящих звонках. Вредоносные приложения смогут воспользоваться этим, чтобы отправить ваши данные третьим лицам."</string>
+ <string name="permlab_writeCallLog" msgid="8552045664743499354">"запись журнала вызовов"</string>
+ <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Приложение сможет вносить изменения в список вызовов планшетного ПК и данные о входящих и исходящих звонках. Вредоносные приложения смогут воспользоваться этим для удаления или изменения информации о звонках."</string>
+ <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Приложение сможет вносить изменения в список вызовов телефона и данные о входящих и исходящих звонках. Вредоносные приложения смогут воспользоваться этим для удаления или изменения информации о звонках."</string>
<string name="permlab_readProfile" msgid="6824681438529842282">"просматривать данные профиля"</string>
<string name="permdesc_readProfile" product="default" msgid="94520753797630679">"Приложение сможет считывать информацию личного профиля, сохраненную на устройстве, такую как ваше имя и контактные данные. Это означает, что приложение сможет получить ваши личные данные и отправить их другим пользователям."</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"изменение данных профиля"</string>
diff --git a/core/res/res/values-sk-rSK/arrays.xml b/core/res/res/values-sk-rSK/donottranslate-maps.xml
index b065ba52431a..b065ba52431a 100644
--- a/core/res/res/values-sk-rSK/arrays.xml
+++ b/core/res/res/values-sk-rSK/donottranslate-maps.xml
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 242b78afa5e9..2e97b82b62e7 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -335,18 +335,12 @@
<string name="permlab_writeContacts" msgid="644616215860933284">"zápis údajov kontaktov"</string>
<string name="permdesc_writeContacts" product="tablet" msgid="988969759110632978">"Umožňuje aplikácii zmeniť všetky kontaktné údaje (adresy) uložené v tablete. Škodlivé aplikácie to môžu využiť a vymazať alebo zmeniť vaše kontaktné údaje."</string>
<string name="permdesc_writeContacts" product="default" msgid="5075164818647934067">"Umožňuje aplikácii čítať všetky kontaktné údaje (adresy) uložené v telefóne. Škodlivé aplikácie to môžu využiť na odoslanie vašich údajov iným osobám."</string>
- <!-- no translation found for permlab_readCallLog (3478133184624102739) -->
- <skip />
- <!-- no translation found for permdesc_readCallLog (3995157599976515002) -->
- <skip />
- <!-- no translation found for permdesc_readCallLog (3452017559804750758) -->
- <skip />
- <!-- no translation found for permlab_writeCallLog (8552045664743499354) -->
- <skip />
- <!-- no translation found for permdesc_writeCallLog (6661806062274119245) -->
- <skip />
- <!-- no translation found for permdesc_writeCallLog (683941736352787842) -->
- <skip />
+ <string name="permlab_readCallLog" msgid="3478133184624102739">"čítať denník hovorov"</string>
+ <string name="permdesc_readCallLog" product="tablet" msgid="3995157599976515002">"Umožňuje aplikácii čítať denník hovorov vo vašom tablete vrátane údajov o prichádzajúcich a odchádzajúcich hovoroch. Škodlivé aplikácie to môžu zneužiť na odosielanie vašich údajov iným osobám."</string>
+ <string name="permdesc_readCallLog" product="default" msgid="3452017559804750758">"Umožňuje aplikácii čítať denník hovorov vo vašom telefóne vrátane údajov o prichádzajúcich a odchádzajúcich hovoroch. Škodlivé aplikácie to môžu zneužiť na odosielanie vašich údajov iným osobám."</string>
+ <string name="permlab_writeCallLog" msgid="8552045664743499354">"zapisovať do denníka hovorov"</string>
+ <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Umožňuje aplikácii upravovať denník hovorov vo vašom tablete vrátane údajov o prichádzajúcich a odchádzajúcich hovoroch. Škodlivé aplikácie to môžu zneužiť na vymazanie alebo úpravu vášho denníka hovorov."</string>
+ <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Umožňuje aplikácii upravovať denník hovorov vo vašom telefóne vrátane údajov o prichádzajúcich a odchádzajúcich hovoroch. Škodlivé aplikácie to môžu zneužiť na vymazanie alebo úpravu vášho denníka hovorov."</string>
<string name="permlab_readProfile" msgid="6824681438529842282">"čítať údaje vášho profilu"</string>
<string name="permdesc_readProfile" product="default" msgid="94520753797630679">"Umožňuje aplikácii čítať informácie v osobnom profile uložené vo vašom zariadení, ako je vaše meno a kontaktné informácie. Znamená to, že ďalšie aplikácie vás môžu identifikovať a poslať ostatným informácie o vašom profile."</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"zapisovať do údajov profilu"</string>
@@ -511,7 +505,7 @@
<string name="permdesc_readDictionary" msgid="8977815988329283705">"Umožňuje aplikácii čítať súkromné slová, názvy a frázy, ktoré mohol používateľ uložiť do slovníka používateľa."</string>
<string name="permlab_writeDictionary" msgid="2296383164914812772">"zapisovať do slovníka definovaného používateľom"</string>
<string name="permdesc_writeDictionary" msgid="8185385716255065291">"Umožňuje aplikácii zapisovať nové slová do používateľského slovníka."</string>
- <string name="permlab_sdcardRead" product="nosdcard" msgid="4086221374639183281">"čítanie obsahu ukl. pries. USB"</string>
+ <string name="permlab_sdcardRead" product="nosdcard" msgid="4086221374639183281">"čítanie obsahu úložiska USB"</string>
<string name="permlab_sdcardRead" product="default" msgid="8537875151845139539">"čítanie obsahu karty SD"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="1055302898999352339">"Umožňuje apl. čítať obsah USB."</string>
<string name="permdesc_sdcardRead" product="default" msgid="7947792373570683542">"Umožňuje aplikácii čítať obsah karty SD."</string>
diff --git a/core/res/res/values-sl-rSI/arrays.xml b/core/res/res/values-sl-rSI/donottranslate-maps.xml
index 41581571d9a8..41581571d9a8 100644
--- a/core/res/res/values-sl-rSI/arrays.xml
+++ b/core/res/res/values-sl-rSI/donottranslate-maps.xml
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 32c55f116044..f66cabb855e8 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -335,18 +335,12 @@
<string name="permlab_writeContacts" msgid="644616215860933284">"pisanje podatkov stika"</string>
<string name="permdesc_writeContacts" product="tablet" msgid="988969759110632978">"Programu omogoča spreminjanje podatkov stikov (naslov), shranjenih v tabličnem računalniku. Zlonamerni programi lahko to uporabijo za brisanje ali spreminjanje podatkov stika."</string>
<string name="permdesc_writeContacts" product="default" msgid="5075164818647934067">"Programu omogoča spreminjanje podatkov stikov (naslov), shranjenih v telefonu. Zlonamerni programi lahko to uporabijo za brisanje ali spreminjanje podatkov stika."</string>
- <!-- no translation found for permlab_readCallLog (3478133184624102739) -->
- <skip />
- <!-- no translation found for permdesc_readCallLog (3995157599976515002) -->
- <skip />
- <!-- no translation found for permdesc_readCallLog (3452017559804750758) -->
- <skip />
- <!-- no translation found for permlab_writeCallLog (8552045664743499354) -->
- <skip />
- <!-- no translation found for permdesc_writeCallLog (6661806062274119245) -->
- <skip />
- <!-- no translation found for permdesc_writeCallLog (683941736352787842) -->
- <skip />
+ <string name="permlab_readCallLog" msgid="3478133184624102739">"branje dnevnika klicev"</string>
+ <string name="permdesc_readCallLog" product="tablet" msgid="3995157599976515002">"Aplikaciji dovoli branje dnevnika klicev v tabličnem računalniku, vključno s podatki o dohodnih in odhodnih klicih. Zlonamerne aplikacije lahko tako pošiljajo vaše podatke drugim."</string>
+ <string name="permdesc_readCallLog" product="default" msgid="3452017559804750758">"Aplikaciji dovoli branje dnevnika klicev v telefonu, vključno s podatki o dohodnih in odhodnih klicih. Zlonamerne aplikacije lahko tako pošiljajo vaše podatke drugim."</string>
+ <string name="permlab_writeCallLog" msgid="8552045664743499354">"pisanje v dnevnik klicev"</string>
+ <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Aplikaciji dovoli spreminjanje dnevnika klicev v tabličnem računalniku, vključno s podatki o dohodnih in odhodnih klicih. Zlonamerne aplikacije lahko tako izbrišejo ali spreminjajo vaš dnevnik klicev."</string>
+ <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Aplikaciji dovoli spreminjanje dnevnika klicev v telefonu, vključno s podatki o dohodnih in odhodnih klicih. Zlonamerne aplikacije lahko tako izbrišejo ali spreminjajo vaš dnevnik klicev."</string>
<string name="permlab_readProfile" msgid="6824681438529842282">"branje podatkov v profilu"</string>
<string name="permdesc_readProfile" product="default" msgid="94520753797630679">"Programu omogoča branje osebnih podatkov v profilu, kot so ime in podatki za stik. To pomeni, da vas lahko program prepozna in vaše podatke o profilu pošlje drugim."</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"pisanje v podatke v profilu"</string>
diff --git a/core/res/res/values-sr-rRS/arrays.xml b/core/res/res/values-sr-rRS/donottranslate-maps.xml
index 98dc954dbdb1..98dc954dbdb1 100644
--- a/core/res/res/values-sr-rRS/arrays.xml
+++ b/core/res/res/values-sr-rRS/donottranslate-maps.xml
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 3cded5a65cf5..66c05617687b 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -335,18 +335,12 @@
<string name="permlab_writeContacts" msgid="644616215860933284">"уписивање података о контактима"</string>
<string name="permdesc_writeContacts" product="tablet" msgid="988969759110632978">"Дозвољава апликацији да измени податке о контакту (адреси) сачуване на таблету. Злонамерне апликације могу то да искористе да би избрисале или измениле податке о контакту."</string>
<string name="permdesc_writeContacts" product="default" msgid="5075164818647934067">"Дозвољава апликацији да измени податке о контакту (адреси) сачуване на телефону. Злонамерне апликације могу то да искористе да би избрисале или измениле податке о контакту."</string>
- <!-- no translation found for permlab_readCallLog (3478133184624102739) -->
- <skip />
- <!-- no translation found for permdesc_readCallLog (3995157599976515002) -->
- <skip />
- <!-- no translation found for permdesc_readCallLog (3452017559804750758) -->
- <skip />
- <!-- no translation found for permlab_writeCallLog (8552045664743499354) -->
- <skip />
- <!-- no translation found for permdesc_writeCallLog (6661806062274119245) -->
- <skip />
- <!-- no translation found for permdesc_writeCallLog (683941736352787842) -->
- <skip />
+ <string name="permlab_readCallLog" msgid="3478133184624102739">"читање евиденције позива"</string>
+ <string name="permdesc_readCallLog" product="tablet" msgid="3995157599976515002">"Дозвољава апликацији да чита евиденцију позива на таблету, укључујући податке о долазним и одлазним позивима. Злонамерне апликације могу ово да користе да би слале податке другим људима."</string>
+ <string name="permdesc_readCallLog" product="default" msgid="3452017559804750758">"Дозвољава апликацији да чита евиденцију позива на телефону, укључујући податке о долазним и одлазним позивима. Злонамерне апликације могу ово да користе да би слале податке другим људима."</string>
+ <string name="permlab_writeCallLog" msgid="8552045664743499354">"писање евиденције позива"</string>
+ <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Дозвољава апликацији да мења евиденцију позива на таблету, укључујући податке о долазним и одлазним позивима. Злонамерне апликације могу ово да користе да би брисале или мењале евиденцију позива."</string>
+ <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Дозвољава апликацији да мења евиденцију позива на телефону, укључујући податке о долазним и одлазним позивима. Злонамерне апликације могу ово да користе да би брисале или мењале евиденцију позива."</string>
<string name="permlab_readProfile" msgid="6824681438529842282">"читање података о профилу"</string>
<string name="permdesc_readProfile" product="default" msgid="94520753797630679">"Дозвољава апликацији да чита личне информације са профила сачуване на уређају, као што су име и контакт информације. То значи да друге апликације могу да вас идентификују и да информације о вашем профилу шаљу другима."</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"уписивање у податке профила"</string>
@@ -511,14 +505,10 @@
<string name="permdesc_readDictionary" msgid="8977815988329283705">"Дозвољава апликацији да чита све приватне речи, називе и фразе које је корисник сачувао у корисничком речнику."</string>
<string name="permlab_writeDictionary" msgid="2296383164914812772">"уписивање у речник који је дефинисао корисник"</string>
<string name="permdesc_writeDictionary" msgid="8185385716255065291">"Дозвољава апликацији да уписује нове речи у кориснички речник."</string>
- <!-- no translation found for permlab_sdcardRead (4086221374639183281) -->
- <skip />
- <!-- no translation found for permlab_sdcardRead (8537875151845139539) -->
- <skip />
- <!-- no translation found for permdesc_sdcardRead (1055302898999352339) -->
- <skip />
- <!-- no translation found for permdesc_sdcardRead (7947792373570683542) -->
- <skip />
+ <string name="permlab_sdcardRead" product="nosdcard" msgid="4086221374639183281">"читање садржаја USB меморије"</string>
+ <string name="permlab_sdcardRead" product="default" msgid="8537875151845139539">"читање садржаја SD картице"</string>
+ <string name="permdesc_sdcardRead" product="nosdcard" msgid="1055302898999352339">"Дозвољава апл. да чита садржај USB меморије."</string>
+ <string name="permdesc_sdcardRead" product="default" msgid="7947792373570683542">"Дозвољава апликацији да чита садржај SD картице."</string>
<string name="permlab_sdcardWrite" product="nosdcard" msgid="85430876310764752">"измена/брисање садржаја USB меморије"</string>
<string name="permlab_sdcardWrite" product="default" msgid="8079403759001777291">"измена/брисање садржаја SD картице"</string>
<string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"Дозвољава апликацији да уписује податке на USB меморију."</string>
diff --git a/core/res/res/values-sv-rSE/arrays.xml b/core/res/res/values-sv-rSE/donottranslate-maps.xml
index 988d356ff16d..988d356ff16d 100644
--- a/core/res/res/values-sv-rSE/arrays.xml
+++ b/core/res/res/values-sv-rSE/donottranslate-maps.xml
diff --git a/core/res/res/values-sw-rTZ/arrays.xml b/core/res/res/values-sw-rTZ/donottranslate-maps.xml
index d1018a776314..d1018a776314 100644
--- a/core/res/res/values-sw-rTZ/arrays.xml
+++ b/core/res/res/values-sw-rTZ/donottranslate-maps.xml
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 4de56edaf2a1..3b870cfe678d 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -335,18 +335,12 @@
<string name="permlab_writeContacts" msgid="644616215860933284">"andika data ya anwani"</string>
<string name="permdesc_writeContacts" product="tablet" msgid="988969759110632978">"Inaruhusu programu kurekebisha data ya mwasiliani(anwani) iliyohifadhiwa kwenye kompyuta yako ki. programu hasidi zinaweza tumia hii kufuta au kurekebisha data yako ya mwasiliani."</string>
<string name="permdesc_writeContacts" product="default" msgid="5075164818647934067">"Inaruhusu programu kurekebisha data ya mwasiliani(anwani) iliyohifadhiwa kwenye simu yako. Programu hasidi zinaweza kutumia hii kufuta au kurekebisha data yako ya mwasiliani."</string>
- <!-- no translation found for permlab_readCallLog (3478133184624102739) -->
- <skip />
- <!-- no translation found for permdesc_readCallLog (3995157599976515002) -->
- <skip />
- <!-- no translation found for permdesc_readCallLog (3452017559804750758) -->
- <skip />
- <!-- no translation found for permlab_writeCallLog (8552045664743499354) -->
- <skip />
- <!-- no translation found for permdesc_writeCallLog (6661806062274119245) -->
- <skip />
- <!-- no translation found for permdesc_writeCallLog (683941736352787842) -->
- <skip />
+ <string name="permlab_readCallLog" msgid="3478133184624102739">"soma kumbukumbu ya simu"</string>
+ <string name="permdesc_readCallLog" product="tablet" msgid="3995157599976515002">"Huruhusu programu kusoma kumbukumbu ya kompyuta kibao yako, ikiwa ni pamoja na simu zinazoingia na kutoka. Huenda programu hasidi zikatumia hii ili kutuma data yako kwa watu wengine."</string>
+ <string name="permdesc_readCallLog" product="default" msgid="3452017559804750758">"Huruhusu programu kusoma kumbukumbu ya simu yako, ikiwa ni pamoja na simu zinazoingia na kutoka. Huenda programu hasidi zikatumia hii ili kutuma data yako kwa watu wengine."</string>
+ <string name="permlab_writeCallLog" msgid="8552045664743499354">"andika kumbukumbu ya simu"</string>
+ <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Huruhusu programu kusoma kumbukumbu ya kompyuta kibao yako, ikiwa ni pamoja na simu zinazoingia na kutoka. Huenda programu hasidi zikatumia hii ili kufuta au kurekebisha kumbukumbu ya simu yako."</string>
+ <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Huruhusu programu kusoma kumbukumbu ya simu yako, ikiwa ni pamoja na simu zinazoingia na kutoka. Huenda programu hasidi zikatumia hii ili kufuta au kurekebisha kumbukumbu ya simu yako."</string>
<string name="permlab_readProfile" msgid="6824681438529842282">"soma data ya maelezo yako mafupi"</string>
<string name="permdesc_readProfile" product="default" msgid="94520753797630679">"Inaruhusu programu kusoma maelezo mafupi ya kibinafsi yaliyohifadhiwa kwenye kifaa chako, kama vile jina lako na taarifa ya kuwasiliana. Hii ina maanisha programu inaweza kukutambua na kutuma taarifa yako fupi ya kibinafsi kwa wengine."</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"andika kwenye data ya maelezo yako mafupi"</string>
diff --git a/core/res/res/values-th-rTH/arrays.xml b/core/res/res/values-th-rTH/donottranslate-maps.xml
index fe765922b955..fe765922b955 100644
--- a/core/res/res/values-th-rTH/arrays.xml
+++ b/core/res/res/values-th-rTH/donottranslate-maps.xml
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 30df3abc58dd..4b59923184da 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -335,18 +335,12 @@
<string name="permlab_writeContacts" msgid="644616215860933284">"เขียนข้อมูลที่อยู่ติดต่อ"</string>
<string name="permdesc_writeContacts" product="tablet" msgid="988969759110632978">"อนุญาตให้แอปพลิเคชันแก้ไขข้อมูลการติดต่อ (ที่อยู่) ที่เก็บไว้ในแท็บเล็ตของคุณ แอปพลิเคชันที่เป็นอันตรายอาจใช้การอนุญาตนี้ลบหรือแก้ไขข้อมูลการติดต่อของคุณ"</string>
<string name="permdesc_writeContacts" product="default" msgid="5075164818647934067">"อนุญาตให้แอปพลิเคชันแก้ไขข้อมูลการติดต่อ (ที่อยู่) ที่เก็บไว้ในโทรศัพท์ของคุณ แอปพลิเคชันที่เป็นอันตรายอาจใช้การอนุญาตนี้ลบหรือแก้ไขข้อมูลการติดต่อของคุณ"</string>
- <!-- no translation found for permlab_readCallLog (3478133184624102739) -->
- <skip />
- <!-- no translation found for permdesc_readCallLog (3995157599976515002) -->
- <skip />
- <!-- no translation found for permdesc_readCallLog (3452017559804750758) -->
- <skip />
- <!-- no translation found for permlab_writeCallLog (8552045664743499354) -->
- <skip />
- <!-- no translation found for permdesc_writeCallLog (6661806062274119245) -->
- <skip />
- <!-- no translation found for permdesc_writeCallLog (683941736352787842) -->
- <skip />
+ <string name="permlab_readCallLog" msgid="3478133184624102739">"อ่านประวัติการโทร"</string>
+ <string name="permdesc_readCallLog" product="tablet" msgid="3995157599976515002">"อนุญาตให้แอปอ่านประวัติการโทรจากแท็บเล็ตของคุณ รวมถึงข้อมูลเกี่ยวกับสายเรียกเข้าและการโทรออก แอปที่เป็นอันตรายอาจใช้สิ่งนี้เพื่อส่งข้อมูลของคุณให้กับบุคคลอื่น"</string>
+ <string name="permdesc_readCallLog" product="default" msgid="3452017559804750758">"อนุญาตให้แอปอ่านประวัติการโทรจากโทรศัพท์ของคุณ รวมถึงข้อมูลเกี่ยวกับสายเรียกเข้าและการโทรออก แอปที่เป็นอันตรายอาจใช้สิ่งนี้เพื่อส่งข้อมูลของคุณให้กับบุคคลอื่น"</string>
+ <string name="permlab_writeCallLog" msgid="8552045664743499354">"เขียนประวัติการโทร"</string>
+ <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"อนุญาตให้แอปแก้ไขประวัติการโทรจากแท็บเล็ตของคุณ รวมถึงข้อมูลเกี่ยวกับสายเรียกเข้าและการโทรออก แอปที่เป็นอันตรายอาจใช้สิ่งนี้เพื่อลบหรือแก้ไขประวัติการโทรของคุณ"</string>
+ <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"อนุญาตให้แอปแก้ไขประวัติการโทรจากโทรศัพท์ของคุณ รวมถึงข้อมูลเกี่ยวกับสายเรียกเข้าและการโทรออก แอปที่เป็นอันตรายอาจใช้สิ่งนี้เพื่อลบหรือแก้ไขประวัติการโทรของคุณ"</string>
<string name="permlab_readProfile" msgid="6824681438529842282">"อ่านข้อมูลโปรไฟล์ของคุณ"</string>
<string name="permdesc_readProfile" product="default" msgid="94520753797630679">"อนุญาตให้แอปพลิเคชันอ่านข้อมูลโปรไฟล์ส่วนบุคคลที่เก็บไว้บนอุปกรณ์ของคุณ เช่น ชื่อและข้อมูลติดต่อ ซึ่งหมายความว่าแอปพลิเคชันจะสามารถระบุตัวตนของคุณและส่งข้อมูลโปรไฟล์ของคุณแก่ผู้อื่นได้"</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"เขียนลงในข้อมูลโปรไฟล์ของคุณ"</string>
@@ -513,8 +507,8 @@
<string name="permdesc_writeDictionary" msgid="8185385716255065291">"อนุญาตให้แอปพลิเคชันเขียนคำใหม่ลงในพจนานุกรมผู้ใช้"</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="4086221374639183281">"อ่านเนื้อหาที่บันทึกใน USB"</string>
<string name="permlab_sdcardRead" product="default" msgid="8537875151845139539">"อ่านเนื้อหาในการ์ด SD"</string>
- <string name="permdesc_sdcardRead" product="nosdcard" msgid="1055302898999352339">"ให้แอปฯ อ่านเนื้อหาใน USB"</string>
- <string name="permdesc_sdcardRead" product="default" msgid="7947792373570683542">"อนุญาตให้แอปพลิเคชันอ่านเนื้อหาของการ์ด SD"</string>
+ <string name="permdesc_sdcardRead" product="nosdcard" msgid="1055302898999352339">"อนุญาตให้แอปอ่านเนื้อหาใน USB"</string>
+ <string name="permdesc_sdcardRead" product="default" msgid="7947792373570683542">"อนุญาตให้แอปอ่านเนื้อหาในการ์ด SD"</string>
<string name="permlab_sdcardWrite" product="nosdcard" msgid="85430876310764752">"แก้ไข/ลบเนื้อหาของที่เก็บข้อมูล USB"</string>
<string name="permlab_sdcardWrite" product="default" msgid="8079403759001777291">"แก้ไข/ลบข้อมูลการ์ด SD"</string>
<string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"อนุญาตให้แอปฯ เขียนลงใน USB"</string>
diff --git a/core/res/res/values-tl-rPH/arrays.xml b/core/res/res/values-tl-rPH/donottranslate-maps.xml
index 2edac64dd7c2..2edac64dd7c2 100644
--- a/core/res/res/values-tl-rPH/arrays.xml
+++ b/core/res/res/values-tl-rPH/donottranslate-maps.xml
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index ce79c7079125..dc22a0864cec 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -335,18 +335,12 @@
<string name="permlab_writeContacts" msgid="644616215860933284">"sumulat ng data ng pakikipag-ugnay"</string>
<string name="permdesc_writeContacts" product="tablet" msgid="988969759110632978">"Pinapayagan ang app na baguhin ang data ng contact (address) na nakaimbak sa iyong tablet. Maaari itong gamitin ng nakakahamak na apps upang burahin o baguhin ang iyong data ng contact."</string>
<string name="permdesc_writeContacts" product="default" msgid="5075164818647934067">"Pinapayagan ang app na baguhin ang data ng contact (address) na nakaimbak sa iyong telepono. Maaari itong gamitin ng nakakahamak na apps upang burahin o baguhin ang iyong data ng contact."</string>
- <!-- no translation found for permlab_readCallLog (3478133184624102739) -->
- <skip />
- <!-- no translation found for permdesc_readCallLog (3995157599976515002) -->
- <skip />
- <!-- no translation found for permdesc_readCallLog (3452017559804750758) -->
- <skip />
- <!-- no translation found for permlab_writeCallLog (8552045664743499354) -->
- <skip />
- <!-- no translation found for permdesc_writeCallLog (6661806062274119245) -->
- <skip />
- <!-- no translation found for permdesc_writeCallLog (683941736352787842) -->
- <skip />
+ <string name="permlab_readCallLog" msgid="3478133184624102739">"basahin ang log ng tawag"</string>
+ <string name="permdesc_readCallLog" product="tablet" msgid="3995157599976515002">"Binibigyang-daan ang app na basahin ang log ng tawag ng iyong tablet, kabilang ang data tungkol sa mga paparating at papalabas na tawag. Maaari itong gamitin ng nakakahamak na apps upang ipadala ang iyong data sa ibang mga tao."</string>
+ <string name="permdesc_readCallLog" product="default" msgid="3452017559804750758">"Binibigyang-daan ang app na basahin ang log ng tawag ng iyong telepono, kabilang ang data tungkol sa mga paparating at papalabas na tawag. Maaari itong gamitin ng nakakahamak na apps upang ipadala ang iyong data sa ibang mga tao."</string>
+ <string name="permlab_writeCallLog" msgid="8552045664743499354">"isulat ang log ng tawag"</string>
+ <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Binibigyan-daan ang app na baguhin ang log ng tawag ng iyong tablet, kabilang ang data tungkol sa mga paparating at papalabas na tawag. Maaari itong gamitin ng nakakahamak na apps upang burahin o baguhin ang iyong log ng tawag."</string>
+ <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Binibigyan-daan ang app na baguhin ang log ng tawag ng iyong telepono, kabilang ang data tungkol sa mga paparating at papalabas na tawag. Maaari itong gamitin ng nakakahamak na apps upang burahin o baguhin ang iyong log ng tawag."</string>
<string name="permlab_readProfile" msgid="6824681438529842282">"basahin ang iyong data ng profile"</string>
<string name="permdesc_readProfile" product="default" msgid="94520753797630679">"Pinapayagan ang app na basahin ang personal na impormasyon ng profile na nakaimbak sa iyong device, gaya ng iyong pangalan at impormasyon ng contact. Nangangahulugan ito na makikilala ka ng app at maipapadala nito ang impormasyon ng iyong profile sa iba."</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"i-write sa iyong data ng profile"</string>
diff --git a/core/res/res/values-tr-rTR/arrays.xml b/core/res/res/values-tr-rTR/donottranslate-maps.xml
index f045cfff50bd..f045cfff50bd 100644
--- a/core/res/res/values-tr-rTR/arrays.xml
+++ b/core/res/res/values-tr-rTR/donottranslate-maps.xml
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 3fc02a9a03ef..419ae9663471 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -335,18 +335,12 @@
<string name="permlab_writeContacts" msgid="644616215860933284">"kişi verileri yaz"</string>
<string name="permdesc_writeContacts" product="tablet" msgid="988969759110632978">"Uygulamaya, tabletinizde depolanan kişi (adres) verilerini değiştirme izni verir. Kötü amaçlı uygulamalar kişi verilerinizi silmek veya değiştirmek için bunu kullanabilir."</string>
<string name="permdesc_writeContacts" product="default" msgid="5075164818647934067">"Uygulamaya, telefonunuzda depolanan kişi (adres) verilerini değiştirme izni verir. Kötü amaçlı uygulamalar kişi verilerinizi silmek veya değiştirmek için bunu kullanabilir."</string>
- <!-- no translation found for permlab_readCallLog (3478133184624102739) -->
- <skip />
- <!-- no translation found for permdesc_readCallLog (3995157599976515002) -->
- <skip />
- <!-- no translation found for permdesc_readCallLog (3452017559804750758) -->
- <skip />
- <!-- no translation found for permlab_writeCallLog (8552045664743499354) -->
- <skip />
- <!-- no translation found for permdesc_writeCallLog (6661806062274119245) -->
- <skip />
- <!-- no translation found for permdesc_writeCallLog (683941736352787842) -->
- <skip />
+ <string name="permlab_readCallLog" msgid="3478133184624102739">"çağrı günlüğünü oku"</string>
+ <string name="permdesc_readCallLog" product="tablet" msgid="3995157599976515002">"Uygulamaya tabletinizin çağrı günlüğünü (gelen ve giden çağrılarla ilgili veriler dahil olmak üzere) okuma izni verir. Kötü amaçlı uygulamalar bu izni kullanarak verilerinizi başka kişilere gönderebilir."</string>
+ <string name="permdesc_readCallLog" product="default" msgid="3452017559804750758">"Uygulamaya telefonunuzun çağrı günlüğünü (gelen ve giden çağrılarla ilgili veriler dahil olmak üzere) okuma izni verir. Kötü amaçlı uygulamalar bu izni kullanarak verilerinizi başka kişilere gönderebilir."</string>
+ <string name="permlab_writeCallLog" msgid="8552045664743499354">"çağrı günlüğüne yaz"</string>
+ <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Uygulamaya tabletinizin çağrı günlüğünde (gelen ve giden çağrılarla ilgili veriler dahil olmak üzere) değişiklik yapma izni verir. Kötü amaçlı uygulamalar bu izni kullanarak çağrı günlüğünüzü silebilir veya değiştirebilir."</string>
+ <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Uygulamaya telefonunuzun çağrı günlüğünde (gelen ve giden çağrılarla ilgili veriler dahil olmak üzere) değişiklik yapma izni verir. Kötü amaçlı uygulamalar bu izni kullanarak çağrı günlüğünüzü silebilir veya değiştirebilir."</string>
<string name="permlab_readProfile" msgid="6824681438529842282">"profil verilerimi oku"</string>
<string name="permdesc_readProfile" product="default" msgid="94520753797630679">"Uygulamaya, adınız ve iletişim bilgileriniz gibi cihazınızda saklanan kişisel profil bilgilerini okuma izni verir. Bu izin, uygulamanın sizi tanımlayabileceği ve profil bilgilerinizi başkalarına gönderebileceği anlamına gelir."</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"profil verilerime yaz"</string>
diff --git a/core/res/res/values-uk-rUA/arrays.xml b/core/res/res/values-uk-rUA/donottranslate-maps.xml
index 746befd86918..746befd86918 100644
--- a/core/res/res/values-uk-rUA/arrays.xml
+++ b/core/res/res/values-uk-rUA/donottranslate-maps.xml
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 3ff5f797a547..13311f130073 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -335,18 +335,12 @@
<string name="permlab_writeContacts" msgid="644616215860933284">"запис. контактні дані"</string>
<string name="permdesc_writeContacts" product="tablet" msgid="988969759110632978">"Дозволяє програмі змінювати контактні дані (адресу), збережені в планшетному ПК. Шкідливі програми можуть використовувати це для видалення чи зміни ваших контактних даних."</string>
<string name="permdesc_writeContacts" product="default" msgid="5075164818647934067">"Дозволяє програмі змінювати контактні дані (адресу), збережені в телефоні. Шкідливі програми можуть використовувати це для видалення чи зміни ваших контактних даних."</string>
- <!-- no translation found for permlab_readCallLog (3478133184624102739) -->
- <skip />
- <!-- no translation found for permdesc_readCallLog (3995157599976515002) -->
- <skip />
- <!-- no translation found for permdesc_readCallLog (3452017559804750758) -->
- <skip />
- <!-- no translation found for permlab_writeCallLog (8552045664743499354) -->
- <skip />
- <!-- no translation found for permdesc_writeCallLog (6661806062274119245) -->
- <skip />
- <!-- no translation found for permdesc_writeCallLog (683941736352787842) -->
- <skip />
+ <string name="permlab_readCallLog" msgid="3478133184624102739">"читати журнал викликів"</string>
+ <string name="permdesc_readCallLog" product="tablet" msgid="3995157599976515002">"Дозволяє програмі читати журнал викликів вашого планшетного ПК, включно з даними про вхідні та вихідні дзвінки. Шкідливі програми можуть використовувати це для надсилання ваших даних іншим людям."</string>
+ <string name="permdesc_readCallLog" product="default" msgid="3452017559804750758">"Дозволяє програмі читати журнал викликів вашого телефону, включно з даними про вхідні та вихідні дзвінки. Шкідливі програми можуть використовувати це для надсилання ваших даних іншим людям."</string>
+ <string name="permlab_writeCallLog" msgid="8552045664743499354">"записувати в журнал викликів"</string>
+ <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Дозволяє програмі змінювати журнал викликів вашого планшетного ПК, включно з даними про вхідні та вихідні дзвінки. Шкідливі програми можуть використовувати це для стирання або зміни вашого журналу викликів."</string>
+ <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Дозволяє програмі змінювати журнал викликів вашого телефону, включно з даними про вхідні та вихідні дзвінки. Шкідливі програми можуть використовувати це для стирання або зміни вашого журналу викликів."</string>
<string name="permlab_readProfile" msgid="6824681438529842282">"читати дані вашого профілю"</string>
<string name="permdesc_readProfile" product="default" msgid="94520753797630679">"Дозволяє програмі читати особисту інформацію профілю, збережену на вашому пристрої, як-от ваше ім’я та контактну інформацію. Це означає, що інші програми можуть ідентифікувати вашу особу та надсилати дані вашого профілю іншим."</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"записувати в дані профілю"</string>
diff --git a/core/res/res/values-vi-rVN/arrays.xml b/core/res/res/values-vi-rVN/donottranslate-maps.xml
index 6b220815fa21..6b220815fa21 100644
--- a/core/res/res/values-vi-rVN/arrays.xml
+++ b/core/res/res/values-vi-rVN/donottranslate-maps.xml
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 435ebbf3f7fd..b94f104daaa3 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -335,18 +335,12 @@
<string name="permlab_writeContacts" msgid="644616215860933284">"ghi dữ liệu liên hệ"</string>
<string name="permdesc_writeContacts" product="tablet" msgid="988969759110632978">"Cho phép ứng dụng sửa đổi dữ liệu (địa chỉ) liên hệ được lưu trữ trên máy tính bảng của bạn. Ứng dụng độc hại có thể sử dụng quyền này để xóa hoặc sửa đổi dữ liệu liên hệ của bạn."</string>
<string name="permdesc_writeContacts" product="default" msgid="5075164818647934067">"Cho phép ứng dụng sửa đổi dữ liệu (địa chỉ) liên hệ được lưu trữ trên điện thoại của bạn. Ứng dụng độc hại có thể sử dụng quyền này để xóa hoặc sửa đổi dữ liệu liên hệ của bạn."</string>
- <!-- no translation found for permlab_readCallLog (3478133184624102739) -->
- <skip />
- <!-- no translation found for permdesc_readCallLog (3995157599976515002) -->
- <skip />
- <!-- no translation found for permdesc_readCallLog (3452017559804750758) -->
- <skip />
- <!-- no translation found for permlab_writeCallLog (8552045664743499354) -->
- <skip />
- <!-- no translation found for permdesc_writeCallLog (6661806062274119245) -->
- <skip />
- <!-- no translation found for permdesc_writeCallLog (683941736352787842) -->
- <skip />
+ <string name="permlab_readCallLog" msgid="3478133184624102739">"đọc nhật ký cuộc gọi"</string>
+ <string name="permdesc_readCallLog" product="tablet" msgid="3995157599976515002">"Cho phép ứng dụng đọc nhật ký cuộc gọi trên máy tính bảng của bạn, bao gồm dữ liệu về các cuộc gọi đến và gọi đi. Các ứng dụng độc hại có thể sử dụng quyền này để gửi dữ liệu của bạn cho những người khác."</string>
+ <string name="permdesc_readCallLog" product="default" msgid="3452017559804750758">"Cho phép ứng dụng đọc nhật ký cuộc gọi trên điện thoại của bạn, bao gồm dữ liệu về các cuộc gọi đến và gọi đi. Các ứng dụng độc hại có thể sử dụng quyền này để gửi dữ liệu của bạn cho những người khác."</string>
+ <string name="permlab_writeCallLog" msgid="8552045664743499354">"ghi nhật ký cuộc gọi"</string>
+ <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Cho phép ứng dụng sửa đổi nhật ký cuộc gọi trên máy tính bảng của bạn, bao gồm dữ liệu về các cuộc gọi đến và gọi đi. Các ứng dụng độc hại có thể sử dụng quyền này để xóa hoặc sửa đổi nhật ký cuộc gọi của bạn."</string>
+ <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Cho phép ứng dụng sửa đổi nhật ký cuộc gọi trên điện thoại của bạn, bao gồm dữ liệu về các cuộc gọi đến và gọi đi. Các ứng dụng độc hại có thể sử dụng quyền này để xóa hoặc sửa đổi nhật ký cuộc gọi của bạn."</string>
<string name="permlab_readProfile" msgid="6824681438529842282">"đọc d.liệu t.sử của bạn"</string>
<string name="permdesc_readProfile" product="default" msgid="94520753797630679">"Cho phép ứng dụng đọc thông tin tiểu sử cá nhân được lưu trữ trên thiết bị, chẳng hạn như tên và thông tin liên hệ của bạn. Điều này có nghĩa là ứng dụng có thể xác định danh tính của bạn và gửi thông tin tiểu sử của bạn cho người khác."</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"ghi dữ liệu t.sử của bạn"</string>
diff --git a/core/res/res/values-zh-rCN/arrays.xml b/core/res/res/values-zh-rCN/donottranslate-maps.xml
index 16da6d91e49f..16da6d91e49f 100644
--- a/core/res/res/values-zh-rCN/arrays.xml
+++ b/core/res/res/values-zh-rCN/donottranslate-maps.xml
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index f21d7b828a69..81d0ec64b5bf 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -335,18 +335,12 @@
<string name="permlab_writeContacts" msgid="644616215860933284">"写入联系数据"</string>
<string name="permdesc_writeContacts" product="tablet" msgid="988969759110632978">"允许应用程序读取您平板电脑上存储的联系人(地址)数据。恶意应用程序可能借此清除或修改您的联系人数据。"</string>
<string name="permdesc_writeContacts" product="default" msgid="5075164818647934067">"允许应用程序修改您手机上存储的联系人(地址)数据。恶意应用程序可能借此清除或修改您的联系人数据。"</string>
- <!-- no translation found for permlab_readCallLog (3478133184624102739) -->
- <skip />
- <!-- no translation found for permdesc_readCallLog (3995157599976515002) -->
- <skip />
- <!-- no translation found for permdesc_readCallLog (3452017559804750758) -->
- <skip />
- <!-- no translation found for permlab_writeCallLog (8552045664743499354) -->
- <skip />
- <!-- no translation found for permdesc_writeCallLog (6661806062274119245) -->
- <skip />
- <!-- no translation found for permdesc_writeCallLog (683941736352787842) -->
- <skip />
+ <string name="permlab_readCallLog" msgid="3478133184624102739">"读取通话记录"</string>
+ <string name="permdesc_readCallLog" product="tablet" msgid="3995157599976515002">"允许该应用读取平板电脑的通话记录,包括有关来电和外拨电话的数据。恶意应用可能会借此将您的数据发送给他人。"</string>
+ <string name="permdesc_readCallLog" product="default" msgid="3452017559804750758">"允许该应用读取手机的通话记录,包括有关来电和外拨电话的数据。恶意应用可能会借此将您的数据发送给他人。"</string>
+ <string name="permlab_writeCallLog" msgid="8552045664743499354">"写入通话记录"</string>
+ <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"允许该应用修改平板电脑的通话记录,包括有关来电和外拨电话的数据。恶意应用可能会借此清除或修改您的通话记录。"</string>
+ <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"允许该应用修改手机的通话记录,包括有关来电和外拨电话的数据。恶意应用可能会借此清除或修改您的通话记录。"</string>
<string name="permlab_readProfile" msgid="6824681438529842282">"读取您的个人资料数据"</string>
<string name="permdesc_readProfile" product="default" msgid="94520753797630679">"允许应用程序读取您设备上存储的个人资料信息,例如您的姓名和联系信息。这意味着应用程序可以识别您的身份,并将您的个人资料信息发送给他人。"</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"写入到您的个人资料数据"</string>
@@ -511,14 +505,10 @@
<string name="permdesc_readDictionary" msgid="8977815988329283705">"允许应用程序读取用户可能在用户词典中已存储的任意私有字词、名称和短语。"</string>
<string name="permlab_writeDictionary" msgid="2296383164914812772">"写入用户定义的词典"</string>
<string name="permdesc_writeDictionary" msgid="8185385716255065291">"允许应用程序向用户词典中写入新词。"</string>
- <!-- no translation found for permlab_sdcardRead (4086221374639183281) -->
- <skip />
- <!-- no translation found for permlab_sdcardRead (8537875151845139539) -->
- <skip />
- <!-- no translation found for permdesc_sdcardRead (1055302898999352339) -->
- <skip />
- <!-- no translation found for permdesc_sdcardRead (7947792373570683542) -->
- <skip />
+ <string name="permlab_sdcardRead" product="nosdcard" msgid="4086221374639183281">"读取 USB 存储设备的内容"</string>
+ <string name="permlab_sdcardRead" product="default" msgid="8537875151845139539">"读取 SD 卡的内容"</string>
+ <string name="permdesc_sdcardRead" product="nosdcard" msgid="1055302898999352339">"允许应用读取 USB 存储设备的内容。"</string>
+ <string name="permdesc_sdcardRead" product="default" msgid="7947792373570683542">"允许应用读取 SD 卡的内容。"</string>
<string name="permlab_sdcardWrite" product="nosdcard" msgid="85430876310764752">"修改/删除 USB 存储设备内容"</string>
<string name="permlab_sdcardWrite" product="default" msgid="8079403759001777291">"修改/删除 SD 卡中的内容"</string>
<string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"允许应用程序写入 USB 存储设备。"</string>
diff --git a/core/res/res/values-zh-rTW/arrays.xml b/core/res/res/values-zh-rTW/donottranslate-maps.xml
index be0795b84af0..be0795b84af0 100644
--- a/core/res/res/values-zh-rTW/arrays.xml
+++ b/core/res/res/values-zh-rTW/donottranslate-maps.xml
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 70689e81be6c..e81e3934dc03 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -335,18 +335,12 @@
<string name="permlab_writeContacts" msgid="644616215860933284">"輸入聯絡人資料"</string>
<string name="permdesc_writeContacts" product="tablet" msgid="988969759110632978">"允許應用程式修改平板電腦上儲存的聯絡人 (地址) 資料。請注意,惡意應用程式可能利用此功能清除或修改您的聯絡人資料。"</string>
<string name="permdesc_writeContacts" product="default" msgid="5075164818647934067">"允許應用程式修改手機上儲存的聯絡人 (地址) 資料。請注意,惡意應用程式可能利用此功能清除或修改您的聯絡人資料。"</string>
- <!-- no translation found for permlab_readCallLog (3478133184624102739) -->
- <skip />
- <!-- no translation found for permdesc_readCallLog (3995157599976515002) -->
- <skip />
- <!-- no translation found for permdesc_readCallLog (3452017559804750758) -->
- <skip />
- <!-- no translation found for permlab_writeCallLog (8552045664743499354) -->
- <skip />
- <!-- no translation found for permdesc_writeCallLog (6661806062274119245) -->
- <skip />
- <!-- no translation found for permdesc_writeCallLog (683941736352787842) -->
- <skip />
+ <string name="permlab_readCallLog" msgid="3478133184624102739">"讀取通話紀錄"</string>
+ <string name="permdesc_readCallLog" product="tablet" msgid="3995157599976515002">"允許應用程式讀取平板電腦的通話紀錄,包括來電和已撥電話相關資料。請注意,惡意應用程式可能利用此功能將您的資料傳送給他人。"</string>
+ <string name="permdesc_readCallLog" product="default" msgid="3452017559804750758">"允許應用程式讀取手機的通話紀錄,包括來電和已撥電話相關資料。請注意,惡意應用程式可能利用此功能將您的資料傳送給他人。"</string>
+ <string name="permlab_writeCallLog" msgid="8552045664743499354">"寫入通話紀錄"</string>
+ <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"允許應用程式修改平板電腦的通話紀錄,包括來電和已撥電話相關資料。請注意,惡意應用程式可能利用此功能刪除或修改您的通話記錄。"</string>
+ <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"允許應用程式修改手機的通話紀錄,包括來電和已撥電話相關資料。請注意,惡意應用程式可能利用此功能刪除或修改您的通話記錄。"</string>
<string name="permlab_readProfile" msgid="6824681438529842282">"讀取您的個人資料"</string>
<string name="permdesc_readProfile" product="default" msgid="94520753797630679">"允許應用程式讀取裝置上儲存的個人資料,例如您的姓名和聯絡資訊。這表示應用程式可以識別您的身分,並將您的個人資料傳送給他人。"</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"寫入您的個人資料"</string>
diff --git a/core/res/res/values-zu-rZA/arrays.xml b/core/res/res/values-zu-rZA/donottranslate-maps.xml
index 5bff0f489ca3..5bff0f489ca3 100644
--- a/core/res/res/values-zu-rZA/arrays.xml
+++ b/core/res/res/values-zu-rZA/donottranslate-maps.xml
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 541133649650..f43835f2664d 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -335,12 +335,12 @@
<string name="permlab_writeContacts" msgid="644616215860933284">"bhala idatha yothintana naye"</string>
<string name="permdesc_writeContacts" product="tablet" msgid="988969759110632978">"Ivumela insiza ukuthi iguqule imininingwane yekheli lokuxhumana eligcinwe ekhompyutheni yakho yepeni. Izinsiza ezinobungozi zingasebenzisa lokhu ukususa noma ziguqule ulwazi lwakho lokuxhuana."</string>
<string name="permdesc_writeContacts" product="default" msgid="5075164818647934067">"Ivumela insiza ukuthi iguqule imininingwane yekheli lokuxhumana eligcinwe ocingweni lwakho. Izinsiza ezinobungozi zingasebenzisa lokhu ukususa noma ziguqule ulwazi lwakho lokuxhuana."</string>
- <string name="permlab_readCallLog" msgid="3478133184624102739">"funda ilogi yekholi"</string>
- <string name="permdesc_readCallLog" product="tablet" msgid="3995157599976515002">"Ivumela uhlelo lokusebenza ukufunda irekhodi lwamakholi lethubhulethi yakho, kufaka phakathi idatha mayelana namakholi angenayo naphumayo. Izinhlelo zikusebenza ezingalungile zingasebenzisa lokhu ukuthumela idatha kwabanye abantu."</string>
- <string name="permdesc_readCallLog" product="default" msgid="3452017559804750758">"Ivumela uhlelo lokusebenza ukufunda irekhodi lwamakholi wakho, kufaka phakathi idatha mayelana namakholi aphumayo nangenayo. Izinhlelo zokusebenza ezingalungile zingasebenzisa lokhu ukuthumela idatha kwabanye abantu."</string>
- <string name="permlab_writeCallLog" msgid="8552045664743499354">"bhala irekhodi lwamakholi"</string>
+ <string name="permlab_readCallLog" msgid="3478133184624102739">"funda irekhodi lamakholi"</string>
+ <string name="permdesc_readCallLog" product="tablet" msgid="3995157599976515002">"Ivumela uhlelo lokusebenza ukufunda irekhodi lamakholi lethubhulethi yakho, kufaka phakathi idatha mayelana namakholi angenayo naphumayo. Izinhlelo zikusebenza ezingalungile zingasebenzisa lokhu ukuthumela idatha kwabanye abantu."</string>
+ <string name="permdesc_readCallLog" product="default" msgid="3452017559804750758">"Ivumela uhlelo lokusebenza ukufunda irekhodi lamakholi akho, kufaka phakathi idatha mayelana namakholi aphumayo nangenayo. Izinhlelo zokusebenza ezingalungile zingasebenzisa lokhu ukuthumela idatha kwabanye abantu."</string>
+ <string name="permlab_writeCallLog" msgid="8552045664743499354">"bhala irekhodi lamakholi"</string>
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Ivumela uhlelo lokusebenza ukushintsha ilogi yekholi yethebulethi yakho, kufaka phakathi idatha mayelana namakholi angenayo naphumayo. Izinhlelo zikusebenza ezingalungile zingasebenzisa lokhu ukusula noma ukushintsha irekhodi lwamakholi wakho."</string>
- <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Ivumela uhlelo lokusebenza ukushintsha irekhodi lwamakholi lefoni yakho, kufaka phakathi idatha mayelana namakholi angenayo naphumayo. Izinhlelo zikusebenza ezingalungile zingasebenzisa lokhu ukusula noma ukushintsha irekhodi lwamakholi wakho."</string>
+ <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Ivumela uhlelo lokusebenza ukushintsha irekhodi lamakholi efoni yakho, kufaka phakathi idatha emayelana namakholi angenayo naphumayo. Izinhlelo zikusebenza ezingalungile zingasebenzisa lokhu ukusula noma ukushintsha irekhodi lwamakholi wakho."</string>
<string name="permlab_readProfile" msgid="6824681438529842282">"bhala imininingo yemininingwane yakho"</string>
<string name="permdesc_readProfile" product="default" msgid="94520753797630679">"Ivumela insiza ukuthi ifunde ulwazi lomuntu lwephrofayli olugcinwe edivayisini yakho njengegama lakho kanye nemininingwane yokuxhumana nawe. Lokhu kuchaza ukuthi izinsa ingakuhlonza bese ithumelela abanye imininingwane yephrofayili yakho."</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"bhala imininingwane yemininingo yakho"</string>
diff --git a/core/res/res/values/arrays.xml b/core/res/res/values/arrays.xml
index ce734fce8bb6..90ddc4b287a7 100644
--- a/core/res/res/values/arrays.xml
+++ b/core/res/res/values/arrays.xml
@@ -338,16 +338,6 @@
<item>#ffffffff</item>
</array>
- <!-- Do not translate. -->
- <integer-array name="maps_starting_lat_lng">
- <item>36149777</item>
- <item>-95993398</item>
- </integer-array>
- <!-- Do not translate. -->
- <integer-array name="maps_starting_zoom">
- <item>3</item>
- </integer-array>
-
<!-- Used in LocalePicker -->
<string-array translatable="false" name="special_locale_codes">
<item>zh_CN</item>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index db908ca20b47..428790f6b734 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -589,12 +589,6 @@
<!-- NumberPicker style. -->
<attr name="numberPickerStyle" format="reference" />
- <!-- NumberPicker up button style. -->
- <attr name="numberPickerUpButtonStyle" format="reference" />
- <!-- NumberPicker down button style. -->
- <attr name="numberPickerDownButtonStyle" format="reference" />
- <!-- NumberPicker input text style. -->
- <attr name="numberPickerInputTextStyle" format="reference" />
<!-- The CalendarView style. -->
<attr name="calendarViewStyle" format="reference" />
@@ -3617,12 +3611,12 @@
<declare-styleable name="NumberPicker">
<!-- @hide Color for the solid color background if such for optimized rendering. -->
<attr name="solidColor" format="color|reference" />
- <!-- @hide Whether the number picker supports fligning. -->
- <attr name="flingable" format="boolean" />
<!-- @hide The divider for making the selection area. -->
<attr name="selectionDivider" format="reference" />
<!-- @hide The height of the selection divider. -->
<attr name="selectionDividerHeight" format="dimension" />
+ <!-- @hide The distance between the two selection dividers. -->
+ <attr name="selectionDividersDistance" format="dimension" />
<!-- @hide The min height of the NumberPicker. -->
<attr name="internalMinHeight" format="dimension" />
<!-- @hide The max height of the NumberPicker. -->
@@ -3631,6 +3625,10 @@
<attr name="internalMinWidth" format="dimension" />
<!-- @hide The max width of the NumberPicker. -->
<attr name="internalMaxWidth" format="dimension" />
+ <!-- @hide The layout of the number picker. -->
+ <attr name="internalLayout" />
+ <!-- @hide The minimal move distance of a swipe to be considered a fling. -->
+ <attr name="minFlingDistance" format="dimension" />
</declare-styleable>
<declare-styleable name="TimePicker">
diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml
index b1a4b42498c7..5ff2c01167ae 100644
--- a/core/res/res/values/colors.xml
+++ b/core/res/res/values/colors.xml
@@ -113,7 +113,7 @@
<color name="lockscreen_owner_info">#ff9a9a9a</color>
<!-- FaceLock -->
- <color name="facelock_color_background">#000000</color>
+ <color name="facelock_spotlight_mask">#CC000000</color>
<!-- For holo theme -->
<drawable name="screen_background_holo_light">#fff3f3f3</drawable>
diff --git a/core/res/res/values/donottranslate-maps.xml b/core/res/res/values/donottranslate-maps.xml
new file mode 100644
index 000000000000..ee32f01cbf77
--- /dev/null
+++ b/core/res/res/values/donottranslate-maps.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/assets/res/any/colors.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR 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">
+
+ <!-- Do not translate. -->
+ <integer-array name="maps_starting_lat_lng">
+ <item>36149777</item>
+ <item>-95993398</item>
+ </integer-array>
+ <!-- Do not translate. -->
+ <integer-array name="maps_starting_zoom">
+ <item>3</item>
+ </integer-array>
+
+</resources>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index a089021b8b1d..ea1a70a4d477 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -974,6 +974,9 @@
<java-symbol type="drawable" name="unlock_halo" />
<java-symbol type="drawable" name="unlock_ring" />
<java-symbol type="drawable" name="unlock_wave" />
+ <java-symbol type="drawable" name="ic_lockscreen_camera" />
+ <java-symbol type="drawable" name="ic_lockscreen_silent" />
+ <java-symbol type="drawable" name="ic_lockscreen_unlock" />
<java-symbol type="layout" name="action_bar_home" />
<java-symbol type="layout" name="action_bar_title_item" />
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 7799f749209c..f6125f006017 100755
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -3190,8 +3190,6 @@
<string name="number_picker_increment_button">Increment</string>
<!-- Description of the button to decrement the NumberPicker value. [CHAR LIMIT=NONE] -->
<string name="number_picker_decrement_button">Decrement</string>
- <!-- Description of the tap and hold action to get into scroll mode in NumberPicker. [CHAR LIMIT=NONE] -->
- <string name="number_picker_increment_scroll_mode"><xliff:g id="value" example="3">%s</xliff:g> touch and hold.</string>
<!-- Description of the scrolling action in NumberPicker. [CHAR LIMIT=NONE] -->
<string name="number_picker_increment_scroll_action">Slide up to increment and down to decrement.</string>
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index a51f3f946e76..288b8b2a1f57 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -521,10 +521,10 @@ please see styles_device_defaults.xml.
</style>
<style name="Widget.NumberPicker">
+ <item name="android:internalLayout">@android:layout/number_picker</item>
<item name="android:orientation">vertical</item>
<item name="android:fadingEdge">vertical</item>
<item name="android:fadingEdgeLength">50dip</item>
- <item name="android:flingable">false</item>
</style>
<style name="Widget.TimePicker">
@@ -536,25 +536,6 @@ please see styles_device_defaults.xml.
<item name="android:calendarViewShown">false</item>
</style>
- <style name="Widget.ImageButton.NumberPickerUpButton">
- <item name="android:background">@android:drawable/numberpicker_up_btn</item>
- <item name="android:paddingTop">22dip</item>
- <item name="android:paddingBottom">22dip</item>
- </style>
-
- <style name="Widget.ImageButton.NumberPickerDownButton">
- <item name="android:background">@android:drawable/numberpicker_down_btn</item>
- <item name="android:paddingTop">22dip</item>
- <item name="android:paddingBottom">22dip</item>
- </style>
-
- <style name="Widget.EditText.NumberPickerInputText">
- <item name="android:textAppearance">@style/TextAppearance.Large.Inverse.NumberPickerInputText</item>
- <item name="android:gravity">center</item>
- <item name="android:singleLine">true</item>
- <item name="android:background">@drawable/numberpicker_input</item>
- </style>
-
<style name="Widget.AutoCompleteTextView" parent="Widget.EditText">
<item name="android:completionHintView">@android:layout/simple_dropdown_hint</item>
<item name="android:completionThreshold">2</item>
@@ -1656,12 +1637,14 @@ please see styles_device_defaults.xml.
</style>
<style name="Widget.Holo.NumberPicker" parent="Widget.NumberPicker">
+ <item name="android:internalLayout">@android:layout/number_picker_with_selector_wheel</item>
<item name="android:solidColor">@android:color/transparent</item>
- <item name="android:flingable">true</item>
<item name="android:selectionDivider">@android:drawable/numberpicker_selection_divider</item>
<item name="android:selectionDividerHeight">2dip</item>
+ <item name="android:selectionDividersDistance">48dip</item>
<item name="android:internalMinWidth">48dip</item>
<item name="android:internalMaxHeight">200dip</item>
+ <item name="android:minFlingDistance">150dip</item>
</style>
<style name="Widget.Holo.TimePicker" parent="Widget.TimePicker">
@@ -1673,31 +1656,6 @@ please see styles_device_defaults.xml.
<item name="android:calendarViewShown">true</item>
</style>
- <style name="Widget.Holo.ImageButton.NumberPickerUpButton">
- <item name="android:background">@null</item>
- <item name="android:src">@android:drawable/numberpicker_up_btn_holo_dark</item>
- <item name="android:paddingTop">16dip</item>
- <item name="android:paddingBottom">22dip</item>
- </style>
-
- <style name="Widget.Holo.ImageButton.NumberPickerDownButton">
- <item name="android:background">@null</item>
- <item name="android:src">@android:drawable/numberpicker_down_btn_holo_dark</item>
- <item name="android:paddingTop">22dip</item>
- <item name="android:paddingBottom">16dip</item>
- </style>
-
- <style name="Widget.Holo.EditText.NumberPickerInputText">
- <item name="android:paddingTop">13sp</item>
- <item name="android:paddingBottom">13sp</item>
- <item name="android:paddingLeft">2sp</item>
- <item name="android:paddingRight">2sp</item>
- <item name="android:gravity">center</item>
- <item name="android:singleLine">true</item>
- <item name="android:textSize">18sp</item>
- <item name="android:background">@null</item>
- </style>
-
<style name="Widget.Holo.ActivityChooserView" parent="Widget.ActivityChooserView">
</style>
@@ -2109,17 +2067,6 @@ please see styles_device_defaults.xml.
<style name="Widget.Holo.Light.DatePicker" parent="Widget.Holo.DatePicker">
</style>
- <style name="Widget.Holo.Light.ImageButton.NumberPickerUpButton" parent="Widget.Holo.ImageButton.NumberPickerUpButton">
- <item name="android:src">@android:drawable/numberpicker_up_btn_holo_light</item>
- </style>
-
- <style name="Widget.Holo.Light.ImageButton.NumberPickerDownButton" parent="Widget.Holo.ImageButton.NumberPickerDownButton">
- <item name="android:src">@android:drawable/numberpicker_down_btn_holo_light</item>
- </style>
-
- <style name="Widget.Holo.Light.EditText.NumberPickerInputText" parent="Widget.Holo.EditText.NumberPickerInputText">
- </style>
-
<style name="Widget.Holo.Light.ActivityChooserView" parent="Widget.Holo.ActivityChooserView">
<item name="android:background">@android:drawable/ab_share_pack_holo_light</item>
</style>
diff --git a/core/res/res/values/styles_device_defaults.xml b/core/res/res/values/styles_device_defaults.xml
index 64198728515f..330e68c0e462 100644
--- a/core/res/res/values/styles_device_defaults.xml
+++ b/core/res/res/values/styles_device_defaults.xml
@@ -200,9 +200,6 @@ easier.
<style name="Widget.DeviceDefault.CompoundButton.Switch" parent="Widget.Holo.CompoundButton.Switch">
</style>
- <style name="Widget.DeviceDefault.EditText.NumberPickerInputText" parent="Widget.Holo.EditText.NumberPickerInputText">
-
- </style>
<style name="Widget.DeviceDefault.ExpandableListView.White" parent="Widget.Holo.ExpandableListView.White">
</style>
@@ -212,12 +209,6 @@ easier.
<style name="Widget.DeviceDefault.GestureOverlayView" parent="Widget.Holo.GestureOverlayView">
</style>
- <style name="Widget.DeviceDefault.ImageButton.NumberPickerDownButton" parent="Widget.Holo.ImageButton.NumberPickerDownButton">
-
- </style>
- <style name="Widget.DeviceDefault.ImageButton.NumberPickerUpButton" parent="Widget.Holo.ImageButton.NumberPickerUpButton">
-
- </style>
<style name="Widget.DeviceDefault.ImageWell" parent="Widget.Holo.ImageWell">
</style>
@@ -465,9 +456,6 @@ easier.
<style name="Widget.DeviceDefault.Light.DatePicker" parent="Widget.Holo.Light.DatePicker">
</style>
- <style name="Widget.DeviceDefault.Light.EditText.NumberPickerInputText" parent="Widget.Holo.Light.EditText.NumberPickerInputText">
-
- </style>
<style name="Widget.DeviceDefault.Light.ExpandableListView.White" parent="Widget.Holo.Light.ExpandableListView.White">
</style>
@@ -477,12 +465,6 @@ easier.
<style name="Widget.DeviceDefault.Light.GestureOverlayView" parent="Widget.Holo.Light.GestureOverlayView">
</style>
- <style name="Widget.DeviceDefault.Light.ImageButton.NumberPickerDownButton" parent="Widget.Holo.Light.ImageButton.NumberPickerDownButton">
-
- </style>
- <style name="Widget.DeviceDefault.Light.ImageButton.NumberPickerUpButton" parent="Widget.Holo.Light.ImageButton.NumberPickerUpButton">
-
- </style>
<style name="Widget.DeviceDefault.Light.ImageWell" parent="Widget.Holo.Light.ImageWell">
</style>
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index 55438b221267..7e06e24d9513 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -345,10 +345,7 @@ please see themes_device_defaults.xml.
<!-- PreferenceFrameLayout attributes -->
<item name="preferenceFrameLayoutStyle">@android:style/Widget.PreferenceFrameLayout</item>
- <!-- NumberPicker styles-->
- <item name="numberPickerUpButtonStyle">@style/Widget.ImageButton.NumberPickerUpButton</item>
- <item name="numberPickerDownButtonStyle">@style/Widget.ImageButton.NumberPickerDownButton</item>
- <item name="numberPickerInputTextStyle">@style/Widget.EditText.NumberPickerInputText</item>
+ <!-- NumberPicker style-->
<item name="numberPickerStyle">@style/Widget.NumberPicker</item>
<!-- CalendarView style-->
@@ -1141,10 +1138,7 @@ please see themes_device_defaults.xml.
<!-- PreferenceFrameLayout attributes -->
<item name="preferenceFrameLayoutStyle">@android:style/Widget.Holo.PreferenceFrameLayout</item>
- <!-- NumberPicker styles-->
- <item name="numberPickerUpButtonStyle">@style/Widget.Holo.ImageButton.NumberPickerUpButton</item>
- <item name="numberPickerDownButtonStyle">@style/Widget.Holo.ImageButton.NumberPickerDownButton</item>
- <item name="numberPickerInputTextStyle">@style/Widget.Holo.EditText.NumberPickerInputText</item>
+ <!-- NumberPicker style-->
<item name="numberPickerStyle">@style/Widget.Holo.NumberPicker</item>
<!-- CalendarView style-->
@@ -1443,10 +1437,7 @@ please see themes_device_defaults.xml.
<item name="searchDialogTheme">@style/Theme.Holo.Light.SearchBar</item>
- <!-- NumberPicker attributes and styles-->
- <item name="numberPickerUpButtonStyle">@style/Widget.Holo.Light.ImageButton.NumberPickerUpButton</item>
- <item name="numberPickerDownButtonStyle">@style/Widget.Holo.Light.ImageButton.NumberPickerDownButton</item>
- <item name="numberPickerInputTextStyle">@style/Widget.Holo.Light.EditText.NumberPickerInputText</item>
+ <!-- NumberPicker style-->
<item name="numberPickerStyle">@style/Widget.Holo.Light.NumberPicker</item>
<!-- CalendarView style-->
diff --git a/core/res/res/values/themes_device_defaults.xml b/core/res/res/values/themes_device_defaults.xml
index 7fd981c30aa6..ae9255a3a907 100644
--- a/core/res/res/values/themes_device_defaults.xml
+++ b/core/res/res/values/themes_device_defaults.xml
@@ -179,10 +179,7 @@ easier.
<!-- PreferenceFrameLayout attributes -->
<item name="preferenceFrameLayoutStyle">@android:style/Widget.DeviceDefault.PreferenceFrameLayout</item>
- <!-- NumberPicker styles-->
- <item name="numberPickerUpButtonStyle">@style/Widget.DeviceDefault.ImageButton.NumberPickerUpButton</item>
- <item name="numberPickerDownButtonStyle">@style/Widget.DeviceDefault.ImageButton.NumberPickerDownButton</item>
- <item name="numberPickerInputTextStyle">@style/Widget.DeviceDefault.EditText.NumberPickerInputText</item>
+ <!-- NumberPicker style-->
<item name="numberPickerStyle">@style/Widget.DeviceDefault.NumberPicker</item>
<!-- CalendarView style-->
@@ -329,10 +326,7 @@ easier.
<item name="searchDialogTheme">@style/Theme.DeviceDefault.Light.SearchBar</item>
- <!-- NumberPicker attributes and styles-->
- <item name="numberPickerUpButtonStyle">@style/Widget.DeviceDefault.Light.ImageButton.NumberPickerUpButton</item>
- <item name="numberPickerDownButtonStyle">@style/Widget.DeviceDefault.Light.ImageButton.NumberPickerDownButton</item>
- <item name="numberPickerInputTextStyle">@style/Widget.DeviceDefault.Light.EditText.NumberPickerInputText</item>
+ <!-- NumberPicker style -->
<item name="numberPickerStyle">@style/Widget.DeviceDefault.Light.NumberPicker</item>
<!-- CalendarView style-->
diff --git a/test-runner/src/android/test/BandwidthTest.java b/core/tests/utillib/src/android/test/BandwidthTest.java
index e02ae00c3df8..6cff0ff98210 100644
--- a/test-runner/src/android/test/BandwidthTest.java
+++ b/core/tests/utillib/src/android/test/BandwidthTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 The Android Open Source Project
+ * Copyright (C) 2012 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,8 +24,6 @@ import java.lang.annotation.RetentionPolicy;
* annotation is present, the test method is profiled for bandwidth metrics and the results
* written through instrumentation output. It can also be used on the class itself,
* which is equivalent to tagging all test methods with this annotation.
- *
- * {@hide} Pending approval for public API.
*/
@Retention(RetentionPolicy.RUNTIME)
public @interface BandwidthTest {
diff --git a/core/tests/utillib/src/android/test/BandwidthTestCase.java b/core/tests/utillib/src/android/test/BandwidthTestCase.java
new file mode 100644
index 000000000000..4f95f77c5581
--- /dev/null
+++ b/core/tests/utillib/src/android/test/BandwidthTestCase.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.test;
+
+import android.net.NetworkStats;
+import android.net.TrafficStats;
+import android.os.Bundle;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+/**
+ * A bandwidth test case that collects bandwidth statistics for tests that are
+ * annotated with {@link BandwidthTest} otherwise the test is executed
+ * as an {@link InstrumentationTestCase}
+ */
+public class BandwidthTestCase extends InstrumentationTestCase {
+ private static final String REPORT_KEY_PACKETS_SENT = "txPackets";
+ private static final String REPORT_KEY_PACKETS_RECEIVED = "rxPackets";
+ private static final String REPORT_KEY_BYTES_SENT = "txBytes";
+ private static final String REPORT_KEY_BYTES_RECEIVED = "rxBytes";
+ private static final String REPORT_KEY_OPERATIONS = "operations";
+
+ @Override
+ protected void runTest() throws Throwable {
+ //This is a copy of {@link InstrumentationTestCase#runTest} with
+ //added logic to handle bandwidth measurements
+ String fName = getName();
+ assertNotNull(fName);
+ Method method = null;
+ Class testClass = null;
+ try {
+ // use getMethod to get all public inherited
+ // methods. getDeclaredMethods returns all
+ // methods of this class but excludes the
+ // inherited ones.
+ testClass = getClass();
+ method = testClass.getMethod(fName, (Class[]) null);
+ } catch (NoSuchMethodException e) {
+ fail("Method \""+fName+"\" not found");
+ }
+
+ if (!Modifier.isPublic(method.getModifiers())) {
+ fail("Method \""+fName+"\" should be public");
+ }
+
+ int runCount = 1;
+ boolean isRepetitive = false;
+ if (method.isAnnotationPresent(FlakyTest.class)) {
+ runCount = method.getAnnotation(FlakyTest.class).tolerance();
+ } else if (method.isAnnotationPresent(RepetitiveTest.class)) {
+ runCount = method.getAnnotation(RepetitiveTest.class).numIterations();
+ isRepetitive = true;
+ }
+
+ if (method.isAnnotationPresent(UiThreadTest.class)) {
+ final int tolerance = runCount;
+ final boolean repetitive = isRepetitive;
+ final Method testMethod = method;
+ final Throwable[] exceptions = new Throwable[1];
+ getInstrumentation().runOnMainSync(new Runnable() {
+ public void run() {
+ try {
+ runMethod(testMethod, tolerance, repetitive);
+ } catch (Throwable throwable) {
+ exceptions[0] = throwable;
+ }
+ }
+ });
+ if (exceptions[0] != null) {
+ throw exceptions[0];
+ }
+ } else if (method.isAnnotationPresent(BandwidthTest.class) ||
+ testClass.isAnnotationPresent(BandwidthTest.class)) {
+ TrafficStats.startDataProfiling(null);
+ runMethod(method, 1, false);
+ NetworkStats stats = TrafficStats.stopDataProfiling(null);
+ NetworkStats.Entry entry = stats.getTotal(null);
+ getInstrumentation().sendStatus(2, getBandwidthStats(entry));
+ } else {
+ runMethod(method, runCount, isRepetitive);
+ }
+ }
+
+ private void runMethod(Method runMethod, int tolerance, boolean isRepetitive) throws Throwable {
+ //This is a copy of {@link InstrumentationTestCase#runMethod}
+ Throwable exception = null;
+
+ int runCount = 0;
+ do {
+ try {
+ runMethod.invoke(this, (Object[]) null);
+ exception = null;
+ } catch (InvocationTargetException e) {
+ e.fillInStackTrace();
+ exception = e.getTargetException();
+ } catch (IllegalAccessException e) {
+ e.fillInStackTrace();
+ exception = e;
+ } finally {
+ runCount++;
+ // Report current iteration number, if test is repetitive
+ if (isRepetitive) {
+ Bundle iterations = new Bundle();
+ iterations.putInt("currentiterations", runCount);
+ getInstrumentation().sendStatus(2, iterations);
+ }
+ }
+ } while ((runCount < tolerance) && (isRepetitive || exception != null));
+
+ if (exception != null) {
+ throw exception;
+ }
+ }
+
+ private Bundle getBandwidthStats(NetworkStats.Entry entry){
+ Bundle bundle = new Bundle();
+ bundle.putLong(REPORT_KEY_BYTES_RECEIVED, entry.rxBytes);
+ bundle.putLong(REPORT_KEY_BYTES_SENT, entry.txBytes);
+ bundle.putLong(REPORT_KEY_PACKETS_RECEIVED, entry.rxPackets);
+ bundle.putLong(REPORT_KEY_PACKETS_SENT, entry.txPackets);
+ bundle.putLong(REPORT_KEY_OPERATIONS, entry.operations);
+ return bundle;
+ }
+}
+
diff --git a/docs/html/guide/developing/debugging/ddms.jd b/docs/html/guide/developing/debugging/ddms.jd
index 4398ec9d8941..80b1e476e418 100644
--- a/docs/html/guide/developing/debugging/ddms.jd
+++ b/docs/html/guide/developing/debugging/ddms.jd
@@ -11,7 +11,19 @@ parent.link=index.html
<li><a href="#running">Running DDMS</a></li>
<li><a href="#how-ddms-works">How DDMS Interacts with a Debugger</a></li>
- <li><a href="#using-ddms">Using DDMS</a></li>
+ <li><a href="#using-ddms">Using DDMS</a>
+ <ol>
+ <li><a href="#heap">Viewing heap usage for a process</a></li>
+ <li><a href="#alloc">Tracking memory allocation of objects</a></li>
+ <li><a href="#emulator">Working with an emulator or device's file system</a></li>
+ <li><a href="#thread">Examining thread information</a></li>
+ <li><a href="#profiling">Starting method profiling</a></li>
+ <li><a href="#network">Using the Network Traffic tool</a></li>
+ <li><a href="#logcat">Using LogCat</a></li>
+ <li><a href="#ops-location">Emulating phone operations and location</a></li>
+ </ol>
+
+ </li>
</ol>
</div>
</div>
@@ -90,7 +102,7 @@ parent.link=index.html
<a href="#running">Running DDMS</a>.
- <h3>Viewing heap usage for a process</h3>
+ <h3 id="heap">Viewing heap usage for a process</h3>
<p>DDMS allows you to view how much heap memory a process is using. This information is useful in
tracking heap usage at a certain point of time during the execution of your application.</p>
@@ -110,7 +122,7 @@ parent.link=index.html
allocated for a particular memory size in bytes.</li>
</ol>
- <h3>Tracking memory allocation of objects</h3>
+ <h3 id="alloc">Tracking memory allocation of objects</h3>
<p>DDMS provides a feature to track objects that are being allocated to memory and to see which
classes and threads are allocating the objects. This allows you to track, in real time, where
@@ -140,7 +152,7 @@ parent.link=index.html
line number of the code that allocated the object.</li>
</ol>
- <h3>Working with an emulator or device's file system</h3>
+ <h3 id="emulator">Working with an emulator or device's file system</h3>
<p>DDMS provides a File Explorer tab that allows you to view, copy, and delete files on the
device. This feature is useful in examining files that are created by your application or if you
@@ -160,7 +172,7 @@ parent.link=index.html
<!-- Need to elaborate more on where things are stored in the file system,
databases, apks, user info, files that are important to look at -->
- <h3>Examining thread information</h3>
+ <h3 id="thread">Examining thread information</h3>
<p>The Threads tab in DDMS shows you the currently running threads for a selected process.</p>
@@ -204,6 +216,67 @@ parent.link=index.html
Profiling</strong>.</li>
</ol>
+ <h3 id="network">Using the Network Traffic tool</h3>
+
+ <p>In Android 4.0, the DDMS (Dalvik Debug Monitor Server) includes a Detailed
+Network Usage tab that makes it possible to track when your application is
+making network requests. Using this tool, you can monitor how and when your app
+transfers data and optimize the underlying code appropriately. You can also
+distinguish between different traffic types by applying a “tag” to network
+sockets before use.</p>
+
+<p>These tags are shown in a stack area chart in DDMS, as shown in figure 2:</p>
+
+<img src="{@docRoot}images/developing/ddms-network.png" />
+<p class="img-caption"><strong>Figure 2.</strong> Network Usage tab.</p>
+
+<p>By monitoring the frequency of your data transfers, and the amount of data
+transferred during each connection, you can identify areas of your application
+that can be made more battery-efficient. Generally, you should look for
+short spikes that can be delayed, or that should cause a later transfer to be
+pre-empted. </p>
+
+<p>To better identify the cause of transfer spikes, the
+{@link android.net.TrafficStats} API allows you
+to tag the data transfers occurring within a thread using {@link
+android.net.TrafficStats#setThreadStatsTag setThreadStatsTag()}, followed
+by manually tagging (and untagging) individual sockets using {@link
+android.net.TrafficStats#tagSocket tagSocket()} and {@link
+android.net.TrafficStats#untagSocket untagSocket()}. For example:</p>
+
+<pre>TrafficStats.setThreadStatsTag(0xF00D);
+TrafficStats.tagSocket(outputSocket);
+// Transfer data using socket
+TrafficStats.untagSocket(outputSocket);</pre>
+
+<p>Alternatively, the Apache {@link org.apache.http.client.HttpClient} and
+{@link java.net.URLConnection} APIs included in the platform
+automatically tag sockets internally based on the active tag (as
+identified by
+{@link android.net.TrafficStats#getThreadStatsTag getThreadStatsTag()}).
+These APIs correctly tag/untag sockets when recycled through
+keep-alive pools. In the following example,
+{@link android.net.TrafficStats#setThreadStatsTag setThreadStatsTag()}
+sets the active tag to be {@code 0xF00D}.
+There can only be one active tag per thread.
+That is the value that will
+be returned by {@link android.net.TrafficStats#getThreadStatsTag getThreadStatsTag()}
+and thus used by {@link org.apache.http.client.HttpClient}
+ to tag sockets. The {@code finally} statement
+invokes
+{@link android.net.TrafficStats#clearThreadStatsTag clearThreadStatsTag()}
+to clear the tag.</p>
+
+<pre>TrafficStats.setThreadStatsTag(0xF00D);
+ try {
+ // Make network request using HttpClient.execute()
+ } finally {
+ TrafficStats.clearThreadStatsTag();
+}</pre>
+
+<p>Socket tagging is supported in Android 4.0, but real-time stats will only be
+displayed on devices running Android 4.0.3 or higher.</p>
+
<h3 id="logcat">Using LogCat</h3>
<p>LogCat is integrated into DDMS, and outputs the messages that you print out using the {@link android.util.Log}
@@ -230,7 +303,7 @@ parent.link=index.html
with the log tags or with the process id that generated the log message. The add filter,
edit filter, and delete filter buttons let you manage your custom filters.</p>
- <h3>Emulating phone operations and location</h3>
+ <h3 id="ops-location">Emulating phone operations and location</h3>
<p>The Emulator control tab lets you simulate a
phone's voice and data network status. This is useful when you want to test your application's
robustness in differing network environments.</p>
diff --git a/docs/html/images/developing/ddms-network.png b/docs/html/images/developing/ddms-network.png
new file mode 100644
index 000000000000..5aa12905a28f
--- /dev/null
+++ b/docs/html/images/developing/ddms-network.png
Binary files differ
diff --git a/docs/html/sdk/android-4.0.3.jd b/docs/html/sdk/android-4.0.3.jd
index 809c83c6e61d..c8563ac2d69a 100644
--- a/docs/html/sdk/android-4.0.3.jd
+++ b/docs/html/sdk/android-4.0.3.jd
@@ -68,15 +68,16 @@ the Android 4.0.x system components will not be available for download.</p>
<p><a href="#" onclick="return toggleContent(this)">
<img src="{@docRoot}assets/images/triangle-opened.png"
class="toggle-content-img" alt="" />
- Android {@sdkPlatformVersion}, Revision 2</a> <em>(January 2012)</em>
+ Revision 2</a> <em>(January 2012)</em>
</a></p>
<div class="toggle-content-toggleme" style="padding-left:2em;">
-<dl>
-<dt>Maintenance release. SDK Tools r14 or higher is required.
-</dt>
-</dl>
+ <p>Maintenance update. The system version is 4.0.3.</p>
+ <dl>
+ <dt>Dependencies:</dt>
+ <dd>SDK Tools r14 or higher is required.</dd>
+ </dl>
</div>
</div>
@@ -86,15 +87,16 @@ class="toggle-content-img" alt="" />
<p><a href="#" onclick="return toggleContent(this)">
<img src="{@docRoot}assets/images/triangle-closed.png"
class="toggle-content-img" alt="" />
- Android {@sdkPlatformVersion}, Revision 1</a> <em>(December 2011)</em>
+ Revision 1</a> <em>(December 2011)</em>
</a></p>
<div class="toggle-content-toggleme" style="padding-left:2em;">
-<dl>
-<dt>Initial release. SDK Tools r14 or higher is required.
-</dt>
-</dl>
+ <p>Initial release. The system version is 4.0.3.</p>
+ <dl>
+ <dt>Dependencies:</dt>
+ <dd>SDK Tools r14 or higher is required.</dd>
+ </dl>
</div>
</div>
diff --git a/docs/html/sdk/compatibility-library.jd b/docs/html/sdk/compatibility-library.jd
index df715520daa8..30d807ff9300 100644
--- a/docs/html/sdk/compatibility-library.jd
+++ b/docs/html/sdk/compatibility-library.jd
@@ -46,11 +46,40 @@ by the directory name, such as {@code v4/} and {@code v13/}.</p>
<p>The sections below provide notes about successive releases of
the Support Package, as denoted by revision number.</p>
-
<div class="toggle-content open">
<p><a href="#" onclick="return toggleContent(this)">
<img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-content-img" />
+ Support Package, revision 7 (March 2012)
+ </a></p>
+
+ <div class="toggle-content-toggleme" style="padding-left:2em">
+ <dl>
+ <dt>Changes for v4 support library:</dt>
+ <dd>
+ <ul>
+ <li>Added {@link android.support.v4.app.ShareCompat}, which provides helper classes
+for sending and receiving content for social sharing applications, including new metadata for
+attributing shared data to the source app. This class also provides compatible integration with the
+new {@link android.widget.ShareActionProvider} in Android 4.0.</li>
+ <li>Added {@link android.support.v4.app.NavUtils} and {@link
+android.support.v4.app.TaskStackBuilder} to provide support for implementing the
+<a href="{@docRoot}design/index.html">Android Design</a> guidelines for navigation. These
+additions include a way to implement the action bar's <em>Up</em> button across versions.
+For an example implementation of this pattern, see the AppNavigation sample in
+({@code <em>&lt;sdk&gt;</em>/samples/<em>&lt;platform&gt;</em>/AppNavigation}).</li>
+ <li>Added {@link android.support.v4.app.NotificationCompat.Builder} to provide a
+compatibility implementation of Android 3.0's {@link android.app.Notification.Builder} helper class
+for creating standardized system notifications.</li>
+ </ul>
+ </dd>
+ </dl>
+ </div>
+
+<div class="toggle-content closed">
+
+ <p><a href="#" onclick="return toggleContent(this)">
+ <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-content-img" />
Support Package, revision 6 (December 2011)
</a></p>
diff --git a/docs/html/sdk/eclipse-adt.jd b/docs/html/sdk/eclipse-adt.jd
index 30825eec060c..c8bf12df1704 100644
--- a/docs/html/sdk/eclipse-adt.jd
+++ b/docs/html/sdk/eclipse-adt.jd
@@ -1,8 +1,8 @@
page.title=ADT Plugin for Eclipse
-adt.zip.version=16.0.1
-adt.zip.download=ADT-16.0.1.zip
-adt.zip.bytes=7000078
-adt.zip.checksum=03a2a23650ddac128c8b9e8aaf0aa433
+adt.zip.version=17.0.0
+adt.zip.download=ADT-17.0.0.zip
+adt.zip.bytes=12836115
+adt.zip.checksum=ecb12c07e534997cd32c66d57f21b770
@jd:body
@@ -108,11 +108,109 @@ padding: .25em 1em;
}
</style>
-
<div class="toggleable opened">
<a href="#" onclick="return toggleDiv(this)">
<img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-img" height="9px"
width="9px" />
+ADT 17.0.0</a> <em>(March 2012)</em>
+ <div class="toggleme">
+<dl>
+ <dt>Dependencies:</dt>
+
+ <dd>
+ <ul>
+ <li>Java 1.6 or higher is required for ADT 17.0.0.</li>
+ <li>Eclipse Helios (Version 3.6.2) or higher is required for ADT 17.0.0.</li>
+ <li>ADT 17.0.0 is designed for use with <a href="{@docRoot}sdk/tools-notes.html">SDK Tools
+ r17</a>. If you haven't already installed SDK Tools r17 into your SDK, use the Android SDK
+ Manager to do so.</li>
+ </ul>
+ </dd>
+
+ <dt>General improvements:</dt>
+ <dd>
+ <ul>
+ <li>New build features
+ <ul>
+ <li>Added feature to automatically setup JAR dependencies. Any {@code .jar} files in the
+ {@code /libs} folder are added to the build configuration (similar to how the Ant build
+ system works). Also, {@code .jar} files needed by library projects are also automatically
+ added to projects that depend on those library projects.</li>
+ <li>Added a feature that allows you to run some code only in debug mode. Builds now
+generate a class called {@code BuildConfig} containing a {@code DEBUG} constant that is
+automatically set according to your build type. You can check the ({@code BuildConfig.DEBUG})
+constant in your code to run debug-only functions.</li>
+ <li>Added support for custom views with custom attributes in libraries. Layouts using
+custom attributes must use the namespace URI {@code http://schemas.android.com/apk/res-auto} instead
+of the URI that includes the app package name. This URI is replaced with the app specific one at
+build time.</li>
+ </ul>
+ </li>
+ <li>Improved Lint features. See the <a href="{@docRoot}sdk/tools-notes.html">SDK Tools r17</a>
+release notes.</li>
+ <li>Improved the Lint user interface
+ <ul>
+ <li>Added <strong>Run Lint</strong> toolbar action with a dropdown menu for selecting
+specific (or all) projects, clearing results and other actions.</li>
+ <li>Updated the results window to be organized as a tree rather than a flat list. Each
+issue type has a single top level item, which makes it easier to quickly scan through the reported
+issues and narrow down to the issues you are most interested in.</li>
+ <li>Added many new toolbar actions to the results window, including expand/collapse,
+ignore in file, ignore in project, ignore everywhere, show options, and configure columns.</li>
+ <li>Added new column options for the <strong>Lint Warnings</strong> tab, such as
+category, priority, project, file and line. The column selection (as well as the column sizes) are
+persisted. You can also click on columns to sort by those values.</li>
+ <li>Added Enable All and Disable All buttons to the Lint Options dialog, and a search
+filter textbox to filter by issue id, summary and severity.</li>
+ </ul>
+ </li>
+ <li>Added Quick Outline for XML editors (Ctrl-O, Command-O). This feature shows the structure
+of the current file including icons and ids, lets you filter and quickly jump to specific ids.</li>
+ <li>Updated the resource chooser to shows the resolved value for resources. For example,
+when selecting {@code @string/hello} the chooser displays a resolved value such as "Hello World").
+The resource chooser also now allows you to edit the chosen value directly.</li>
+ <li>Updated Layout Editor so that it does not assign default ids to layouts, includes and
+merge tags. This behavior tended to pollute the namespace with a lot of unused resources since
+layouts are not usually manipulated via code, or referenced from XML. (The RelativeLayout editor
+automatically assigns ids to views without ids when pointing to them.)</li>
+ <li>Added ability to export screenshots from the Layout Editor</li>
+ </ul>
+ </dd>
+
+ <dt>Bug fixes:</dt>
+ <dd>
+ <ul>
+ <li>Fixed problem using Layout Editor with {@link android.widget.SlidingDrawer} which could
+ not be dragged into the layout on some platforms.</li>
+ <li>Fixed preview rendering for {@link android.widget.SlidingDrawer} and
+ {@link android.widget.TabHost}.
+ (<a href="http://code.google.com/p/android/issues/detail?id=23022">Issue 23022</a>).</li>
+ <li>Fixed issues that could prevent layout rendering due to unresolvable resources.
+ (<a href="http://code.google.com/p/android/issues/detail?id=21046">Issue 21046</a>,
+ <a href="http://code.google.com/p/android/issues/detail?id=21051">Issue 21051</a>)</li>
+ <li>Fixed a bug in resource chooser which made some types of framework resources impossible to
+select. (<a href="http://code.google.com/p/android/issues/detail?id=20589">Issue 20589</a>)</li>
+ <li>Fixed a bug in the formatter where a certain whitespace pattern could result in a
+ non-space character getting deleted.
+ (<a href="http://code.google.com/p/android/issues/detail?id=23940">Issue 23940</a>)</li>
+ <li>Fixed a locale bug affecting Turkish locales in particular.
+ (<a href="http://code.google.com/p/android/issues/detail?id=23747">Issue 23747</a>)</li>
+ <li>Fixed issue where dex complains about duplicate classes in cases where a Library
+ Project depends on the same jar files or Java-only projects.</li>
+ <li>Fixed issue where test projects had to independently reference the library projects used
+ by an app project. Now referencing only the app project is enough.</li>
+ </ul>
+ </dd>
+
+</dl>
+
+</div>
+</div>
+
+<div class="toggleable closed">
+ <a href="#" onclick="return toggleDiv(this)">
+ <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-img" height="9px"
+width="9px" />
ADT 16.0.1</a> <em>(December 2011)</em>
<div class="toggleme">
<dl>
@@ -182,11 +280,11 @@ ADT 15.0.1</a> <em>(November 2011)</em>
<div class="toggleme">
<dl>
<dt>Dependencies:</dt>
-
+
<dd>ADT 15.0.1 is designed for use with <a href="{@docRoot}sdk/tools-notes.html">SDK Tools r15</a>.
If you haven't already installed SDK Tools r15 into your SDK, use the Android SDK Manager to
do so.</dd>
-
+
<dt>Bug fixes:</dt>
<dd>
<ul>
diff --git a/docs/html/sdk/index.jd b/docs/html/sdk/index.jd
index 5cf05e0ec1bc..c09b3c23ef3e 100644
--- a/docs/html/sdk/index.jd
+++ b/docs/html/sdk/index.jd
@@ -2,21 +2,21 @@ page.title=Android SDK
page.metaDescription=Download the official Android SDK to develop apps for Android-powered devices.
sdk.redirect=0
-sdk.win_installer=installer_r16-windows.exe
-sdk.win_installer_bytes=29561554
-sdk.win_installer_checksum=3521dda4904886b05980590f83cf3469
+sdk.win_installer=installer_r17-windows.exe
+sdk.win_installer_bytes=37410775
+sdk.win_installer_checksum=5afaf6511ebaa52bd6d1dba4afc61e41
-sdk.win_download=android-sdk_r16-windows.zip
-sdk.win_bytes=29562413
-sdk.win_checksum=6b926d0c0a871f1a946e65259984701a
+sdk.win_download=android-sdk_r17-windows.zip
+sdk.win_bytes=37417953
+sdk.win_checksum=3af1baeb39707e54df068e939aea5a79
-sdk.mac_download=android-sdk_r16-macosx.zip
-sdk.mac_bytes=26158334
-sdk.mac_checksum=d1dc2b6f13eed5e3ce5cf26c4e4c47aa
+sdk.mac_download=android-sdk_r17-macosx.zip
+sdk.mac_bytes=33867836
+sdk.mac_checksum=52639aae036b7c2e47cf291696b23236
-sdk.linux_download=android-sdk_r16-linux.tgz
-sdk.linux_bytes=22048174
-sdk.linux_checksum=3ba457f731d51da3741c29c8830a4583
+sdk.linux_download=android-sdk_r17-linux.tgz
+sdk.linux_bytes=29706368
+sdk.linux_checksum=14e99dfa8eb1a8fadd2f3557322245c4
@jd:body
diff --git a/docs/html/sdk/requirements.jd b/docs/html/sdk/requirements.jd
index c970f6c9c0be..c76e8c8b82a3 100644
--- a/docs/html/sdk/requirements.jd
+++ b/docs/html/sdk/requirements.jd
@@ -24,7 +24,7 @@ Android applications using the Android SDK. </p>
<h4 style="margin-top:.25em"><em>Eclipse IDE</em></h4>
<ul>
- <li>Eclipse 3.6 (Helios) or greater
+ <li>Eclipse 3.6.2 (Helios) or greater
<p class="note"><strong>Note:</strong> Eclipse 3.5 (Galileo) is no longer
supported with the latest version of ADT.</p></li>
<li>Eclipse <a href="http://www.eclipse.org/jdt">JDT</a> plugin (included
@@ -41,8 +41,8 @@ packages: </p>
<li>Eclipse IDE for Java EE Developers</li>
</ul>
</li>
- <li><a href="http://www.oracle.com/technetwork/java/javase/downloads/index.html">JDK 5 or JDK
-6</a> (JRE alone is not sufficient)</li>
+ <li><a href="http://www.oracle.com/technetwork/java/javase/downloads/index.html">JDK 6</a>
+ (JRE alone is not sufficient)</li>
<li><a href="eclipse-adt.html">Android Development Tools plugin</a>
(recommended)</li>
<li><strong>Not</strong> compatible with Gnu Compiler for Java (gcj)</li>
@@ -51,8 +51,8 @@ packages: </p>
<h4><em>Other development environments or IDEs</em></h4>
<ul>
- <li><a href="http://www.oracle.com/technetwork/java/javase/downloads/index.html">JDK 5 or JDK
-6</a> (JRE alone is not sufficient)</li>
+ <li><a href="http://www.oracle.com/technetwork/java/javase/downloads/index.html">JDK 6</a>
+ (JRE alone is not sufficient)</li>
<li><a href="http://ant.apache.org/">Apache Ant</a> 1.8 or later</li>
<li><strong>Not</strong> compatible with Gnu Compiler for Java (gcj)</li>
</ul>
diff --git a/docs/html/sdk/sdk_toc.cs b/docs/html/sdk/sdk_toc.cs
index f7541f7167e5..5a5517c5ea1d 100644
--- a/docs/html/sdk/sdk_toc.cs
+++ b/docs/html/sdk/sdk_toc.cs
@@ -81,7 +81,8 @@ class="new">new!</span></li>
<div><a href="<?cs var:toroot ?>sdk/android-4.0-highlights.html">
<span class="en">Android 4.0.x Platform</span></a> <span class="new">new!</span></div>
<ul>
- <li><a href="<?cs var:toroot ?>sdk/android-4.0.3.html">Android 4.0.3 Platform</a> <span class="new">new!</span></li>
+ <li><a href="<?cs var:toroot ?>sdk/android-4.0.3.html">Android 4.0.3 Platform</a>
+ <span class="new">new!</span></li>
<li><a href="<?cs var:toroot ?>sdk/android-4.0.html">Android 4.0 Platform</a> </li>
</ul>
</li>
@@ -152,10 +153,10 @@ class="new">new!</span></li>
</li>
</ul>
<ul>
- <li><a href="<?cs var:toroot ?>sdk/tools-notes.html">SDK Tools, r16</a> <span
+ <li><a href="<?cs var:toroot ?>sdk/tools-notes.html">SDK Tools, r17</a> <span
class="new">new!</span></li>
<li><a href="<?cs var:toroot ?>sdk/win-usb.html">Google USB Driver, r4</a></li>
- <li><a href="<?cs var:toroot ?>sdk/compatibility-library.html">Support Package, r6</a>
+ <li><a href="<?cs var:toroot ?>sdk/compatibility-library.html">Support Package, r7</a>
<span class="new">new!</span></li>
</ul>
</li>
@@ -171,7 +172,7 @@ class="new">new!</span></li>
<span style="display:none" class="zh-TW"></span>
</span>
<ul>
- <li><a href="<?cs var:toroot ?>sdk/eclipse-adt.html">ADT 16.0.1
+ <li><a href="<?cs var:toroot ?>sdk/eclipse-adt.html">ADT 17.0.0
<span style="display:none" class="de"></span>
<span style="display:none" class="es"></span>
<span style="display:none" class="fr"></span>
diff --git a/docs/html/sdk/tools-notes.jd b/docs/html/sdk/tools-notes.jd
index 91bcb7d2c33e..bbbca81cd719 100644
--- a/docs/html/sdk/tools-notes.jd
+++ b/docs/html/sdk/tools-notes.jd
@@ -64,11 +64,112 @@ padding: .25em 1em;
}
</style>
-
<div class="toggleable opened">
<a href="#" onclick="return toggleDiv(this)">
<img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-img" height="9px"
width="9px" />
+ SDK Tools, Revision 17</a> <em>(March 2012)</em>
+
+ <div class="toggleme">
+ <p class="caution"><strong>Important:</strong> To download the new Android
+ 4.0 system components from the Android SDK Manager, you must first update the
+ SDK tools to revision 14 or later and restart the Android SDK Manager. If you do not,
+ the Android 4.0 system components will not be available for download.</p>
+
+ <dl>
+ <dt>Dependencies:</dt>
+ <dd>
+ <ul>
+ <li>Android SDK Platform-tools revision 9 or later.</li>
+ <li>If you are developing in Eclipse with ADT, note that the SDK Tools r17 is designed for
+ use with ADT 17.0.0 and later. If you haven't already, we highly recommend updating your
+ <a href="{@docRoot}sdk/eclipse-adt.html">ADT Plugin</a> to 17.0.0.</li>
+ <li>If you are developing outside Eclipse, you must have
+ <a href="http://ant.apache.org/">Apache Ant</a> 1.8 or later.</li>
+ </ul>
+ </dd>
+ <dt>General notes:</dt>
+ <dd>
+ <ul>
+ <li>Emulator
+ <ul>
+ <li>Added support for hardware accelerated graphics rendering. This feature requires an
+API Level 15, Revision 3 or later system image.
+(<a href="{@docRoot}guide/developing/devices/emulator.html#accel-graphics">more info</a>)
+ <p class="note"><strong>Note:</strong> As of the SDK Tools Revision 17 release, the
+API Level 15, Revision 3 system image is not yet available.</p>
+ </li>
+ <li>Added support for running Android x86 system images in virtualization mode on
+Windows and Mac OS X.
+(<a href="{@docRoot}guide/developing/devices/emulator.html#accel-vm">more info</a>)</li>
+ <li>Added experimental support for multi-touch input by enabing the emulator to receive
+ touch input from a USB-tethered physical Android device.
+ (<a href="http://tools.android.com/tips/hardware-emulation">more info</a>)</li>
+ </ul>
+ </li>
+ <li>Added viewing of live detailed network usage of an app in DDMS. (<a
+ href="http://tools.android.com/recent/detailednetworkusageinddms">more info</a>)</li>
+ <li>ProGuard
+ <ul>
+ <li>Updated the bundled ProGuard tool to version 4.7. In addition to many new features,
+this update fixes the {@code Conversion to Dalvik format failed with error 1} error some users have
+experienced.</li>
+ <li>Updated the default {@code proguard.cfg} file with better default flags for
+ Android.</li>
+ <li>Split the ProGuard configuration file has been in half, with project specific flags
+kept in project and the generic Android flags distributed (and updated) with the tools
+themselves.</li>
+ </ul>
+ </li>
+ <li>Build
+ <ul>
+ <li>Added a feature that allows you to run some code only in debug mode. Builds now
+generate a class called {@code BuildConfig} containing a {@code DEBUG} constant that is
+automatically set according to your build type. You can check the ({@code BuildConfig.DEBUG})
+constant in your code to run debug-only functions.</li>
+ <li>Fixed issue when a project and its libraries include the same jar file in their libs
+ folder.</li>
+ <li>Added support for custom views with custom attributes in libraries. Layouts using
+custom attributes must use the namespace URI {@code http://schemas.android.com/apk/res-auto} instead
+of the URI that includes the app package name. This URI is replaced with the app specific one at
+build time.</li>
+ </ul>
+ </li>
+ <li>Lint
+ <ul>
+ <li>Updated Lint to check Android application code. Lint rules which previously
+performed pattern based searches in the application code (such as the unused resource check) have
+been rewritten to use the more accurate Java-style parse trees.</li>
+ <li>Added support for checking library projects. This change means that rules such as
+the unused resource check properly handle resources declared in a library project and referenced in
+a downstream project.</li>
+ <li>Added ability to suppress Lint warnings in Java code with the new
+{@code @SuppressLint} annotation, and in XML files with the new tools: namespace and
+ignore attribute. (<a
+ href="http://tools.android.com/recent/ignoringlintwarnings">more info</a>)</li>
+ <li>New Lint checks:
+ <ul>
+ <li>Added check for Android API calls that require a version of Android higher than
+ the minimum supported version. You can use the new {@code @TargetApi} annotation
+ to suppress warnings when the code is wrapped in a system version condition.
+ (<a href="http://tools.android.com/recent/lintapicheck">more info</a>)</li>
+ <li>Added over 20 new Lint rules, including checks for
+ <a href="http://tools.android.com/recent/lintperformancechecks">performance</a>,
+ XML layouts, manifest and file handling.</li>
+ </ul>
+ </li>
+ </ul>
+ </li>
+ </ul>
+ </dd>
+ </dl>
+ </div>
+</div>
+
+<div class="toggleable closed">
+ <a href="#" onclick="return toggleDiv(this)">
+ <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-img" height="9px"
+ width="9px" />
SDK Tools, Revision 16</a> <em>(December 2011)</em>
<div class="toggleme">
@@ -92,10 +193,10 @@ padding: .25em 1em;
<dt>General notes:</dt>
<dd>
<ul>
- <li>Added Lint tools to detect common errors in Android projects.
+ <li>Added Lint tools to detect common errors in Android projects.
(<a href="http://tools.android.com/recent/lint">more info</a>)</li>
<li>Added sensor emulation support, which allows the emulator to read sensor data from a
- physical Android device.
+ physical Android device.
(<a href="http://tools.android.com/recent/sensoremulation">more info</a>)</li>
<li>Added support for using a webcam to emulate a camera on Mac OS X.</li>
</ul>
diff --git a/graphics/java/android/graphics/BitmapFactory.java b/graphics/java/android/graphics/BitmapFactory.java
index f0d1643703fd..c5705f6b8809 100644
--- a/graphics/java/android/graphics/BitmapFactory.java
+++ b/graphics/java/android/graphics/BitmapFactory.java
@@ -32,6 +32,8 @@ import java.io.InputStream;
* and byte-arrays.
*/
public class BitmapFactory {
+ private static final int DECODE_BUFFER_SIZE = 16 * 1024;
+
public static class Options {
/**
* Create a default Options object, which if left unchanged will give
@@ -469,7 +471,7 @@ public class BitmapFactory {
// we need mark/reset to work properly
if (!is.markSupported()) {
- is = new BufferedInputStream(is, 16 * 1024);
+ is = new BufferedInputStream(is, DECODE_BUFFER_SIZE);
}
// so we can call reset() if a given codec gives up after reading up to
@@ -477,11 +479,30 @@ public class BitmapFactory {
// value should be.
is.mark(1024);
- Bitmap bm;
+ Bitmap bm;
+ boolean finish = true;
if (is instanceof AssetManager.AssetInputStream) {
- bm = nativeDecodeAsset(((AssetManager.AssetInputStream) is).getAssetInt(),
- outPadding, opts);
+ final int asset = ((AssetManager.AssetInputStream) is).getAssetInt();
+
+ if (opts == null || (opts.inScaled && opts.inBitmap == null)) {
+ float scale = 1.0f;
+ int targetDensity = 0;
+ if (opts != null) {
+ final int density = opts.inDensity;
+ targetDensity = opts.inTargetDensity;
+ if (density != 0 && targetDensity != 0) {
+ scale = targetDensity / (float) density;
+ }
+ }
+
+ bm = nativeDecodeAsset(asset, outPadding, opts, true, scale);
+ if (bm != null && targetDensity != 0) bm.setDensity(targetDensity);
+
+ finish = false;
+ } else {
+ bm = nativeDecodeAsset(asset, outPadding, opts);
+ }
} else {
// pass some temp storage down to the native code. 1024 is made up,
// but should be large enough to avoid too many small calls back
@@ -490,13 +511,32 @@ public class BitmapFactory {
byte [] tempStorage = null;
if (opts != null) tempStorage = opts.inTempStorage;
if (tempStorage == null) tempStorage = new byte[16 * 1024];
- bm = nativeDecodeStream(is, tempStorage, outPadding, opts);
+
+ if (opts == null || (opts.inScaled && opts.inBitmap == null)) {
+ float scale = 1.0f;
+ int targetDensity = 0;
+ if (opts != null) {
+ final int density = opts.inDensity;
+ targetDensity = opts.inTargetDensity;
+ if (density != 0 && targetDensity != 0) {
+ scale = targetDensity / (float) density;
+ }
+ }
+
+ bm = nativeDecodeStream(is, tempStorage, outPadding, opts, true, scale);
+ if (bm != null && targetDensity != 0) bm.setDensity(targetDensity);
+
+ finish = false;
+ } else {
+ bm = nativeDecodeStream(is, tempStorage, outPadding, opts);
+ }
}
+
if (bm == null && opts != null && opts.inBitmap != null) {
throw new IllegalArgumentException("Problem decoding into existing bitmap");
}
- return finishDecode(bm, outPadding, opts);
+ return finish ? finishDecode(bm, outPadding, opts) : bm;
}
private static Bitmap finishDecode(Bitmap bm, Rect outPadding, Options opts) {
@@ -524,12 +564,13 @@ public class BitmapFactory {
bm = Bitmap.createScaledBitmap(oldBitmap, (int) (bm.getWidth() * scale + 0.5f),
(int) (bm.getHeight() * scale + 0.5f), true);
if (bm != oldBitmap) oldBitmap.recycle();
- }
- if (isNinePatch) {
- if (scale != 1.0f) np = nativeScaleNinePatch(np, scale, outPadding);
- bm.setNinePatchChunk(np);
+ if (isNinePatch) {
+ np = nativeScaleNinePatch(np, scale, outPadding);
+ bm.setNinePatchChunk(np);
+ }
}
+
bm.setDensity(targetDensity);
}
@@ -597,9 +638,13 @@ public class BitmapFactory {
private static native Bitmap nativeDecodeStream(InputStream is, byte[] storage,
Rect padding, Options opts);
+ private static native Bitmap nativeDecodeStream(InputStream is, byte[] storage,
+ Rect padding, Options opts, boolean applyScale, float scale);
private static native Bitmap nativeDecodeFileDescriptor(FileDescriptor fd,
Rect padding, Options opts);
private static native Bitmap nativeDecodeAsset(int asset, Rect padding, Options opts);
+ private static native Bitmap nativeDecodeAsset(int asset, Rect padding, Options opts,
+ boolean applyScale, float scale);
private static native Bitmap nativeDecodeByteArray(byte[] data, int offset,
int length, Options opts);
private static native byte[] nativeScaleNinePatch(byte[] chunk, float scale, Rect pad);
diff --git a/include/common_time/local_clock.h b/include/common_time/local_clock.h
index 845d1c21614d..384c3dec011c 100644
--- a/include/common_time/local_clock.h
+++ b/include/common_time/local_clock.h
@@ -28,7 +28,7 @@ namespace android {
class LocalClock {
public:
- LocalClock();
+ LocalClock();
bool initCheck();
diff --git a/include/media/AudioTrack.h b/include/media/AudioTrack.h
index 552e829b066d..ad27a1e1ca4a 100644
--- a/include/media/AudioTrack.h
+++ b/include/media/AudioTrack.h
@@ -169,7 +169,7 @@ public:
callback_t cbf = 0,
void* user = 0,
int notificationFrames = 0,
- int sessionId = 0);
+ int sessionId = 0);
/* Creates an audio track and registers it with AudioFlinger. With this constructor,
* the PCM data to be rendered by AudioTrack is passed in a shared memory buffer
@@ -215,7 +215,7 @@ public:
int notificationFrames = 0,
const sp<IMemory>& sharedBuffer = 0,
bool threadCanCallJava = false,
- int sessionId = 0);
+ int sessionId = 0);
/* Result of constructing the AudioTrack. This must be checked
@@ -468,6 +468,7 @@ protected:
// body of AudioTrackThread::threadLoop()
bool processAudioBuffer(const sp<AudioTrackThread>& thread);
+
status_t createTrack_l(audio_stream_type_t streamType,
uint32_t sampleRate,
audio_format_t format,
diff --git a/include/media/stagefright/MetaData.h b/include/media/stagefright/MetaData.h
index 8b4b8edd64bc..00b86792f1e6 100644
--- a/include/media/stagefright/MetaData.h
+++ b/include/media/stagefright/MetaData.h
@@ -70,6 +70,8 @@ enum {
kKeyThumbnailTime = 'thbT', // int64_t (usecs)
kKeyTrackID = 'trID',
kKeyIsDRM = 'idrm', // int32_t (bool)
+ kKeyEncoderDelay = 'encd', // int32_t (frames)
+ kKeyEncoderPadding = 'encp', // int32_t (frames)
kKeyAlbum = 'albu', // cstring
kKeyArtist = 'arti', // cstring
diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h
index 4bbb04f36a41..38d0374ca089 100644
--- a/libs/hwui/DisplayListRenderer.h
+++ b/libs/hwui/DisplayListRenderer.h
@@ -51,7 +51,7 @@ namespace uirenderer {
// Set to 1 to enable native processing of View properties. 0 by default. Eventually this
// will go away and we will always use this approach for accelerated apps.
-#define USE_DISPLAY_LIST_PROPERTIES 0
+#define USE_DISPLAY_LIST_PROPERTIES 1
#define TRANSLATION 0x0001
#define ROTATION 0x0002
diff --git a/media/java/android/media/MediaRecorder.java b/media/java/android/media/MediaRecorder.java
index 2fe45ecf978a..2175131d5e28 100644
--- a/media/java/android/media/MediaRecorder.java
+++ b/media/java/android/media/MediaRecorder.java
@@ -124,9 +124,15 @@ public class MediaRecorder
/**
* Sets a Surface to show a preview of recorded media (video). Calls this
* before prepare() to make sure that the desirable preview display is
- * set.
+ * set. If {@link #setCamera(Camera)} is used and the surface has been
+ * already set to the camera, application do not need to call this. If
+ * this is called with non-null surface, the preview surface of the camera
+ * will be replaced by the new surface. If this method is called with null
+ * surface or not called at all, media recorder will not change the preview
+ * surface of the camera.
*
* @param sv the Surface to use for the preview
+ * @see android.hardware.Camera#setPreviewDisplay(android.view.SurfaceHolder)
*/
public void setPreviewDisplay(Surface sv) {
mSurface = sv;
diff --git a/media/jni/Android.mk b/media/jni/Android.mk
index a98275afa0e2..079a284b5c08 100644
--- a/media/jni/Android.mk
+++ b/media/jni/Android.mk
@@ -22,6 +22,7 @@ LOCAL_SHARED_LIBRARIES := \
libutils \
libbinder \
libmedia \
+ libmedia_native \
libskia \
libui \
libcutils \
diff --git a/media/jni/audioeffect/Android.mk b/media/jni/audioeffect/Android.mk
index b5d8b7b21a46..0059bb23abde 100644
--- a/media/jni/audioeffect/Android.mk
+++ b/media/jni/audioeffect/Android.mk
@@ -10,7 +10,8 @@ LOCAL_SHARED_LIBRARIES := \
libutils \
libandroid_runtime \
libnativehelper \
- libmedia
+ libmedia \
+ libmedia_native
LOCAL_C_INCLUDES := \
$(call include-path-for, audio-effects)
diff --git a/media/jni/soundpool/Android.mk b/media/jni/soundpool/Android.mk
index 9ff2e243eabd..98d644921fe6 100644
--- a/media/jni/soundpool/Android.mk
+++ b/media/jni/soundpool/Android.mk
@@ -12,7 +12,8 @@ LOCAL_SHARED_LIBRARIES := \
libbinder \
libandroid_runtime \
libnativehelper \
- libmedia
+ libmedia \
+ libmedia_native
LOCAL_MODULE:= libsoundpool
diff --git a/media/libaah_rtp/Android.mk b/media/libaah_rtp/Android.mk
index 1e87cf0471d6..6c927bae3c07 100644
--- a/media/libaah_rtp/Android.mk
+++ b/media/libaah_rtp/Android.mk
@@ -29,6 +29,7 @@ LOCAL_SHARED_LIBRARIES := \
libcommon_time_client \
libbinder \
libmedia \
+ libmedia_native \
libstagefright \
libstagefright_foundation \
libutils
@@ -37,4 +38,3 @@ LOCAL_LDLIBS := \
-lpthread
include $(BUILD_SHARED_LIBRARY)
-
diff --git a/media/libmedia/Android.mk b/media/libmedia/Android.mk
index 8b009aa2383f..21e8f2995cee 100644
--- a/media/libmedia/Android.mk
+++ b/media/libmedia/Android.mk
@@ -48,7 +48,7 @@ LOCAL_SRC_FILES:= \
LOCAL_SHARED_LIBRARIES := \
libui libcutils libutils libbinder libsonivox libicuuc libexpat \
libcamera_client libstagefright_foundation \
- libgui libdl libaudioutils
+ libgui libdl libaudioutils libmedia_native
LOCAL_WHOLE_STATIC_LIBRARY := libmedia_helper
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index 60143c600f8d..55cd3ad5c341 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -195,6 +195,7 @@ status_t AudioTrack::set(
if (AudioSystem::getOutputSamplingRate(&afSampleRate, streamType) != NO_ERROR) {
return NO_INIT;
}
+
uint32_t afLatency;
if (AudioSystem::getOutputLatency(&afLatency, streamType) != NO_ERROR) {
return NO_INIT;
@@ -204,9 +205,11 @@ status_t AudioTrack::set(
if (streamType == AUDIO_STREAM_DEFAULT) {
streamType = AUDIO_STREAM_MUSIC;
}
+
if (sampleRate == 0) {
sampleRate = afSampleRate;
}
+
// these below should probably come from the audioFlinger too...
if (format == AUDIO_FORMAT_DEFAULT) {
format = AUDIO_FORMAT_PCM_16_BIT;
diff --git a/media/libmediaplayerservice/Android.mk b/media/libmediaplayerservice/Android.mk
index 41bcab07d28f..ba5c7763da53 100644
--- a/media/libmediaplayerservice/Android.mk
+++ b/media/libmediaplayerservice/Android.mk
@@ -23,6 +23,7 @@ LOCAL_SHARED_LIBRARIES := \
libvorbisidec \
libsonivox \
libmedia \
+ libmedia_native \
libcamera_client \
libandroid_runtime \
libstagefright \
diff --git a/media/libstagefright/Android.mk b/media/libstagefright/Android.mk
index 047b4cb6d8e3..77714f3e94b3 100644
--- a/media/libstagefright/Android.mk
+++ b/media/libstagefright/Android.mk
@@ -79,6 +79,7 @@ LOCAL_SHARED_LIBRARIES := \
libicuuc \
liblog \
libmedia \
+ libmedia_native \
libsonivox \
libssl \
libstagefright_omx \
diff --git a/media/libstagefright/CameraSource.cpp b/media/libstagefright/CameraSource.cpp
index 0d67800ad1bd..fd3f89267d07 100755
--- a/media/libstagefright/CameraSource.cpp
+++ b/media/libstagefright/CameraSource.cpp
@@ -515,9 +515,13 @@ status_t CameraSource::initWithCameraAccess(
return err;
}
- // This CHECK is good, since we just passed the lock/unlock
- // check earlier by calling mCamera->setParameters().
- CHECK_EQ((status_t)OK, mCamera->setPreviewDisplay(mSurface));
+ // Set the preview display. Skip this if mSurface is null because
+ // applications may already set a surface to the camera.
+ if (mSurface != NULL) {
+ // This CHECK is good, since we just passed the lock/unlock
+ // check earlier by calling mCamera->setParameters().
+ CHECK_EQ((status_t)OK, mCamera->setPreviewDisplay(mSurface));
+ }
// By default, do not store metadata in video buffers
mIsMetaDataStoredInVideoBuffers = false;
diff --git a/media/libstagefright/MP3Extractor.cpp b/media/libstagefright/MP3Extractor.cpp
index 69209b55b180..6abaf23ba310 100644
--- a/media/libstagefright/MP3Extractor.cpp
+++ b/media/libstagefright/MP3Extractor.cpp
@@ -311,10 +311,18 @@ MP3Extractor::MP3Extractor(
mMeta->setInt32(kKeyBitRate, bitrate * 1000);
mMeta->setInt32(kKeyChannelCount, num_channels);
- mSeeker = XINGSeeker::CreateFromSource(mDataSource, mFirstFramePos);
+ sp<XINGSeeker> seeker = XINGSeeker::CreateFromSource(mDataSource, mFirstFramePos);
- if (mSeeker == NULL) {
+ if (seeker == NULL) {
mSeeker = VBRISeeker::CreateFromSource(mDataSource, post_id3_pos);
+ } else {
+ mSeeker = seeker;
+ int encd = seeker->getEncoderDelay();
+ int encp = seeker->getEncoderPadding();
+ if (encd != 0 || encp != 0) {
+ mMeta->setInt32(kKeyEncoderDelay, encd);
+ mMeta->setInt32(kKeyEncoderPadding, encp);
+ }
}
if (mSeeker != NULL) {
@@ -340,6 +348,37 @@ MP3Extractor::MP3Extractor(
}
mInitCheck = OK;
+
+ // get iTunes-style gapless info if present
+ ID3 id3(mDataSource);
+ if (id3.isValid()) {
+ ID3::Iterator *com = new ID3::Iterator(id3, "COM");
+ if (com->done()) {
+ delete com;
+ com = new ID3::Iterator(id3, "COMM");
+ }
+ while(!com->done()) {
+ String8 commentdesc;
+ String8 commentvalue;
+ com->getString(&commentdesc, &commentvalue);
+ const char * desc = commentdesc.string();
+ const char * value = commentvalue.string();
+
+ // first 3 characters are the language, which we don't care about
+ if(strlen(desc) > 3 && strcmp(desc + 3, "iTunSMPB") == 0) {
+
+ int32_t delay, padding;
+ if (sscanf(value, " %*x %x %x %*x", &delay, &padding) == 2) {
+ mMeta->setInt32(kKeyEncoderDelay, delay);
+ mMeta->setInt32(kKeyEncoderPadding, padding);
+ }
+ break;
+ }
+ com->next();
+ }
+ delete com;
+ com = NULL;
+ }
}
size_t MP3Extractor::countTracks() {
diff --git a/media/libstagefright/XINGSeeker.cpp b/media/libstagefright/XINGSeeker.cpp
index 8c99c76f2d1a..9c91134922e7 100644
--- a/media/libstagefright/XINGSeeker.cpp
+++ b/media/libstagefright/XINGSeeker.cpp
@@ -14,6 +14,9 @@
* limitations under the License.
*/
+#define LOG_TAG "XINGSEEKER"
+#include <utils/Log.h>
+
#include "include/XINGSeeker.h"
#include "include/avc_utils.h"
@@ -24,7 +27,9 @@ namespace android {
XINGSeeker::XINGSeeker()
: mDurationUs(-1),
- mSizeBytes(0) {
+ mSizeBytes(0),
+ mEncoderDelay(0),
+ mEncoderPadding(0) {
}
bool XINGSeeker::getDuration(int64_t *durationUs) {
@@ -76,8 +81,6 @@ sp<XINGSeeker> XINGSeeker::CreateFromSource(
seeker->mFirstFramePos = first_frame_pos;
- ALOGI("xingseeker first frame pos: %lld", first_frame_pos);
-
seeker->mSizeBytes = 0;
seeker->mTOCValid = false;
seeker->mDurationUs = 0;
@@ -111,6 +114,8 @@ sp<XINGSeeker> XINGSeeker::CreateFromSource(
else offset += 9;
}
+ int xingbase = offset;
+
if (source->readAt(offset, &buffer, 4) < 4) { // XING header ID
return NULL;
}
@@ -161,10 +166,31 @@ sp<XINGSeeker> XINGSeeker::CreateFromSource(
// do something with the quality indicator
offset += 4;
}
+
+ if (source->readAt(xingbase + 0xaf - 0x24, &buffer, 1) < 1) { // encoding flags
+ return false;
+ }
+
+ ALOGV("nogap preceding: %s, nogap continued in next: %s",
+ (buffer[0] & 0x80) ? "true" : "false",
+ (buffer[0] & 0x40) ? "true" : "false");
#endif
+ if (source->readAt(xingbase + 0xb1 - 0x24, &buffer, 3) == 3) {
+ seeker->mEncoderDelay = (buffer[0] << 4) + (buffer[1] >> 4);
+ seeker->mEncoderPadding = ((buffer[1] & 0xf) << 8) + buffer[2];
+ }
+
return seeker;
}
+int32_t XINGSeeker::getEncoderDelay() {
+ return mEncoderDelay;
+}
+
+int32_t XINGSeeker::getEncoderPadding() {
+ return mEncoderPadding;
+}
+
} // namespace android
diff --git a/media/libstagefright/id3/ID3.cpp b/media/libstagefright/id3/ID3.cpp
index 2e929265f438..ca140545e0c5 100644
--- a/media/libstagefright/id3/ID3.cpp
+++ b/media/libstagefright/id3/ID3.cpp
@@ -463,40 +463,65 @@ static void convertISO8859ToString8(
tmp = NULL;
}
-void ID3::Iterator::getString(String8 *id) const {
+// the 2nd argument is used to get the data following the \0 in a comment field
+void ID3::Iterator::getString(String8 *id, String8 *comment) const {
+ getstring(id, false);
+ if (comment != NULL) {
+ getstring(comment, true);
+ }
+}
+
+// comment fields (COM/COMM) contain an initial short descriptor, followed by \0,
+// followed by more data. The data following the \0 can be retrieved by setting
+// "otherdata" to true.
+void ID3::Iterator::getstring(String8 *id, bool otherdata) const {
id->setTo("");
- if (mFrameData == NULL) {
+ const uint8_t *frameData = mFrameData;
+ if (frameData == NULL) {
return;
}
+ uint8_t encoding = *frameData;
+
if (mParent.mVersion == ID3_V1 || mParent.mVersion == ID3_V1_1) {
if (mOffset == 126 || mOffset == 127) {
// Special treatment for the track number and genre.
char tmp[16];
- sprintf(tmp, "%d", (int)*mFrameData);
+ sprintf(tmp, "%d", (int)*frameData);
id->setTo(tmp);
return;
}
- convertISO8859ToString8(mFrameData, mFrameSize, id);
+ convertISO8859ToString8(frameData, mFrameSize, id);
return;
}
size_t n = mFrameSize - getHeaderLength() - 1;
+ if (otherdata) {
+ // skip past the encoding, language, and the 0 separator
+ frameData += 4;
+ int32_t i = n - 4;
+ while(--i >= 0 && *++frameData != 0) ;
+ int skipped = (frameData - mFrameData);
+ if (skipped >= n) {
+ return;
+ }
+ n -= skipped;
+ }
- if (*mFrameData == 0x00) {
+ if (encoding == 0x00) {
// ISO 8859-1
- convertISO8859ToString8(mFrameData + 1, n, id);
- } else if (*mFrameData == 0x03) {
+ convertISO8859ToString8(frameData + 1, n, id);
+ } else if (encoding == 0x03) {
// UTF-8
- id->setTo((const char *)(mFrameData + 1), n);
- } else if (*mFrameData == 0x02) {
+ id->setTo((const char *)(frameData + 1), n);
+ } else if (encoding == 0x02) {
// UTF-16 BE, no byte order mark.
// API wants number of characters, not number of bytes...
int len = n / 2;
- const char16_t *framedata = (const char16_t *) (mFrameData + 1);
+ const char16_t *framedata = (const char16_t *) (frameData + 1);
char16_t *framedatacopy = NULL;
#if BYTE_ORDER == LITTLE_ENDIAN
framedatacopy = new char16_t[len];
@@ -513,7 +538,7 @@ void ID3::Iterator::getString(String8 *id) const {
// UCS-2
// API wants number of characters, not number of bytes...
int len = n / 2;
- const char16_t *framedata = (const char16_t *) (mFrameData + 1);
+ const char16_t *framedata = (const char16_t *) (frameData + 1);
char16_t *framedatacopy = NULL;
if (*framedata == 0xfffe) {
// endianness marker doesn't match host endianness, convert
diff --git a/media/libstagefright/include/ID3.h b/media/libstagefright/include/ID3.h
index 98c82a4d6bbe..87140084e6e4 100644
--- a/media/libstagefright/include/ID3.h
+++ b/media/libstagefright/include/ID3.h
@@ -50,7 +50,7 @@ struct ID3 {
bool done() const;
void getID(String8 *id) const;
- void getString(String8 *s) const;
+ void getString(String8 *s, String8 *ss = NULL) const;
const uint8_t *getData(size_t *length) const;
void next();
@@ -65,6 +65,7 @@ struct ID3 {
void findFrame();
size_t getHeaderLength() const;
+ void getstring(String8 *s, bool secondhalf) const;
Iterator(const Iterator &);
Iterator &operator=(const Iterator &);
diff --git a/media/libstagefright/include/XINGSeeker.h b/media/libstagefright/include/XINGSeeker.h
index 85109791d9b8..c4085768b04e 100644
--- a/media/libstagefright/include/XINGSeeker.h
+++ b/media/libstagefright/include/XINGSeeker.h
@@ -31,10 +31,15 @@ struct XINGSeeker : public MP3Seeker {
virtual bool getDuration(int64_t *durationUs);
virtual bool getOffsetForTime(int64_t *timeUs, off64_t *pos);
+ virtual int32_t getEncoderDelay();
+ virtual int32_t getEncoderPadding();
+
private:
int64_t mFirstFramePos;
int64_t mDurationUs;
int32_t mSizeBytes;
+ int32_t mEncoderDelay;
+ int32_t mEncoderPadding;
// TOC entries in XING header. Skip the first one since it's always 0.
unsigned char mTOC[99];
diff --git a/media/libstagefright/timedtext/TimedText3GPPSource.cpp b/media/libstagefright/timedtext/TimedText3GPPSource.cpp
index c423ef063f30..4854121d3618 100644
--- a/media/libstagefright/timedtext/TimedText3GPPSource.cpp
+++ b/media/libstagefright/timedtext/TimedText3GPPSource.cpp
@@ -39,19 +39,21 @@ TimedText3GPPSource::~TimedText3GPPSource() {
}
status_t TimedText3GPPSource::read(
- int64_t *timeUs, Parcel *parcel, const MediaSource::ReadOptions *options) {
+ int64_t *startTimeUs, int64_t *endTimeUs, Parcel *parcel,
+ const MediaSource::ReadOptions *options) {
MediaBuffer *textBuffer = NULL;
status_t err = mSource->read(&textBuffer, options);
if (err != OK) {
return err;
}
CHECK(textBuffer != NULL);
- textBuffer->meta_data()->findInt64(kKeyTime, timeUs);
- // TODO: this is legacy code. when 'timeUs' can be <= 0?
- if (*timeUs > 0) {
- extractAndAppendLocalDescriptions(*timeUs, textBuffer, parcel);
- }
+ textBuffer->meta_data()->findInt64(kKeyTime, startTimeUs);
+ CHECK_GE(*startTimeUs, 0);
+ extractAndAppendLocalDescriptions(*startTimeUs, textBuffer, parcel);
textBuffer->release();
+ // endTimeUs is a dummy parameter for 3gpp timed text format.
+ // Set a negative value to it to mark it is unavailable.
+ *endTimeUs = -1;
return OK;
}
diff --git a/media/libstagefright/timedtext/TimedText3GPPSource.h b/media/libstagefright/timedtext/TimedText3GPPSource.h
index 4ec3d8a13dfb..417094073121 100644
--- a/media/libstagefright/timedtext/TimedText3GPPSource.h
+++ b/media/libstagefright/timedtext/TimedText3GPPSource.h
@@ -33,7 +33,8 @@ public:
virtual status_t start() { return mSource->start(); }
virtual status_t stop() { return mSource->stop(); }
virtual status_t read(
- int64_t *timeUs,
+ int64_t *startTimeUs,
+ int64_t *endTimeUs,
Parcel *parcel,
const MediaSource::ReadOptions *options = NULL);
virtual status_t extractGlobalDescriptions(Parcel *parcel);
diff --git a/media/libstagefright/timedtext/TimedTextPlayer.cpp b/media/libstagefright/timedtext/TimedTextPlayer.cpp
index 8717914f984c..917c62a9ca33 100644
--- a/media/libstagefright/timedtext/TimedTextPlayer.cpp
+++ b/media/libstagefright/timedtext/TimedTextPlayer.cpp
@@ -31,6 +31,7 @@
namespace android {
static const int64_t kAdjustmentProcessingTimeUs = 100000ll;
+static const int64_t kWaitTimeUsToRetryRead = 100000ll;
TimedTextPlayer::TimedTextPlayer(const wp<MediaPlayerBase> &listener)
: mListener(listener),
@@ -139,13 +140,25 @@ void TimedTextPlayer::doSeekAndRead(int64_t seekTimeUs) {
}
void TimedTextPlayer::doRead(MediaSource::ReadOptions* options) {
- int64_t timeUs = 0;
+ int64_t startTimeUs = 0;
+ int64_t endTimeUs = 0;
sp<ParcelEvent> parcelEvent = new ParcelEvent();
- status_t err = mSource->read(&timeUs, &(parcelEvent->parcel), options);
- if (err != OK) {
+ status_t err = mSource->read(&startTimeUs, &endTimeUs,
+ &(parcelEvent->parcel), options);
+ if (err == WOULD_BLOCK) {
+ postTextEventDelayUs(NULL, kWaitTimeUsToRetryRead);
+ return;
+ } else if (err != OK) {
notifyError(err);
- } else {
- postTextEvent(parcelEvent, timeUs);
+ return;
+ }
+
+ postTextEvent(parcelEvent, startTimeUs);
+ if (endTimeUs > 0) {
+ CHECK_GE(endTimeUs, startTimeUs);
+ // send an empty timed text to clear the subtitle when it reaches to the
+ // end time.
+ postTextEvent(NULL, endTimeUs);
}
}
@@ -162,6 +175,13 @@ void TimedTextPlayer::postTextEvent(const sp<ParcelEvent>& parcel, int64_t timeU
} else {
delayUs = timeUs - positionUs - kAdjustmentProcessingTimeUs;
}
+ postTextEventDelayUs(parcel, delayUs);
+ }
+}
+
+void TimedTextPlayer::postTextEventDelayUs(const sp<ParcelEvent>& parcel, int64_t delayUs) {
+ sp<MediaPlayerBase> listener = mListener.promote();
+ if (listener != NULL) {
sp<AMessage> msg = new AMessage(kWhatSendSubtitle, id());
msg->setInt32("generation", mSendSubtitleGeneration);
if (parcel != NULL) {
diff --git a/media/libstagefright/timedtext/TimedTextPlayer.h b/media/libstagefright/timedtext/TimedTextPlayer.h
index b869f187d819..47aff035fa24 100644
--- a/media/libstagefright/timedtext/TimedTextPlayer.h
+++ b/media/libstagefright/timedtext/TimedTextPlayer.h
@@ -67,6 +67,7 @@ private:
void doRead(MediaSource::ReadOptions* options = NULL);
void onTextEvent();
void postTextEvent(const sp<ParcelEvent>& parcel = NULL, int64_t timeUs = -1);
+ void postTextEventDelayUs(const sp<ParcelEvent>& parcel = NULL, int64_t delayUs = -1);
void notifyError(int error = 0);
void notifyListener(const Parcel *parcel = NULL);
diff --git a/media/libstagefright/timedtext/TimedTextSRTSource.cpp b/media/libstagefright/timedtext/TimedTextSRTSource.cpp
index c44a99b400df..7b1f7f65baaf 100644
--- a/media/libstagefright/timedtext/TimedTextSRTSource.cpp
+++ b/media/libstagefright/timedtext/TimedTextSRTSource.cpp
@@ -19,6 +19,7 @@
#include <utils/Log.h>
#include <binder/Parcel.h>
+#include <media/stagefright/foundation/ADebug.h> // for CHECK_xx
#include <media/stagefright/foundation/AString.h>
#include <media/stagefright/DataSource.h>
#include <media/stagefright/MediaDefs.h> // for MEDIA_MIMETYPE_xxx
@@ -63,19 +64,18 @@ status_t TimedTextSRTSource::stop() {
}
status_t TimedTextSRTSource::read(
- int64_t *timeUs,
+ int64_t *startTimeUs,
+ int64_t *endTimeUs,
Parcel *parcel,
const MediaSource::ReadOptions *options) {
- int64_t endTimeUs;
AString text;
- status_t err = getText(options, &text, timeUs, &endTimeUs);
+ status_t err = getText(options, &text, startTimeUs, endTimeUs);
if (err != OK) {
return err;
}
- if (*timeUs > 0) {
- extractAndAppendLocalDescriptions(*timeUs, text, parcel);
- }
+ CHECK_GE(*startTimeUs, 0);
+ extractAndAppendLocalDescriptions(*startTimeUs, text, parcel);
return OK;
}
diff --git a/media/libstagefright/timedtext/TimedTextSRTSource.h b/media/libstagefright/timedtext/TimedTextSRTSource.h
index 62710a01e735..e1371b866d5b 100644
--- a/media/libstagefright/timedtext/TimedTextSRTSource.h
+++ b/media/libstagefright/timedtext/TimedTextSRTSource.h
@@ -36,7 +36,8 @@ public:
virtual status_t start();
virtual status_t stop();
virtual status_t read(
- int64_t *timeUs,
+ int64_t *startTimeUs,
+ int64_t *endTimeUs,
Parcel *parcel,
const MediaSource::ReadOptions *options = NULL);
virtual sp<MetaData> getFormat();
diff --git a/media/libstagefright/timedtext/TimedTextSource.h b/media/libstagefright/timedtext/TimedTextSource.h
index 93493426267c..756cc310b8cb 100644
--- a/media/libstagefright/timedtext/TimedTextSource.h
+++ b/media/libstagefright/timedtext/TimedTextSource.h
@@ -43,7 +43,8 @@ class TimedTextSource : public RefBase {
virtual status_t stop() = 0;
// Returns subtitle parcel and its start time.
virtual status_t read(
- int64_t *timeUs,
+ int64_t *startTimeUs,
+ int64_t *endTimeUs,
Parcel *parcel,
const MediaSource::ReadOptions *options = NULL) = 0;
virtual status_t extractGlobalDescriptions(Parcel *parcel) {
diff --git a/packages/SystemUI/res/layout/navigation_bar.xml b/packages/SystemUI/res/layout/navigation_bar.xml
index bb80098c6cc3..8fbab7441330 100644
--- a/packages/SystemUI/res/layout/navigation_bar.xml
+++ b/packages/SystemUI/res/layout/navigation_bar.xml
@@ -144,11 +144,11 @@
/>
</LinearLayout>
- <View android:id="@+id/deadzone"
+ <com.android.systemui.statusbar.policy.DeadZone
+ android:id="@+id/deadzone"
android:layout_height="@dimen/navigation_bar_deadzone_size"
android:layout_width="match_parent"
android:layout_gravity="top"
- android:clickable="true"
/>
</FrameLayout>
@@ -272,11 +272,11 @@
/>
</LinearLayout>
- <View android:id="@+id/deadzone"
+ <com.android.systemui.statusbar.policy.DeadZone
+ android:id="@+id/deadzone"
android:layout_width="@dimen/navigation_bar_deadzone_size"
android:layout_height="match_parent"
android:layout_gravity="left"
- android:clickable="true"
/>
</FrameLayout>
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentTasksLoader.java b/packages/SystemUI/src/com/android/systemui/recent/RecentTasksLoader.java
index 92f4ca96a2e4..f5894eab17aa 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentTasksLoader.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentTasksLoader.java
@@ -242,7 +242,7 @@ public class RecentTasksLoader {
// We load in two stages: first, we update progress with just the first screenful
// of items. Then, we update with the rest of the items
final int origPri = Process.getThreadPriority(Process.myTid());
- Process.setThreadPriority(Process.THREAD_GROUP_BG_NONINTERACTIVE);
+ Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
final PackageManager pm = mContext.getPackageManager();
final ActivityManager am = (ActivityManager)
mContext.getSystemService(Context.ACTIVITY_SERVICE);
@@ -326,7 +326,7 @@ public class RecentTasksLoader {
@Override
protected Void doInBackground(Void... params) {
final int origPri = Process.getThreadPriority(Process.myTid());
- Process.setThreadPriority(Process.THREAD_GROUP_BG_NONINTERACTIVE);
+ Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
while (true) {
if (isCancelled()) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeadZone.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeadZone.java
new file mode 100644
index 000000000000..19fbe9636c0d
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeadZone.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.policy;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.view.View;
+
+import com.android.systemui.R;
+
+public class DeadZone extends View {
+ public DeadZone(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public DeadZone(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs);
+ }
+
+ // I made you a touch event
+ @Override
+ public boolean onTouchEvent (MotionEvent event) {
+ return true; // but I eated it
+ }
+}
+
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java b/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java
index 9f3de699d37a..25af2e6f944b 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java
@@ -22,6 +22,7 @@ import com.android.internal.telephony.IccCard.State;
import com.android.internal.widget.DigitalClock;
import com.android.internal.widget.LockPatternUtils;
import com.android.internal.widget.TransportControlView;
+import com.android.internal.policy.impl.KeyguardUpdateMonitor.InfoCallbackImpl;
import com.android.internal.policy.impl.KeyguardUpdateMonitor.SimStateCallback;
import java.util.ArrayList;
@@ -625,9 +626,9 @@ class KeyguardStatusViewManager implements OnClickListener {
}
}
- private KeyguardUpdateMonitor.InfoCallback mInfoCallback
- = new KeyguardUpdateMonitor.InfoCallback() {
+ private InfoCallbackImpl mInfoCallback = new InfoCallbackImpl() {
+ @Override
public void onRefreshBatteryInfo(boolean showBatteryInfo, boolean pluggedIn,
int batteryLevel) {
mShowingBatteryInfo = showBatteryInfo;
@@ -637,33 +638,24 @@ class KeyguardStatusViewManager implements OnClickListener {
update(BATTERY_INFO, getAltTextMessage(tmpIcon));
}
+ @Override
public void onTimeChanged() {
refreshDate();
}
+ @Override
public void onRefreshCarrierInfo(CharSequence plmn, CharSequence spn) {
mPlmn = plmn;
mSpn = spn;
updateCarrierStateWithSimStatus(mSimState);
}
- public void onRingerModeChanged(int state) {
-
- }
-
+ @Override
public void onPhoneStateChanged(int phoneState) {
mPhoneState = phoneState;
updateEmergencyCallButtonState(phoneState);
}
- /** {@inheritDoc} */
- public void onClockVisibilityChanged() {
- // ignored
- }
-
- public void onDeviceProvisioned() {
- // ignored
- }
};
private SimStateCallback mSimStateCallback = new SimStateCallback() {
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java b/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java
index 91ab05318bfd..804cd9efe5e8 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java
@@ -16,6 +16,7 @@
package com.android.internal.policy.impl;
+import android.app.admin.DevicePolicyManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -103,6 +104,7 @@ public class KeyguardUpdateMonitor {
private static final int MSG_PHONE_STATE_CHANGED = 306;
private static final int MSG_CLOCK_VISIBILITY_CHANGED = 307;
private static final int MSG_DEVICE_PROVISIONED = 308;
+ protected static final int MSG_DPM_STATE_CHANGED = 309;
/**
* When we receive a
@@ -204,6 +206,9 @@ public class KeyguardUpdateMonitor {
case MSG_DEVICE_PROVISIONED:
handleDeviceProvisioned();
break;
+ case MSG_DPM_STATE_CHANGED:
+ handleDevicePolicyManagerStateChanged();
+ break;
}
}
};
@@ -262,6 +267,7 @@ public class KeyguardUpdateMonitor {
filter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
filter.addAction(SPN_STRINGS_UPDATED_ACTION);
filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
+ filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
context.registerReceiver(new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
@@ -293,11 +299,20 @@ public class KeyguardUpdateMonitor {
} else if (TelephonyManager.ACTION_PHONE_STATE_CHANGED.equals(action)) {
String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
mHandler.sendMessage(mHandler.obtainMessage(MSG_PHONE_STATE_CHANGED, state));
+ } else if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED
+ .equals(action)) {
+ mHandler.sendMessage(mHandler.obtainMessage(MSG_DPM_STATE_CHANGED));
}
}
}, filter);
}
+ protected void handleDevicePolicyManagerStateChanged() {
+ for (int i = 0; i < mInfoCallbacks.size(); i++) {
+ mInfoCallbacks.get(i).onDevicePolicyManagerStateChanged();
+ }
+ }
+
protected void handleDeviceProvisioned() {
for (int i = 0; i < mInfoCallbacks.size(); i++) {
mInfoCallbacks.get(i).onDeviceProvisioned();
@@ -521,6 +536,40 @@ public class KeyguardUpdateMonitor {
* Called when the device becomes provisioned
*/
void onDeviceProvisioned();
+
+ /**
+ * Called when the device policy changes.
+ * See {@link DevicePolicyManager#ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED}
+ */
+ void onDevicePolicyManagerStateChanged();
+ }
+
+ // Simple class that allows methods to easily be overwritten
+ public static class InfoCallbackImpl implements InfoCallback {
+ public void onRefreshBatteryInfo(boolean showBatteryInfo, boolean pluggedIn,
+ int batteryLevel) {
+ }
+
+ public void onTimeChanged() {
+ }
+
+ public void onRefreshCarrierInfo(CharSequence plmn, CharSequence spn) {
+ }
+
+ public void onRingerModeChanged(int state) {
+ }
+
+ public void onPhoneStateChanged(int phoneState) {
+ }
+
+ public void onClockVisibilityChanged() {
+ }
+
+ public void onDeviceProvisioned() {
+ }
+
+ public void onDevicePolicyManagerStateChanged() {
+ }
}
/**
@@ -653,4 +702,10 @@ public class KeyguardUpdateMonitor {
public boolean getMaxFaceUnlockAttemptsReached() {
return mFailedFaceUnlockAttempts >= FAILED_FACE_UNLOCK_ATTEMPTS_BEFORE_BACKUP;
}
+
+ public boolean isSimLocked() {
+ return mSimState == IccCard.State.PIN_REQUIRED
+ || mSimState == IccCard.State.PUK_REQUIRED
+ || mSimState == IccCard.State.PERM_DISABLED;
+ }
}
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java b/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
index 52d6d24b16f6..377ea66406cd 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
@@ -18,6 +18,7 @@ package com.android.internal.policy.impl;
import static android.provider.Settings.System.SCREEN_OFF_TIMEOUT;
+import com.android.internal.policy.impl.KeyguardUpdateMonitor.InfoCallbackImpl;
import com.android.internal.telephony.IccCard;
import com.android.internal.widget.LockPatternUtils;
@@ -90,7 +91,7 @@ import android.view.WindowManagerPolicy;
* thread of the keyguard.
*/
public class KeyguardViewMediator implements KeyguardViewCallback,
- KeyguardUpdateMonitor.InfoCallback, KeyguardUpdateMonitor.SimStateCallback {
+ KeyguardUpdateMonitor.SimStateCallback {
private static final int KEYGUARD_DISPLAY_TIMEOUT_DELAY_DEFAULT = 30000;
private final static boolean DEBUG = false;
private final static boolean DBG_WAKE = false;
@@ -265,6 +266,20 @@ public class KeyguardViewMediator implements KeyguardViewCallback,
private int mLockSoundStreamId;
private int mMasterStreamMaxVolume;
+ InfoCallbackImpl mInfoCallback = new InfoCallbackImpl() {
+
+ @Override
+ public void onClockVisibilityChanged() {
+ adjustStatusBarLocked();
+ }
+
+ @Override
+ public void onDeviceProvisioned() {
+ mContext.sendBroadcast(mUserPresentIntent);
+ }
+
+ };
+
public KeyguardViewMediator(Context context, PhoneWindowManager callback,
LocalPowerManager powerManager) {
mContext = context;
@@ -293,7 +308,8 @@ public class KeyguardViewMediator implements KeyguardViewCallback,
mUpdateMonitor = new KeyguardUpdateMonitor(context);
- mUpdateMonitor.registerInfoCallback(this);
+ mUpdateMonitor.registerInfoCallback(mInfoCallback);
+
mUpdateMonitor.registerSimStateCallback(this);
mLockPatternUtils = new LockPatternUtils(mContext);
@@ -750,8 +766,8 @@ public class KeyguardViewMediator implements KeyguardViewCallback,
case PUK_REQUIRED:
synchronized (this) {
if (!isShowing()) {
- if (DEBUG) Log.d(TAG, "INTENT_VALUE_ICC_LOCKED and keygaurd isn't showing, we need "
- + "to show the keyguard so the user can enter their sim pin");
+ if (DEBUG) Log.d(TAG, "INTENT_VALUE_ICC_LOCKED and keygaurd isn't showing, "
+ + "we need to show keyguard so user can enter their sim pin");
doKeyguardLocked();
} else {
resetStateLocked();
@@ -1306,38 +1322,4 @@ public class KeyguardViewMediator implements KeyguardViewCallback,
}
}
- /** {@inheritDoc} */
- public void onClockVisibilityChanged() {
- adjustStatusBarLocked();
- }
-
- /** {@inheritDoc} */
- public void onPhoneStateChanged(int phoneState) {
- // ignored
- }
-
- /** {@inheritDoc} */
- public void onRefreshBatteryInfo(boolean showBatteryInfo, boolean pluggedIn, int batteryLevel) {
- // ignored
- }
-
- /** {@inheritDoc} */
- public void onRefreshCarrierInfo(CharSequence plmn, CharSequence spn) {
- // ignored
- }
-
- /** {@inheritDoc} */
- public void onRingerModeChanged(int state) {
- // ignored
- }
-
- /** {@inheritDoc} */
- public void onTimeChanged() {
- // ignored
- }
-
- /** {@inheritDoc} */
- public void onDeviceProvisioned() {
- mContext.sendBroadcast(mUserPresentIntent);
- }
}
diff --git a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
index 3ca57c607d62..2e7769b44d79 100644
--- a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
+++ b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
@@ -17,6 +17,8 @@
package com.android.internal.policy.impl;
import com.android.internal.R;
+import com.android.internal.policy.impl.KeyguardUpdateMonitor.InfoCallback;
+import com.android.internal.policy.impl.KeyguardUpdateMonitor.InfoCallbackImpl;
import com.android.internal.policy.impl.LockPatternKeyguardView.UnlockMode;
import com.android.internal.policy.IFaceLockCallback;
import com.android.internal.policy.IFaceLockInterface;
@@ -80,8 +82,7 @@ import java.io.IOException;
* {@link com.android.internal.policy.impl.KeyguardViewManager}
* via its {@link com.android.internal.policy.impl.KeyguardViewCallback}, as appropriate.
*/
-public class LockPatternKeyguardView extends KeyguardViewBase implements Handler.Callback,
- KeyguardUpdateMonitor.InfoCallback {
+public class LockPatternKeyguardView extends KeyguardViewBase implements Handler.Callback {
private static final int TRANSPORT_USERACTIVITY_TIMEOUT = 10000;
@@ -133,12 +134,6 @@ public class LockPatternKeyguardView extends KeyguardViewBase implements Handler
// So the user has a consistent amount of time when brought to the backup method from FaceLock
private final int BACKUP_LOCK_TIMEOUT = 5000;
- /**
- * The current {@link KeyguardScreen} will use this to communicate back to us.
- */
- KeyguardScreenCallback mKeyguardScreenCallback;
-
-
private boolean mRequiresSim;
//True if we have some sort of overlay on top of the Lockscreen
//Also true if we've activated a phone call, either emergency dialing or incoming
@@ -150,6 +145,10 @@ public class LockPatternKeyguardView extends KeyguardViewBase implements Handler
//True if this device is currently plugged in
private boolean mPluggedIn;
+ // The music control widget
+ private TransportControlView mTransportControlView;
+
+ private Parcelable mSavedState;
/**
* Either a lock screen (an informational keyguard screen), or an unlock
@@ -216,7 +215,6 @@ public class LockPatternKeyguardView extends KeyguardViewBase implements Handler
*/
private boolean mIsVerifyUnlockOnly = false;
-
/**
* Used to lookup the state of the lock pattern
*/
@@ -274,10 +272,6 @@ public class LockPatternKeyguardView extends KeyguardViewBase implements Handler
}
};
- private TransportControlView mTransportControlView;
-
- private Parcelable mSavedState;
-
/**
* @return Whether we are stuck on the lock screen because the sim is
* missing.
@@ -290,181 +284,184 @@ public class LockPatternKeyguardView extends KeyguardViewBase implements Handler
}
/**
- * @param context Used to inflate, and create views.
- * @param callback Keyguard callback object for pokewakelock(), etc.
- * @param updateMonitor Knows the state of the world, and passed along to each
- * screen so they can use the knowledge, and also register for callbacks
- * on dynamic information.
- * @param lockPatternUtils Used to look up state of lock pattern.
+ * The current {@link KeyguardScreen} will use this to communicate back to us.
*/
- public LockPatternKeyguardView(
- Context context, KeyguardViewCallback callback, KeyguardUpdateMonitor updateMonitor,
- LockPatternUtils lockPatternUtils, KeyguardWindowController controller) {
- super(context, callback);
-
- mHandler = new Handler(this);
- mConfiguration = context.getResources().getConfiguration();
- mEnableFallback = false;
- mRequiresSim = TextUtils.isEmpty(SystemProperties.get("keyguard.no_require_sim"));
- mUpdateMonitor = updateMonitor;
- mLockPatternUtils = lockPatternUtils;
- mWindowController = controller;
- mHasOverlay = false;
- mPluggedIn = mUpdateMonitor.isDevicePluggedIn();
- mScreenOn = ((PowerManager)context.getSystemService(Context.POWER_SERVICE)).isScreenOn();
-
- mUpdateMonitor.registerInfoCallback(this);
-
- mKeyguardScreenCallback = new KeyguardScreenCallback() {
-
- public void goToLockScreen() {
- mForgotPattern = false;
- if (mIsVerifyUnlockOnly) {
- // navigating away from unlock screen during verify mode means
- // we are done and the user failed to authenticate.
- mIsVerifyUnlockOnly = false;
- getCallback().keyguardDone(false);
- } else {
- updateScreen(Mode.LockScreen, false);
- }
- }
-
- public void goToUnlockScreen() {
- final IccCard.State simState = mUpdateMonitor.getSimState();
- if (stuckOnLockScreenBecauseSimMissing()
- || (simState == IccCard.State.PUK_REQUIRED
- && !mLockPatternUtils.isPukUnlockScreenEnable())){
- // stuck on lock screen when sim missing or
- // puk'd but puk unlock screen is disabled
- return;
- }
- if (!isSecure()) {
- getCallback().keyguardDone(true);
- } else {
- updateScreen(Mode.UnlockScreen, false);
- }
+ KeyguardScreenCallback mKeyguardScreenCallback = new KeyguardScreenCallback() {
+
+ public void goToLockScreen() {
+ mForgotPattern = false;
+ if (mIsVerifyUnlockOnly) {
+ // navigating away from unlock screen during verify mode means
+ // we are done and the user failed to authenticate.
+ mIsVerifyUnlockOnly = false;
+ getCallback().keyguardDone(false);
+ } else {
+ updateScreen(Mode.LockScreen, false);
}
+ }
- public void forgotPattern(boolean isForgotten) {
- if (mEnableFallback) {
- mForgotPattern = isForgotten;
- updateScreen(Mode.UnlockScreen, false);
- }
+ public void goToUnlockScreen() {
+ final IccCard.State simState = mUpdateMonitor.getSimState();
+ if (stuckOnLockScreenBecauseSimMissing()
+ || (simState == IccCard.State.PUK_REQUIRED
+ && !mLockPatternUtils.isPukUnlockScreenEnable())){
+ // stuck on lock screen when sim missing or
+ // puk'd but puk unlock screen is disabled
+ return;
}
-
- public boolean isSecure() {
- return LockPatternKeyguardView.this.isSecure();
+ if (!isSecure()) {
+ getCallback().keyguardDone(true);
+ } else {
+ updateScreen(Mode.UnlockScreen, false);
}
+ }
- public boolean isVerifyUnlockOnly() {
- return mIsVerifyUnlockOnly;
+ public void forgotPattern(boolean isForgotten) {
+ if (mEnableFallback) {
+ mForgotPattern = isForgotten;
+ updateScreen(Mode.UnlockScreen, false);
}
+ }
- public void recreateMe(Configuration config) {
- removeCallbacks(mRecreateRunnable);
- post(mRecreateRunnable);
- }
+ public boolean isSecure() {
+ return LockPatternKeyguardView.this.isSecure();
+ }
- public void takeEmergencyCallAction() {
- mHasOverlay = true;
+ public boolean isVerifyUnlockOnly() {
+ return mIsVerifyUnlockOnly;
+ }
- // Continue showing FaceLock area until dialer comes up or call is resumed
- if (usingFaceLock() && mFaceLockServiceRunning) {
- showFaceLockAreaWithTimeout(FACELOCK_VIEW_AREA_EMERGENCY_DIALER_TIMEOUT);
- }
+ public void recreateMe(Configuration config) {
+ removeCallbacks(mRecreateRunnable);
+ post(mRecreateRunnable);
+ }
- // FaceLock must be stopped if it is running when emergency call is pressed
- stopAndUnbindFromFaceLock();
+ public void takeEmergencyCallAction() {
+ mHasOverlay = true;
- pokeWakelock(EMERGENCY_CALL_TIMEOUT);
- if (TelephonyManager.getDefault().getCallState()
- == TelephonyManager.CALL_STATE_OFFHOOK) {
- mLockPatternUtils.resumeCall();
- } else {
- Intent intent = new Intent(ACTION_EMERGENCY_DIAL);
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
- | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
- getContext().startActivity(intent);
- }
+ // Continue showing FaceLock area until dialer comes up or call is resumed
+ if (usingFaceLock() && mFaceLockServiceRunning) {
+ showFaceLockAreaWithTimeout(FACELOCK_VIEW_AREA_EMERGENCY_DIALER_TIMEOUT);
}
- public void pokeWakelock() {
- getCallback().pokeWakelock();
- }
+ // FaceLock must be stopped if it is running when emergency call is pressed
+ stopAndUnbindFromFaceLock();
- public void pokeWakelock(int millis) {
- getCallback().pokeWakelock(millis);
+ pokeWakelock(EMERGENCY_CALL_TIMEOUT);
+ if (TelephonyManager.getDefault().getCallState()
+ == TelephonyManager.CALL_STATE_OFFHOOK) {
+ mLockPatternUtils.resumeCall();
+ } else {
+ Intent intent = new Intent(ACTION_EMERGENCY_DIAL);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+ | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
+ getContext().startActivity(intent);
}
+ }
- public void keyguardDone(boolean authenticated) {
- getCallback().keyguardDone(authenticated);
- mSavedState = null; // clear state so we re-establish when locked again
- }
+ public void pokeWakelock() {
+ getCallback().pokeWakelock();
+ }
- public void keyguardDoneDrawing() {
- // irrelevant to keyguard screen, they shouldn't be calling this
- }
+ public void pokeWakelock(int millis) {
+ getCallback().pokeWakelock(millis);
+ }
- public void reportFailedUnlockAttempt() {
- mUpdateMonitor.reportFailedAttempt();
- final int failedAttempts = mUpdateMonitor.getFailedAttempts();
- if (DEBUG) Log.d(TAG, "reportFailedPatternAttempt: #" + failedAttempts +
- " (enableFallback=" + mEnableFallback + ")");
+ public void keyguardDone(boolean authenticated) {
+ getCallback().keyguardDone(authenticated);
+ mSavedState = null; // clear state so we re-establish when locked again
+ }
- final boolean usingPattern = mLockPatternUtils.getKeyguardStoredPasswordQuality()
- == DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;
+ public void keyguardDoneDrawing() {
+ // irrelevant to keyguard screen, they shouldn't be calling this
+ }
- final int failedAttemptsBeforeWipe = mLockPatternUtils.getDevicePolicyManager()
- .getMaximumFailedPasswordsForWipe(null);
+ public void reportFailedUnlockAttempt() {
+ mUpdateMonitor.reportFailedAttempt();
+ final int failedAttempts = mUpdateMonitor.getFailedAttempts();
+ if (DEBUG) Log.d(TAG, "reportFailedPatternAttempt: #" + failedAttempts +
+ " (enableFallback=" + mEnableFallback + ")");
- final int failedAttemptWarning = LockPatternUtils.FAILED_ATTEMPTS_BEFORE_RESET
- - LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT;
+ final boolean usingPattern = mLockPatternUtils.getKeyguardStoredPasswordQuality()
+ == DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;
- final int remainingBeforeWipe = failedAttemptsBeforeWipe > 0 ?
- (failedAttemptsBeforeWipe - failedAttempts)
- : Integer.MAX_VALUE; // because DPM returns 0 if no restriction
+ final int failedAttemptsBeforeWipe = mLockPatternUtils.getDevicePolicyManager()
+ .getMaximumFailedPasswordsForWipe(null);
- if (remainingBeforeWipe < LockPatternUtils.FAILED_ATTEMPTS_BEFORE_WIPE_GRACE) {
- // If we reach this code, it means the user has installed a DevicePolicyManager
- // that requests device wipe after N attempts. Once we get below the grace
- // period, we'll post this dialog every time as a clear warning until the
- // bombshell hits and the device is wiped.
- if (remainingBeforeWipe > 0) {
- showAlmostAtWipeDialog(failedAttempts, remainingBeforeWipe);
- } else {
- // Too many attempts. The device will be wiped shortly.
- Slog.i(TAG, "Too many unlock attempts; device will be wiped!");
- showWipeDialog(failedAttempts);
- }
+ final int failedAttemptWarning = LockPatternUtils.FAILED_ATTEMPTS_BEFORE_RESET
+ - LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT;
+
+ final int remainingBeforeWipe = failedAttemptsBeforeWipe > 0 ?
+ (failedAttemptsBeforeWipe - failedAttempts)
+ : Integer.MAX_VALUE; // because DPM returns 0 if no restriction
+
+ if (remainingBeforeWipe < LockPatternUtils.FAILED_ATTEMPTS_BEFORE_WIPE_GRACE) {
+ // If we reach this code, it means the user has installed a DevicePolicyManager
+ // that requests device wipe after N attempts. Once we get below the grace
+ // period, we'll post this dialog every time as a clear warning until the
+ // bombshell hits and the device is wiped.
+ if (remainingBeforeWipe > 0) {
+ showAlmostAtWipeDialog(failedAttempts, remainingBeforeWipe);
} else {
- boolean showTimeout =
- (failedAttempts % LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT) == 0;
- if (usingPattern && mEnableFallback) {
- if (failedAttempts == failedAttemptWarning) {
- showAlmostAtAccountLoginDialog();
- showTimeout = false; // don't show both dialogs
- } else if (failedAttempts >= LockPatternUtils.FAILED_ATTEMPTS_BEFORE_RESET) {
- mLockPatternUtils.setPermanentlyLocked(true);
- updateScreen(mMode, false);
- // don't show timeout dialog because we show account unlock screen next
- showTimeout = false;
- }
- }
- if (showTimeout) {
- showTimeoutDialog();
+ // Too many attempts. The device will be wiped shortly.
+ Slog.i(TAG, "Too many unlock attempts; device will be wiped!");
+ showWipeDialog(failedAttempts);
+ }
+ } else {
+ boolean showTimeout =
+ (failedAttempts % LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT) == 0;
+ if (usingPattern && mEnableFallback) {
+ if (failedAttempts == failedAttemptWarning) {
+ showAlmostAtAccountLoginDialog();
+ showTimeout = false; // don't show both dialogs
+ } else if (failedAttempts >= LockPatternUtils.FAILED_ATTEMPTS_BEFORE_RESET) {
+ mLockPatternUtils.setPermanentlyLocked(true);
+ updateScreen(mMode, false);
+ // don't show timeout dialog because we show account unlock screen next
+ showTimeout = false;
}
}
- mLockPatternUtils.reportFailedPasswordAttempt();
+ if (showTimeout) {
+ showTimeoutDialog();
+ }
}
+ mLockPatternUtils.reportFailedPasswordAttempt();
+ }
- public boolean doesFallbackUnlockScreenExist() {
- return mEnableFallback;
- }
+ public boolean doesFallbackUnlockScreenExist() {
+ return mEnableFallback;
+ }
- public void reportSuccessfulUnlockAttempt() {
- mLockPatternUtils.reportSuccessfulPasswordAttempt();
- }
- };
+ public void reportSuccessfulUnlockAttempt() {
+ mLockPatternUtils.reportSuccessfulPasswordAttempt();
+ }
+ };
+
+ /**
+ * @param context Used to inflate, and create views.
+ * @param callback Keyguard callback object for pokewakelock(), etc.
+ * @param updateMonitor Knows the state of the world, and passed along to each
+ * screen so they can use the knowledge, and also register for callbacks
+ * on dynamic information.
+ * @param lockPatternUtils Used to look up state of lock pattern.
+ */
+ public LockPatternKeyguardView(
+ Context context, KeyguardViewCallback callback, KeyguardUpdateMonitor updateMonitor,
+ LockPatternUtils lockPatternUtils, KeyguardWindowController controller) {
+ super(context, callback);
+
+ mHandler = new Handler(this);
+ mConfiguration = context.getResources().getConfiguration();
+ mEnableFallback = false;
+ mRequiresSim = TextUtils.isEmpty(SystemProperties.get("keyguard.no_require_sim"));
+ mUpdateMonitor = updateMonitor;
+ mLockPatternUtils = lockPatternUtils;
+ mWindowController = controller;
+ mHasOverlay = false;
+ mPluggedIn = mUpdateMonitor.isDevicePluggedIn();
+ mScreenOn = ((PowerManager)context.getSystemService(Context.POWER_SERVICE)).isScreenOn();
+
+ mUpdateMonitor.registerInfoCallback(mInfoCallback);
/**
* We'll get key events the current screen doesn't use. see
@@ -707,6 +704,8 @@ public class LockPatternKeyguardView extends KeyguardViewBase implements Handler
@Override
protected void onDetachedFromWindow() {
+ mUpdateMonitor.removeCallback(mInfoCallback);
+
removeCallbacks(mRecreateRunnable);
// When view is hidden, need to unbind from FaceLock service if we are using FaceLock
@@ -726,46 +725,39 @@ public class LockPatternKeyguardView extends KeyguardViewBase implements Handler
post(mRecreateRunnable);
}
- /** When somebody plugs in or unplugs the device, we don't want to display faceunlock */
- @Override
- public void onRefreshBatteryInfo(boolean showBatteryInfo, boolean pluggedIn, int batteryLevel) {
- mHasOverlay |= mPluggedIn != pluggedIn;
- mPluggedIn = pluggedIn;
- //If it's already running, don't close it down: the unplug didn't start it
- if (!mFaceLockServiceRunning) {
- stopAndUnbindFromFaceLock();
- hideFaceLockArea();
- }
- }
-
- //Ignore these events; they are implemented only because they come from the same interface
- @Override
- public void onTimeChanged() {}
- @Override
- public void onRefreshCarrierInfo(CharSequence plmn, CharSequence spn) {}
- @Override
- public void onRingerModeChanged(int state) {}
+ InfoCallbackImpl mInfoCallback = new InfoCallbackImpl() {
- @Override
- public void onClockVisibilityChanged() {
- int visFlags = getSystemUiVisibility() & ~View.STATUS_BAR_DISABLE_CLOCK;
- setSystemUiVisibility(visFlags
- | (mUpdateMonitor.isClockVisible() ? View.STATUS_BAR_DISABLE_CLOCK : 0));
- }
+ /** When somebody plugs in or unplugs the device, we don't want to display faceunlock */
+ @Override
+ public void onRefreshBatteryInfo(boolean showBatteryInfo, boolean pluggedIn,
+ int batteryLevel) {
+ mHasOverlay |= mPluggedIn != pluggedIn;
+ mPluggedIn = pluggedIn;
+ //If it's already running, don't close it down: the unplug didn't start it
+ if (!mFaceLockServiceRunning) {
+ stopAndUnbindFromFaceLock();
+ hideFaceLockArea();
+ }
+ }
- @Override
- public void onDeviceProvisioned() {}
+ @Override
+ public void onClockVisibilityChanged() {
+ int visFlags = getSystemUiVisibility() & ~View.STATUS_BAR_DISABLE_CLOCK;
+ setSystemUiVisibility(visFlags
+ | (mUpdateMonitor.isClockVisible() ? View.STATUS_BAR_DISABLE_CLOCK : 0));
+ }
- //We need to stop faceunlock when a phonecall comes in
- @Override
- public void onPhoneStateChanged(int phoneState) {
- if (DEBUG) Log.d(TAG, "phone state: " + phoneState);
- if(phoneState == TelephonyManager.CALL_STATE_RINGING) {
- mHasOverlay = true;
- stopAndUnbindFromFaceLock();
- hideFaceLockArea();
+ //We need to stop faceunlock when a phonecall comes in
+ @Override
+ public void onPhoneStateChanged(int phoneState) {
+ if (DEBUG) Log.d(TAG, "phone state: " + phoneState);
+ if(phoneState == TelephonyManager.CALL_STATE_RINGING) {
+ mHasOverlay = true;
+ stopAndUnbindFromFaceLock();
+ hideFaceLockArea();
+ }
}
- }
+ };
@Override
protected boolean dispatchHoverEvent(MotionEvent event) {
diff --git a/policy/src/com/android/internal/policy/impl/LockScreen.java b/policy/src/com/android/internal/policy/impl/LockScreen.java
index edf519940816..c9a130b984e0 100644
--- a/policy/src/com/android/internal/policy/impl/LockScreen.java
+++ b/policy/src/com/android/internal/policy/impl/LockScreen.java
@@ -17,6 +17,11 @@
package com.android.internal.policy.impl;
import com.android.internal.R;
+import com.android.internal.policy.impl.KeyguardUpdateMonitor.InfoCallback;
+import com.android.internal.policy.impl.KeyguardUpdateMonitor.InfoCallbackImpl;
+import com.android.internal.policy.impl.KeyguardUpdateMonitor.SimStateCallback;
+import com.android.internal.policy.impl.LockScreen.MultiWaveViewMethods;
+import com.android.internal.telephony.IccCard.State;
import com.android.internal.widget.LockPatternUtils;
import com.android.internal.widget.SlidingTab;
import com.android.internal.widget.WaveView;
@@ -60,6 +65,9 @@ class LockScreen extends LinearLayout implements KeyguardScreen {
private KeyguardUpdateMonitor mUpdateMonitor;
private KeyguardScreenCallback mCallback;
+ // set to 'true' to show the ring/silence target when camera isn't available
+ private boolean mEnableRingSilenceFallback = false;
+
// current configuration state of keyboard and display
private int mKeyboardHidden;
private int mCreationOrientation;
@@ -71,6 +79,31 @@ class LockScreen extends LinearLayout implements KeyguardScreen {
private KeyguardStatusViewManager mStatusViewManager;
private UnlockWidgetCommonMethods mUnlockWidgetMethods;
private View mUnlockWidget;
+ public boolean mCameraDisabled;
+
+ InfoCallbackImpl mInfoCallback = new InfoCallbackImpl() {
+
+ @Override
+ public void onRingerModeChanged(int state) {
+ boolean silent = AudioManager.RINGER_MODE_NORMAL != state;
+ if (silent != mSilentMode) {
+ mSilentMode = silent;
+ mUnlockWidgetMethods.updateResources();
+ }
+ }
+
+ @Override
+ public void onDevicePolicyManagerStateChanged() {
+ updateCameraTarget();
+ }
+
+ };
+
+ SimStateCallback mSimStateCallback = new SimStateCallback() {
+ public void onSimStateChanged(State simState) {
+ updateCameraTarget();
+ }
+ };
private interface UnlockWidgetCommonMethods {
// Update resources based on phone state
@@ -84,6 +117,13 @@ class LockScreen extends LinearLayout implements KeyguardScreen {
// Animate the widget if it supports ping()
public void ping();
+
+ // Enable or disable a target. ResourceId is the id of the *drawable* associated with the
+ // target.
+ public void setEnabled(int resourceId, boolean enabled);
+
+ // Get the target position for the given resource. Returns -1 if not found.
+ public int getTargetPosition(int resourceId);
}
class SlidingTabMethods implements SlidingTab.OnTriggerListener, UnlockWidgetCommonMethods {
@@ -144,6 +184,14 @@ class LockScreen extends LinearLayout implements KeyguardScreen {
public void ping() {
}
+
+ public void setEnabled(int resourceId, boolean enabled) {
+ // Not used
+ }
+
+ public int getTargetPosition(int resourceId) {
+ return -1; // Not supported
+ }
}
class WaveViewMethods implements WaveView.OnTriggerListener, UnlockWidgetCommonMethods {
@@ -181,39 +229,40 @@ class LockScreen extends LinearLayout implements KeyguardScreen {
}
public void ping() {
}
+ public void setEnabled(int resourceId, boolean enabled) {
+ // Not used
+ }
+ public int getTargetPosition(int resourceId) {
+ return -1; // Not supported
+ }
}
class MultiWaveViewMethods implements MultiWaveView.OnTriggerListener,
UnlockWidgetCommonMethods {
-
private final MultiWaveView mMultiWaveView;
- private boolean mCameraDisabled;
MultiWaveViewMethods(MultiWaveView multiWaveView) {
mMultiWaveView = multiWaveView;
- final boolean cameraDisabled = mLockPatternUtils.getDevicePolicyManager()
- .getCameraDisabled(null);
- if (cameraDisabled) {
- Log.v(TAG, "Camera disabled by Device Policy");
- mCameraDisabled = true;
- } else {
- // Camera is enabled if resource is initially defined for MultiWaveView
- // in the lockscreen layout file
- mCameraDisabled = mMultiWaveView.getTargetResourceId()
- != R.array.lockscreen_targets_with_camera;
- }
+ }
+
+ public boolean isCameraTargetPresent() {
+ return mMultiWaveView
+ .getTargetPosition(com.android.internal.R.drawable.ic_lockscreen_camera) != -1;
}
public void updateResources() {
int resId;
- if (mCameraDisabled) {
- // Fall back to showing ring/silence if camera is disabled by DPM...
+ if (mCameraDisabled && mEnableRingSilenceFallback) {
+ // Fall back to showing ring/silence if camera is disabled...
resId = mSilentMode ? R.array.lockscreen_targets_when_silent
: R.array.lockscreen_targets_when_soundon;
} else {
resId = R.array.lockscreen_targets_with_camera;
}
- mMultiWaveView.setTargetResources(resId);
+ if (mMultiWaveView.getTargetResourceId() != resId) {
+ mMultiWaveView.setTargetResources(resId);
+ }
+ setEnabled(com.android.internal.R.drawable.ic_lockscreen_camera, !mCameraDisabled);
}
public void onGrabbed(View v, int handle) {
@@ -225,29 +274,39 @@ class LockScreen extends LinearLayout implements KeyguardScreen {
}
public void onTrigger(View v, int target) {
- if (target == 0 || target == 1) { // 0 = unlock/portrait, 1 = unlock/landscape
- mCallback.goToUnlockScreen();
- } else if (target == 2 || target == 3) { // 2 = alt/portrait, 3 = alt/landscape
- if (!mCameraDisabled) {
- // Start the Camera
- Intent intent = new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA);
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
- | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
- try {
- ActivityManagerNative.getDefault().dismissKeyguardOnNextActivity();
- } catch (RemoteException e) {
- Log.w(TAG, "can't dismiss keyguard on launch");
- }
- try {
- mContext.startActivity(intent);
- } catch (ActivityNotFoundException e) {
- Log.w(TAG, "Camera application not found");
- }
- } else {
+ final int resId = mMultiWaveView.getResourceIdForTarget(target);
+ switch (resId) {
+ case com.android.internal.R.drawable.ic_lockscreen_camera:
+ launchCamera();
+ mCallback.pokeWakelock();
+ break;
+
+ case com.android.internal.R.drawable.ic_lockscreen_silent:
toggleRingMode();
- mUnlockWidgetMethods.updateResources();
mCallback.pokeWakelock();
- }
+ break;
+
+ case com.android.internal.R.drawable.ic_lockscreen_unlock:
+ mCallback.goToUnlockScreen();
+ break;
+ }
+ }
+
+ private void launchCamera() {
+ Intent intent = new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA);
+ intent.setFlags(
+ Intent.FLAG_ACTIVITY_NEW_TASK
+ | Intent.FLAG_ACTIVITY_SINGLE_TOP
+ | Intent.FLAG_ACTIVITY_CLEAR_TOP);
+ try {
+ ActivityManagerNative.getDefault().dismissKeyguardOnNextActivity();
+ } catch (RemoteException e) {
+ Log.w(TAG, "can't dismiss keyguard on launch");
+ }
+ try {
+ mContext.startActivity(intent);
+ } catch (ActivityNotFoundException e) {
+ Log.w(TAG, "Camera application not found");
}
}
@@ -271,6 +330,14 @@ class LockScreen extends LinearLayout implements KeyguardScreen {
public void ping() {
mMultiWaveView.ping();
}
+
+ public void setEnabled(int resourceId, boolean enabled) {
+ mMultiWaveView.setEnableTarget(resourceId, enabled);
+ }
+
+ public int getTargetPosition(int resourceId) {
+ return mMultiWaveView.getTargetPosition(resourceId);
+ }
}
private void requestUnlockScreen() {
@@ -328,11 +395,8 @@ class LockScreen extends LinearLayout implements KeyguardScreen {
mLockPatternUtils = lockPatternUtils;
mUpdateMonitor = updateMonitor;
mCallback = callback;
-
mEnableMenuKeyInLockScreen = shouldEnableMenuKey();
-
mCreationOrientation = configuration.orientation;
-
mKeyboardHidden = configuration.hardKeyboardHidden;
if (LockPatternKeyguardView.DEBUG_CONFIGURATION) {
@@ -358,10 +422,16 @@ class LockScreen extends LinearLayout implements KeyguardScreen {
mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
mSilentMode = isSilentMode();
-
mUnlockWidget = findViewById(R.id.unlock_widget);
- if (mUnlockWidget instanceof SlidingTab) {
- SlidingTab slidingTabView = (SlidingTab) mUnlockWidget;
+ mUnlockWidgetMethods = createUnlockMethods(mUnlockWidget);
+
+ if (DBG) Log.v(TAG, "*** LockScreen accel is "
+ + (mUnlockWidget.isHardwareAccelerated() ? "on":"off"));
+ }
+
+ private UnlockWidgetCommonMethods createUnlockMethods(View unlockWidget) {
+ if (unlockWidget instanceof SlidingTab) {
+ SlidingTab slidingTabView = (SlidingTab) unlockWidget;
slidingTabView.setHoldAfterTrigger(true, false);
slidingTabView.setLeftHintText(R.string.lockscreen_unlock_label);
slidingTabView.setLeftTabResources(
@@ -371,26 +441,35 @@ class LockScreen extends LinearLayout implements KeyguardScreen {
R.drawable.jog_tab_left_unlock);
SlidingTabMethods slidingTabMethods = new SlidingTabMethods(slidingTabView);
slidingTabView.setOnTriggerListener(slidingTabMethods);
- mUnlockWidgetMethods = slidingTabMethods;
- } else if (mUnlockWidget instanceof WaveView) {
- WaveView waveView = (WaveView) mUnlockWidget;
+ return slidingTabMethods;
+ } else if (unlockWidget instanceof WaveView) {
+ WaveView waveView = (WaveView) unlockWidget;
WaveViewMethods waveViewMethods = new WaveViewMethods(waveView);
waveView.setOnTriggerListener(waveViewMethods);
- mUnlockWidgetMethods = waveViewMethods;
- } else if (mUnlockWidget instanceof MultiWaveView) {
- MultiWaveView multiWaveView = (MultiWaveView) mUnlockWidget;
+ return waveViewMethods;
+ } else if (unlockWidget instanceof MultiWaveView) {
+ MultiWaveView multiWaveView = (MultiWaveView) unlockWidget;
MultiWaveViewMethods multiWaveViewMethods = new MultiWaveViewMethods(multiWaveView);
multiWaveView.setOnTriggerListener(multiWaveViewMethods);
- mUnlockWidgetMethods = multiWaveViewMethods;
+ return multiWaveViewMethods;
} else {
- throw new IllegalStateException("Unrecognized unlock widget: " + mUnlockWidget);
+ throw new IllegalStateException("Unrecognized unlock widget: " + unlockWidget);
}
+ }
- // Update widget with initial ring state
+ private void updateCameraTarget() {
+ boolean disabledByAdmin = mLockPatternUtils.getDevicePolicyManager()
+ .getCameraDisabled(null);
+ boolean disabledBySimState = mUpdateMonitor.isSimLocked();
+ boolean targetPresent = (mUnlockWidgetMethods instanceof MultiWaveViewMethods)
+ ? ((MultiWaveViewMethods) mUnlockWidgetMethods).isCameraTargetPresent() : false;
+ if (disabledByAdmin) {
+ Log.v(TAG, "Camera disabled by Device Policy");
+ } else if (disabledBySimState) {
+ Log.v(TAG, "Camera disabled by Sim State");
+ }
+ mCameraDisabled = disabledByAdmin || disabledBySimState || !targetPresent;
mUnlockWidgetMethods.updateResources();
-
- if (DBG) Log.v(TAG, "*** LockScreen accel is "
- + (mUnlockWidget.isHardwareAccelerated() ? "on":"off"));
}
private boolean isSilentMode() {
@@ -448,6 +527,8 @@ class LockScreen extends LinearLayout implements KeyguardScreen {
/** {@inheritDoc} */
public void onPause() {
+ mUpdateMonitor.removeCallback(mInfoCallback);
+ mUpdateMonitor.removeCallback(mSimStateCallback);
mStatusViewManager.onPause();
mUnlockWidgetMethods.reset(false);
}
@@ -460,27 +541,21 @@ class LockScreen extends LinearLayout implements KeyguardScreen {
/** {@inheritDoc} */
public void onResume() {
+ // We don't want to show the camera target if SIM state prevents us from
+ // launching the camera. So watch for SIM changes...
+ mUpdateMonitor.registerSimStateCallback(mSimStateCallback);
+ mUpdateMonitor.registerInfoCallback(mInfoCallback);
+
mStatusViewManager.onResume();
postDelayed(mOnResumePing, ON_RESUME_PING_DELAY);
}
/** {@inheritDoc} */
public void cleanUp() {
- mUpdateMonitor.removeCallback(this); // this must be first
+ mUpdateMonitor.removeCallback(mInfoCallback); // this must be first
+ mUpdateMonitor.removeCallback(mSimStateCallback);
mLockPatternUtils = null;
mUpdateMonitor = null;
mCallback = null;
}
-
- /** {@inheritDoc} */
- public void onRingerModeChanged(int state) {
- boolean silent = AudioManager.RINGER_MODE_NORMAL != state;
- if (silent != mSilentMode) {
- mSilentMode = silent;
- mUnlockWidgetMethods.updateResources();
- }
- }
-
- public void onPhoneStateChanged(String newState) {
- }
}
diff --git a/policy/src/com/android/internal/policy/impl/SimPukUnlockScreen.java b/policy/src/com/android/internal/policy/impl/SimPukUnlockScreen.java
index ba06996064fe..f3e7d4a95a7a 100644
--- a/policy/src/com/android/internal/policy/impl/SimPukUnlockScreen.java
+++ b/policy/src/com/android/internal/policy/impl/SimPukUnlockScreen.java
@@ -106,7 +106,7 @@ public class SimPukUnlockScreen extends LinearLayout implements KeyguardScreen,
mHeaderText.setSelected(true);
mKeyguardStatusViewManager = new KeyguardStatusViewManager(this, updateMonitor,
- lockpatternutils, callback, false);
+ lockpatternutils, callback, true);
mPinText.setFocusableInTouchMode(true);
mPinText.setOnFocusChangeListener(this);
diff --git a/services/audioflinger/Android.mk b/services/audioflinger/Android.mk
index 5164213b6fbc..257f62ca0281 100644
--- a/services/audioflinger/Android.mk
+++ b/services/audioflinger/Android.mk
@@ -15,6 +15,7 @@ LOCAL_C_INCLUDES := \
$(call include-path-for, audio-effects) \
$(call include-path-for, audio-utils)
+# FIXME keep libmedia_native but remove libmedia after split
LOCAL_SHARED_LIBRARIES := \
libaudioutils \
libcommon_time_client \
@@ -22,6 +23,7 @@ LOCAL_SHARED_LIBRARIES := \
libutils \
libbinder \
libmedia \
+ libmedia_native \
libhardware \
libhardware_legacy \
libeffects \
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 85168ce4b088..3ab4e343e99a 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -894,7 +894,8 @@ status_t AudioFlinger::setParameters(audio_io_handle_t ioHandle, const String8&
// indicate output device change to all input threads for pre processing
AudioParameter param = AudioParameter(keyValuePairs);
int value;
- if (param.getInt(String8(AudioParameter::keyRouting), value) == NO_ERROR) {
+ if ((param.getInt(String8(AudioParameter::keyRouting), value) == NO_ERROR) &&
+ (value != 0)) {
for (size_t i = 0; i < mRecordThreads.size(); i++) {
mRecordThreads.valueAt(i)->setParameters(keyValuePairs);
}
@@ -1588,7 +1589,7 @@ void AudioFlinger::PlaybackThread::onFirstRef()
}
// PlaybackThread::createTrack_l() must be called with AudioFlinger::mLock held
-sp<AudioFlinger::PlaybackThread::Track> AudioFlinger::PlaybackThread::createTrack_l(
+sp<AudioFlinger::PlaybackThread::Track> AudioFlinger::PlaybackThread::createTrack_l(
const sp<AudioFlinger::Client>& client,
audio_stream_type_t streamType,
uint32_t sampleRate,
@@ -2337,7 +2338,7 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::MixerThread::prepareTrac
size_t tracksWithEffect = 0;
float masterVolume = mMasterVolume;
- bool masterMute = mMasterMute;
+ bool masterMute = mMasterMute;
if (masterMute) {
masterVolume = 0;
@@ -2376,7 +2377,7 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::MixerThread::prepareTrac
// +1 for rounding and +1 for additional sample needed for interpolation
minFrames = (mFrameCount * t->sampleRate()) / mSampleRate + 1 + 1;
// add frames already consumed but not yet released by the resampler
- // because cblk->framesReady() will include these frames
+ // because cblk->framesReady() will include these frames
minFrames += mAudioMixer->getUnreleasedFrames(track->name());
// the minimum track buffer size is normally twice the number of frames necessary
// to fill one buffer and the resampler should not leave more than one buffer worth
@@ -2514,6 +2515,7 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::MixerThread::prepareTrac
// reset retry count
track->mRetryCount = kMaxTrackRetries;
+
// If one track is ready, set the mixer ready if:
// - the mixer was not ready during previous round OR
// - no other track is not ready
@@ -3372,19 +3374,19 @@ AudioFlinger::ThreadBase::TrackBase::TrackBase(
}
} else {
mCblk = (audio_track_cblk_t *)(new uint8_t[size]);
- // construct the shared structure in-place.
- new(mCblk) audio_track_cblk_t();
- // clear all buffers
- mCblk->frameCount = frameCount;
- mCblk->sampleRate = sampleRate;
- mChannelCount = channelCount;
- mChannelMask = channelMask;
- mBuffer = (char*)mCblk + sizeof(audio_track_cblk_t);
- memset(mBuffer, 0, frameCount*channelCount*sizeof(int16_t));
- // Force underrun condition to avoid false underrun callback until first data is
- // written to buffer (other flags are cleared)
- mCblk->flags = CBLK_UNDERRUN_ON;
- mBufferEnd = (uint8_t *)mBuffer + bufferSize;
+ // construct the shared structure in-place.
+ new(mCblk) audio_track_cblk_t();
+ // clear all buffers
+ mCblk->frameCount = frameCount;
+ mCblk->sampleRate = sampleRate;
+ mChannelCount = channelCount;
+ mChannelMask = channelMask;
+ mBuffer = (char*)mCblk + sizeof(audio_track_cblk_t);
+ memset(mBuffer, 0, frameCount*channelCount*sizeof(int16_t));
+ // Force underrun condition to avoid false underrun callback until first data is
+ // written to buffer (other flags are cleared)
+ mCblk->flags = CBLK_UNDERRUN_ON;
+ mBufferEnd = (uint8_t *)mBuffer + bufferSize;
}
}
@@ -3792,16 +3794,9 @@ AudioFlinger::PlaybackThread::TimedTrack::create(
if (!client->reserveTimedTrack())
return NULL;
- sp<TimedTrack> track = new TimedTrack(
+ return new TimedTrack(
thread, client, streamType, sampleRate, format, channelMask, frameCount,
sharedBuffer, sessionId);
-
- if (track == NULL) {
- client->releaseTimedTrack();
- return NULL;
- }
-
- return track;
}
AudioFlinger::PlaybackThread::TimedTrack::TimedTrack(
diff --git a/services/audioflinger/AudioMixer.cpp b/services/audioflinger/AudioMixer.cpp
index bd4c939f0fcd..98852fd7e8de 100644
--- a/services/audioflinger/AudioMixer.cpp
+++ b/services/audioflinger/AudioMixer.cpp
@@ -136,7 +136,7 @@ void AudioMixer::deleteTrackName(int name)
invalidateState(1<<name);
}
if (track.resampler != NULL) {
- // delete the resampler
+ // delete the resampler
delete track.resampler;
track.resampler = NULL;
track.sampleRate = mSampleRate;
diff --git a/services/camera/libcameraservice/Android.mk b/services/camera/libcameraservice/Android.mk
index e35435ef5400..3cae1f52b2dc 100644
--- a/services/camera/libcameraservice/Android.mk
+++ b/services/camera/libcameraservice/Android.mk
@@ -15,6 +15,7 @@ LOCAL_SHARED_LIBRARIES:= \
libbinder \
libcutils \
libmedia \
+ libmedia_native \
libcamera_client \
libgui \
libhardware
diff --git a/services/java/com/android/server/BootReceiver.java b/services/java/com/android/server/BootReceiver.java
index da654387f435..22874e686eb2 100644
--- a/services/java/com/android/server/BootReceiver.java
+++ b/services/java/com/android/server/BootReceiver.java
@@ -20,13 +20,13 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
-import android.net.Downloads;
import android.os.Build;
import android.os.DropBoxManager;
import android.os.FileObserver;
import android.os.FileUtils;
import android.os.RecoverySystem;
import android.os.SystemProperties;
+import android.provider.Downloads;
import android.util.Slog;
import java.io.File;
@@ -78,9 +78,8 @@ public class BootReceiver extends BroadcastReceiver {
}.start();
}
- private void removeOldUpdatePackages(Context ctx) {
- Downloads.ByUri.removeAllDownloadsByPackage(
- ctx, OLD_UPDATER_PACKAGE, OLD_UPDATER_CLASS);
+ private void removeOldUpdatePackages(Context context) {
+ Downloads.removeAllDownloadsByPackage(context, OLD_UPDATER_PACKAGE, OLD_UPDATER_CLASS);
}
private void logBootEvents(Context ctx) throws IOException {
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index caee1ab658e1..d21212fe6ecb 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -2258,7 +2258,7 @@ public final class ActivityManagerService extends ActivityManagerNative
for (int i=0; i<N; i++) {
PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
- pal.startFlags, doResume && i == (N-1));
+ pal.startFlags, doResume && i == (N-1), null);
}
mPendingActivityLaunches.clear();
}
@@ -4252,7 +4252,8 @@ public final class ActivityManagerService extends ActivityManagerNative
public IIntentSender getIntentSender(int type,
String packageName, IBinder token, String resultWho,
- int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
+ int requestCode, Intent[] intents, String[] resolvedTypes,
+ int flags, Bundle options) {
enforceNotIsolatedCaller("getIntentSender");
// Refuse possible leaked file descriptors
if (intents != null) {
@@ -4278,6 +4279,11 @@ public final class ActivityManagerService extends ActivityManagerNative
"Intent array length does not match resolvedTypes length");
}
}
+ if (options != null) {
+ if (options.hasFileDescriptors()) {
+ throw new IllegalArgumentException("File descriptors passed in options");
+ }
+ }
synchronized(this) {
int callingUid = Binder.getCallingUid();
@@ -4300,7 +4306,7 @@ public final class ActivityManagerService extends ActivityManagerNative
Slog.i(TAG_MU, "Getting intent sender for origCallingUid="
+ Binder.getOrigCallingUid());
return getIntentSenderLocked(type, packageName, Binder.getOrigCallingUid(),
- token, resultWho, requestCode, intents, resolvedTypes, flags);
+ token, resultWho, requestCode, intents, resolvedTypes, flags, options);
} catch (RemoteException e) {
throw new SecurityException(e);
@@ -4310,7 +4316,8 @@ public final class ActivityManagerService extends ActivityManagerNative
IIntentSender getIntentSenderLocked(int type,
String packageName, int callingUid, IBinder token, String resultWho,
- int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
+ int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
+ Bundle options) {
if (DEBUG_MU)
Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
ActivityRecord activity = null;
@@ -4332,7 +4339,7 @@ public final class ActivityManagerService extends ActivityManagerNative
PendingIntentRecord.Key key = new PendingIntentRecord.Key(
type, packageName, activity, resultWho,
- requestCode, intents, resolvedTypes, flags);
+ requestCode, intents, resolvedTypes, flags, options);
WeakReference<PendingIntentRecord> ref;
ref = mIntentSenderRecords.get(key);
PendingIntentRecord rec = ref != null ? ref.get() : null;
diff --git a/services/java/com/android/server/am/ActivityRecord.java b/services/java/com/android/server/am/ActivityRecord.java
index b42d98ea844d..53cb2b07a337 100644
--- a/services/java/com/android/server/am/ActivityRecord.java
+++ b/services/java/com/android/server/am/ActivityRecord.java
@@ -20,6 +20,7 @@ import com.android.server.AttributeCache;
import com.android.server.am.ActivityStack.ActivityState;
import android.app.Activity;
+import android.app.ActivityOptions;
import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.ActivityInfo;
@@ -95,6 +96,7 @@ final class ActivityRecord {
ArrayList results; // pending ActivityResult objs we have received
HashSet<WeakReference<PendingIntentRecord>> pendingResults; // all pending intents for this act
ArrayList newIntents; // any pending new intents for single-top mode
+ ActivityOptions pendingOptions; // most recently given options
HashSet<ConnectionRecord> connections; // All ConnectionRecord we hold
UriPermissionOwner uriPermissions; // current special URI access perms.
ProcessRecord app; // if non-null, hosting application
@@ -538,6 +540,28 @@ final class ActivityRecord {
}
}
+ void updateOptionsLocked(Bundle options) {
+ if (options != null) {
+ pendingOptions = new ActivityOptions(options);
+ }
+ }
+
+ void applyOptionsLocked() {
+ if (pendingOptions != null) {
+ if (pendingOptions.isCustomAnimation()) {
+ service.mWindowManager.overridePendingAppTransition(
+ pendingOptions.getPackageName(),
+ pendingOptions.getCustomEnterResId(),
+ pendingOptions.getCustomExitResId());
+ }
+ pendingOptions = null;
+ }
+ }
+
+ void clearOptionsLocked() {
+ pendingOptions = null;
+ }
+
void removeUriPermissionsLocked() {
if (uriPermissions != null) {
uriPermissions.removeUriPermissionsLocked();
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index 13ee008a6008..7e8df356e2a4 100644
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -22,6 +22,7 @@ import com.android.server.am.ActivityManagerService.PendingActivityLaunch;
import android.app.Activity;
import android.app.ActivityManager;
+import android.app.ActivityOptions;
import android.app.AppGlobals;
import android.app.IActivityManager;
import android.app.IThumbnailRetriever;
@@ -1456,6 +1457,7 @@ final class ActivityStack {
// We are starting up the next activity, so tell the window manager
// that the previous one will be hidden soon. This way it can know
// to ignore it when computing the desired screen orientation.
+ boolean noAnim = false;
if (prev != null) {
if (prev.finishing) {
if (DEBUG_TRANSITION) Slog.v(TAG,
@@ -1474,6 +1476,7 @@ final class ActivityStack {
if (DEBUG_TRANSITION) Slog.v(TAG,
"Prepare open transition: prev=" + prev);
if (mNoAnimActivities.contains(next)) {
+ noAnim = true;
mService.mWindowManager.prepareAppTransition(
WindowManagerPolicy.TRANSIT_NONE, false);
} else {
@@ -1490,6 +1493,7 @@ final class ActivityStack {
if (DEBUG_TRANSITION) Slog.v(TAG,
"Prepare open transition: no previous");
if (mNoAnimActivities.contains(next)) {
+ noAnim = true;
mService.mWindowManager.prepareAppTransition(
WindowManagerPolicy.TRANSIT_NONE, false);
} else {
@@ -1497,6 +1501,11 @@ final class ActivityStack {
WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN, false);
}
}
+ if (!noAnim) {
+ next.applyOptionsLocked();
+ } else {
+ next.clearOptionsLocked();
+ }
if (next.app != null && next.app.thread != null) {
if (DEBUG_SWITCH) Slog.v(TAG, "Resume running: " + next);
@@ -1655,7 +1664,7 @@ final class ActivityStack {
}
private final void startActivityLocked(ActivityRecord r, boolean newTask,
- boolean doResume, boolean keepCurTransition) {
+ boolean doResume, boolean keepCurTransition, Bundle options) {
final int NH = mHistory.size();
int addPos = -1;
@@ -1748,6 +1757,7 @@ final class ActivityStack {
: WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN, keepCurTransition);
mNoAnimActivities.remove(r);
}
+ r.updateOptionsLocked(options);
mService.mWindowManager.addAppToken(
addPos, r.appToken, r.task.taskId, r.info.screenOrientation, r.fullscreen);
boolean doShow = true;
@@ -2457,7 +2467,7 @@ final class ActivityStack {
}
err = startActivityUncheckedLocked(r, sourceRecord,
- startFlags, true);
+ startFlags, true, options);
if (mDismissKeyguardOnNextActivity && mPausingActivity == null) {
// Someone asked to have the keyguard dismissed on the next
// activity start, but we are not actually doing an activity
@@ -2480,7 +2490,8 @@ final class ActivityStack {
}
final int startActivityUncheckedLocked(ActivityRecord r,
- ActivityRecord sourceRecord, int startFlags, boolean doResume) {
+ ActivityRecord sourceRecord, int startFlags, boolean doResume,
+ Bundle options) {
final Intent intent = r.intent;
final int callingUid = r.launchedFromUid;
final int userId = r.userId;
@@ -2591,6 +2602,7 @@ final class ActivityStack {
// We really do want to push this one into the
// user's face, right now.
moveHomeToFrontFromLaunchLocked(launchFlags);
+ r.updateOptionsLocked(options);
moveTaskToFrontLocked(taskTop.task, r);
}
}
@@ -2794,6 +2806,7 @@ final class ActivityStack {
if (where >= 0) {
ActivityRecord top = moveActivityToFrontLocked(where);
logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task);
+ top.updateOptionsLocked(options);
top.deliverNewIntentLocked(callingUid, r.intent);
if (doResume) {
resumeTopActivityLocked(null);
@@ -2829,7 +2842,7 @@ final class ActivityStack {
EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, r.task.taskId);
}
logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task);
- startActivityLocked(r, newTask, doResume, keepCurTransition);
+ startActivityLocked(r, newTask, doResume, keepCurTransition, options);
return ActivityManager.START_SUCCESS;
}
@@ -2944,7 +2957,7 @@ final class ActivityStack {
ActivityManager.INTENT_SENDER_ACTIVITY, "android",
realCallingUid, null, null, 0, new Intent[] { intent },
new String[] { resolvedType }, PendingIntent.FLAG_CANCEL_CURRENT
- | PendingIntent.FLAG_ONE_SHOT);
+ | PendingIntent.FLAG_ONE_SHOT, null);
Intent newIntent = new Intent();
if (requestCode >= 0) {
@@ -3095,9 +3108,15 @@ final class ActivityStack {
"FLAG_CANT_SAVE_STATE not supported here");
}
+ Bundle theseOptions;
+ if (options != null && i == intents.length-1) {
+ theseOptions = options;
+ } else {
+ theseOptions = null;
+ }
int res = startActivityLocked(caller, intent, resolvedTypes[i],
aInfo, resultTo, null, -1, callingPid, callingUid,
- 0, options, componentSpecified, outActivity);
+ 0, theseOptions, componentSpecified, outActivity);
if (res < 0) {
return res;
}
diff --git a/services/java/com/android/server/am/PendingIntentRecord.java b/services/java/com/android/server/am/PendingIntentRecord.java
index 9676084d3455..ad15da1a9211 100644
--- a/services/java/com/android/server/am/PendingIntentRecord.java
+++ b/services/java/com/android/server/am/PendingIntentRecord.java
@@ -49,6 +49,7 @@ class PendingIntentRecord extends IIntentSender.Stub {
final int requestCode;
final Intent requestIntent;
final String requestResolvedType;
+ final Bundle options;
Intent[] allIntents;
String[] allResolvedTypes;
final int flags;
@@ -57,7 +58,7 @@ class PendingIntentRecord extends IIntentSender.Stub {
private static final int ODD_PRIME_NUMBER = 37;
Key(int _t, String _p, ActivityRecord _a, String _w,
- int _r, Intent[] _i, String[] _it, int _f) {
+ int _r, Intent[] _i, String[] _it, int _f, Bundle _o) {
type = _t;
packageName = _p;
activity = _a;
@@ -68,6 +69,7 @@ class PendingIntentRecord extends IIntentSender.Stub {
allIntents = _i;
allResolvedTypes = _it;
flags = _f;
+ options = _o;
int hash = 23;
hash = (ODD_PRIME_NUMBER*hash) + _f;
@@ -215,6 +217,13 @@ class PendingIntentRecord extends IIntentSender.Stub {
boolean sendFinish = finishedReceiver != null;
switch (key.type) {
case ActivityManager.INTENT_SENDER_ACTIVITY:
+ if (options == null) {
+ options = key.options;
+ } else if (key.options != null) {
+ Bundle opts = new Bundle(key.options);
+ opts.putAll(options);
+ options = opts;
+ }
try {
if (key.allIntents != null && key.allIntents.length > 1) {
Intent[] allIntents = new Intent[key.allIntents.length];
diff --git a/services/java/com/android/server/net/NetworkPolicyManagerService.java b/services/java/com/android/server/net/NetworkPolicyManagerService.java
index 2ad24e2e5f63..0e04d59b025b 100644
--- a/services/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -157,6 +157,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
private static final int VERSION_ADDED_METERED = 4;
private static final int VERSION_SPLIT_SNOOZE = 5;
private static final int VERSION_ADDED_TIMEZONE = 6;
+ private static final int VERSION_ADDED_INFERRED = 7;
// @VisibleForTesting
public static final int TYPE_WARNING = 0x1;
@@ -179,6 +180,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
private static final String ATTR_LAST_WARNING_SNOOZE = "lastWarningSnooze";
private static final String ATTR_LAST_LIMIT_SNOOZE = "lastLimitSnooze";
private static final String ATTR_METERED = "metered";
+ private static final String ATTR_INFERRED = "inferred";
private static final String ATTR_UID = "uid";
private static final String ATTR_POLICY = "policy";
@@ -522,6 +524,11 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
case MATCH_MOBILE_3G_LOWER:
case MATCH_MOBILE_4G:
case MATCH_MOBILE_ALL:
+ // mobile templates aren't relevant in airplane mode
+ if (isAirplaneModeOn(mContext)) {
+ return false;
+ }
+
// mobile templates are relevant when subscriberid is active
return Objects.equal(getActiveSubscriberId(), template.getSubscriberId());
}
@@ -932,7 +939,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
final NetworkTemplate template = buildTemplateMobileAll(subscriberId);
mNetworkPolicy.put(template, new NetworkPolicy(template, cycleDay, cycleTimezone,
- warningBytes, LIMIT_DISABLED, SNOOZE_NEVER, SNOOZE_NEVER, true));
+ warningBytes, LIMIT_DISABLED, SNOOZE_NEVER, SNOOZE_NEVER, true, true));
writePolicyLocked();
}
}
@@ -1004,12 +1011,18 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
} else {
lastWarningSnooze = SNOOZE_NEVER;
}
+ final boolean inferred;
+ if (version >= VERSION_ADDED_INFERRED) {
+ inferred = readBooleanAttribute(in, ATTR_INFERRED);
+ } else {
+ inferred = false;
+ }
final NetworkTemplate template = new NetworkTemplate(
networkTemplate, subscriberId);
mNetworkPolicy.put(template, new NetworkPolicy(template, cycleDay,
cycleTimezone, warningBytes, limitBytes, lastWarningSnooze,
- lastLimitSnooze, metered));
+ lastLimitSnooze, metered, inferred));
} else if (TAG_UID_POLICY.equals(tag)) {
final int uid = readIntAttribute(in, ATTR_UID);
@@ -1064,7 +1077,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
out.startDocument(null, true);
out.startTag(null, TAG_POLICY_LIST);
- writeIntAttribute(out, ATTR_VERSION, VERSION_ADDED_TIMEZONE);
+ writeIntAttribute(out, ATTR_VERSION, VERSION_ADDED_INFERRED);
writeBooleanAttribute(out, ATTR_RESTRICT_BACKGROUND, mRestrictBackground);
// write all known network policies
@@ -1084,6 +1097,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
writeLongAttribute(out, ATTR_LAST_WARNING_SNOOZE, policy.lastWarningSnooze);
writeLongAttribute(out, ATTR_LAST_LIMIT_SNOOZE, policy.lastLimitSnooze);
writeBooleanAttribute(out, ATTR_METERED, policy.metered);
+ writeBooleanAttribute(out, ATTR_INFERRED, policy.inferred);
out.endTag(null, TAG_NETWORK_POLICY);
}
@@ -1714,6 +1728,11 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
mHandler.getLooper().getQueue().addIdleHandler(handler);
}
+ public static boolean isAirplaneModeOn(Context context) {
+ return Settings.System.getInt(
+ context.getContentResolver(), Settings.System.AIRPLANE_MODE_ON, 0) != 0;
+ }
+
private static void collectKeys(SparseIntArray source, SparseBooleanArray target) {
final int size = source.size();
for (int i = 0; i < size; i++) {
diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java
index 9f45effc8c66..bc98f866f7a2 100644
--- a/services/java/com/android/server/pm/PackageManagerService.java
+++ b/services/java/com/android/server/pm/PackageManagerService.java
@@ -20,6 +20,10 @@ import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER;
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
+import static android.content.pm.PackageManager.ENFORCEMENT_DEFAULT;
+import static android.content.pm.PackageManager.ENFORCEMENT_YES;
+import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
+import static android.Manifest.permission.GRANT_REVOKE_PERMISSIONS;
import static libcore.io.OsConstants.S_ISLNK;
import com.android.internal.app.IMediaContainerService;
@@ -1872,6 +1876,9 @@ public class PackageManagerService extends IPackageManager.Stub {
return PackageManager.PERMISSION_GRANTED;
}
}
+ if (!isPermissionEnforcedLocked(permName)) {
+ return PackageManager.PERMISSION_GRANTED;
+ }
}
return PackageManager.PERMISSION_DENIED;
}
@@ -1890,6 +1897,9 @@ public class PackageManagerService extends IPackageManager.Stub {
return PackageManager.PERMISSION_GRANTED;
}
}
+ if (!isPermissionEnforcedLocked(permName)) {
+ return PackageManager.PERMISSION_GRANTED;
+ }
}
return PackageManager.PERMISSION_DENIED;
}
@@ -8835,4 +8845,44 @@ public class PackageManagerService extends IPackageManager.Stub {
public List<UserInfo> getUsers() {
return mUserManager.getUsers();
}
+
+ @Override
+ public void setPermissionEnforcement(String permission, int enforcement) {
+ mContext.enforceCallingOrSelfPermission(GRANT_REVOKE_PERMISSIONS, null);
+ if (READ_EXTERNAL_STORAGE.equals(permission)) {
+ synchronized (mPackages) {
+ if (mSettings.mReadExternalStorageEnforcement != enforcement) {
+ mSettings.mReadExternalStorageEnforcement = enforcement;
+ mSettings.writeLPr();
+ }
+ }
+ } else {
+ throw new IllegalArgumentException("No selective enforcement for " + permission);
+ }
+ }
+
+ @Override
+ public int getPermissionEnforcement(String permission) {
+ mContext.enforceCallingOrSelfPermission(GRANT_REVOKE_PERMISSIONS, null);
+ if (READ_EXTERNAL_STORAGE.equals(permission)) {
+ synchronized (mPackages) {
+ return mSettings.mReadExternalStorageEnforcement;
+ }
+ } else {
+ throw new IllegalArgumentException("No selective enforcement for " + permission);
+ }
+ }
+
+ private boolean isPermissionEnforcedLocked(String permission) {
+ if (READ_EXTERNAL_STORAGE.equals(permission)) {
+ switch (mSettings.mReadExternalStorageEnforcement) {
+ case ENFORCEMENT_DEFAULT:
+ return false;
+ case ENFORCEMENT_YES:
+ return true;
+ }
+ }
+
+ return true;
+ }
}
diff --git a/services/java/com/android/server/pm/Settings.java b/services/java/com/android/server/pm/Settings.java
index 5da6ac9ec6ef..363d020447d6 100644
--- a/services/java/com/android/server/pm/Settings.java
+++ b/services/java/com/android/server/pm/Settings.java
@@ -20,6 +20,7 @@ import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER;
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
+import static android.content.pm.PackageManager.ENFORCEMENT_DEFAULT;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.JournaledFile;
@@ -74,6 +75,9 @@ final class Settings {
private static final boolean DEBUG_STOPPED = false;
+ private static final String TAG_READ_EXTERNAL_STORAGE = "read-external-storage";
+ private static final String ATTR_ENFORCEMENT = "enforcement";
+
private final File mSettingsFilename;
private final File mBackupSettingsFilename;
private final File mPackageListFilename;
@@ -91,6 +95,8 @@ final class Settings {
int mInternalSdkPlatform;
int mExternalSdkPlatform;
+ int mReadExternalStorageEnforcement = ENFORCEMENT_DEFAULT;
+
/** Device identity for the purpose of package verification. */
private VerifierDeviceIdentity mVerifierDeviceIdentity;
@@ -864,13 +870,20 @@ final class Settings {
serializer.attribute(null, "internal", Integer.toString(mInternalSdkPlatform));
serializer.attribute(null, "external", Integer.toString(mExternalSdkPlatform));
serializer.endTag(null, "last-platform-version");
-
+
if (mVerifierDeviceIdentity != null) {
serializer.startTag(null, "verifier");
serializer.attribute(null, "device", mVerifierDeviceIdentity.toString());
serializer.endTag(null, "verifier");
}
+ if (mReadExternalStorageEnforcement != ENFORCEMENT_DEFAULT) {
+ serializer.startTag(null, TAG_READ_EXTERNAL_STORAGE);
+ serializer.attribute(
+ null, ATTR_ENFORCEMENT, Integer.toString(mReadExternalStorageEnforcement));
+ serializer.endTag(null, TAG_READ_EXTERNAL_STORAGE);
+ }
+
serializer.startTag(null, "permission-trees");
for (BasePermission bp : mPermissionTrees.values()) {
writePermissionLPr(serializer, bp);
@@ -1291,6 +1304,12 @@ final class Settings {
Slog.w(PackageManagerService.TAG, "Discard invalid verifier device id: "
+ e.getMessage());
}
+ } else if (TAG_READ_EXTERNAL_STORAGE.equals(tagName)) {
+ final String enforcement = parser.getAttributeValue(null, ATTR_ENFORCEMENT);
+ try {
+ mReadExternalStorageEnforcement = Integer.parseInt(enforcement);
+ } catch (NumberFormatException e) {
+ }
} else {
Slog.w(PackageManagerService.TAG, "Unknown element under <packages>: "
+ parser.getName());
diff --git a/services/java/com/android/server/wm/AppWindowToken.java b/services/java/com/android/server/wm/AppWindowToken.java
index 67b667ad1557..3ae9f2405649 100644
--- a/services/java/com/android/server/wm/AppWindowToken.java
+++ b/services/java/com/android/server/wm/AppWindowToken.java
@@ -135,6 +135,10 @@ class AppWindowToken extends WindowToken {
animLayerAdjustment = adj;
updateLayers();
}
+ // Start out animation gone if window is gone, or visible if window is visible.
+ transformation.clear();
+ transformation.setAlpha(reportedVisible ? 1 : 0);
+ hasTransformation = true;
}
public void setDummyAnimation() {
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 69936577e57b..407b7324806c 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -8675,7 +8675,6 @@ public class WindowManagerService extends IWindowManager.Stub
} else {
mDimAnimator.show(innerDw, innerDh);
}
- mDimAnimator.show(innerDw, innerDh);
mDimAnimator.updateParameters(mContext.getResources(),
w, currentTime);
}
diff --git a/services/java/com/android/server/wm/WindowState.java b/services/java/com/android/server/wm/WindowState.java
index 57d03741309a..9fc704942d60 100644
--- a/services/java/com/android/server/wm/WindowState.java
+++ b/services/java/com/android/server/wm/WindowState.java
@@ -640,6 +640,10 @@ final class WindowState implements WindowManagerPolicy.WindowState {
mAnimation = anim;
mAnimation.restrictDuration(WindowManagerService.MAX_ANIMATION_DURATION);
mAnimation.scaleCurrentDuration(mService.mWindowAnimationScale);
+ // Start out animation gone if window is gone, or visible if window is visible.
+ mTransformation.clear();
+ mTransformation.setAlpha(mLastHidden ? 0 : 1);
+ mHasLocalTransformation = true;
}
public void clearAnimation() {
@@ -933,13 +937,15 @@ final class WindowState implements WindowManagerPolicy.WindowState {
if (!mService.showSurfaceRobustlyLocked(this)) {
return false;
}
+
+ mService.enableScreenIfNeededLocked();
+
+ mService.applyEnterAnimationLocked(this);
+
mLastAlpha = -1;
mHasDrawn = true;
mLastHidden = false;
mReadyToShow = false;
- mService.enableScreenIfNeededLocked();
-
- mService.applyEnterAnimationLocked(this);
int i = mChildWindows.size();
while (i > 0) {
diff --git a/test-runner/src/android/test/BandwidthTestRunner.java b/test-runner/src/android/test/BandwidthTestRunner.java
deleted file mode 100644
index 9c5478d39388..000000000000
--- a/test-runner/src/android/test/BandwidthTestRunner.java
+++ /dev/null
@@ -1,92 +0,0 @@
-// Copyright 2011 Google Inc. All Rights Reserved.
-
-package android.test;
-
-import android.net.NetworkStats;
-import android.net.NetworkStats.Entry;
-import android.net.TrafficStats;
-import android.os.Bundle;
-
-import junit.framework.AssertionFailedError;
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestListener;
-
-import java.lang.reflect.Method;
-
-/**
- * A specialized {@link android.app.Instrumentation} that can collect Bandwidth statistics during
- * the execution of the test.
- * This is used in place of {@link InstrumentationTestRunner}.
- * i.e. adb shell am instrumentation -w -e class com.android.foo.FooTest \
- * com.android.foo/android.test.BandwidthTestRunner
- *
- * @see NetworkStats and @see TrafficStats for details of the collected statistics
- * @hide
- */
-public class BandwidthTestRunner extends InstrumentationTestRunner implements TestListener {
- private static final String REPORT_KEY_PACKETS_SENT = "txPackets";
- private static final String REPORT_KEY_PACKETS_RECEIVED = "rxPackets";
- private static final String REPORT_KEY_BYTES_SENT = "txBytes";
- private static final String REPORT_KEY_BYTES_RECEIVED = "rxBytes";
- private static final String REPORT_KEY_OPERATIONS = "operations";
-
- private boolean mHasClassAnnotation;
- private boolean mIsBandwidthTest;
- private Bundle mTestResult;
-
- @Override
- public void onCreate(Bundle arguments) {
- super.onCreate(arguments);
- addTestListener(this);
- }
-
- public void addError(Test test, Throwable t) {
- }
-
- public void addFailure(Test test, AssertionFailedError t) {
- }
-
- public void startTest(Test test) {
- String testClass = test.getClass().getName();
- String testName = ((TestCase)test).getName();
- Method testMethod = null;
- try {
- testMethod = test.getClass().getMethod(testName);
- } catch (NoSuchMethodException e) {
- // ignore- the test with given name does not exist. Will be handled during test
- // execution
- }
- try {
- // Look for BandwdthTest annotation on both test class and test method
- if (testMethod != null ) {
- if (testMethod.isAnnotationPresent(BandwidthTest.class) ){
- mIsBandwidthTest = true;
- TrafficStats.startDataProfiling(null);
- } else if (test.getClass().isAnnotationPresent(BandwidthTest.class)){
- mIsBandwidthTest = true;
- TrafficStats.startDataProfiling(null);
- }
- }
- } catch (SecurityException e) {
- // ignore - the test with given name cannot be accessed. Will be handled during
- // test execution
- }
- }
-
- public void endTest(Test test) {
- if (mIsBandwidthTest){
- mTestResult = new Bundle();
- mIsBandwidthTest=false;
- NetworkStats stats = TrafficStats.stopDataProfiling(null);
- Entry entry = stats.getTotal(null);
- mTestResult.putLong(REPORT_KEY_BYTES_RECEIVED, entry.rxBytes);
- mTestResult.putLong(REPORT_KEY_BYTES_SENT, entry.txBytes);
- mTestResult.putLong(REPORT_KEY_PACKETS_RECEIVED, entry.rxPackets);
- mTestResult.putLong(REPORT_KEY_PACKETS_SENT, entry.txPackets);
- mTestResult.putLong(REPORT_KEY_OPERATIONS, entry.operations);
- System.out.println(mTestResult.toString());
- sendStatus(0, mTestResult);
- }
- }
-}
diff --git a/tests/TileBenchmark/src/com/test/tilebenchmark/PlaybackGraphs.java b/tests/TileBenchmark/src/com/test/tilebenchmark/PlaybackGraphs.java
index a3ae9be579ec..065e86f35629 100644
--- a/tests/TileBenchmark/src/com/test/tilebenchmark/PlaybackGraphs.java
+++ b/tests/TileBenchmark/src/com/test/tilebenchmark/PlaybackGraphs.java
@@ -37,10 +37,10 @@ public class PlaybackGraphs {
private static Paint whiteLabels;
private static double viewportCoverage(TileData view, TileData tile) {
- if (tile.left < view.right
- && tile.right >= view.left
- && tile.top < view.bottom
- && tile.bottom >= view.top) {
+ if (tile.left < (view.right * view.scale)
+ && tile.right >= (view.left * view.scale)
+ && tile.top < (view.bottom * view.scale)
+ && tile.bottom >= (view.top * view.scale)) {
return 1.0f;
}
return 0.0f;
@@ -215,7 +215,7 @@ public class PlaybackGraphs {
int lastBar = 0;
for (int frameIndex = 0; frameIndex < data.frames.length; frameIndex++) {
TileData frame[] = data.frames[frameIndex];
- int newBar = (frame[0].top + frame[0].bottom) / 2;
+ int newBar = (int)((frame[0].top + frame[0].bottom) * frame[0].scale / 2.0f);
MetricGen s = Metrics[metricIndex];
double absoluteValue = s.getValue(frame);
diff --git a/tests/TileBenchmark/src/com/test/tilebenchmark/RunData.java b/tests/TileBenchmark/src/com/test/tilebenchmark/RunData.java
index 2da61cc8acf8..5e48afd2b103 100644
--- a/tests/TileBenchmark/src/com/test/tilebenchmark/RunData.java
+++ b/tests/TileBenchmark/src/com/test/tilebenchmark/RunData.java
@@ -46,7 +46,8 @@ public class RunData implements Serializable {
public String toString() {
return "Tile (" + left + "," + top + ")->("
- + right + "," + bottom + ")";
+ + right + "," + bottom + ")"
+ + (isReady ? "ready" : "NOTready") + " at scale " + scale;
}
}
diff --git a/tools/aapt/Bundle.h b/tools/aapt/Bundle.h
index 8e3a1c9d11af..daeadc06fba9 100644
--- a/tools/aapt/Bundle.h
+++ b/tools/aapt/Bundle.h
@@ -83,7 +83,7 @@ public:
bool getForce(void) const { return mForce; }
void setForce(bool val) { mForce = val; }
void setGrayscaleTolerance(int val) { mGrayscaleTolerance = val; }
- int getGrayscaleTolerance() { return mGrayscaleTolerance; }
+ int getGrayscaleTolerance() const { return mGrayscaleTolerance; }
bool getMakePackageDirs(void) const { return mMakePackageDirs; }
void setMakePackageDirs(bool val) { mMakePackageDirs = val; }
bool getUpdate(void) const { return mUpdate; }
@@ -166,14 +166,14 @@ public:
void setExtraPackages(const char* val) { mExtraPackages = val; }
const char* getMaxResVersion() const { return mMaxResVersion; }
void setMaxResVersion(const char * val) { mMaxResVersion = val; }
- bool getDebugMode() { return mDebugMode; }
+ bool getDebugMode() const { return mDebugMode; }
void setDebugMode(bool val) { mDebugMode = val; }
- bool getNonConstantId() { return mNonConstantId; }
+ bool getNonConstantId() const { return mNonConstantId; }
void setNonConstantId(bool val) { mNonConstantId = val; }
const char* getProduct() const { return mProduct; }
void setProduct(const char * val) { mProduct = val; }
void setUseCrunchCache(bool val) { mUseCrunchCache = val; }
- bool getUseCrunchCache() { return mUseCrunchCache; }
+ bool getUseCrunchCache() const { return mUseCrunchCache; }
/*
* Set and get the file specification.
diff --git a/tools/aapt/Images.cpp b/tools/aapt/Images.cpp
index 6402e3cb38d8..2b9b056776dc 100644
--- a/tools/aapt/Images.cpp
+++ b/tools/aapt/Images.cpp
@@ -964,7 +964,7 @@ static void write_png(const char* imageName,
compression_type));
}
-status_t preProcessImage(Bundle* bundle, const sp<AaptAssets>& assets,
+status_t preProcessImage(const Bundle* bundle, const sp<AaptAssets>& assets,
const sp<AaptFile>& file, String8* outNewLeafName)
{
String8 ext(file->getPath().getPathExtension());
@@ -1084,7 +1084,7 @@ bail:
return error;
}
-status_t preProcessImageToCache(Bundle* bundle, String8 source, String8 dest)
+status_t preProcessImageToCache(const Bundle* bundle, const String8& source, const String8& dest)
{
png_structp read_ptr = NULL;
png_infop read_info = NULL;
diff --git a/tools/aapt/Images.h b/tools/aapt/Images.h
index 4816905572c9..91b6554c02c9 100644
--- a/tools/aapt/Images.h
+++ b/tools/aapt/Images.h
@@ -15,10 +15,10 @@
using android::String8;
-status_t preProcessImage(Bundle* bundle, const sp<AaptAssets>& assets,
+status_t preProcessImage(const Bundle* bundle, const sp<AaptAssets>& assets,
const sp<AaptFile>& file, String8* outNewLeafName);
-status_t preProcessImageToCache(Bundle* bundle, String8 source, String8 dest);
+status_t preProcessImageToCache(const Bundle* bundle, const String8& source, const String8& dest);
status_t postProcessImage(const sp<AaptAssets>& assets,
ResourceTable* table, const sp<AaptFile>& file);
diff --git a/tools/aapt/Resource.cpp b/tools/aapt/Resource.cpp
index 7eaf5280f5d4..b9ec30ca4915 100644
--- a/tools/aapt/Resource.cpp
+++ b/tools/aapt/Resource.cpp
@@ -14,6 +14,8 @@
#include "FileFinder.h"
#include "CacheUpdater.h"
+#include <utils/WorkQueue.h>
+
#if HAVE_PRINTF_ZD
# define ZD "%zd"
# define ZD_TYPE ssize_t
@@ -24,6 +26,9 @@
#define NOISY(x) // x
+// Number of threads to use for preprocessing images.
+static const size_t MAX_THREADS = 4;
+
// ==========================================================================
// ==========================================================================
// ==========================================================================
@@ -302,21 +307,52 @@ static status_t makeFileResources(Bundle* bundle, const sp<AaptAssets>& assets,
return hasErrors ? UNKNOWN_ERROR : NO_ERROR;
}
-static status_t preProcessImages(Bundle* bundle, const sp<AaptAssets>& assets,
+class PreProcessImageWorkUnit : public WorkQueue::WorkUnit {
+public:
+ PreProcessImageWorkUnit(const Bundle* bundle, const sp<AaptAssets>& assets,
+ const sp<AaptFile>& file, volatile bool* hasErrors) :
+ mBundle(bundle), mAssets(assets), mFile(file), mHasErrors(hasErrors) {
+ }
+
+ virtual bool run() {
+ status_t status = preProcessImage(mBundle, mAssets, mFile, NULL);
+ if (status) {
+ *mHasErrors = true;
+ }
+ return true; // continue even if there are errors
+ }
+
+private:
+ const Bundle* mBundle;
+ sp<AaptAssets> mAssets;
+ sp<AaptFile> mFile;
+ volatile bool* mHasErrors;
+};
+
+static status_t preProcessImages(const Bundle* bundle, const sp<AaptAssets>& assets,
const sp<ResourceTypeSet>& set, const char* type)
{
- bool hasErrors = false;
+ volatile bool hasErrors = false;
ssize_t res = NO_ERROR;
if (bundle->getUseCrunchCache() == false) {
+ WorkQueue wq(MAX_THREADS, false);
ResourceDirIterator it(set, String8(type));
- Vector<sp<AaptFile> > newNameFiles;
- Vector<String8> newNamePaths;
while ((res=it.next()) == NO_ERROR) {
- res = preProcessImage(bundle, assets, it.getFile(), NULL);
- if (res < NO_ERROR) {
+ PreProcessImageWorkUnit* w = new PreProcessImageWorkUnit(
+ bundle, assets, it.getFile(), &hasErrors);
+ status_t status = wq.schedule(w);
+ if (status) {
+ fprintf(stderr, "preProcessImages failed: schedule() returned %d\n", status);
hasErrors = true;
+ delete w;
+ break;
}
}
+ status_t status = wq.finish();
+ if (status) {
+ fprintf(stderr, "preProcessImages failed: finish() returned %d\n", status);
+ hasErrors = true;
+ }
}
return (hasErrors || (res < NO_ERROR)) ? UNKNOWN_ERROR : NO_ERROR;
}
diff --git a/tools/aapt/StringPool.cpp b/tools/aapt/StringPool.cpp
index 46a4c3262b66..839eda5151b0 100644
--- a/tools/aapt/StringPool.cpp
+++ b/tools/aapt/StringPool.cpp
@@ -9,6 +9,7 @@
#include <utils/ByteOrder.h>
#include <utils/SortedVector.h>
+#include <cutils/qsort_r_compat.h>
#if HAVE_PRINTF_ZD
# define ZD "%zd"
@@ -71,14 +72,16 @@ String8 StringPool::entry::makeConfigsString() const {
}
int StringPool::entry::compare(const entry& o) const {
- // Strings with styles go first, to reduce the size of the
- // styles array.
+ // Strings with styles go first, to reduce the size of the styles array.
+ // We don't care about the relative order of these strings.
if (hasStyles) {
return o.hasStyles ? 0 : -1;
}
if (o.hasStyles) {
return 1;
}
+
+ // Sort unstyled strings by type, then by logical configuration.
int comp = configTypeName.compare(o.configTypeName);
if (comp != 0) {
return comp;
@@ -211,11 +214,11 @@ status_t StringPool::addStyleSpan(size_t idx, const entry_style_span& span)
return NO_ERROR;
}
-int StringPool::config_sort(const size_t* lhs, const size_t* rhs, void* state)
+int StringPool::config_sort(void* state, const void* lhs, const void* rhs)
{
StringPool* pool = (StringPool*)state;
- const entry& lhe = pool->mEntries[pool->mEntryArray[*lhs]];
- const entry& rhe = pool->mEntries[pool->mEntryArray[*rhs]];
+ const entry& lhe = pool->mEntries[pool->mEntryArray[*static_cast<const size_t*>(lhs)]];
+ const entry& rhe = pool->mEntries[pool->mEntryArray[*static_cast<const size_t*>(rhs)]];
return lhe.compare(rhe);
}
@@ -230,13 +233,17 @@ void StringPool::sortByConfig()
// At that point it maps from the new position in the array to the
// original position the entry appeared.
Vector<size_t> newPosToOriginalPos;
- for (size_t i=0; i<mEntryArray.size(); i++) {
+ newPosToOriginalPos.setCapacity(N);
+ for (size_t i=0; i < N; i++) {
newPosToOriginalPos.add(i);
}
// Sort the array.
NOISY(printf("SORTING STRINGS BY CONFIGURATION...\n"));
- newPosToOriginalPos.sort(config_sort, this);
+ // Vector::sort uses insertion sort, which is very slow for this data set.
+ // Use quicksort instead because we don't need a stable sort here.
+ qsort_r_compat(newPosToOriginalPos.editArray(), N, sizeof(size_t), this, config_sort);
+ //newPosToOriginalPos.sort(config_sort, this);
NOISY(printf("DONE SORTING STRINGS BY CONFIGURATION.\n"));
// Create the reverse mapping from the original position in the array
diff --git a/tools/aapt/StringPool.h b/tools/aapt/StringPool.h
index 060dc6811c8b..d5010086b292 100644
--- a/tools/aapt/StringPool.h
+++ b/tools/aapt/StringPool.h
@@ -139,7 +139,7 @@ public:
const Vector<size_t>* offsetsForString(const String16& val) const;
private:
- static int config_sort(const size_t* lhs, const size_t* rhs, void* state);
+ static int config_sort(void* state, const void* lhs, const void* rhs);
const bool mUTF8;
diff --git a/voip/jni/rtp/Android.mk b/voip/jni/rtp/Android.mk
index 49b711d4b84e..d7257133b845 100644
--- a/voip/jni/rtp/Android.mk
+++ b/voip/jni/rtp/Android.mk
@@ -37,6 +37,7 @@ LOCAL_SHARED_LIBRARIES := \
libcutils \
libutils \
libmedia \
+ libmedia_native \
libstagefright_amrnb_common
LOCAL_STATIC_LIBRARIES := libgsm libstagefright_amrnbdec libstagefright_amrnbenc
diff --git a/voip/jni/rtp/AudioGroup.cpp b/voip/jni/rtp/AudioGroup.cpp
index 1139577f1f93..b9bbd164ded7 100644
--- a/voip/jni/rtp/AudioGroup.cpp
+++ b/voip/jni/rtp/AudioGroup.cpp
@@ -809,9 +809,9 @@ bool AudioGroup::DeviceThread::threadLoop()
AudioTrack track;
AudioRecord record;
if (track.set(AUDIO_STREAM_VOICE_CALL, sampleRate, AUDIO_FORMAT_PCM_16_BIT,
- AUDIO_CHANNEL_OUT_MONO, output) != NO_ERROR || record.set(
- AUDIO_SOURCE_VOICE_COMMUNICATION, sampleRate, AUDIO_FORMAT_PCM_16_BIT,
- AUDIO_CHANNEL_IN_MONO, input) != NO_ERROR) {
+ AUDIO_CHANNEL_OUT_MONO, output) != NO_ERROR ||
+ record.set(AUDIO_SOURCE_VOICE_COMMUNICATION, sampleRate, AUDIO_FORMAT_PCM_16_BIT,
+ AUDIO_CHANNEL_IN_MONO, input) != NO_ERROR) {
ALOGE("cannot initialize audio device");
return false;
}