summaryrefslogtreecommitdiffstats
path: root/packages
diff options
context:
space:
mode:
Diffstat (limited to 'packages')
-rw-r--r--packages/BackupRestoreConfirmation/res/values-sw/strings.xml6
-rw-r--r--packages/Keyguard/Android.mk31
-rw-r--r--packages/Keyguard/AndroidManifest.xml49
-rw-r--r--packages/Keyguard/NOTICE190
-rw-r--r--packages/Keyguard/proguard.flags2
-rw-r--r--packages/Keyguard/res/anim/keyguard_action_assist_enter.xml32
-rw-r--r--packages/Keyguard/res/anim/keyguard_action_assist_exit.xml23
-rw-r--r--packages/Keyguard/res/anim/keyguard_security_animate_in.xml33
-rw-r--r--packages/Keyguard/res/anim/keyguard_security_animate_out.xml32
-rw-r--r--packages/Keyguard/res/anim/keyguard_security_fade_in.xml22
-rw-r--r--packages/Keyguard/res/anim/keyguard_security_fade_out.xml21
-rw-r--r--packages/Keyguard/res/anim/lock_screen_enter.xml24
-rw-r--r--packages/Keyguard/res/anim/lock_screen_exit.xml36
-rw-r--r--packages/Keyguard/res/drawable-hdpi/ic_action_assist_generic_activated.pngbin0 -> 9647 bytes
-rw-r--r--packages/Keyguard/res/drawable-hdpi/ic_action_assist_generic_normal.pngbin0 -> 2455 bytes
-rw-r--r--packages/Keyguard/res/drawable-hdpi/ic_facial_backup.pngbin0 -> 583 bytes
-rw-r--r--packages/Keyguard/res/drawable-hdpi/ic_input_delete.pngbin0 -> 1031 bytes
-rw-r--r--packages/Keyguard/res/drawable-hdpi/ic_lockscreen_alarm.pngbin0 -> 1398 bytes
-rw-r--r--packages/Keyguard/res/drawable-hdpi/ic_lockscreen_camera_activated.pngbin0 -> 7214 bytes
-rw-r--r--packages/Keyguard/res/drawable-hdpi/ic_lockscreen_camera_normal.pngbin0 -> 1630 bytes
-rw-r--r--packages/Keyguard/res/drawable-hdpi/ic_lockscreen_emergencycall_normal.pngbin0 -> 915 bytes
-rw-r--r--packages/Keyguard/res/drawable-hdpi/ic_lockscreen_emergencycall_pressed.pngbin0 -> 1754 bytes
-rw-r--r--packages/Keyguard/res/drawable-hdpi/ic_lockscreen_forgotpassword_normal.pngbin0 -> 757 bytes
-rw-r--r--packages/Keyguard/res/drawable-hdpi/ic_lockscreen_forgotpassword_pressed.pngbin0 -> 1403 bytes
-rw-r--r--packages/Keyguard/res/drawable-hdpi/ic_lockscreen_glowdot.pngbin0 -> 738 bytes
-rw-r--r--packages/Keyguard/res/drawable-hdpi/ic_lockscreen_google_activated.pngbin0 -> 12152 bytes
-rw-r--r--packages/Keyguard/res/drawable-hdpi/ic_lockscreen_google_focused.pngbin0 -> 22219 bytes
-rw-r--r--packages/Keyguard/res/drawable-hdpi/ic_lockscreen_google_normal.pngbin0 -> 12262 bytes
-rw-r--r--packages/Keyguard/res/drawable-hdpi/ic_lockscreen_handle_normal.pngbin0 -> 7896 bytes
-rw-r--r--packages/Keyguard/res/drawable-hdpi/ic_lockscreen_handle_pressed.pngbin0 -> 8378 bytes
-rw-r--r--packages/Keyguard/res/drawable-hdpi/ic_lockscreen_ime.pngbin0 -> 202 bytes
-rw-r--r--packages/Keyguard/res/drawable-hdpi/ic_lockscreen_lock_normal.pngbin0 -> 3020 bytes
-rw-r--r--packages/Keyguard/res/drawable-hdpi/ic_lockscreen_lock_pressed.pngbin0 -> 8376 bytes
-rw-r--r--packages/Keyguard/res/drawable-hdpi/ic_lockscreen_player_background.9.pngbin0 -> 129 bytes
-rw-r--r--packages/Keyguard/res/drawable-hdpi/ic_lockscreen_search_activated.pngbin0 -> 2028 bytes
-rw-r--r--packages/Keyguard/res/drawable-hdpi/ic_lockscreen_search_normal.pngbin0 -> 2070 bytes
-rw-r--r--packages/Keyguard/res/drawable-hdpi/ic_lockscreen_silent_activated.pngbin0 -> 7780 bytes
-rw-r--r--packages/Keyguard/res/drawable-hdpi/ic_lockscreen_silent_focused.pngbin0 -> 12968 bytes
-rw-r--r--packages/Keyguard/res/drawable-hdpi/ic_lockscreen_silent_normal.pngbin0 -> 5716 bytes
-rw-r--r--packages/Keyguard/res/drawable-hdpi/ic_lockscreen_sim.pngbin0 -> 4083 bytes
-rw-r--r--packages/Keyguard/res/drawable-hdpi/ic_lockscreen_soundon_activated.pngbin0 -> 7454 bytes
-rw-r--r--packages/Keyguard/res/drawable-hdpi/ic_lockscreen_soundon_focused.pngbin0 -> 12774 bytes
-rw-r--r--packages/Keyguard/res/drawable-hdpi/ic_lockscreen_soundon_normal.pngbin0 -> 5172 bytes
-rw-r--r--packages/Keyguard/res/drawable-hdpi/ic_lockscreen_unlock_activated.pngbin0 -> 6729 bytes
-rw-r--r--packages/Keyguard/res/drawable-hdpi/ic_lockscreen_unlock_normal.pngbin0 -> 1376 bytes
-rw-r--r--packages/Keyguard/res/drawable-hdpi/ic_media_next.pngbin0 -> 1073 bytes
-rw-r--r--packages/Keyguard/res/drawable-hdpi/ic_media_play.pngbin0 -> 1163 bytes
-rw-r--r--packages/Keyguard/res/drawable-hdpi/ic_media_previous.pngbin0 -> 1067 bytes
-rw-r--r--packages/Keyguard/res/drawable-hdpi/intro_bg.pngbin0 -> 202336 bytes
-rw-r--r--packages/Keyguard/res/drawable-hdpi/kg_add_widget.pngbin0 -> 1648 bytes
-rw-r--r--packages/Keyguard/res/drawable-hdpi/kg_add_widget_disabled.pngbin0 -> 1066 bytes
-rw-r--r--packages/Keyguard/res/drawable-hdpi/kg_add_widget_pressed.pngbin0 -> 1004 bytes
-rw-r--r--packages/Keyguard/res/drawable-hdpi/kg_bouncer_bg_white.9.pngbin0 -> 546 bytes
-rw-r--r--packages/Keyguard/res/drawable-hdpi/kg_security_grip.9.pngbin0 -> 140 bytes
-rw-r--r--packages/Keyguard/res/drawable-hdpi/kg_security_lock.pngbin0 -> 2700 bytes
-rw-r--r--packages/Keyguard/res/drawable-hdpi/kg_security_lock_focused.pngbin0 -> 2377 bytes
-rw-r--r--packages/Keyguard/res/drawable-hdpi/kg_security_lock_normal.pngbin0 -> 2688 bytes
-rw-r--r--packages/Keyguard/res/drawable-hdpi/kg_security_lock_pressed.pngbin0 -> 1760 bytes
-rw-r--r--packages/Keyguard/res/drawable-hdpi/kg_widget_bg_padded.9.pngbin0 -> 3272 bytes
-rw-r--r--packages/Keyguard/res/drawable-hdpi/kg_widget_delete_drop_target.pngbin0 -> 1003 bytes
-rw-r--r--packages/Keyguard/res/drawable-hdpi/lockscreen_protection_pattern.pngbin0 -> 347 bytes
-rw-r--r--packages/Keyguard/res/drawable-hdpi/sym_keyboard_return_holo.pngbin0 -> 1104 bytes
-rw-r--r--packages/Keyguard/res/drawable-ldpi/ic_input_delete.pngbin0 -> 825 bytes
-rw-r--r--packages/Keyguard/res/drawable-ldpi/ic_media_next.pngbin0 -> 735 bytes
-rw-r--r--packages/Keyguard/res/drawable-ldpi/ic_media_play.pngbin0 -> 673 bytes
-rw-r--r--packages/Keyguard/res/drawable-ldpi/ic_media_previous.pngbin0 -> 770 bytes
-rw-r--r--packages/Keyguard/res/drawable-mdpi/ic_action_assist_generic_activated.pngbin0 -> 5808 bytes
-rw-r--r--packages/Keyguard/res/drawable-mdpi/ic_action_assist_generic_normal.pngbin0 -> 1601 bytes
-rw-r--r--packages/Keyguard/res/drawable-mdpi/ic_facial_backup.pngbin0 -> 520 bytes
-rw-r--r--packages/Keyguard/res/drawable-mdpi/ic_input_delete.pngbin0 -> 786 bytes
-rw-r--r--packages/Keyguard/res/drawable-mdpi/ic_lockscreen_alarm.pngbin0 -> 839 bytes
-rw-r--r--packages/Keyguard/res/drawable-mdpi/ic_lockscreen_camera_activated.pngbin0 -> 4543 bytes
-rw-r--r--packages/Keyguard/res/drawable-mdpi/ic_lockscreen_camera_normal.pngbin0 -> 1186 bytes
-rw-r--r--packages/Keyguard/res/drawable-mdpi/ic_lockscreen_emergencycall_normal.pngbin0 -> 660 bytes
-rw-r--r--packages/Keyguard/res/drawable-mdpi/ic_lockscreen_emergencycall_pressed.pngbin0 -> 1223 bytes
-rw-r--r--packages/Keyguard/res/drawable-mdpi/ic_lockscreen_forgotpassword_normal.pngbin0 -> 591 bytes
-rw-r--r--packages/Keyguard/res/drawable-mdpi/ic_lockscreen_forgotpassword_pressed.pngbin0 -> 947 bytes
-rw-r--r--packages/Keyguard/res/drawable-mdpi/ic_lockscreen_glowdot.pngbin0 -> 538 bytes
-rw-r--r--packages/Keyguard/res/drawable-mdpi/ic_lockscreen_google_activated.pngbin0 -> 7057 bytes
-rw-r--r--packages/Keyguard/res/drawable-mdpi/ic_lockscreen_google_focused.pngbin0 -> 11446 bytes
-rw-r--r--packages/Keyguard/res/drawable-mdpi/ic_lockscreen_google_normal.pngbin0 -> 6519 bytes
-rw-r--r--packages/Keyguard/res/drawable-mdpi/ic_lockscreen_handle_normal.pngbin0 -> 4412 bytes
-rw-r--r--packages/Keyguard/res/drawable-mdpi/ic_lockscreen_handle_pressed.pngbin0 -> 4299 bytes
-rw-r--r--packages/Keyguard/res/drawable-mdpi/ic_lockscreen_ime.pngbin0 -> 157 bytes
-rw-r--r--packages/Keyguard/res/drawable-mdpi/ic_lockscreen_lock_normal.pngbin0 -> 1883 bytes
-rw-r--r--packages/Keyguard/res/drawable-mdpi/ic_lockscreen_lock_pressed.pngbin0 -> 4800 bytes
-rw-r--r--packages/Keyguard/res/drawable-mdpi/ic_lockscreen_player_background.9.pngbin0 -> 118 bytes
-rw-r--r--packages/Keyguard/res/drawable-mdpi/ic_lockscreen_search_activated.pngbin0 -> 1937 bytes
-rw-r--r--packages/Keyguard/res/drawable-mdpi/ic_lockscreen_search_normal.pngbin0 -> 1937 bytes
-rw-r--r--packages/Keyguard/res/drawable-mdpi/ic_lockscreen_silent_activated.pngbin0 -> 4740 bytes
-rw-r--r--packages/Keyguard/res/drawable-mdpi/ic_lockscreen_silent_focused.pngbin0 -> 7048 bytes
-rw-r--r--packages/Keyguard/res/drawable-mdpi/ic_lockscreen_silent_normal.pngbin0 -> 3123 bytes
-rw-r--r--packages/Keyguard/res/drawable-mdpi/ic_lockscreen_sim.pngbin0 -> 2602 bytes
-rw-r--r--packages/Keyguard/res/drawable-mdpi/ic_lockscreen_soundon_activated.pngbin0 -> 4538 bytes
-rw-r--r--packages/Keyguard/res/drawable-mdpi/ic_lockscreen_soundon_focused.pngbin0 -> 7042 bytes
-rw-r--r--packages/Keyguard/res/drawable-mdpi/ic_lockscreen_soundon_normal.pngbin0 -> 2871 bytes
-rw-r--r--packages/Keyguard/res/drawable-mdpi/ic_lockscreen_unlock_activated.pngbin0 -> 4237 bytes
-rw-r--r--packages/Keyguard/res/drawable-mdpi/ic_lockscreen_unlock_normal.pngbin0 -> 1041 bytes
-rw-r--r--packages/Keyguard/res/drawable-mdpi/ic_media_next.pngbin0 -> 843 bytes
-rw-r--r--packages/Keyguard/res/drawable-mdpi/ic_media_play.pngbin0 -> 897 bytes
-rw-r--r--packages/Keyguard/res/drawable-mdpi/ic_media_previous.pngbin0 -> 837 bytes
-rw-r--r--packages/Keyguard/res/drawable-mdpi/intro_bg.pngbin0 -> 90061 bytes
-rw-r--r--packages/Keyguard/res/drawable-mdpi/kg_add_widget.pngbin0 -> 1185 bytes
-rw-r--r--packages/Keyguard/res/drawable-mdpi/kg_add_widget_disabled.pngbin0 -> 832 bytes
-rw-r--r--packages/Keyguard/res/drawable-mdpi/kg_add_widget_pressed.pngbin0 -> 809 bytes
-rw-r--r--packages/Keyguard/res/drawable-mdpi/kg_bouncer_bg_white.9.pngbin0 -> 397 bytes
-rw-r--r--packages/Keyguard/res/drawable-mdpi/kg_security_grip.9.pngbin0 -> 136 bytes
-rw-r--r--packages/Keyguard/res/drawable-mdpi/kg_security_lock.pngbin0 -> 1921 bytes
-rw-r--r--packages/Keyguard/res/drawable-mdpi/kg_security_lock_focused.pngbin0 -> 1567 bytes
-rw-r--r--packages/Keyguard/res/drawable-mdpi/kg_security_lock_normal.pngbin0 -> 1899 bytes
-rw-r--r--packages/Keyguard/res/drawable-mdpi/kg_security_lock_pressed.pngbin0 -> 1347 bytes
-rw-r--r--packages/Keyguard/res/drawable-mdpi/kg_widget_bg_padded.9.pngbin0 -> 3149 bytes
-rw-r--r--packages/Keyguard/res/drawable-mdpi/kg_widget_delete_drop_target.pngbin0 -> 802 bytes
-rw-r--r--packages/Keyguard/res/drawable-mdpi/lockscreen_protection_pattern.pngbin0 -> 351 bytes
-rw-r--r--packages/Keyguard/res/drawable-mdpi/sym_keyboard_return_holo.pngbin0 -> 823 bytes
-rw-r--r--packages/Keyguard/res/drawable-nodpi/app_icon.pngbin0 -> 154535 bytes
-rw-r--r--packages/Keyguard/res/drawable-sw600dp-hdpi/ic_lockscreen_handle_normal.pngbin0 -> 13316 bytes
-rw-r--r--packages/Keyguard/res/drawable-sw600dp-hdpi/ic_lockscreen_handle_pressed.pngbin0 -> 15564 bytes
-rw-r--r--packages/Keyguard/res/drawable-sw600dp-mdpi/ic_lockscreen_handle_normal.pngbin0 -> 6774 bytes
-rw-r--r--packages/Keyguard/res/drawable-sw600dp-mdpi/ic_lockscreen_handle_pressed.pngbin0 -> 8147 bytes
-rw-r--r--packages/Keyguard/res/drawable-sw600dp-xhdpi/ic_lockscreen_handle_normal.pngbin0 -> 21777 bytes
-rw-r--r--packages/Keyguard/res/drawable-sw600dp-xhdpi/ic_lockscreen_handle_pressed.pngbin0 -> 25531 bytes
-rw-r--r--packages/Keyguard/res/drawable-xhdpi/ic_action_assist_generic_activated.pngbin0 -> 13973 bytes
-rw-r--r--packages/Keyguard/res/drawable-xhdpi/ic_action_assist_generic_normal.pngbin0 -> 3230 bytes
-rw-r--r--packages/Keyguard/res/drawable-xhdpi/ic_facial_backup.pngbin0 -> 841 bytes
-rw-r--r--packages/Keyguard/res/drawable-xhdpi/ic_input_delete.pngbin0 -> 1307 bytes
-rw-r--r--packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_alarm.pngbin0 -> 2130 bytes
-rw-r--r--packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_camera_activated.pngbin0 -> 10375 bytes
-rw-r--r--packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_camera_normal.pngbin0 -> 2341 bytes
-rw-r--r--packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_emergencycall_normal.pngbin0 -> 1165 bytes
-rw-r--r--packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_emergencycall_pressed.pngbin0 -> 2287 bytes
-rw-r--r--packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_forgotpassword_normal.pngbin0 -> 957 bytes
-rw-r--r--packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_forgotpassword_pressed.pngbin0 -> 1907 bytes
-rw-r--r--packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_glowdot.pngbin0 -> 964 bytes
-rw-r--r--packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_google_activated.pngbin0 -> 17254 bytes
-rw-r--r--packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_google_focused.pngbin0 -> 31637 bytes
-rw-r--r--packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_google_normal.pngbin0 -> 18528 bytes
-rw-r--r--packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_handle_normal.pngbin0 -> 11519 bytes
-rw-r--r--packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_handle_pressed.pngbin0 -> 12182 bytes
-rw-r--r--packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_ime.pngbin0 -> 217 bytes
-rw-r--r--packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_lock_normal.pngbin0 -> 4173 bytes
-rw-r--r--packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_lock_pressed.pngbin0 -> 12221 bytes
-rw-r--r--packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_player_background.9.pngbin0 -> 144 bytes
-rw-r--r--packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_silent_activated.pngbin0 -> 11182 bytes
-rw-r--r--packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_silent_focused.pngbin0 -> 19515 bytes
-rw-r--r--packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_silent_normal.pngbin0 -> 8633 bytes
-rw-r--r--packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_sim.pngbin0 -> 5201 bytes
-rw-r--r--packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_soundon_activated.pngbin0 -> 10638 bytes
-rw-r--r--packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_soundon_focused.pngbin0 -> 19513 bytes
-rw-r--r--packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_soundon_normal.pngbin0 -> 7698 bytes
-rw-r--r--packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_unlock_activated.pngbin0 -> 9615 bytes
-rw-r--r--packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_unlock_normal.pngbin0 -> 1760 bytes
-rw-r--r--packages/Keyguard/res/drawable-xhdpi/ic_media_next.pngbin0 -> 1364 bytes
-rw-r--r--packages/Keyguard/res/drawable-xhdpi/ic_media_play.pngbin0 -> 1617 bytes
-rw-r--r--packages/Keyguard/res/drawable-xhdpi/ic_media_previous.pngbin0 -> 1372 bytes
-rw-r--r--packages/Keyguard/res/drawable-xhdpi/intro_bg.pngbin0 -> 343210 bytes
-rw-r--r--packages/Keyguard/res/drawable-xhdpi/kg_add_widget.pngbin0 -> 2220 bytes
-rw-r--r--packages/Keyguard/res/drawable-xhdpi/kg_add_widget_disabled.pngbin0 -> 1351 bytes
-rw-r--r--packages/Keyguard/res/drawable-xhdpi/kg_add_widget_pressed.pngbin0 -> 1251 bytes
-rw-r--r--packages/Keyguard/res/drawable-xhdpi/kg_bouncer_bg_white.9.pngbin0 -> 775 bytes
-rw-r--r--packages/Keyguard/res/drawable-xhdpi/kg_security_grip.9.pngbin0 -> 149 bytes
-rw-r--r--packages/Keyguard/res/drawable-xhdpi/kg_security_lock.pngbin0 -> 3499 bytes
-rw-r--r--packages/Keyguard/res/drawable-xhdpi/kg_security_lock_focused.pngbin0 -> 3277 bytes
-rw-r--r--packages/Keyguard/res/drawable-xhdpi/kg_security_lock_normal.pngbin0 -> 3517 bytes
-rw-r--r--packages/Keyguard/res/drawable-xhdpi/kg_security_lock_pressed.pngbin0 -> 2173 bytes
-rw-r--r--packages/Keyguard/res/drawable-xhdpi/kg_widget_bg_padded.9.pngbin0 -> 3474 bytes
-rw-r--r--packages/Keyguard/res/drawable-xhdpi/kg_widget_delete_drop_target.pngbin0 -> 1392 bytes
-rw-r--r--packages/Keyguard/res/drawable-xhdpi/lockscreen_protection_pattern.pngbin0 -> 365 bytes
-rw-r--r--packages/Keyguard/res/drawable-xhdpi/sym_keyboard_return_holo.pngbin0 -> 1501 bytes
-rw-r--r--packages/Keyguard/res/drawable/ic_action_assist_generic.xml36
-rw-r--r--packages/Keyguard/res/drawable/ic_lockscreen_camera.xml36
-rw-r--r--packages/Keyguard/res/drawable/ic_lockscreen_handle.xml30
-rw-r--r--packages/Keyguard/res/drawable/ic_lockscreen_outerring.xml24
-rw-r--r--packages/Keyguard/res/drawable/ic_lockscreen_silent.xml36
-rw-r--r--packages/Keyguard/res/drawable/ic_lockscreen_soundon.xml36
-rw-r--r--packages/Keyguard/res/drawable/ic_lockscreen_unlock.xml36
-rw-r--r--packages/Keyguard/res/drawable/ic_lockscreen_unlock_phantom.xml36
-rw-r--r--packages/Keyguard/res/drawable/keyguard_add_widget_button.xml21
-rw-r--r--packages/Keyguard/res/drawable/keyguard_expand_challenge_handle.xml21
-rw-r--r--packages/Keyguard/res/drawable/lockscreen_emergency_button.xml21
-rw-r--r--packages/Keyguard/res/drawable/lockscreen_forgot_password_button.xml21
-rw-r--r--packages/Keyguard/res/layout-land/keyguard_host_view.xml81
-rw-r--r--packages/Keyguard/res/layout-land/keyguard_status_area.xml56
-rw-r--r--packages/Keyguard/res/layout-land/keyguard_widget_pager.xml30
-rw-r--r--packages/Keyguard/res/layout-port/keyguard_host_view.xml94
-rw-r--r--packages/Keyguard/res/layout-port/keyguard_status_area.xml59
-rw-r--r--packages/Keyguard/res/layout-port/keyguard_widget_pager.xml31
-rw-r--r--packages/Keyguard/res/layout-sw600dp-port/keyguard_host_view.xml82
-rw-r--r--packages/Keyguard/res/layout-sw600dp/keyguard_glow_pad_container.xml24
-rw-r--r--packages/Keyguard/res/layout/keyguard_account_view.xml88
-rw-r--r--packages/Keyguard/res/layout/keyguard_add_widget.xml42
-rw-r--r--packages/Keyguard/res/layout/keyguard_emergency_carrier_area.xml75
-rw-r--r--packages/Keyguard/res/layout/keyguard_emergency_carrier_area_empty.xml31
-rw-r--r--packages/Keyguard/res/layout/keyguard_face_unlock_view.xml79
-rw-r--r--packages/Keyguard/res/layout/keyguard_glow_pad_container.xml26
-rw-r--r--packages/Keyguard/res/layout/keyguard_glow_pad_view.xml46
-rw-r--r--packages/Keyguard/res/layout/keyguard_message_area.xml33
-rw-r--r--packages/Keyguard/res/layout/keyguard_message_area_large.xml31
-rw-r--r--packages/Keyguard/res/layout/keyguard_multi_user_avatar.xml45
-rw-r--r--packages/Keyguard/res/layout/keyguard_multi_user_selector.xml39
-rw-r--r--packages/Keyguard/res/layout/keyguard_password_view.xml105
-rw-r--r--packages/Keyguard/res/layout/keyguard_pattern_view.xml79
-rw-r--r--packages/Keyguard/res/layout/keyguard_pin_view.xml224
-rw-r--r--packages/Keyguard/res/layout/keyguard_selector_view.xml64
-rw-r--r--packages/Keyguard/res/layout/keyguard_sim_pin_view.xml230
-rw-r--r--packages/Keyguard/res/layout/keyguard_sim_puk_view.xml230
-rw-r--r--packages/Keyguard/res/layout/keyguard_status_view.xml68
-rw-r--r--packages/Keyguard/res/layout/keyguard_test_activity.xml47
-rw-r--r--packages/Keyguard/res/layout/keyguard_transport_control_view.xml112
-rw-r--r--packages/Keyguard/res/layout/keyguard_widget_remove_drop_target.xml33
-rw-r--r--packages/Keyguard/res/menu/optionmenu.xml17
-rw-r--r--packages/Keyguard/res/values-af/strings.xml164
-rw-r--r--packages/Keyguard/res/values-am/strings.xml164
-rw-r--r--packages/Keyguard/res/values-ar/strings.xml164
-rw-r--r--packages/Keyguard/res/values-be/strings.xml164
-rw-r--r--packages/Keyguard/res/values-bg/strings.xml164
-rw-r--r--packages/Keyguard/res/values-ca/strings.xml164
-rw-r--r--packages/Keyguard/res/values-cs/strings.xml164
-rw-r--r--packages/Keyguard/res/values-da/strings.xml164
-rw-r--r--packages/Keyguard/res/values-de/strings.xml164
-rw-r--r--packages/Keyguard/res/values-el/strings.xml164
-rw-r--r--packages/Keyguard/res/values-en-rGB/strings.xml164
-rw-r--r--packages/Keyguard/res/values-es-rUS/strings.xml164
-rw-r--r--packages/Keyguard/res/values-es/strings.xml164
-rw-r--r--packages/Keyguard/res/values-et/strings.xml164
-rw-r--r--packages/Keyguard/res/values-fa/strings.xml164
-rw-r--r--packages/Keyguard/res/values-fi/strings.xml164
-rw-r--r--packages/Keyguard/res/values-fr/strings.xml164
-rw-r--r--packages/Keyguard/res/values-hi/strings.xml164
-rw-r--r--packages/Keyguard/res/values-hr/strings.xml164
-rw-r--r--packages/Keyguard/res/values-hu/strings.xml164
-rw-r--r--packages/Keyguard/res/values-in/strings.xml164
-rw-r--r--packages/Keyguard/res/values-it/strings.xml164
-rw-r--r--packages/Keyguard/res/values-iw/strings.xml164
-rw-r--r--packages/Keyguard/res/values-ja/strings.xml164
-rw-r--r--packages/Keyguard/res/values-ko/strings.xml164
-rw-r--r--packages/Keyguard/res/values-land/alias.xml23
-rw-r--r--packages/Keyguard/res/values-land/arrays.xml72
-rw-r--r--packages/Keyguard/res/values-land/bools.xml22
-rw-r--r--packages/Keyguard/res/values-land/dimens.xml51
-rw-r--r--packages/Keyguard/res/values-land/integers.xml26
-rw-r--r--packages/Keyguard/res/values-large/dimens.xml35
-rw-r--r--packages/Keyguard/res/values-lt/strings.xml164
-rw-r--r--packages/Keyguard/res/values-lv/strings.xml164
-rw-r--r--packages/Keyguard/res/values-ms/strings.xml164
-rw-r--r--packages/Keyguard/res/values-nb/strings.xml164
-rw-r--r--packages/Keyguard/res/values-nl/strings.xml164
-rw-r--r--packages/Keyguard/res/values-pl/strings.xml164
-rw-r--r--packages/Keyguard/res/values-port/alias.xml23
-rw-r--r--packages/Keyguard/res/values-port/bools.xml21
-rw-r--r--packages/Keyguard/res/values-port/integers.xml23
-rw-r--r--packages/Keyguard/res/values-pt-rPT/strings.xml164
-rw-r--r--packages/Keyguard/res/values-pt/strings.xml164
-rw-r--r--packages/Keyguard/res/values-rm/strings.xml249
-rw-r--r--packages/Keyguard/res/values-ro/strings.xml164
-rw-r--r--packages/Keyguard/res/values-ru/strings.xml164
-rw-r--r--packages/Keyguard/res/values-sk/strings.xml164
-rw-r--r--packages/Keyguard/res/values-sl/strings.xml164
-rw-r--r--packages/Keyguard/res/values-sr/strings.xml164
-rw-r--r--packages/Keyguard/res/values-sv/strings.xml164
-rw-r--r--packages/Keyguard/res/values-sw/strings.xml164
-rw-r--r--packages/Keyguard/res/values-sw380dp-land/dimens.xml23
-rw-r--r--packages/Keyguard/res/values-sw380dp/dimens.xml23
-rw-r--r--packages/Keyguard/res/values-sw600dp-land/arrays.xml72
-rw-r--r--packages/Keyguard/res/values-sw600dp-land/dimens.xml26
-rw-r--r--packages/Keyguard/res/values-sw600dp-land/integers.xml23
-rw-r--r--packages/Keyguard/res/values-sw600dp-port/integers.xml22
-rw-r--r--packages/Keyguard/res/values-sw600dp/alias.xml23
-rw-r--r--packages/Keyguard/res/values-sw600dp/bools.xml27
-rw-r--r--packages/Keyguard/res/values-sw600dp/dimens.xml71
-rw-r--r--packages/Keyguard/res/values-sw600dp/integers.xml21
-rw-r--r--packages/Keyguard/res/values-sw720dp-land/dimens.xml29
-rw-r--r--packages/Keyguard/res/values-sw720dp-port/integers.xml22
-rw-r--r--packages/Keyguard/res/values-sw720dp/dimens.xml66
-rw-r--r--packages/Keyguard/res/values-th/strings.xml164
-rw-r--r--packages/Keyguard/res/values-tl/strings.xml164
-rw-r--r--packages/Keyguard/res/values-tr/strings.xml164
-rw-r--r--packages/Keyguard/res/values-uk/strings.xml164
-rw-r--r--packages/Keyguard/res/values-vi/strings.xml164
-rw-r--r--packages/Keyguard/res/values-xlarge/dimens.xml27
-rw-r--r--packages/Keyguard/res/values-zh-rCN/strings.xml164
-rw-r--r--packages/Keyguard/res/values-zh-rTW/strings.xml164
-rw-r--r--packages/Keyguard/res/values-zu/strings.xml164
-rw-r--r--packages/Keyguard/res/values/activitystrings.xml34
-rw-r--r--packages/Keyguard/res/values/alias.xml52
-rw-r--r--packages/Keyguard/res/values/arrays.xml93
-rw-r--r--packages/Keyguard/res/values/attrs.xml136
-rw-r--r--packages/Keyguard/res/values/bools.xml22
-rw-r--r--packages/Keyguard/res/values/colors.xml26
-rw-r--r--packages/Keyguard/res/values/config.xml32
-rw-r--r--packages/Keyguard/res/values/dimens.xml167
-rw-r--r--packages/Keyguard/res/values/integers.xml24
-rw-r--r--packages/Keyguard/res/values/strings.xml327
-rw-r--r--packages/Keyguard/res/values/styles.xml55
-rwxr-xr-xpackages/Keyguard/scripts/copy_profile_icons.sh14
-rwxr-xr-xpackages/Keyguard/scripts/new_merge.py165
-rw-r--r--packages/Keyguard/src/com/android/keyguard/BiometricSensorUnlock.java68
-rw-r--r--packages/Keyguard/src/com/android/keyguard/CameraWidgetFrame.java457
-rw-r--r--packages/Keyguard/src/com/android/keyguard/CarrierText.java257
-rw-r--r--packages/Keyguard/src/com/android/keyguard/ChallengeLayout.java97
-rw-r--r--packages/Keyguard/src/com/android/keyguard/CheckLongPressHelper.java82
-rw-r--r--packages/Keyguard/src/com/android/keyguard/ClockView.java223
-rw-r--r--packages/Keyguard/src/com/android/keyguard/EmergencyButton.java130
-rw-r--r--packages/Keyguard/src/com/android/keyguard/FaceUnlock.java462
-rw-r--r--packages/Keyguard/src/com/android/keyguard/KeyguardAbsKeyInputView.java262
-rw-r--r--packages/Keyguard/src/com/android/keyguard/KeyguardAccountView.java332
-rw-r--r--packages/Keyguard/src/com/android/keyguard/KeyguardActivityLauncher.java274
-rw-r--r--packages/Keyguard/src/com/android/keyguard/KeyguardCircleFramedDrawable.java160
-rw-r--r--packages/Keyguard/src/com/android/keyguard/KeyguardFaceUnlockView.java243
-rw-r--r--packages/Keyguard/src/com/android/keyguard/KeyguardGlowStripView.java137
-rw-r--r--packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java1596
-rw-r--r--packages/Keyguard/src/com/android/keyguard/KeyguardLinearLayout.java46
-rw-r--r--packages/Keyguard/src/com/android/keyguard/KeyguardMessageArea.java305
-rw-r--r--packages/Keyguard/src/com/android/keyguard/KeyguardMultiUserAvatar.java229
-rw-r--r--packages/Keyguard/src/com/android/keyguard/KeyguardMultiUserSelectorView.java166
-rw-r--r--packages/Keyguard/src/com/android/keyguard/KeyguardPINView.java118
-rw-r--r--packages/Keyguard/src/com/android/keyguard/KeyguardPasswordView.java207
-rw-r--r--packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java411
-rw-r--r--packages/Keyguard/src/com/android/keyguard/KeyguardSecurityCallback.java68
-rw-r--r--packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java45
-rw-r--r--packages/Keyguard/src/com/android/keyguard/KeyguardSecurityModel.java147
-rw-r--r--packages/Keyguard/src/com/android/keyguard/KeyguardSecurityView.java87
-rw-r--r--packages/Keyguard/src/com/android/keyguard/KeyguardSecurityViewFlipper.java278
-rw-r--r--packages/Keyguard/src/com/android/keyguard/KeyguardSecurityViewHelper.java94
-rw-r--r--packages/Keyguard/src/com/android/keyguard/KeyguardSelectorView.java283
-rw-r--r--packages/Keyguard/src/com/android/keyguard/KeyguardService.java120
-rw-r--r--packages/Keyguard/src/com/android/keyguard/KeyguardSimPinView.java211
-rw-r--r--packages/Keyguard/src/com/android/keyguard/KeyguardSimPukView.java280
-rw-r--r--packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java154
-rw-r--r--packages/Keyguard/src/com/android/keyguard/KeyguardStatusViewManager.java0
-rw-r--r--packages/Keyguard/src/com/android/keyguard/KeyguardTestActivity.java356
-rw-r--r--packages/Keyguard/src/com/android/keyguard/KeyguardTransportControlView.java527
-rw-r--r--packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java839
-rw-r--r--packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java115
-rw-r--r--packages/Keyguard/src/com/android/keyguard/KeyguardViewBase.java263
-rw-r--r--packages/Keyguard/src/com/android/keyguard/KeyguardViewManager.java457
-rw-r--r--packages/Keyguard/src/com/android/keyguard/KeyguardViewMediator.java1457
-rw-r--r--packages/Keyguard/src/com/android/keyguard/KeyguardViewStateManager.java333
-rw-r--r--packages/Keyguard/src/com/android/keyguard/KeyguardWidgetCarousel.java288
-rw-r--r--packages/Keyguard/src/com/android/keyguard/KeyguardWidgetFrame.java527
-rw-r--r--packages/Keyguard/src/com/android/keyguard/KeyguardWidgetPager.java920
-rw-r--r--packages/Keyguard/src/com/android/keyguard/LiftToActivateListener.java71
-rw-r--r--packages/Keyguard/src/com/android/keyguard/MultiPaneChallengeLayout.java564
-rw-r--r--packages/Keyguard/src/com/android/keyguard/NumPadKey.java127
-rw-r--r--packages/Keyguard/src/com/android/keyguard/ObscureSpeechDelegate.java101
-rw-r--r--packages/Keyguard/src/com/android/keyguard/PagedView.java2562
-rw-r--r--packages/Keyguard/src/com/android/keyguard/SecurityMessageDisplay.java31
-rw-r--r--packages/Keyguard/src/com/android/keyguard/SlidingChallengeLayout.java1242
-rw-r--r--packages/SystemUI/AndroidManifest.xml2
-rw-r--r--packages/SystemUI/res/values-ar/strings.xml2
-rw-r--r--packages/SystemUI/res/values-ca/strings.xml2
-rw-r--r--packages/SystemUI/res/values-es-rUS/strings.xml4
-rw-r--r--packages/SystemUI/res/values-pl/strings.xml6
-rw-r--r--packages/SystemUI/res/values-ru/strings.xml6
-rw-r--r--packages/SystemUI/res/values-sv/strings.xml8
-rw-r--r--packages/SystemUI/res/values-uk/strings.xml16
-rw-r--r--packages/SystemUI/src/com/android/systemui/SystemUIService.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/FixedSizeDrawable.java4
358 files changed, 31929 insertions, 35 deletions
diff --git a/packages/BackupRestoreConfirmation/res/values-sw/strings.xml b/packages/BackupRestoreConfirmation/res/values-sw/strings.xml
index 493c168..24d9c39 100644
--- a/packages/BackupRestoreConfirmation/res/values-sw/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-sw/strings.xml
@@ -17,7 +17,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="backup_confirm_title" msgid="827563724209303345">"Kuhifadhi kikamilifu"</string>
- <string name="restore_confirm_title" msgid="5469365809567486602">"Kurejeza kamili"</string>
+ <string name="restore_confirm_title" msgid="5469365809567486602">"Kurejesha kila kitu"</string>
<string name="backup_confirm_text" msgid="1878021282758896593">"Chelezo kamili la data iliyounganishwa kwenye eneo kazi la kompyuta limeombwa. Unataka kuruhusu hii kutendeka?"\n\n" Ikiwa hukuomba chelezo mwenyewe, usikubali uendeshaji kuendelea."</string>
<string name="allow_backup_button_label" msgid="4217228747769644068">"Cheleza data yangu"</string>
<string name="deny_backup_button_label" msgid="6009119115581097708">"Usicheleze"</string>
@@ -32,7 +32,7 @@
<string name="restore_enc_password_text" msgid="6140898525580710823">"Ikiwa data iliyorejeshwa upya, tafadhali ingiza nenosiri lililo hapo chini:"</string>
<string name="toast_backup_started" msgid="550354281452756121">"Inaanza kuhifadhi..."</string>
<string name="toast_backup_ended" msgid="3818080769548726424">"Imemaliza kuhifadhi"</string>
- <string name="toast_restore_started" msgid="7881679218971277385">"Inaanza kurejeza..."</string>
- <string name="toast_restore_ended" msgid="1764041639199696132">"Kurejeza kumekamilika"</string>
+ <string name="toast_restore_started" msgid="7881679218971277385">"Inaanza kurejesha..."</string>
+ <string name="toast_restore_ended" msgid="1764041639199696132">"Kurejesha kumekamilika"</string>
<string name="toast_timeout" msgid="5276598587087626877">"Muda wa uendeshaji umeisha"</string>
</resources>
diff --git a/packages/Keyguard/Android.mk b/packages/Keyguard/Android.mk
new file mode 100644
index 0000000..2f8edad
--- /dev/null
+++ b/packages/Keyguard/Android.mk
@@ -0,0 +1,31 @@
+# Copyright (C) 2013 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files) $(call all-subdir-Iaidl-files)
+
+LOCAL_JAVA_LIBRARIES := services
+
+LOCAL_PACKAGE_NAME := Keyguard
+
+LOCAL_CERTIFICATE := platform
+
+LOCAL_PROGUARD_FLAG_FILES := proguard.flags
+
+include $(BUILD_PACKAGE)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/packages/Keyguard/AndroidManifest.xml b/packages/Keyguard/AndroidManifest.xml
new file mode 100644
index 0000000..38e764a
--- /dev/null
+++ b/packages/Keyguard/AndroidManifest.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.keyguard"
+ android:sharedUserId="android.uid.systemui"
+ coreApp="true">
+ <uses-sdk android:minSdkVersion="10" android:targetSdkVersion="17"/>
+ <uses-permission android:name="android.permission.VIBRATE" />
+ <uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />
+ <uses-permission android:name="android.permission.GET_ACCOUNTS" />
+ <uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />
+ <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
+ <uses-permission android:name="android.permission.WAKE_LOCK" />
+ <uses-permission android:name="android.permission.STATUS_BAR" />
+ <uses-permission android:name="android.permission.DEVICE_POWER" />
+ <uses-permission android:name="android.permission.MANAGE_USERS" />
+ <uses-permission android:name="android.permission.MANAGE_APP_TOKENS" />
+ <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+ <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
+ <uses-permission android:name="android.permission.BIND_APPWIDGET" />
+ <uses-permission android:name="android.permission.INTERNAL_SYSTEM_WINDOW" />
+ <uses-permission android:name="android.permission.BIND_DEVICE_ADMIN" />
+ <uses-permission android:name="android.permission.CHANGE_COMPONENT_ENABLED_STATE" />
+
+ <application android:label="@string/app_name" android:icon="@drawable/app_icon"
+ android:process="com.android.systemui.keyguard"
+ android:persistent="true" >
+
+ <service android:name=".KeyguardService"
+ android:exported="true" />
+
+ </application>
+</manifest>
diff --git a/packages/Keyguard/NOTICE b/packages/Keyguard/NOTICE
new file mode 100644
index 0000000..33ff961
--- /dev/null
+++ b/packages/Keyguard/NOTICE
@@ -0,0 +1,190 @@
+
+ Copyright (c) 2005-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.
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
diff --git a/packages/Keyguard/proguard.flags b/packages/Keyguard/proguard.flags
new file mode 100644
index 0000000..00ca0fa
--- /dev/null
+++ b/packages/Keyguard/proguard.flags
@@ -0,0 +1,2 @@
+-keep public class com.android.keyguard.KeyguardService
+
diff --git a/packages/Keyguard/res/anim/keyguard_action_assist_enter.xml b/packages/Keyguard/res/anim/keyguard_action_assist_enter.xml
new file mode 100644
index 0000000..f3333b7
--- /dev/null
+++ b/packages/Keyguard/res/anim/keyguard_action_assist_enter.xml
@@ -0,0 +1,32 @@
+<?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.
+*/
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shareInterpolator="false" android:zAdjustment="top">
+
+ <alpha android:fromAlpha="0" android:toAlpha="1.0"
+ android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
+ android:interpolator="@android:interpolator/decelerate_cubic"
+ android:duration="300"/>
+
+ <translate android:fromYDelta="100%" android:toYDelta="0"
+ android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
+ android:interpolator="@android:interpolator/decelerate_cubic"
+ android:duration="300" />
+</set>
diff --git a/packages/Keyguard/res/anim/keyguard_action_assist_exit.xml b/packages/Keyguard/res/anim/keyguard_action_assist_exit.xml
new file mode 100644
index 0000000..b4ed278
--- /dev/null
+++ b/packages/Keyguard/res/anim/keyguard_action_assist_exit.xml
@@ -0,0 +1,23 @@
+<?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.
+*/
+-->
+
+<translate xmlns:android="http://schemas.android.com/apk/res/android"
+ android:interpolator="@android:anim/accelerate_interpolator"
+ android:fromXDelta="0" android:toXDelta="0"
+ android:duration="300" />
diff --git a/packages/Keyguard/res/anim/keyguard_security_animate_in.xml b/packages/Keyguard/res/anim/keyguard_security_animate_in.xml
new file mode 100644
index 0000000..4ee30c3
--- /dev/null
+++ b/packages/Keyguard/res/anim/keyguard_security_animate_in.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android" android:shareInterpolator="false">
+
+ <scale
+ android:interpolator="@android:anim/decelerate_interpolator"
+ android:fromXScale="0.0"
+ android:toXScale="1.0"
+ android:fromYScale="1.0"
+ android:toYScale="1.0"
+ android:pivotX="50%"
+ android:pivotY="50%"
+ android:fillEnabled="true"
+ android:fillAfter="true"
+ android:duration="@integer/kg_security_flip_duration"
+ android:startOffset="@integer/kg_security_flip_duration" />
+
+</set>
+
diff --git a/packages/Keyguard/res/anim/keyguard_security_animate_out.xml b/packages/Keyguard/res/anim/keyguard_security_animate_out.xml
new file mode 100644
index 0000000..76d065c
--- /dev/null
+++ b/packages/Keyguard/res/anim/keyguard_security_animate_out.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android" android:shareInterpolator="false">
+
+ <scale
+ android:interpolator="@android:anim/accelerate_interpolator"
+ android:fromXScale="1.0"
+ android:toXScale="0.0"
+ android:fromYScale="1.0"
+ android:toYScale="1.0"
+ android:pivotX="50%"
+ android:pivotY="50%"
+ android:fillEnabled="true"
+ android:fillAfter="true"
+ android:duration="@integer/kg_security_flip_duration" />
+
+</set>
+
diff --git a/packages/Keyguard/res/anim/keyguard_security_fade_in.xml b/packages/Keyguard/res/anim/keyguard_security_fade_in.xml
new file mode 100644
index 0000000..c66c604
--- /dev/null
+++ b/packages/Keyguard/res/anim/keyguard_security_fade_in.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<alpha xmlns:android="http://schemas.android.com/apk/res/android"
+ android:interpolator="@android:interpolator/decelerate_quad"
+ android:fromAlpha="0.0" android:toAlpha="1.0"
+ android:duration="@integer/kg_security_fade_duration" />
+
+
diff --git a/packages/Keyguard/res/anim/keyguard_security_fade_out.xml b/packages/Keyguard/res/anim/keyguard_security_fade_out.xml
new file mode 100644
index 0000000..6465b35
--- /dev/null
+++ b/packages/Keyguard/res/anim/keyguard_security_fade_out.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<alpha xmlns:android="http://schemas.android.com/apk/res/android"
+ android:interpolator="@android:interpolator/accelerate_quad"
+ android:fromAlpha="1.0"
+ android:toAlpha="0.0"
+ android:duration="@integer/kg_security_fade_duration"
+/>
diff --git a/packages/Keyguard/res/anim/lock_screen_enter.xml b/packages/Keyguard/res/anim/lock_screen_enter.xml
new file mode 100644
index 0000000..4344cf9
--- /dev/null
+++ b/packages/Keyguard/res/anim/lock_screen_enter.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2007, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+ android:interpolator="@android:interpolator/accelerate_cubic">
+ <alpha android:fromAlpha="0.0" android:toAlpha="1.0"
+ android:duration="@integer/config_activityDefaultDur" />
+</set>
diff --git a/packages/Keyguard/res/anim/lock_screen_exit.xml b/packages/Keyguard/res/anim/lock_screen_exit.xml
new file mode 100644
index 0000000..c75b3cc
--- /dev/null
+++ b/packages/Keyguard/res/anim/lock_screen_exit.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2007, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+ android:zAdjustment="top"
+ android:shareInterpolator="false">
+ <scale
+ android:fromXScale="1.0" android:toXScale="1.10"
+ android:fromYScale="1.0" android:toYScale="1.10"
+ android:pivotX="50%p" android:pivotY="50%p"
+ android:fillEnabled="true" android:fillAfter="true"
+ android:interpolator="@android:interpolator/accelerate_quint"
+ android:duration="@android:integer/config_shortAnimTime" />
+ <alpha
+ android:fromAlpha="1.0" android:toAlpha="0"
+ android:fillEnabled="true" android:fillAfter="true"
+ android:interpolator="@android:interpolator/accelerate_quad"
+ android:duration="@android:integer/config_shortAnimTime"/>
+</set>
diff --git a/packages/Keyguard/res/drawable-hdpi/ic_action_assist_generic_activated.png b/packages/Keyguard/res/drawable-hdpi/ic_action_assist_generic_activated.png
new file mode 100644
index 0000000..c0e2098
--- /dev/null
+++ b/packages/Keyguard/res/drawable-hdpi/ic_action_assist_generic_activated.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-hdpi/ic_action_assist_generic_normal.png b/packages/Keyguard/res/drawable-hdpi/ic_action_assist_generic_normal.png
new file mode 100644
index 0000000..a852e2c
--- /dev/null
+++ b/packages/Keyguard/res/drawable-hdpi/ic_action_assist_generic_normal.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-hdpi/ic_facial_backup.png b/packages/Keyguard/res/drawable-hdpi/ic_facial_backup.png
new file mode 100644
index 0000000..2956109
--- /dev/null
+++ b/packages/Keyguard/res/drawable-hdpi/ic_facial_backup.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-hdpi/ic_input_delete.png b/packages/Keyguard/res/drawable-hdpi/ic_input_delete.png
new file mode 100644
index 0000000..5d638bd
--- /dev/null
+++ b/packages/Keyguard/res/drawable-hdpi/ic_input_delete.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_alarm.png b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_alarm.png
new file mode 100644
index 0000000..d7a8cfc
--- /dev/null
+++ b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_alarm.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_camera_activated.png b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_camera_activated.png
new file mode 100644
index 0000000..19c8eb2
--- /dev/null
+++ b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_camera_activated.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_camera_normal.png b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_camera_normal.png
new file mode 100644
index 0000000..c79a245
--- /dev/null
+++ b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_camera_normal.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_emergencycall_normal.png b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_emergencycall_normal.png
new file mode 100644
index 0000000..460495a
--- /dev/null
+++ b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_emergencycall_normal.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_emergencycall_pressed.png b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_emergencycall_pressed.png
new file mode 100644
index 0000000..b0f7ae9
--- /dev/null
+++ b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_emergencycall_pressed.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_forgotpassword_normal.png b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_forgotpassword_normal.png
new file mode 100644
index 0000000..6402d3d
--- /dev/null
+++ b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_forgotpassword_normal.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_forgotpassword_pressed.png b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_forgotpassword_pressed.png
new file mode 100644
index 0000000..83be046
--- /dev/null
+++ b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_forgotpassword_pressed.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_glowdot.png b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_glowdot.png
new file mode 100644
index 0000000..983c45e
--- /dev/null
+++ b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_glowdot.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_google_activated.png b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_google_activated.png
new file mode 100644
index 0000000..2c4847c
--- /dev/null
+++ b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_google_activated.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_google_focused.png b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_google_focused.png
new file mode 100644
index 0000000..d98557d
--- /dev/null
+++ b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_google_focused.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_google_normal.png b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_google_normal.png
new file mode 100644
index 0000000..656f3ba
--- /dev/null
+++ b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_google_normal.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_handle_normal.png b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_handle_normal.png
new file mode 100644
index 0000000..1780ec0
--- /dev/null
+++ b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_handle_normal.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_handle_pressed.png b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_handle_pressed.png
new file mode 100644
index 0000000..58a5f16
--- /dev/null
+++ b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_handle_pressed.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_ime.png b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_ime.png
new file mode 100644
index 0000000..29a7989
--- /dev/null
+++ b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_ime.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_lock_normal.png b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_lock_normal.png
new file mode 100644
index 0000000..732133c
--- /dev/null
+++ b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_lock_normal.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_lock_pressed.png b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_lock_pressed.png
new file mode 100644
index 0000000..0bbf62f
--- /dev/null
+++ b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_lock_pressed.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_player_background.9.png b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_player_background.9.png
new file mode 100644
index 0000000..fbb75b5
--- /dev/null
+++ b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_player_background.9.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_search_activated.png b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_search_activated.png
new file mode 100644
index 0000000..0d2e2ef
--- /dev/null
+++ b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_search_activated.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_search_normal.png b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_search_normal.png
new file mode 100644
index 0000000..66d14ae
--- /dev/null
+++ b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_search_normal.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_silent_activated.png b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_silent_activated.png
new file mode 100644
index 0000000..7060d59
--- /dev/null
+++ b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_silent_activated.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_silent_focused.png b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_silent_focused.png
new file mode 100644
index 0000000..f9a8c7c
--- /dev/null
+++ b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_silent_focused.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_silent_normal.png b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_silent_normal.png
new file mode 100644
index 0000000..b47cd08
--- /dev/null
+++ b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_silent_normal.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_sim.png b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_sim.png
new file mode 100644
index 0000000..7cf9e36
--- /dev/null
+++ b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_sim.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_soundon_activated.png b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_soundon_activated.png
new file mode 100644
index 0000000..88d0a9f
--- /dev/null
+++ b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_soundon_activated.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_soundon_focused.png b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_soundon_focused.png
new file mode 100644
index 0000000..6e16e40
--- /dev/null
+++ b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_soundon_focused.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_soundon_normal.png b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_soundon_normal.png
new file mode 100644
index 0000000..0dd81c0
--- /dev/null
+++ b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_soundon_normal.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_unlock_activated.png b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_unlock_activated.png
new file mode 100644
index 0000000..374a62a
--- /dev/null
+++ b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_unlock_activated.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_unlock_normal.png b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_unlock_normal.png
new file mode 100644
index 0000000..3960893
--- /dev/null
+++ b/packages/Keyguard/res/drawable-hdpi/ic_lockscreen_unlock_normal.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-hdpi/ic_media_next.png b/packages/Keyguard/res/drawable-hdpi/ic_media_next.png
new file mode 100644
index 0000000..6e27b81
--- /dev/null
+++ b/packages/Keyguard/res/drawable-hdpi/ic_media_next.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-hdpi/ic_media_play.png b/packages/Keyguard/res/drawable-hdpi/ic_media_play.png
new file mode 100644
index 0000000..2746d17
--- /dev/null
+++ b/packages/Keyguard/res/drawable-hdpi/ic_media_play.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-hdpi/ic_media_previous.png b/packages/Keyguard/res/drawable-hdpi/ic_media_previous.png
new file mode 100644
index 0000000..85b3766
--- /dev/null
+++ b/packages/Keyguard/res/drawable-hdpi/ic_media_previous.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-hdpi/intro_bg.png b/packages/Keyguard/res/drawable-hdpi/intro_bg.png
new file mode 100644
index 0000000..a758e7d
--- /dev/null
+++ b/packages/Keyguard/res/drawable-hdpi/intro_bg.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-hdpi/kg_add_widget.png b/packages/Keyguard/res/drawable-hdpi/kg_add_widget.png
new file mode 100644
index 0000000..7456705
--- /dev/null
+++ b/packages/Keyguard/res/drawable-hdpi/kg_add_widget.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-hdpi/kg_add_widget_disabled.png b/packages/Keyguard/res/drawable-hdpi/kg_add_widget_disabled.png
new file mode 100644
index 0000000..f24cf642
--- /dev/null
+++ b/packages/Keyguard/res/drawable-hdpi/kg_add_widget_disabled.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-hdpi/kg_add_widget_pressed.png b/packages/Keyguard/res/drawable-hdpi/kg_add_widget_pressed.png
new file mode 100644
index 0000000..55112ca
--- /dev/null
+++ b/packages/Keyguard/res/drawable-hdpi/kg_add_widget_pressed.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-hdpi/kg_bouncer_bg_white.9.png b/packages/Keyguard/res/drawable-hdpi/kg_bouncer_bg_white.9.png
new file mode 100644
index 0000000..cfd5db3
--- /dev/null
+++ b/packages/Keyguard/res/drawable-hdpi/kg_bouncer_bg_white.9.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-hdpi/kg_security_grip.9.png b/packages/Keyguard/res/drawable-hdpi/kg_security_grip.9.png
new file mode 100644
index 0000000..1e40aef
--- /dev/null
+++ b/packages/Keyguard/res/drawable-hdpi/kg_security_grip.9.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-hdpi/kg_security_lock.png b/packages/Keyguard/res/drawable-hdpi/kg_security_lock.png
new file mode 100644
index 0000000..c3c94c4
--- /dev/null
+++ b/packages/Keyguard/res/drawable-hdpi/kg_security_lock.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-hdpi/kg_security_lock_focused.png b/packages/Keyguard/res/drawable-hdpi/kg_security_lock_focused.png
new file mode 100644
index 0000000..9a82799
--- /dev/null
+++ b/packages/Keyguard/res/drawable-hdpi/kg_security_lock_focused.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-hdpi/kg_security_lock_normal.png b/packages/Keyguard/res/drawable-hdpi/kg_security_lock_normal.png
new file mode 100644
index 0000000..d608707
--- /dev/null
+++ b/packages/Keyguard/res/drawable-hdpi/kg_security_lock_normal.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-hdpi/kg_security_lock_pressed.png b/packages/Keyguard/res/drawable-hdpi/kg_security_lock_pressed.png
new file mode 100644
index 0000000..7ca995d
--- /dev/null
+++ b/packages/Keyguard/res/drawable-hdpi/kg_security_lock_pressed.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-hdpi/kg_widget_bg_padded.9.png b/packages/Keyguard/res/drawable-hdpi/kg_widget_bg_padded.9.png
new file mode 100644
index 0000000..dff1dfa
--- /dev/null
+++ b/packages/Keyguard/res/drawable-hdpi/kg_widget_bg_padded.9.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-hdpi/kg_widget_delete_drop_target.png b/packages/Keyguard/res/drawable-hdpi/kg_widget_delete_drop_target.png
new file mode 100644
index 0000000..84549ff
--- /dev/null
+++ b/packages/Keyguard/res/drawable-hdpi/kg_widget_delete_drop_target.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-hdpi/lockscreen_protection_pattern.png b/packages/Keyguard/res/drawable-hdpi/lockscreen_protection_pattern.png
new file mode 100644
index 0000000..681d8be
--- /dev/null
+++ b/packages/Keyguard/res/drawable-hdpi/lockscreen_protection_pattern.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-hdpi/sym_keyboard_return_holo.png b/packages/Keyguard/res/drawable-hdpi/sym_keyboard_return_holo.png
new file mode 100644
index 0000000..f1bcf48
--- /dev/null
+++ b/packages/Keyguard/res/drawable-hdpi/sym_keyboard_return_holo.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-ldpi/ic_input_delete.png b/packages/Keyguard/res/drawable-ldpi/ic_input_delete.png
new file mode 100644
index 0000000..d7eff17
--- /dev/null
+++ b/packages/Keyguard/res/drawable-ldpi/ic_input_delete.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-ldpi/ic_media_next.png b/packages/Keyguard/res/drawable-ldpi/ic_media_next.png
new file mode 100644
index 0000000..99927fd
--- /dev/null
+++ b/packages/Keyguard/res/drawable-ldpi/ic_media_next.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-ldpi/ic_media_play.png b/packages/Keyguard/res/drawable-ldpi/ic_media_play.png
new file mode 100644
index 0000000..e7c1972
--- /dev/null
+++ b/packages/Keyguard/res/drawable-ldpi/ic_media_play.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-ldpi/ic_media_previous.png b/packages/Keyguard/res/drawable-ldpi/ic_media_previous.png
new file mode 100644
index 0000000..df04322
--- /dev/null
+++ b/packages/Keyguard/res/drawable-ldpi/ic_media_previous.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-mdpi/ic_action_assist_generic_activated.png b/packages/Keyguard/res/drawable-mdpi/ic_action_assist_generic_activated.png
new file mode 100644
index 0000000..f88f7e1
--- /dev/null
+++ b/packages/Keyguard/res/drawable-mdpi/ic_action_assist_generic_activated.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-mdpi/ic_action_assist_generic_normal.png b/packages/Keyguard/res/drawable-mdpi/ic_action_assist_generic_normal.png
new file mode 100644
index 0000000..7426994
--- /dev/null
+++ b/packages/Keyguard/res/drawable-mdpi/ic_action_assist_generic_normal.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-mdpi/ic_facial_backup.png b/packages/Keyguard/res/drawable-mdpi/ic_facial_backup.png
new file mode 100644
index 0000000..6ed1327
--- /dev/null
+++ b/packages/Keyguard/res/drawable-mdpi/ic_facial_backup.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-mdpi/ic_input_delete.png b/packages/Keyguard/res/drawable-mdpi/ic_input_delete.png
new file mode 100644
index 0000000..47c8708
--- /dev/null
+++ b/packages/Keyguard/res/drawable-mdpi/ic_input_delete.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_alarm.png b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_alarm.png
new file mode 100644
index 0000000..330ade1
--- /dev/null
+++ b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_alarm.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_camera_activated.png b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_camera_activated.png
new file mode 100644
index 0000000..862f33b
--- /dev/null
+++ b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_camera_activated.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_camera_normal.png b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_camera_normal.png
new file mode 100644
index 0000000..30df0a3
--- /dev/null
+++ b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_camera_normal.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_emergencycall_normal.png b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_emergencycall_normal.png
new file mode 100644
index 0000000..cae795f
--- /dev/null
+++ b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_emergencycall_normal.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_emergencycall_pressed.png b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_emergencycall_pressed.png
new file mode 100644
index 0000000..2867956
--- /dev/null
+++ b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_emergencycall_pressed.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_forgotpassword_normal.png b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_forgotpassword_normal.png
new file mode 100644
index 0000000..a7e063a
--- /dev/null
+++ b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_forgotpassword_normal.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_forgotpassword_pressed.png b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_forgotpassword_pressed.png
new file mode 100644
index 0000000..53af5a5
--- /dev/null
+++ b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_forgotpassword_pressed.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_glowdot.png b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_glowdot.png
new file mode 100644
index 0000000..056c3f17
--- /dev/null
+++ b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_glowdot.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_google_activated.png b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_google_activated.png
new file mode 100644
index 0000000..32a68e0
--- /dev/null
+++ b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_google_activated.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_google_focused.png b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_google_focused.png
new file mode 100644
index 0000000..3f96d03
--- /dev/null
+++ b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_google_focused.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_google_normal.png b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_google_normal.png
new file mode 100644
index 0000000..2f7efcf
--- /dev/null
+++ b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_google_normal.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_handle_normal.png b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_handle_normal.png
new file mode 100644
index 0000000..1d547e1
--- /dev/null
+++ b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_handle_normal.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_handle_pressed.png b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_handle_pressed.png
new file mode 100644
index 0000000..0187a02
--- /dev/null
+++ b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_handle_pressed.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_ime.png b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_ime.png
new file mode 100644
index 0000000..b27e059
--- /dev/null
+++ b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_ime.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_lock_normal.png b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_lock_normal.png
new file mode 100644
index 0000000..30eb974
--- /dev/null
+++ b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_lock_normal.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_lock_pressed.png b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_lock_pressed.png
new file mode 100644
index 0000000..aab2f6b
--- /dev/null
+++ b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_lock_pressed.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_player_background.9.png b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_player_background.9.png
new file mode 100644
index 0000000..17d97c4
--- /dev/null
+++ b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_player_background.9.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_search_activated.png b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_search_activated.png
new file mode 100644
index 0000000..73c6be6
--- /dev/null
+++ b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_search_activated.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_search_normal.png b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_search_normal.png
new file mode 100644
index 0000000..73c6be6
--- /dev/null
+++ b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_search_normal.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_silent_activated.png b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_silent_activated.png
new file mode 100644
index 0000000..2bc3f52
--- /dev/null
+++ b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_silent_activated.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_silent_focused.png b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_silent_focused.png
new file mode 100644
index 0000000..6a5af9d
--- /dev/null
+++ b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_silent_focused.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_silent_normal.png b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_silent_normal.png
new file mode 100644
index 0000000..c288ce4
--- /dev/null
+++ b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_silent_normal.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_sim.png b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_sim.png
new file mode 100644
index 0000000..2e259c3
--- /dev/null
+++ b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_sim.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_soundon_activated.png b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_soundon_activated.png
new file mode 100644
index 0000000..637eec6
--- /dev/null
+++ b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_soundon_activated.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_soundon_focused.png b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_soundon_focused.png
new file mode 100644
index 0000000..db59b5f
--- /dev/null
+++ b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_soundon_focused.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_soundon_normal.png b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_soundon_normal.png
new file mode 100644
index 0000000..eb6ceed
--- /dev/null
+++ b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_soundon_normal.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_unlock_activated.png b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_unlock_activated.png
new file mode 100644
index 0000000..68409c5
--- /dev/null
+++ b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_unlock_activated.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_unlock_normal.png b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_unlock_normal.png
new file mode 100644
index 0000000..52866f2
--- /dev/null
+++ b/packages/Keyguard/res/drawable-mdpi/ic_lockscreen_unlock_normal.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-mdpi/ic_media_next.png b/packages/Keyguard/res/drawable-mdpi/ic_media_next.png
new file mode 100644
index 0000000..fcd73d9
--- /dev/null
+++ b/packages/Keyguard/res/drawable-mdpi/ic_media_next.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-mdpi/ic_media_play.png b/packages/Keyguard/res/drawable-mdpi/ic_media_play.png
new file mode 100644
index 0000000..7966bbc
--- /dev/null
+++ b/packages/Keyguard/res/drawable-mdpi/ic_media_play.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-mdpi/ic_media_previous.png b/packages/Keyguard/res/drawable-mdpi/ic_media_previous.png
new file mode 100644
index 0000000..b653d05
--- /dev/null
+++ b/packages/Keyguard/res/drawable-mdpi/ic_media_previous.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-mdpi/intro_bg.png b/packages/Keyguard/res/drawable-mdpi/intro_bg.png
new file mode 100644
index 0000000..540da31
--- /dev/null
+++ b/packages/Keyguard/res/drawable-mdpi/intro_bg.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-mdpi/kg_add_widget.png b/packages/Keyguard/res/drawable-mdpi/kg_add_widget.png
new file mode 100644
index 0000000..1cab0d9
--- /dev/null
+++ b/packages/Keyguard/res/drawable-mdpi/kg_add_widget.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-mdpi/kg_add_widget_disabled.png b/packages/Keyguard/res/drawable-mdpi/kg_add_widget_disabled.png
new file mode 100644
index 0000000..02e0f0e
--- /dev/null
+++ b/packages/Keyguard/res/drawable-mdpi/kg_add_widget_disabled.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-mdpi/kg_add_widget_pressed.png b/packages/Keyguard/res/drawable-mdpi/kg_add_widget_pressed.png
new file mode 100644
index 0000000..34a7aaa
--- /dev/null
+++ b/packages/Keyguard/res/drawable-mdpi/kg_add_widget_pressed.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-mdpi/kg_bouncer_bg_white.9.png b/packages/Keyguard/res/drawable-mdpi/kg_bouncer_bg_white.9.png
new file mode 100644
index 0000000..e3cb6db
--- /dev/null
+++ b/packages/Keyguard/res/drawable-mdpi/kg_bouncer_bg_white.9.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-mdpi/kg_security_grip.9.png b/packages/Keyguard/res/drawable-mdpi/kg_security_grip.9.png
new file mode 100644
index 0000000..334a39b
--- /dev/null
+++ b/packages/Keyguard/res/drawable-mdpi/kg_security_grip.9.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-mdpi/kg_security_lock.png b/packages/Keyguard/res/drawable-mdpi/kg_security_lock.png
new file mode 100644
index 0000000..a39f380
--- /dev/null
+++ b/packages/Keyguard/res/drawable-mdpi/kg_security_lock.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-mdpi/kg_security_lock_focused.png b/packages/Keyguard/res/drawable-mdpi/kg_security_lock_focused.png
new file mode 100644
index 0000000..c3608f9
--- /dev/null
+++ b/packages/Keyguard/res/drawable-mdpi/kg_security_lock_focused.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-mdpi/kg_security_lock_normal.png b/packages/Keyguard/res/drawable-mdpi/kg_security_lock_normal.png
new file mode 100644
index 0000000..7957c79
--- /dev/null
+++ b/packages/Keyguard/res/drawable-mdpi/kg_security_lock_normal.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-mdpi/kg_security_lock_pressed.png b/packages/Keyguard/res/drawable-mdpi/kg_security_lock_pressed.png
new file mode 100644
index 0000000..41715f5
--- /dev/null
+++ b/packages/Keyguard/res/drawable-mdpi/kg_security_lock_pressed.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-mdpi/kg_widget_bg_padded.9.png b/packages/Keyguard/res/drawable-mdpi/kg_widget_bg_padded.9.png
new file mode 100644
index 0000000..c313df1
--- /dev/null
+++ b/packages/Keyguard/res/drawable-mdpi/kg_widget_bg_padded.9.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-mdpi/kg_widget_delete_drop_target.png b/packages/Keyguard/res/drawable-mdpi/kg_widget_delete_drop_target.png
new file mode 100644
index 0000000..219f3e5
--- /dev/null
+++ b/packages/Keyguard/res/drawable-mdpi/kg_widget_delete_drop_target.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-mdpi/lockscreen_protection_pattern.png b/packages/Keyguard/res/drawable-mdpi/lockscreen_protection_pattern.png
new file mode 100644
index 0000000..30bcea5
--- /dev/null
+++ b/packages/Keyguard/res/drawable-mdpi/lockscreen_protection_pattern.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-mdpi/sym_keyboard_return_holo.png b/packages/Keyguard/res/drawable-mdpi/sym_keyboard_return_holo.png
new file mode 100644
index 0000000..d5a7708
--- /dev/null
+++ b/packages/Keyguard/res/drawable-mdpi/sym_keyboard_return_holo.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-nodpi/app_icon.png b/packages/Keyguard/res/drawable-nodpi/app_icon.png
new file mode 100644
index 0000000..ea31bd8
--- /dev/null
+++ b/packages/Keyguard/res/drawable-nodpi/app_icon.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-sw600dp-hdpi/ic_lockscreen_handle_normal.png b/packages/Keyguard/res/drawable-sw600dp-hdpi/ic_lockscreen_handle_normal.png
new file mode 100644
index 0000000..f28fe38
--- /dev/null
+++ b/packages/Keyguard/res/drawable-sw600dp-hdpi/ic_lockscreen_handle_normal.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-sw600dp-hdpi/ic_lockscreen_handle_pressed.png b/packages/Keyguard/res/drawable-sw600dp-hdpi/ic_lockscreen_handle_pressed.png
new file mode 100644
index 0000000..728fc67
--- /dev/null
+++ b/packages/Keyguard/res/drawable-sw600dp-hdpi/ic_lockscreen_handle_pressed.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-sw600dp-mdpi/ic_lockscreen_handle_normal.png b/packages/Keyguard/res/drawable-sw600dp-mdpi/ic_lockscreen_handle_normal.png
new file mode 100644
index 0000000..99e742f
--- /dev/null
+++ b/packages/Keyguard/res/drawable-sw600dp-mdpi/ic_lockscreen_handle_normal.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-sw600dp-mdpi/ic_lockscreen_handle_pressed.png b/packages/Keyguard/res/drawable-sw600dp-mdpi/ic_lockscreen_handle_pressed.png
new file mode 100644
index 0000000..c7da024
--- /dev/null
+++ b/packages/Keyguard/res/drawable-sw600dp-mdpi/ic_lockscreen_handle_pressed.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-sw600dp-xhdpi/ic_lockscreen_handle_normal.png b/packages/Keyguard/res/drawable-sw600dp-xhdpi/ic_lockscreen_handle_normal.png
new file mode 100644
index 0000000..75e4783
--- /dev/null
+++ b/packages/Keyguard/res/drawable-sw600dp-xhdpi/ic_lockscreen_handle_normal.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-sw600dp-xhdpi/ic_lockscreen_handle_pressed.png b/packages/Keyguard/res/drawable-sw600dp-xhdpi/ic_lockscreen_handle_pressed.png
new file mode 100644
index 0000000..534c10b
--- /dev/null
+++ b/packages/Keyguard/res/drawable-sw600dp-xhdpi/ic_lockscreen_handle_pressed.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xhdpi/ic_action_assist_generic_activated.png b/packages/Keyguard/res/drawable-xhdpi/ic_action_assist_generic_activated.png
new file mode 100644
index 0000000..500b157
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xhdpi/ic_action_assist_generic_activated.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xhdpi/ic_action_assist_generic_normal.png b/packages/Keyguard/res/drawable-xhdpi/ic_action_assist_generic_normal.png
new file mode 100644
index 0000000..d0e4cf3
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xhdpi/ic_action_assist_generic_normal.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xhdpi/ic_facial_backup.png b/packages/Keyguard/res/drawable-xhdpi/ic_facial_backup.png
new file mode 100644
index 0000000..942cf23
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xhdpi/ic_facial_backup.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xhdpi/ic_input_delete.png b/packages/Keyguard/res/drawable-xhdpi/ic_input_delete.png
new file mode 100644
index 0000000..8b822d9
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xhdpi/ic_input_delete.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_alarm.png b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_alarm.png
new file mode 100644
index 0000000..e6cceef
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_alarm.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_camera_activated.png b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_camera_activated.png
new file mode 100644
index 0000000..760ef2d
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_camera_activated.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_camera_normal.png b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_camera_normal.png
new file mode 100644
index 0000000..093bc05
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_camera_normal.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_emergencycall_normal.png b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_emergencycall_normal.png
new file mode 100644
index 0000000..a61f7a5
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_emergencycall_normal.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_emergencycall_pressed.png b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_emergencycall_pressed.png
new file mode 100644
index 0000000..dd5e481
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_emergencycall_pressed.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_forgotpassword_normal.png b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_forgotpassword_normal.png
new file mode 100644
index 0000000..e4172ce
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_forgotpassword_normal.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_forgotpassword_pressed.png b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_forgotpassword_pressed.png
new file mode 100644
index 0000000..e2c7621
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_forgotpassword_pressed.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_glowdot.png b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_glowdot.png
new file mode 100644
index 0000000..cbd039a
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_glowdot.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_google_activated.png b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_google_activated.png
new file mode 100644
index 0000000..d643f83
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_google_activated.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_google_focused.png b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_google_focused.png
new file mode 100644
index 0000000..51863f4
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_google_focused.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_google_normal.png b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_google_normal.png
new file mode 100644
index 0000000..9a9bf68
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_google_normal.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_handle_normal.png b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_handle_normal.png
new file mode 100644
index 0000000..b09071b
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_handle_normal.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_handle_pressed.png b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_handle_pressed.png
new file mode 100644
index 0000000..2d28009
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_handle_pressed.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_ime.png b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_ime.png
new file mode 100644
index 0000000..a40ddeb
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_ime.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_lock_normal.png b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_lock_normal.png
new file mode 100644
index 0000000..c44a330
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_lock_normal.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_lock_pressed.png b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_lock_pressed.png
new file mode 100644
index 0000000..2264dc3
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_lock_pressed.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_player_background.9.png b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_player_background.9.png
new file mode 100644
index 0000000..393bca6
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_player_background.9.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_silent_activated.png b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_silent_activated.png
new file mode 100644
index 0000000..2900045
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_silent_activated.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_silent_focused.png b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_silent_focused.png
new file mode 100644
index 0000000..5a93472
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_silent_focused.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_silent_normal.png b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_silent_normal.png
new file mode 100644
index 0000000..73f6a2e
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_silent_normal.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_sim.png b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_sim.png
new file mode 100644
index 0000000..f4de96a
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_sim.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_soundon_activated.png b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_soundon_activated.png
new file mode 100644
index 0000000..da2adc2
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_soundon_activated.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_soundon_focused.png b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_soundon_focused.png
new file mode 100644
index 0000000..0485af0
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_soundon_focused.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_soundon_normal.png b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_soundon_normal.png
new file mode 100644
index 0000000..6af5375
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_soundon_normal.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_unlock_activated.png b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_unlock_activated.png
new file mode 100644
index 0000000..8a0331d
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_unlock_activated.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_unlock_normal.png b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_unlock_normal.png
new file mode 100644
index 0000000..0422117
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xhdpi/ic_lockscreen_unlock_normal.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xhdpi/ic_media_next.png b/packages/Keyguard/res/drawable-xhdpi/ic_media_next.png
new file mode 100644
index 0000000..4def965
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xhdpi/ic_media_next.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xhdpi/ic_media_play.png b/packages/Keyguard/res/drawable-xhdpi/ic_media_play.png
new file mode 100644
index 0000000..ccfef18
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xhdpi/ic_media_play.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xhdpi/ic_media_previous.png b/packages/Keyguard/res/drawable-xhdpi/ic_media_previous.png
new file mode 100644
index 0000000..c4472ae
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xhdpi/ic_media_previous.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xhdpi/intro_bg.png b/packages/Keyguard/res/drawable-xhdpi/intro_bg.png
new file mode 100644
index 0000000..00466c5
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xhdpi/intro_bg.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xhdpi/kg_add_widget.png b/packages/Keyguard/res/drawable-xhdpi/kg_add_widget.png
new file mode 100644
index 0000000..d71905f
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xhdpi/kg_add_widget.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xhdpi/kg_add_widget_disabled.png b/packages/Keyguard/res/drawable-xhdpi/kg_add_widget_disabled.png
new file mode 100644
index 0000000..55fa1ac
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xhdpi/kg_add_widget_disabled.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xhdpi/kg_add_widget_pressed.png b/packages/Keyguard/res/drawable-xhdpi/kg_add_widget_pressed.png
new file mode 100644
index 0000000..4b86727
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xhdpi/kg_add_widget_pressed.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xhdpi/kg_bouncer_bg_white.9.png b/packages/Keyguard/res/drawable-xhdpi/kg_bouncer_bg_white.9.png
new file mode 100644
index 0000000..b9e30e2
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xhdpi/kg_bouncer_bg_white.9.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xhdpi/kg_security_grip.9.png b/packages/Keyguard/res/drawable-xhdpi/kg_security_grip.9.png
new file mode 100644
index 0000000..c33b9d3
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xhdpi/kg_security_grip.9.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xhdpi/kg_security_lock.png b/packages/Keyguard/res/drawable-xhdpi/kg_security_lock.png
new file mode 100644
index 0000000..81d577e
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xhdpi/kg_security_lock.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xhdpi/kg_security_lock_focused.png b/packages/Keyguard/res/drawable-xhdpi/kg_security_lock_focused.png
new file mode 100644
index 0000000..db22016
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xhdpi/kg_security_lock_focused.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xhdpi/kg_security_lock_normal.png b/packages/Keyguard/res/drawable-xhdpi/kg_security_lock_normal.png
new file mode 100644
index 0000000..17ebb5f
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xhdpi/kg_security_lock_normal.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xhdpi/kg_security_lock_pressed.png b/packages/Keyguard/res/drawable-xhdpi/kg_security_lock_pressed.png
new file mode 100644
index 0000000..186b6ff
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xhdpi/kg_security_lock_pressed.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xhdpi/kg_widget_bg_padded.9.png b/packages/Keyguard/res/drawable-xhdpi/kg_widget_bg_padded.9.png
new file mode 100644
index 0000000..a84bfa3
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xhdpi/kg_widget_bg_padded.9.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xhdpi/kg_widget_delete_drop_target.png b/packages/Keyguard/res/drawable-xhdpi/kg_widget_delete_drop_target.png
new file mode 100644
index 0000000..d4965d9
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xhdpi/kg_widget_delete_drop_target.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xhdpi/lockscreen_protection_pattern.png b/packages/Keyguard/res/drawable-xhdpi/lockscreen_protection_pattern.png
new file mode 100644
index 0000000..c13afe2
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xhdpi/lockscreen_protection_pattern.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xhdpi/sym_keyboard_return_holo.png b/packages/Keyguard/res/drawable-xhdpi/sym_keyboard_return_holo.png
new file mode 100644
index 0000000..55174e0
--- /dev/null
+++ b/packages/Keyguard/res/drawable-xhdpi/sym_keyboard_return_holo.png
Binary files differ
diff --git a/packages/Keyguard/res/drawable/ic_action_assist_generic.xml b/packages/Keyguard/res/drawable/ic_action_assist_generic.xml
new file mode 100644
index 0000000..60f5d5d
--- /dev/null
+++ b/packages/Keyguard/res/drawable/ic_action_assist_generic.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <item
+ android:state_enabled="true"
+ android:state_active="false"
+ android:state_focused="false"
+ android:drawable="@drawable/ic_action_assist_generic_normal" />
+
+ <item
+ android:state_enabled="true"
+ android:state_active="true"
+ android:state_focused="false"
+ android:drawable="@drawable/ic_action_assist_generic_activated" />
+
+ <item
+ android:state_enabled="true"
+ android:state_active="false"
+ android:state_focused="true"
+ android:drawable="@drawable/ic_action_assist_generic_activated" />
+
+</selector>
diff --git a/packages/Keyguard/res/drawable/ic_lockscreen_camera.xml b/packages/Keyguard/res/drawable/ic_lockscreen_camera.xml
new file mode 100644
index 0000000..41277fe
--- /dev/null
+++ b/packages/Keyguard/res/drawable/ic_lockscreen_camera.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT 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_enabled="true"
+ android:state_active="false"
+ android:state_focused="false"
+ android:drawable="@drawable/ic_lockscreen_camera_normal" />
+
+ <item
+ android:state_enabled="true"
+ android:state_active="true"
+ android:state_focused="false"
+ android:drawable="@drawable/ic_lockscreen_camera_activated" />
+
+ <item
+ android:state_enabled="true"
+ android:state_active="false"
+ android:state_focused="true"
+ android:drawable="@drawable/ic_lockscreen_camera_activated" />
+
+</selector>
diff --git a/packages/Keyguard/res/drawable/ic_lockscreen_handle.xml b/packages/Keyguard/res/drawable/ic_lockscreen_handle.xml
new file mode 100644
index 0000000..e7b4a6e
--- /dev/null
+++ b/packages/Keyguard/res/drawable/ic_lockscreen_handle.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT 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_enabled="true"
+ android:state_active="false"
+ android:state_focused="false"
+ android:drawable="@drawable/ic_lockscreen_handle_normal" />
+
+ <item
+ android:state_enabled="true"
+ android:state_active="true"
+ android:state_focused="false"
+ android:drawable="@drawable/ic_lockscreen_handle_pressed" />
+
+</selector>
diff --git a/packages/Keyguard/res/drawable/ic_lockscreen_outerring.xml b/packages/Keyguard/res/drawable/ic_lockscreen_outerring.xml
new file mode 100644
index 0000000..75bea70
--- /dev/null
+++ b/packages/Keyguard/res/drawable/ic_lockscreen_outerring.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="oval"
+ >
+ <size android:height="@dimen/keyguard_lockscreen_outerring_diameter"
+ android:width="@dimen/keyguard_lockscreen_outerring_diameter" />
+ <solid android:color="#00000000" />
+ <stroke android:color="#1affffff" android:width="2dp" />
+</shape>
diff --git a/packages/Keyguard/res/drawable/ic_lockscreen_silent.xml b/packages/Keyguard/res/drawable/ic_lockscreen_silent.xml
new file mode 100644
index 0000000..df23278
--- /dev/null
+++ b/packages/Keyguard/res/drawable/ic_lockscreen_silent.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT 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_enabled="true"
+ android:state_active="false"
+ android:state_focused="false"
+ android:drawable="@drawable/ic_lockscreen_silent_normal" />
+
+ <item
+ android:state_enabled="true"
+ android:state_active="true"
+ android:state_focused="false"
+ android:drawable="@drawable/ic_lockscreen_silent_activated" />
+
+ <item
+ android:state_enabled="true"
+ android:state_active="false"
+ android:state_focused="true"
+ android:drawable="@drawable/ic_lockscreen_silent_activated" />
+
+</selector>
diff --git a/packages/Keyguard/res/drawable/ic_lockscreen_soundon.xml b/packages/Keyguard/res/drawable/ic_lockscreen_soundon.xml
new file mode 100644
index 0000000..b44c86c
--- /dev/null
+++ b/packages/Keyguard/res/drawable/ic_lockscreen_soundon.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT 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_enabled="true"
+ android:state_active="false"
+ android:state_focused="false"
+ android:drawable="@drawable/ic_lockscreen_soundon_normal" />
+
+ <item
+ android:state_enabled="true"
+ android:state_active="true"
+ android:state_focused="false"
+ android:drawable="@drawable/ic_lockscreen_soundon_activated" />
+
+ <item
+ android:state_enabled="true"
+ android:state_active="false"
+ android:state_focused="true"
+ android:drawable="@drawable/ic_lockscreen_soundon_activated" />
+
+</selector>
diff --git a/packages/Keyguard/res/drawable/ic_lockscreen_unlock.xml b/packages/Keyguard/res/drawable/ic_lockscreen_unlock.xml
new file mode 100644
index 0000000..bb1d0ee
--- /dev/null
+++ b/packages/Keyguard/res/drawable/ic_lockscreen_unlock.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT 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_enabled="true"
+ android:state_active="false"
+ android:state_focused="false"
+ android:drawable="@drawable/ic_lockscreen_unlock_normal" />
+
+ <item
+ android:state_enabled="true"
+ android:state_active="true"
+ android:state_focused="false"
+ android:drawable="@drawable/ic_lockscreen_unlock_activated" />
+
+ <item
+ android:state_enabled="true"
+ android:state_active="false"
+ android:state_focused="true"
+ android:drawable="@drawable/ic_lockscreen_unlock_activated" />
+
+</selector>
diff --git a/packages/Keyguard/res/drawable/ic_lockscreen_unlock_phantom.xml b/packages/Keyguard/res/drawable/ic_lockscreen_unlock_phantom.xml
new file mode 100644
index 0000000..83f0aed
--- /dev/null
+++ b/packages/Keyguard/res/drawable/ic_lockscreen_unlock_phantom.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT 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_enabled="true"
+ android:state_active="false"
+ android:state_focused="false"
+ android:drawable="@color/transparent" />
+
+ <item
+ android:state_enabled="true"
+ android:state_active="true"
+ android:state_focused="false"
+ android:drawable="@drawable/ic_lockscreen_unlock_activated" />
+
+ <item
+ android:state_enabled="true"
+ android:state_active="false"
+ android:state_focused="true"
+ android:drawable="@drawable/ic_lockscreen_unlock_activated" />
+
+</selector>
diff --git a/packages/Keyguard/res/drawable/keyguard_add_widget_button.xml b/packages/Keyguard/res/drawable/keyguard_add_widget_button.xml
new file mode 100644
index 0000000..c26f81d
--- /dev/null
+++ b/packages/Keyguard/res/drawable/keyguard_add_widget_button.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_pressed="true" android:drawable="@drawable/kg_add_widget_pressed" />
+ <item android:state_enabled="false" android:drawable="@drawable/kg_add_widget_disabled" />
+ <item android:drawable="@drawable/kg_add_widget" />
+</selector>
diff --git a/packages/Keyguard/res/drawable/keyguard_expand_challenge_handle.xml b/packages/Keyguard/res/drawable/keyguard_expand_challenge_handle.xml
new file mode 100644
index 0000000..3e0780b
--- /dev/null
+++ b/packages/Keyguard/res/drawable/keyguard_expand_challenge_handle.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_focused="true" android:drawable="@drawable/kg_security_lock_focused" />
+ <item android:state_pressed="true" android:drawable="@drawable/kg_security_lock_pressed" />
+ <item android:drawable="@drawable/kg_security_lock_normal" />
+</selector>
diff --git a/packages/Keyguard/res/drawable/lockscreen_emergency_button.xml b/packages/Keyguard/res/drawable/lockscreen_emergency_button.xml
new file mode 100644
index 0000000..4ec6a96
--- /dev/null
+++ b/packages/Keyguard/res/drawable/lockscreen_emergency_button.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_enabled="true" android:drawable="@drawable/ic_lockscreen_emergencycall_normal" />
+ <item android:state_pressed="true" android:drawable="@drawable/ic_lockscreen_emergencycall_pressed" />
+ <item android:drawable="@drawable/ic_lockscreen_emergencycall_normal" />
+</selector>
diff --git a/packages/Keyguard/res/drawable/lockscreen_forgot_password_button.xml b/packages/Keyguard/res/drawable/lockscreen_forgot_password_button.xml
new file mode 100644
index 0000000..6c081bf
--- /dev/null
+++ b/packages/Keyguard/res/drawable/lockscreen_forgot_password_button.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_enabled="true" android:drawable="@drawable/ic_lockscreen_forgotpassword_normal" />
+ <item android:state_pressed="true" android:drawable="@drawable/ic_lockscreen_forgotpassword_pressed" />
+ <item android:drawable="@drawable/ic_lockscreen_forgotpassword_normal" />
+</selector>
diff --git a/packages/Keyguard/res/layout-land/keyguard_host_view.xml b/packages/Keyguard/res/layout-land/keyguard_host_view.xml
new file mode 100644
index 0000000..eeb9ee7
--- /dev/null
+++ b/packages/Keyguard/res/layout-land/keyguard_host_view.xml
@@ -0,0 +1,81 @@
+<?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.
+*/
+-->
+
+<!-- This is the host view that generally contains two sub views: the widget view
+ and the security view. -->
+<com.android.keyguard.KeyguardHostView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/res/com.android.keyguard"
+ android:id="@+id/keyguard_host_view"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="horizontal">
+
+ <com.android.keyguard.MultiPaneChallengeLayout
+ android:id="@+id/multi_pane_challenge"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="horizontal"
+ android:clipChildren="false">
+
+ <include layout="@layout/keyguard_widget_remove_drop_target"
+ android:id="@+id/keyguard_widget_pager_delete_target"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="top|center_horizontal"
+ androidprv:layout_childType="pageDeleteDropTarget" />
+
+ <include layout="@layout/keyguard_widget_pager"
+ android:id="@+id/app_widget_container"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ androidprv:layout_centerWithinArea="0.55"
+ androidprv:layout_childType="widget"
+ androidprv:layout_maxWidth="480dp"
+ androidprv:layout_maxHeight="480dp" />
+ <include layout="@layout/keyguard_multi_user_selector"/>
+
+ <View android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ androidprv:layout_childType="scrim"
+ android:background="#99000000" />
+
+ <com.android.keyguard.KeyguardSecurityContainer
+ android:id="@+id/keyguard_security_container"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ androidprv:layout_childType="challenge"
+ androidprv:layout_centerWithinArea="0.55">
+ <com.android.keyguard.KeyguardSecurityViewFlipper
+ android:id="@+id/view_flipper"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:clipChildren="false"
+ android:clipToPadding="false"
+ android:paddingLeft="@dimen/keyguard_security_view_margin"
+ android:paddingTop="@dimen/keyguard_security_view_margin"
+ android:paddingRight="@dimen/keyguard_security_view_margin"
+ android:paddingBottom="@dimen/keyguard_security_view_margin"
+ android:gravity="center">
+ </com.android.keyguard.KeyguardSecurityViewFlipper>
+ </com.android.keyguard.KeyguardSecurityContainer>
+
+ </com.android.keyguard.MultiPaneChallengeLayout>
+</com.android.keyguard.KeyguardHostView>
+
diff --git a/packages/Keyguard/res/layout-land/keyguard_status_area.xml b/packages/Keyguard/res/layout-land/keyguard_status_area.xml
new file mode 100644
index 0000000..51ee740
--- /dev/null
+++ b/packages/Keyguard/res/layout-land/keyguard_status_area.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2009, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License")
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<!-- This is a view that shows general status information in Keyguard. -->
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/keyguard_status_area"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="end"
+ android:layout_marginTop="-16dp"
+ android:orientation="vertical">
+
+ <TextView
+ android:id="@+id/date"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="end"
+ android:layout_marginEnd="@dimen/kg_status_line_font_right_margin"
+ android:singleLine="true"
+ android:ellipsize="marquee"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:textSize="@dimen/kg_status_date_font_size"
+ />
+
+ <TextView
+ android:id="@+id/alarm_status"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="end"
+ android:layout_marginTop="28dp"
+ android:layout_marginEnd="@dimen/kg_status_line_font_right_margin"
+ android:singleLine="true"
+ android:ellipsize="marquee"
+ android:textAppearance="?android:attr/textAppearance"
+ android:textSize="@dimen/kg_status_line_font_size"
+ android:drawablePadding="4dip"
+ />
+
+</LinearLayout> \ No newline at end of file
diff --git a/packages/Keyguard/res/layout-land/keyguard_widget_pager.xml b/packages/Keyguard/res/layout-land/keyguard_widget_pager.xml
new file mode 100644
index 0000000..da31065
--- /dev/null
+++ b/packages/Keyguard/res/layout-land/keyguard_widget_pager.xml
@@ -0,0 +1,30 @@
+<?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.
+*/
+-->
+
+<!-- This is the selector widget that allows the user to select an action. -->
+<com.android.keyguard.KeyguardWidgetCarousel
+ xmlns:androidprv="http://schemas.android.com/apk/res/com.android.keyguard"
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:paddingLeft="25dp"
+ android:paddingRight="25dp"
+ android:paddingTop="25dp"
+ android:paddingBottom="25dp"
+ android:clipToPadding="false"
+ androidprv:pageSpacing="10dp">
+</com.android.keyguard.KeyguardWidgetCarousel>
diff --git a/packages/Keyguard/res/layout-port/keyguard_host_view.xml b/packages/Keyguard/res/layout-port/keyguard_host_view.xml
new file mode 100644
index 0000000..8498dcf
--- /dev/null
+++ b/packages/Keyguard/res/layout-port/keyguard_host_view.xml
@@ -0,0 +1,94 @@
+<?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.
+*/
+-->
+
+<!-- This is the host view that generally contains two sub views: the widget view
+ and the security view. -->
+<com.android.keyguard.KeyguardHostView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/res/com.android.keyguard"
+ android:id="@+id/keyguard_host_view"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:gravity="center_horizontal"
+ android:orientation="vertical">
+
+ <com.android.keyguard.SlidingChallengeLayout
+ android:id="@+id/sliding_layout"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ androidprv:layout_childType="pageDeleteDropTarget">
+ <include layout="@layout/keyguard_widget_remove_drop_target"
+ android:id="@+id/keyguard_widget_pager_delete_target"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="top|center_horizontal" />
+ </FrameLayout>
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ androidprv:layout_childType="widgets">
+ <include layout="@layout/keyguard_widget_pager"
+ android:id="@+id/app_widget_container"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_gravity="center"/>
+ </FrameLayout>
+
+ <View android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ androidprv:layout_childType="scrim"
+ android:background="#99000000" />
+
+ <com.android.keyguard.KeyguardSecurityContainer
+ android:id="@+id/keyguard_security_container"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ androidprv:layout_maxHeight="@dimen/keyguard_security_height"
+ androidprv:layout_childType="challenge"
+ android:padding="0dp"
+ android:gravity="bottom|center_horizontal">
+ <com.android.keyguard.KeyguardSecurityViewFlipper
+ android:id="@+id/view_flipper"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:clipChildren="false"
+ android:clipToPadding="false"
+ android:paddingTop="@dimen/keyguard_security_view_margin"
+ android:gravity="center">
+ </com.android.keyguard.KeyguardSecurityViewFlipper>
+ </com.android.keyguard.KeyguardSecurityContainer>
+
+ <ImageButton
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/kg_widget_pager_bottom_padding"
+ androidprv:layout_childType="expandChallengeHandle"
+ android:focusable="true"
+ android:background="@null"
+ android:src="@drawable/keyguard_expand_challenge_handle"
+ android:scaleType="center"
+ android:contentDescription="@string/keyguard_accessibility_expand_lock_area" />
+
+ </com.android.keyguard.SlidingChallengeLayout>
+</com.android.keyguard.KeyguardHostView>
+
diff --git a/packages/Keyguard/res/layout-port/keyguard_status_area.xml b/packages/Keyguard/res/layout-port/keyguard_status_area.xml
new file mode 100644
index 0000000..d274457
--- /dev/null
+++ b/packages/Keyguard/res/layout-port/keyguard_status_area.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2009, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License")
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<!-- This is a view that shows general status information in Keyguard. -->
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/keyguard_status_area"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="right"
+ android:orientation="vertical">
+
+ <LinearLayout
+ android:orientation="horizontal"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="0dp"
+ android:layout_gravity="right">
+ <TextView
+ android:id="@+id/date"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginEnd="@dimen/kg_status_line_font_right_margin"
+ android:singleLine="true"
+ android:ellipsize="marquee"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:textSize="@dimen/kg_status_date_font_size"
+ />
+
+ <TextView
+ android:id="@+id/alarm_status"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginEnd="@dimen/kg_status_line_font_right_margin"
+ android:singleLine="true"
+ android:ellipsize="marquee"
+ android:textAppearance="?android:attr/textAppearance"
+ android:textSize="@dimen/kg_status_line_font_size"
+ android:drawablePadding="4dip"
+ />
+ </LinearLayout>
+
+</LinearLayout>
diff --git a/packages/Keyguard/res/layout-port/keyguard_widget_pager.xml b/packages/Keyguard/res/layout-port/keyguard_widget_pager.xml
new file mode 100644
index 0000000..d0a07ca
--- /dev/null
+++ b/packages/Keyguard/res/layout-port/keyguard_widget_pager.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.
+*/
+-->
+
+<!-- This is the selector widget that allows the user to select an action. -->
+<com.android.keyguard.KeyguardWidgetPager
+ xmlns:androidprv="http://schemas.android.com/apk/res/com.android.keyguard"
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/app_widget_container"
+ android:paddingLeft="25dp"
+ android:paddingRight="25dp"
+ android:paddingTop="25dp"
+ android:paddingBottom="@dimen/kg_widget_pager_bottom_padding"
+ android:clipToPadding="false"
+ androidprv:pageSpacing="10dp">
+</com.android.keyguard.KeyguardWidgetPager>
diff --git a/packages/Keyguard/res/layout-sw600dp-port/keyguard_host_view.xml b/packages/Keyguard/res/layout-sw600dp-port/keyguard_host_view.xml
new file mode 100644
index 0000000..77bc9b5
--- /dev/null
+++ b/packages/Keyguard/res/layout-sw600dp-port/keyguard_host_view.xml
@@ -0,0 +1,82 @@
+<?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.
+*/
+-->
+
+<!-- This is the host view that generally contains two sub views: the widget view
+ and the security view. -->
+<com.android.keyguard.KeyguardHostView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/res/com.android.keyguard"
+ android:id="@+id/keyguard_host_view"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="horizontal">
+
+ <com.android.keyguard.MultiPaneChallengeLayout
+ android:id="@+id/multi_pane_challenge"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:clipChildren="false"
+ android:orientation="vertical">
+
+ <include layout="@layout/keyguard_widget_remove_drop_target"
+ android:id="@+id/keyguard_widget_pager_delete_target"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="top|center_horizontal"
+ androidprv:layout_childType="pageDeleteDropTarget" />
+
+ <include layout="@layout/keyguard_widget_pager"
+ android:id="@+id/app_widget_container"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ androidprv:layout_centerWithinArea="0.5"
+ androidprv:layout_childType="widget"
+ androidprv:layout_maxWidth="480dp"
+ androidprv:layout_maxHeight="480dp" />
+
+ <include layout="@layout/keyguard_multi_user_selector"/>
+
+ <View android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ androidprv:layout_childType="scrim"
+ android:background="#99000000" />
+
+ <com.android.keyguard.KeyguardSecurityContainer
+ android:id="@+id/keyguard_security_container"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ androidprv:layout_centerWithinArea="0.5"
+ androidprv:layout_childType="challenge"
+ android:layout_gravity="center_horizontal|bottom">
+ <com.android.keyguard.KeyguardSecurityViewFlipper
+ android:id="@+id/view_flipper"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:clipChildren="false"
+ android:clipToPadding="false"
+ android:paddingLeft="@dimen/keyguard_security_view_margin"
+ android:paddingTop="@dimen/keyguard_security_view_margin"
+ android:paddingRight="@dimen/keyguard_security_view_margin"
+ android:paddingBottom="@dimen/keyguard_security_view_margin"
+ android:gravity="center">
+ </com.android.keyguard.KeyguardSecurityViewFlipper>
+ </com.android.keyguard.KeyguardSecurityContainer>
+
+ </com.android.keyguard.MultiPaneChallengeLayout>
+</com.android.keyguard.KeyguardHostView>
diff --git a/packages/Keyguard/res/layout-sw600dp/keyguard_glow_pad_container.xml b/packages/Keyguard/res/layout-sw600dp/keyguard_glow_pad_container.xml
new file mode 100644
index 0000000..930b14e
--- /dev/null
+++ b/packages/Keyguard/res/layout-sw600dp/keyguard_glow_pad_container.xml
@@ -0,0 +1,24 @@
+<?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">
+ <include layout="@layout/keyguard_glow_pad_view"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center" />
+</merge> \ No newline at end of file
diff --git a/packages/Keyguard/res/layout/keyguard_account_view.xml b/packages/Keyguard/res/layout/keyguard_account_view.xml
new file mode 100644
index 0000000..766effa
--- /dev/null
+++ b/packages/Keyguard/res/layout/keyguard_account_view.xml
@@ -0,0 +1,88 @@
+<?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.
+*/
+-->
+<com.android.keyguard.KeyguardAccountView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/res/com.android.keyguard"
+ android:id="@+id/keyguard_account_view"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ androidprv:layout_maxWidth="@dimen/keyguard_security_width"
+ androidprv:layout_maxHeight="@dimen/keyguard_security_height"
+ android:orientation="vertical">
+
+ <include layout="@layout/keyguard_message_area"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
+
+ <RelativeLayout
+ android:layout_width="match_parent"
+ android:layout_height="0dip"
+ android:layout_weight="1">
+
+ <EditText
+ android:id="@+id/login"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="8dip"
+ android:layout_marginStart="7dip"
+ android:layout_marginEnd="7dip"
+ android:layout_alignParentTop="true"
+ android:hint="@string/kg_login_username_hint"
+ android:inputType="textEmailAddress"
+ />
+
+ <EditText
+ android:id="@+id/password"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_below="@id/login"
+ android:layout_toLeftOf="@+id/ok"
+ android:layout_marginTop="15dip"
+ android:layout_marginStart="7dip"
+ android:layout_marginEnd="7dip"
+ android:inputType="textPassword"
+ android:hint="@string/kg_login_password_hint"
+ android:nextFocusRight="@+id/ok"
+ android:nextFocusDown="@+id/ok"
+ />
+
+ <!-- ok below password, aligned to right of screen -->
+ <Button
+ android:id="@+id/ok"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_margin="7dip"
+ android:layout_alignParentEnd="true"
+ android:layout_below="@id/login"
+ android:text="@string/kg_login_submit_button"
+ />
+
+ </RelativeLayout>
+
+ <!-- no room for ECA on this screen right now
+ <include layout="@layout/keyguard_eca"
+ android:id="@+id/keyguard_selector_fade_container"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:layout_gravity="bottom|center_horizontal"
+ android:gravity="center_horizontal" />
+ -->
+
+</com.android.keyguard.KeyguardAccountView>
diff --git a/packages/Keyguard/res/layout/keyguard_add_widget.xml b/packages/Keyguard/res/layout/keyguard_add_widget.xml
new file mode 100644
index 0000000..01b616c
--- /dev/null
+++ b/packages/Keyguard/res/layout/keyguard_add_widget.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2009, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License")
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<!-- This is a view that shows general status information in Keyguard. -->
+<com.android.keyguard.KeyguardWidgetFrame
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/keyguard_add_widget"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ >
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:contentDescription="@string/keyguard_accessibility_widget_empty_slot"
+ >
+ <ImageView
+ android:id="@+id/keyguard_add_widget_view"
+ android:clickable="true"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:padding="24dp"
+ android:src="@drawable/keyguard_add_widget_button"
+ android:contentDescription="@string/keyguard_accessibility_add_widget"/>
+ </FrameLayout>
+</com.android.keyguard.KeyguardWidgetFrame>
diff --git a/packages/Keyguard/res/layout/keyguard_emergency_carrier_area.xml b/packages/Keyguard/res/layout/keyguard_emergency_carrier_area.xml
new file mode 100644
index 0000000..1e2de92
--- /dev/null
+++ b/packages/Keyguard/res/layout/keyguard_emergency_carrier_area.xml
@@ -0,0 +1,75 @@
+<?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.
+*/
+-->
+
+<!-- This contains emergency call button and carrier as shared by pin/pattern/password screens -->
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:gravity="center"
+ android:layout_gravity="center_horizontal"
+ android:layout_alignParentBottom="true"
+ android:clickable="true">
+
+ <com.android.keyguard.CarrierText
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:singleLine="true"
+ android:ellipsize="marquee"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:textSize="@dimen/kg_status_line_font_size"
+ android:textColor="?android:attr/textColorSecondary"/>
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="-10dip"
+ style="?android:attr/buttonBarStyle"
+ android:orientation="horizontal"
+ android:gravity="center"
+ android:weightSum="2">
+
+ <com.android.keyguard.EmergencyButton
+ android:id="@+id/emergency_call_button"
+ android:layout_width="0dip"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:drawableLeft="@drawable/lockscreen_emergency_button"
+ android:text="@string/kg_emergency_call_label"
+ style="?android:attr/buttonBarButtonStyle"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:textSize="@dimen/kg_status_line_font_size"
+ android:textColor="?android:attr/textColorSecondary"
+ android:drawablePadding="8dip" />
+
+ <Button android:id="@+id/forgot_password_button"
+ android:layout_width="0dip"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:drawableLeft="@drawable/lockscreen_forgot_password_button"
+ style="?android:attr/buttonBarButtonStyle"
+ android:textSize="@dimen/kg_status_line_font_size"
+ android:textColor="?android:attr/textColorSecondary"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:drawablePadding="8dip"
+ android:visibility="gone"/>
+ </LinearLayout>
+
+</LinearLayout>
diff --git a/packages/Keyguard/res/layout/keyguard_emergency_carrier_area_empty.xml b/packages/Keyguard/res/layout/keyguard_emergency_carrier_area_empty.xml
new file mode 100644
index 0000000..2f4adae
--- /dev/null
+++ b/packages/Keyguard/res/layout/keyguard_emergency_carrier_area_empty.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.
+*/
+-->
+
+<!-- This is a blank layout to simplify implementation on landscape on phones
+ it is referenced indirectly by keyguard_eca -->
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="0dip"
+ android:layout_height="0dip"
+ android:orientation="vertical"
+ android:gravity="center"
+ android:layout_gravity="center_horizontal"
+ android:layout_alignParentBottom="true">
+
+</LinearLayout>
diff --git a/packages/Keyguard/res/layout/keyguard_face_unlock_view.xml b/packages/Keyguard/res/layout/keyguard_face_unlock_view.xml
new file mode 100644
index 0000000..94c68a5
--- /dev/null
+++ b/packages/Keyguard/res/layout/keyguard_face_unlock_view.xml
@@ -0,0 +1,79 @@
+<?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.
+*/
+-->
+
+<!-- This is the screen that allows the user to unlock by showing their face. -->
+<com.android.keyguard.KeyguardFaceUnlockView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/res/com.android.keyguard"
+ android:id="@+id/keyguard_face_unlock_view"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ androidprv:layout_maxWidth="@dimen/keyguard_security_width"
+ androidprv:layout_maxHeight="@dimen/keyguard_security_height"
+ android:contentDescription="@string/keyguard_accessibility_face_unlock">
+
+ <include layout="@layout/keyguard_message_area"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ />
+
+ <FrameLayout
+ android:id="@+id/keyguard_bouncer_frame"
+ android:background="@drawable/kg_bouncer_bg_white"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1"
+ >
+ <com.android.internal.widget.FaceUnlockView
+ android:id="@+id/face_unlock_area_view"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_gravity="center_horizontal"
+ android:background="@drawable/intro_bg"
+ android:gravity="center">
+
+ <View
+ android:id="@+id/spotlightMask"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="@color/facelock_spotlight_mask"
+ />
+
+ <ImageButton
+ android:id="@+id/face_unlock_cancel_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:padding="5dip"
+ android:layout_alignParentTop="true"
+ android:layout_alignParentEnd="true"
+ android:background="#00000000"
+ android:src="@drawable/ic_facial_backup"
+ />
+ </com.android.internal.widget.FaceUnlockView>
+ </FrameLayout>
+
+ <include layout="@layout/keyguard_eca"
+ android:id="@+id/keyguard_selector_fade_container"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:layout_gravity="bottom|center_horizontal"
+ android:gravity="center_horizontal" />
+</com.android.keyguard.KeyguardFaceUnlockView>
diff --git a/packages/Keyguard/res/layout/keyguard_glow_pad_container.xml b/packages/Keyguard/res/layout/keyguard_glow_pad_container.xml
new file mode 100644
index 0000000..376d0e9
--- /dev/null
+++ b/packages/Keyguard/res/layout/keyguard_glow_pad_container.xml
@@ -0,0 +1,26 @@
+<?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">
+ <include layout="@layout/keyguard_glow_pad_view"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="bottom|center_horizontal"
+ android:layout_marginBottom="-80dp"/>
+</merge> \ No newline at end of file
diff --git a/packages/Keyguard/res/layout/keyguard_glow_pad_view.xml b/packages/Keyguard/res/layout/keyguard_glow_pad_view.xml
new file mode 100644
index 0000000..3a466dd
--- /dev/null
+++ b/packages/Keyguard/res/layout/keyguard_glow_pad_view.xml
@@ -0,0 +1,46 @@
+<?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.
+*/
+-->
+
+<!-- This is the selector widget that allows the user to select an action. -->
+<com.android.internal.widget.multiwaveview.GlowPadView
+ xmlns:prvandroid="http://schemas.android.com/apk/prv/res/android"
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/glow_pad_view"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:orientation="horizontal"
+ android:gravity="@integer/kg_selector_gravity"
+ android:contentDescription="@string/keyguard_accessibility_slide_area"
+
+ prvandroid:targetDrawables="@array/lockscreen_targets_unlock_only"
+ prvandroid:targetDescriptions="@array/lockscreen_target_descriptions_unlock_only"
+ prvandroid:directionDescriptions="@array/lockscreen_direction_descriptions"
+ prvandroid:handleDrawable="@drawable/ic_lockscreen_handle"
+ prvandroid:outerRingDrawable="@drawable/ic_lockscreen_outerring"
+ prvandroid:outerRadius="@dimen/glowpadview_target_placement_radius"
+ prvandroid:innerRadius="@dimen/glowpadview_inner_radius"
+ prvandroid:snapMargin="@dimen/glowpadview_snap_margin"
+ prvandroid:firstItemOffset="@integer/kg_glowpad_rotation_offset"
+ prvandroid:magneticTargets="true"
+ prvandroid:feedbackCount="1"
+ prvandroid:vibrationDuration="20"
+ prvandroid:glowRadius="@dimen/glowpadview_glow_radius"
+ prvandroid:pointDrawable="@drawable/ic_lockscreen_glowdot"
+ prvandroid:allowScaling="true" />
diff --git a/packages/Keyguard/res/layout/keyguard_message_area.xml b/packages/Keyguard/res/layout/keyguard_message_area.xml
new file mode 100644
index 0000000..a709e98
--- /dev/null
+++ b/packages/Keyguard/res/layout/keyguard_message_area.xml
@@ -0,0 +1,33 @@
+<?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.
+*/
+-->
+
+<!-- This contains emergency call button and carrier as shared by pin/pattern/password screens -->
+<com.android.keyguard.KeyguardMessageArea
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center"
+ android:id="@+id/keyguard_message_area"
+ android:singleLine="true"
+ android:ellipsize="marquee"
+ android:textAppearance="?android:attr/textAppearance"
+ android:textSize="@dimen/kg_status_line_font_size"
+ android:textColor="?android:attr/textColorSecondary"
+ android:clickable="true" />
+
diff --git a/packages/Keyguard/res/layout/keyguard_message_area_large.xml b/packages/Keyguard/res/layout/keyguard_message_area_large.xml
new file mode 100644
index 0000000..ab6246d
--- /dev/null
+++ b/packages/Keyguard/res/layout/keyguard_message_area_large.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.
+*/
+-->
+
+<!-- This contains emergency call button and carrier as shared by pin/pattern/password screens -->
+<com.android.keyguard.KeyguardMessageArea
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center"
+ android:id="@+id/keyguard_message_area"
+ android:maxLines="4"
+ android:textAppearance="?android:attr/textAppearance"
+ android:textSize="@dimen/kg_status_line_font_size"
+ android:textColor="?android:attr/textColorSecondary" />
+
diff --git a/packages/Keyguard/res/layout/keyguard_multi_user_avatar.xml b/packages/Keyguard/res/layout/keyguard_multi_user_avatar.xml
new file mode 100644
index 0000000..41b0be9
--- /dev/null
+++ b/packages/Keyguard/res/layout/keyguard_multi_user_avatar.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2009, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License")
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<!-- This is a view that shows general status information in Keyguard. -->
+<com.android.keyguard.KeyguardMultiUserAvatar
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="@dimen/keyguard_avatar_size"
+ android:layout_height="@dimen/keyguard_avatar_size"
+ android:background="#00000000"
+ android:gravity="center_horizontal">
+ <ImageView
+ android:id="@+id/keyguard_user_avatar"
+ android:scaleType="center"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_gravity="center"/>
+ <TextView
+ android:id="@+id/keyguard_user_name"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="bottom"
+ android:gravity="center"
+ android:textSize="@dimen/keyguard_avatar_name_size"
+ android:textColor="#ffffff"
+ android:singleLine="true"
+ android:ellipsize="end"
+ android:paddingLeft="2dp"
+ android:paddingRight="2dp" />
+</com.android.keyguard.KeyguardMultiUserAvatar>
diff --git a/packages/Keyguard/res/layout/keyguard_multi_user_selector.xml b/packages/Keyguard/res/layout/keyguard_multi_user_selector.xml
new file mode 100644
index 0000000..c1d5326
--- /dev/null
+++ b/packages/Keyguard/res/layout/keyguard_multi_user_selector.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2009, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License")
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<com.android.keyguard.KeyguardMultiUserSelectorView
+ xmlns:androidprv="http://schemas.android.com/apk/res/com.android.keyguard"
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ androidprv:layout_childType="userSwitcher"
+ android:id="@+id/keyguard_user_selector"
+ android:orientation="horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="bottom"
+ android:contentDescription="@string/keyguard_accessibility_user_selector"
+ android:visibility="gone">
+
+ <com.android.keyguard.KeyguardLinearLayout
+ android:id="@+id/keyguard_users_grid"
+ android:orientation="horizontal"
+ android:layout_width="wrap_content"
+ android:layout_marginBottom="@dimen/keyguard_muliuser_selector_margin"
+ android:layout_height="@dimen/keyguard_avatar_size"
+ android:layout_gravity="center|bottom" />
+
+</com.android.keyguard.KeyguardMultiUserSelectorView>
diff --git a/packages/Keyguard/res/layout/keyguard_password_view.xml b/packages/Keyguard/res/layout/keyguard_password_view.xml
new file mode 100644
index 0000000..d8012bf
--- /dev/null
+++ b/packages/Keyguard/res/layout/keyguard_password_view.xml
@@ -0,0 +1,105 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 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.
+*/
+-->
+<com.android.keyguard.KeyguardPasswordView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/res/com.android.keyguard"
+ android:id="@+id/keyguard_password_view"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ androidprv:layout_maxWidth="@dimen/keyguard_security_width"
+ androidprv:layout_maxHeight="@dimen/keyguard_security_height"
+ android:gravity="bottom"
+ android:contentDescription="@string/keyguard_accessibility_password_unlock"
+ >
+
+ <Space
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1"
+ />
+
+ <include layout="@layout/keyguard_message_area"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
+
+ <!-- Password entry field -->
+ <!-- Note: the entire container is styled to look like the edit field,
+ since the backspace/IME switcher looks better inside -->
+ <FrameLayout
+ android:id="@+id/keyguard_bouncer_frame"
+ android:background="@drawable/kg_bouncer_bg_white"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ >
+ <LinearLayout
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:orientation="horizontal"
+ android:background="#70000000"
+ android:layout_marginTop="8dp"
+ android:layout_marginBottom="8dp"
+ >
+
+ <EditText android:id="@+id/passwordEntry"
+ android:layout_width="0dip"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:gravity="center_horizontal"
+ android:layout_gravity="center_vertical"
+ android:layout_marginStart="@dimen/keyguard_lockscreen_pin_margin_left"
+ android:singleLine="true"
+ android:textStyle="normal"
+ android:inputType="textPassword"
+ android:textSize="36sp"
+ android:background="@null"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:textColor="#ffffffff"
+ android:imeOptions="flagForceAscii|actionDone"
+ />
+
+ <ImageView android:id="@+id/switch_ime_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/ic_lockscreen_ime"
+ android:clickable="true"
+ android:padding="8dip"
+ android:layout_gravity="center"
+ android:background="?android:attr/selectableItemBackground"
+ android:visibility="gone"
+ />
+
+ </LinearLayout>
+ </FrameLayout>
+
+ <Space
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1"
+ />
+
+ <include layout="@layout/keyguard_eca"
+ android:id="@+id/keyguard_selector_fade_container"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:layout_gravity="bottom|center_horizontal"
+ android:gravity="center_horizontal" />
+
+</com.android.keyguard.KeyguardPasswordView>
diff --git a/packages/Keyguard/res/layout/keyguard_pattern_view.xml b/packages/Keyguard/res/layout/keyguard_pattern_view.xml
new file mode 100644
index 0000000..0c9380c
--- /dev/null
+++ b/packages/Keyguard/res/layout/keyguard_pattern_view.xml
@@ -0,0 +1,79 @@
+<?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.
+*/
+-->
+
+<!-- This is the screen that shows the 9 circle unlock widget and instructs
+ the user how to unlock their device, or make an emergency call. This
+ is the portrait layout. -->
+<com.android.keyguard.KeyguardPatternView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/res/com.android.keyguard"
+ android:id="@+id/keyguard_pattern_view"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ androidprv:layout_maxWidth="@dimen/keyguard_security_width"
+ androidprv:layout_maxHeight="@dimen/keyguard_security_height"
+ android:gravity="center_horizontal"
+ android:contentDescription="@string/keyguard_accessibility_pattern_unlock">
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <LinearLayout
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:orientation="vertical"
+ android:layout_gravity="center">
+
+ <include layout="@layout/keyguard_message_area"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ />
+
+ <FrameLayout
+ android:id="@+id/keyguard_bouncer_frame"
+ android:background="@drawable/kg_bouncer_bg_white"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1"
+ >
+ <com.android.internal.widget.LockPatternView
+ android:id="@+id/lockPatternView"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ android:layout_marginEnd="8dip"
+ android:layout_marginBottom="4dip"
+ android:layout_marginStart="8dip"
+ android:layout_gravity="center_horizontal"
+ android:gravity="center"
+ android:contentDescription="@string/keyguard_accessibility_pattern_area" />
+ </FrameLayout>
+ <include layout="@layout/keyguard_eca"
+ android:id="@+id/keyguard_selector_fade_container"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:layout_gravity="bottom|center_horizontal"
+ android:gravity="center_horizontal" />
+ </LinearLayout>
+ </FrameLayout>
+
+</com.android.keyguard.KeyguardPatternView>
diff --git a/packages/Keyguard/res/layout/keyguard_pin_view.xml b/packages/Keyguard/res/layout/keyguard_pin_view.xml
new file mode 100644
index 0000000..00c6a21
--- /dev/null
+++ b/packages/Keyguard/res/layout/keyguard_pin_view.xml
@@ -0,0 +1,224 @@
+<?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.
+*/
+-->
+
+<com.android.keyguard.KeyguardPINView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/res/com.android.keyguard"
+ android:id="@+id/keyguard_pin_view"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ androidprv:layout_maxWidth="@dimen/keyguard_security_width"
+ androidprv:layout_maxHeight="@dimen/keyguard_security_height"
+ android:orientation="vertical"
+ android:contentDescription="@string/keyguard_accessibility_pin_unlock"
+ >
+ <include layout="@layout/keyguard_message_area"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ />
+ <LinearLayout
+ android:id="@+id/keyguard_bouncer_frame"
+ android:background="@drawable/kg_bouncer_bg_white"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:orientation="vertical"
+ android:layout_weight="1"
+ android:layoutDirection="ltr"
+ >
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:orientation="horizontal"
+ android:layout_weight="1"
+ >
+ <TextView android:id="@+id/pinEntry"
+ android:editable="true"
+ android:layout_width="0dip"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ android:gravity="center"
+ android:layout_marginStart="@dimen/keyguard_lockscreen_pin_margin_left"
+ android:singleLine="true"
+ android:cursorVisible="false"
+ android:background="@null"
+ android:textAppearance="@style/TextAppearance.NumPadKey"
+ android:imeOptions="flagForceAscii|actionDone"
+ />
+ <ImageButton android:id="@+id/delete_button"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:gravity="center_vertical"
+ android:src="@drawable/ic_input_delete"
+ android:clickable="true"
+ android:paddingTop="8dip"
+ android:paddingBottom="8dip"
+ android:paddingLeft="24dp"
+ android:paddingRight="24dp"
+ android:background="?android:attr/selectableItemBackground"
+ android:contentDescription="@string/keyboardview_keycode_delete"
+ />
+ </LinearLayout>
+ <View
+ android:layout_width="wrap_content"
+ android:layout_height="1dp"
+ android:background="#55FFFFFF"
+ />
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1"
+ android:orientation="horizontal"
+ >
+ <view class="com.android.keyguard.NumPadKey"
+ android:id="@+id/key1"
+ style="@style/Widget.Button.NumPadKey"
+ android:layout_width="0px"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ androidprv:textView="@+id/pinEntry"
+ androidprv:digit="1"
+ />
+ <view class="com.android.keyguard.NumPadKey"
+ android:id="@+id/key2"
+ style="@style/Widget.Button.NumPadKey"
+ android:layout_width="0px"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ androidprv:textView="@+id/pinEntry"
+ androidprv:digit="2"
+ />
+ <view class="com.android.keyguard.NumPadKey"
+ android:id="@+id/key3"
+ style="@style/Widget.Button.NumPadKey"
+ android:layout_width="0px"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ androidprv:textView="@+id/pinEntry"
+ androidprv:digit="3"
+ />
+ </LinearLayout>
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1"
+ android:orientation="horizontal"
+ >
+ <view class="com.android.keyguard.NumPadKey"
+ android:id="@+id/key4"
+ style="@style/Widget.Button.NumPadKey"
+ android:layout_width="0px"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ androidprv:textView="@+id/pinEntry"
+ androidprv:digit="4"
+ />
+ <view class="com.android.keyguard.NumPadKey"
+ android:id="@+id/key5"
+ style="@style/Widget.Button.NumPadKey"
+ android:layout_width="0px"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ androidprv:textView="@+id/pinEntry"
+ androidprv:digit="5"
+ />
+ <view class="com.android.keyguard.NumPadKey"
+ android:id="@+id/key6"
+ style="@style/Widget.Button.NumPadKey"
+ android:layout_width="0px"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ androidprv:textView="@+id/pinEntry"
+ androidprv:digit="6"
+ />
+ </LinearLayout>
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:orientation="horizontal"
+ android:layout_weight="1"
+ >
+ <view class="com.android.keyguard.NumPadKey"
+ android:id="@+id/key7"
+ style="@style/Widget.Button.NumPadKey"
+ android:layout_width="0px"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ androidprv:textView="@+id/pinEntry"
+ androidprv:digit="7"
+ />
+ <view class="com.android.keyguard.NumPadKey"
+ android:id="@+id/key8"
+ style="@style/Widget.Button.NumPadKey"
+ android:layout_width="0px"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ androidprv:textView="@+id/pinEntry"
+ androidprv:digit="8"
+ />
+ <view class="com.android.keyguard.NumPadKey"
+ android:id="@+id/key9"
+ style="@style/Widget.Button.NumPadKey"
+ android:layout_width="0px"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ androidprv:textView="@+id/pinEntry"
+ androidprv:digit="9"
+ />
+ </LinearLayout>
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1"
+ android:orientation="horizontal"
+ >
+ <Space
+ android:layout_width="0px"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ />
+ <view class="com.android.keyguard.NumPadKey"
+ android:id="@+id/key0"
+ style="@style/Widget.Button.NumPadKey"
+ android:layout_width="0px"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ androidprv:textView="@+id/pinEntry"
+ androidprv:digit="0"
+ />
+ <ImageButton
+ android:id="@+id/key_enter"
+ style="@style/Widget.Button.NumPadKey"
+ android:layout_width="0px"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ android:paddingRight="30dp"
+ android:src="@drawable/sym_keyboard_return_holo"
+ android:contentDescription="@string/keyboardview_keycode_enter"
+ />
+ </LinearLayout>
+ </LinearLayout>
+ <include layout="@layout/keyguard_eca"
+ android:id="@+id/keyguard_selector_fade_container"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:layout_gravity="bottom|center_horizontal"
+ android:gravity="center_horizontal" />
+
+</com.android.keyguard.KeyguardPINView>
diff --git a/packages/Keyguard/res/layout/keyguard_selector_view.xml b/packages/Keyguard/res/layout/keyguard_selector_view.xml
new file mode 100644
index 0000000..6cb5e67
--- /dev/null
+++ b/packages/Keyguard/res/layout/keyguard_selector_view.xml
@@ -0,0 +1,64 @@
+<?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.
+*/
+-->
+
+<!-- This is the selector widget that allows the user to select an action. -->
+<com.android.keyguard.KeyguardSelectorView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/res/com.android.keyguard"
+ android:id="@+id/keyguard_selector_view"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ androidprv:layout_maxWidth="420dp"
+ androidprv:layout_maxHeight="@dimen/keyguard_security_height"
+ android:clipChildren="false"
+ android:clipToPadding="false"
+ android:orientation="vertical"
+ android:contentDescription="@string/keyguard_accessibility_slide_unlock">
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_gravity="center"
+ android:clipChildren="false"
+ android:clipToPadding="false"
+ android:gravity="center">
+
+ <include layout="@layout/keyguard_message_area"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
+
+ <View
+ android:id="@+id/keyguard_selector_view_frame"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_marginLeft="16dp"
+ android:layout_marginRight="16dp"
+ android:background="@drawable/kg_bouncer_bg_white"/>
+
+ <include layout="@layout/keyguard_glow_pad_container" />
+
+ <include layout="@layout/keyguard_eca"
+ android:id="@+id/keyguard_selector_fade_container"
+ android:layout_width="match_parent"
+ android:layout_height="48dp"
+ android:layout_gravity="bottom|center_horizontal" />
+ </FrameLayout>
+
+</com.android.keyguard.KeyguardSelectorView>
+
diff --git a/packages/Keyguard/res/layout/keyguard_sim_pin_view.xml b/packages/Keyguard/res/layout/keyguard_sim_pin_view.xml
new file mode 100644
index 0000000..eccac19
--- /dev/null
+++ b/packages/Keyguard/res/layout/keyguard_sim_pin_view.xml
@@ -0,0 +1,230 @@
+<?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.
+*/
+-->
+<!-- This is the SIM PIN view that allows the user to enter a SIM PIN to unlock the device. -->
+<com.android.keyguard.KeyguardSimPinView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/res/com.android.keyguard"
+ android:id="@+id/keyguard_sim_pin_view"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ androidprv:layout_maxWidth="@dimen/keyguard_security_width"
+ androidprv:layout_maxHeight="@dimen/keyguard_security_height"
+ android:gravity="center_horizontal">
+
+ <ImageView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:src="@drawable/ic_lockscreen_sim"/>
+
+ <include layout="@layout/keyguard_message_area"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ />
+ <LinearLayout
+ android:id="@+id/keyguard_bouncer_frame"
+ android:background="@drawable/kg_bouncer_bg_white"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:orientation="vertical"
+ android:layout_weight="1"
+ android:layoutDirection="ltr"
+ >
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:orientation="horizontal"
+ android:layout_weight="1"
+ >
+ <TextView android:id="@+id/pinEntry"
+ android:editable="true"
+ android:layout_width="0dip"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ android:gravity="center"
+ android:layout_marginStart="@dimen/keyguard_lockscreen_pin_margin_left"
+ android:singleLine="true"
+ android:cursorVisible="false"
+ android:background="@null"
+ android:textAppearance="@style/TextAppearance.NumPadKey"
+ android:imeOptions="flagForceAscii|actionDone"
+ />
+ <ImageButton android:id="@+id/delete_button"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:gravity="center_vertical"
+ android:src="@drawable/ic_input_delete"
+ android:clickable="true"
+ android:paddingTop="8dip"
+ android:paddingBottom="8dip"
+ android:paddingLeft="24dp"
+ android:paddingRight="24dp"
+ android:background="?android:attr/selectableItemBackground"
+ android:contentDescription="@string/keyboardview_keycode_delete"
+ />
+ </LinearLayout>
+ <View
+ android:layout_width="wrap_content"
+ android:layout_height="1dp"
+ android:background="#55FFFFFF"
+ />
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1"
+ android:orientation="horizontal"
+ >
+ <view class="com.android.keyguard.NumPadKey"
+ android:id="@+id/key1"
+ style="@style/Widget.Button.NumPadKey"
+ android:layout_width="0px"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ androidprv:textView="@+id/pinEntry"
+ androidprv:digit="1"
+ />
+ <view class="com.android.keyguard.NumPadKey"
+ android:id="@+id/key2"
+ style="@style/Widget.Button.NumPadKey"
+ android:layout_width="0px"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ androidprv:textView="@+id/pinEntry"
+ androidprv:digit="2"
+ />
+ <view class="com.android.keyguard.NumPadKey"
+ android:id="@+id/key3"
+ style="@style/Widget.Button.NumPadKey"
+ android:layout_width="0px"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ androidprv:textView="@+id/pinEntry"
+ androidprv:digit="3"
+ />
+ </LinearLayout>
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1"
+ android:orientation="horizontal"
+ >
+ <view class="com.android.keyguard.NumPadKey"
+ android:id="@+id/key4"
+ style="@style/Widget.Button.NumPadKey"
+ android:layout_width="0px"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ androidprv:textView="@+id/pinEntry"
+ androidprv:digit="4"
+ />
+ <view class="com.android.keyguard.NumPadKey"
+ android:id="@+id/key5"
+ style="@style/Widget.Button.NumPadKey"
+ android:layout_width="0px"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ androidprv:textView="@+id/pinEntry"
+ androidprv:digit="5"
+ />
+ <view class="com.android.keyguard.NumPadKey"
+ android:id="@+id/key6"
+ style="@style/Widget.Button.NumPadKey"
+ android:layout_width="0px"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ androidprv:textView="@+id/pinEntry"
+ androidprv:digit="6"
+ />
+ </LinearLayout>
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:orientation="horizontal"
+ android:layout_weight="1"
+ >
+ <view class="com.android.keyguard.NumPadKey"
+ android:id="@+id/key7"
+ style="@style/Widget.Button.NumPadKey"
+ android:layout_width="0px"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ androidprv:textView="@+id/pinEntry"
+ androidprv:digit="7"
+ />
+ <view class="com.android.keyguard.NumPadKey"
+ android:id="@+id/key8"
+ style="@style/Widget.Button.NumPadKey"
+ android:layout_width="0px"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ androidprv:textView="@+id/pinEntry"
+ androidprv:digit="8"
+ />
+ <view class="com.android.keyguard.NumPadKey"
+ android:id="@+id/key9"
+ style="@style/Widget.Button.NumPadKey"
+ android:layout_width="0px"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ androidprv:textView="@+id/pinEntry"
+ androidprv:digit="9"
+ />
+ </LinearLayout>
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1"
+ android:orientation="horizontal"
+ >
+ <Space
+ android:layout_width="0px"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ />
+ <view class="com.android.keyguard.NumPadKey"
+ android:id="@+id/key0"
+ style="@style/Widget.Button.NumPadKey"
+ android:layout_width="0px"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ androidprv:textView="@+id/pinEntry"
+ androidprv:digit="0"
+ />
+ <ImageButton
+ android:id="@+id/key_enter"
+ style="@style/Widget.Button.NumPadKey"
+ android:layout_width="0px"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ android:paddingRight="30dp"
+ android:src="@drawable/sym_keyboard_return_holo"
+ android:contentDescription="@string/keyboardview_keycode_enter"
+ />
+ </LinearLayout>
+ </LinearLayout>
+
+ <include layout="@layout/keyguard_eca"
+ android:id="@+id/keyguard_selector_fade_container"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:layout_gravity="bottom|center_horizontal"
+ android:gravity="center_horizontal" />
+
+</com.android.keyguard.KeyguardSimPinView>
diff --git a/packages/Keyguard/res/layout/keyguard_sim_puk_view.xml b/packages/Keyguard/res/layout/keyguard_sim_puk_view.xml
new file mode 100644
index 0000000..fe37203
--- /dev/null
+++ b/packages/Keyguard/res/layout/keyguard_sim_puk_view.xml
@@ -0,0 +1,230 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 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.
+*/
+-->
+<!-- This is the SIM PUK view that allows the user to recover their device by entering the
+ carrier-provided PUK code and entering a new SIM PIN for it. -->
+<com.android.keyguard.KeyguardSimPukView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/res/com.android.keyguard"
+ android:id="@+id/keyguard_sim_puk_view"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ androidprv:layout_maxWidth="@dimen/keyguard_security_width"
+ androidprv:layout_maxHeight="@dimen/keyguard_security_height"
+ android:gravity="center_horizontal">
+
+ <ImageView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:src="@drawable/ic_lockscreen_sim"/>
+
+ <include layout="@layout/keyguard_message_area"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ />
+ <LinearLayout
+ android:id="@+id/keyguard_bouncer_frame"
+ android:background="@drawable/kg_bouncer_bg_white"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:orientation="vertical"
+ android:layout_weight="1"
+ android:layoutDirection="ltr"
+ >
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:orientation="horizontal"
+ android:layout_weight="1"
+ >
+ <TextView android:id="@+id/pinEntry"
+ android:editable="true"
+ android:layout_width="0dip"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ android:gravity="center"
+ android:layout_marginStart="@dimen/keyguard_lockscreen_pin_margin_left"
+ android:singleLine="true"
+ android:cursorVisible="false"
+ android:background="@null"
+ android:textAppearance="@style/TextAppearance.NumPadKey"
+ android:imeOptions="flagForceAscii|actionDone"
+ />
+ <ImageButton android:id="@+id/delete_button"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:gravity="center_vertical"
+ android:src="@drawable/ic_input_delete"
+ android:clickable="true"
+ android:paddingTop="8dip"
+ android:paddingBottom="8dip"
+ android:paddingLeft="24dp"
+ android:paddingRight="24dp"
+ android:background="?android:attr/selectableItemBackground"
+ android:contentDescription="@string/keyboardview_keycode_delete"
+ />
+ </LinearLayout>
+ <View
+ android:layout_width="wrap_content"
+ android:layout_height="1dp"
+ android:background="#55FFFFFF"
+ />
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1"
+ android:orientation="horizontal"
+ >
+ <view class="com.android.keyguard.NumPadKey"
+ android:id="@+id/key1"
+ style="@style/Widget.Button.NumPadKey"
+ android:layout_width="0px"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ androidprv:textView="@+id/pinEntry"
+ androidprv:digit="1"
+ />
+ <view class="com.android.keyguard.NumPadKey"
+ android:id="@+id/key2"
+ style="@style/Widget.Button.NumPadKey"
+ android:layout_width="0px"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ androidprv:textView="@+id/pinEntry"
+ androidprv:digit="2"
+ />
+ <view class="com.android.keyguard.NumPadKey"
+ android:id="@+id/key3"
+ style="@style/Widget.Button.NumPadKey"
+ android:layout_width="0px"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ androidprv:textView="@+id/pinEntry"
+ androidprv:digit="3"
+ />
+ </LinearLayout>
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1"
+ android:orientation="horizontal"
+ >
+ <view class="com.android.keyguard.NumPadKey"
+ android:id="@+id/key4"
+ style="@style/Widget.Button.NumPadKey"
+ android:layout_width="0px"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ androidprv:textView="@+id/pinEntry"
+ androidprv:digit="4"
+ />
+ <view class="com.android.keyguard.NumPadKey"
+ android:id="@+id/key5"
+ style="@style/Widget.Button.NumPadKey"
+ android:layout_width="0px"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ androidprv:textView="@+id/pinEntry"
+ androidprv:digit="5"
+ />
+ <view class="com.android.keyguard.NumPadKey"
+ android:id="@+id/key6"
+ style="@style/Widget.Button.NumPadKey"
+ android:layout_width="0px"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ androidprv:textView="@+id/pinEntry"
+ androidprv:digit="6"
+ />
+ </LinearLayout>
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:orientation="horizontal"
+ android:layout_weight="1"
+ >
+ <view class="com.android.keyguard.NumPadKey"
+ android:id="@+id/key7"
+ style="@style/Widget.Button.NumPadKey"
+ android:layout_width="0px"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ androidprv:textView="@+id/pinEntry"
+ androidprv:digit="7"
+ />
+ <view class="com.android.keyguard.NumPadKey"
+ android:id="@+id/key8"
+ style="@style/Widget.Button.NumPadKey"
+ android:layout_width="0px"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ androidprv:textView="@+id/pinEntry"
+ androidprv:digit="8"
+ />
+ <view class="com.android.keyguard.NumPadKey"
+ android:id="@+id/key9"
+ style="@style/Widget.Button.NumPadKey"
+ android:layout_width="0px"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ androidprv:textView="@+id/pinEntry"
+ androidprv:digit="9"
+ />
+ </LinearLayout>
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1"
+ android:orientation="horizontal"
+ >
+ <Space
+ android:layout_width="0px"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ />
+ <view class="com.android.keyguard.NumPadKey"
+ android:id="@+id/key0"
+ style="@style/Widget.Button.NumPadKey"
+ android:layout_width="0px"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ androidprv:textView="@+id/pinEntry"
+ androidprv:digit="0"
+ />
+ <ImageButton
+ android:id="@+id/key_enter"
+ style="@style/Widget.Button.NumPadKey"
+ android:layout_width="0px"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ android:paddingRight="30dp"
+ android:src="@drawable/sym_keyboard_return_holo"
+ android:contentDescription="@string/keyboardview_keycode_enter"
+ />
+ </LinearLayout>
+ </LinearLayout>
+
+ <include layout="@layout/keyguard_eca"
+ android:id="@+id/keyguard_selector_fade_container"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:layout_gravity="bottom|center_horizontal"
+ android:gravity="center_horizontal" />
+</com.android.keyguard.KeyguardSimPukView>
diff --git a/packages/Keyguard/res/layout/keyguard_status_view.xml b/packages/Keyguard/res/layout/keyguard_status_view.xml
new file mode 100644
index 0000000..2304d9f
--- /dev/null
+++ b/packages/Keyguard/res/layout/keyguard_status_view.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2009, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License")
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<!-- This is a view that shows general status information in Keyguard. -->
+<com.android.keyguard.KeyguardWidgetFrame
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/res/com.android.keyguard"
+ android:id="@+id/keyguard_status_view"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ androidprv:layout_maxWidth="@dimen/keyguard_security_width"
+ androidprv:layout_maxHeight="@dimen/keyguard_security_height"
+ android:gravity="center_horizontal">
+
+ <com.android.keyguard.KeyguardStatusView
+ android:id="@+id/keyguard_status_view_face_palm"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:gravity="center_horizontal|top"
+ android:contentDescription="@string/keyguard_accessibility_status">
+
+ <LinearLayout android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal|top"
+ android:orientation="vertical"
+ android:focusable="true">
+ <com.android.keyguard.ClockView
+ android:id="@+id/clock_view"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginEnd="@dimen/kg_status_line_font_right_margin"
+ android:layout_gravity="right">
+
+ <TextView android:id="@+id/clock_text"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:singleLine="true"
+ android:ellipsize="none"
+ android:textSize="@dimen/kg_status_clock_font_size"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:textColor="#ffffffff"
+ android:drawablePadding="2dip"
+ />
+
+ </com.android.keyguard.ClockView>
+
+ <include layout="@layout/keyguard_status_area" />
+ </LinearLayout>
+
+ </com.android.keyguard.KeyguardStatusView>
+</com.android.keyguard.KeyguardWidgetFrame>
diff --git a/packages/Keyguard/res/layout/keyguard_test_activity.xml b/packages/Keyguard/res/layout/keyguard_test_activity.xml
new file mode 100644
index 0000000..a3b75b0
--- /dev/null
+++ b/packages/Keyguard/res/layout/keyguard_test_activity.xml
@@ -0,0 +1,47 @@
+<?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.
+*/
+-->
+
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:gravity="center">
+
+ <Button android:id="@+id/do_keyguard"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/do_keyguard" />
+
+ <Button android:id="@+id/on_screen_turned_off"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/on_screen_turned_off" />
+
+ <Button android:id="@+id/on_screen_turned_on"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/on_screen_turned_on" />
+
+ <Button android:id="@+id/verify_unlock"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/verify_unlock" />
+
+</LinearLayout>
diff --git a/packages/Keyguard/res/layout/keyguard_transport_control_view.xml b/packages/Keyguard/res/layout/keyguard_transport_control_view.xml
new file mode 100644
index 0000000..7e36f9f
--- /dev/null
+++ b/packages/Keyguard/res/layout/keyguard_transport_control_view.xml
@@ -0,0 +1,112 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<!-- This is a view to control music playback in keyguard. -->
+<com.android.keyguard.KeyguardTransportControlView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:gravity="center_horizontal"
+ android:id="@+id/keyguard_transport_control">
+
+ <!-- FrameLayout used as scrim to show between album art and buttons -->
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:foreground="@drawable/ic_lockscreen_player_background"
+ android:contentDescription="@string/keygaurd_accessibility_media_controls">
+ <!-- Use ImageView for its cropping features; otherwise could be android:background -->
+ <ImageView
+ android:id="@+id/albumart"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_gravity="fill"
+ android:scaleType="centerCrop"
+ android:adjustViewBounds="false"
+ />
+ </FrameLayout>
+
+ <LinearLayout
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="bottom">
+ <TextView
+ android:id="@+id/title"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="8dip"
+ android:layout_marginStart="16dip"
+ android:layout_marginEnd="16dip"
+ android:gravity="center_horizontal"
+ android:singleLine="true"
+ android:ellipsize="end"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ />
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:layout_marginTop="5dip">
+ <FrameLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_weight="1">
+ <ImageView
+ android:id="@+id/btn_prev"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:src="@drawable/ic_media_previous"
+ android:clickable="true"
+ android:background="?android:attr/selectableItemBackground"
+ android:padding="10dip"
+ android:contentDescription="@string/keyguard_accessibility_transport_prev_description"/>
+ </FrameLayout>
+ <FrameLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_weight="1">
+ <ImageView
+ android:id="@+id/btn_play"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:clickable="true"
+ android:src="@drawable/ic_media_play"
+ android:background="?android:attr/selectableItemBackground"
+ android:padding="10dip"
+ android:contentDescription="@string/keyguard_accessibility_transport_play_description"/>
+ </FrameLayout>
+ <FrameLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_weight="1">
+ <ImageView
+ android:id="@+id/btn_next"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:clickable="true"
+ android:src="@drawable/ic_media_next"
+ android:background="?android:attr/selectableItemBackground"
+ android:padding="10dip"
+ android:contentDescription="@string/keyguard_accessibility_transport_next_description"/>
+ </FrameLayout>
+ </LinearLayout>
+ </LinearLayout>
+
+</com.android.keyguard.KeyguardTransportControlView>
diff --git a/packages/Keyguard/res/layout/keyguard_widget_remove_drop_target.xml b/packages/Keyguard/res/layout/keyguard_widget_remove_drop_target.xml
new file mode 100644
index 0000000..294c386
--- /dev/null
+++ b/packages/Keyguard/res/layout/keyguard_widget_remove_drop_target.xml
@@ -0,0 +1,33 @@
+<?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.
+*/
+-->
+<TextView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:gravity="center"
+ android:padding="30dp"
+ android:paddingLeft="60dp"
+ android:paddingRight="60dp"
+ android:drawableLeft="@drawable/kg_widget_delete_drop_target"
+ android:drawablePadding="4dp"
+ android:text="@string/kg_reordering_delete_drop_target_text"
+ android:textColor="#FFF"
+ android:textSize="13sp"
+ android:shadowColor="#000"
+ android:shadowDy="1.0"
+ android:shadowRadius="1.0"
+ android:visibility="gone" />
diff --git a/packages/Keyguard/res/menu/optionmenu.xml b/packages/Keyguard/res/menu/optionmenu.xml
new file mode 100644
index 0000000..22f300d
--- /dev/null
+++ b/packages/Keyguard/res/menu/optionmenu.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:id="@+id/none_menu_item"
+ android:title="@string/none_menu_item" />
+ <item android:id="@+id/pin_menu_item"
+ android:title="@string/pin_menu_item" />
+ <item android:id="@+id/password_menu_item"
+ android:title="@string/password_menu_item" />
+ <item android:id="@+id/pattern_menu_item"
+ android:title="@string/pattern_menu_item" />
+ <item android:id="@+id/sim_pin_menu_item"
+ android:title="@string/sim_pin_menu_item" />
+ <item android:id="@+id/sim_puk_menu_item"
+ android:title="@string/sim_puk_menu_item" />
+ <item android:id="@+id/add_widget_item"
+ android:title="@string/add_widget_item" />
+</menu>
diff --git a/packages/Keyguard/res/values-af/strings.xml b/packages/Keyguard/res/values-af/strings.xml
new file mode 100644
index 0000000..7bc978b
--- /dev/null
+++ b/packages/Keyguard/res/values-af/strings.xml
@@ -0,0 +1,164 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/* //device/apps/common/assets/res/any/strings.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:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Voer PIN-kode in"</string>
+ <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Voer PUK en nuwe PIN-kode in"</string>
+ <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK-kode"</string>
+ <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Nuwe PIN-kode"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Raak om wagwoord in te voer"</font></string>
+ <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Voer wagwoord in om te ontsluit"</string>
+ <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Voer PIN in om te ontsluit"</string>
+ <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Verkeerde PIN-kode."</string>
+ <string name="keyguard_label_text" msgid="861796461028298424">"Om te ontsluit, druk Kieslys dan 0."</string>
+ <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Maksimum gesigontsluit-pogings oorskry"</string>
+ <!-- no translation found for keyguard_charged (3272223906073492454) -->
+ <skip />
+ <!-- no translation found for keyguard_plugged_in (8117572000639998388) -->
+ <skip />
+ <!-- no translation found for keyguard_low_battery (8143808018719173859) -->
+ <skip />
+ <!-- no translation found for keyguard_instructions_when_pattern_disabled (1332288268600329841) -->
+ <skip />
+ <!-- no translation found for keyguard_network_locked_message (9169717779058037168) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message_short (494980561304211931) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (1445849005909260039) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (3481110395508637643) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions (5210891509995942250) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions_long (5968985489463870358) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_message_short (8340813989586622356) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_instructions (5892940909699723544) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_locked_message (6875773413306380902) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_puk_locked_message (3747232467471801633) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_unlock_progress_dialog_message (7975221805033614426) -->
+ <skip />
+ <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Legstuk %2$d van %3$d."</string>
+ <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Voeg legstuk by."</string>
+ <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Leeg"</string>
+ <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Ontsluitruimte uitgevou."</string>
+ <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Ontsluitruimte ingevou."</string>
+ <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g>-legstuk."</string>
+ <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"Gebruikerkieser"</string>
+ <string name="keyguard_accessibility_status" msgid="8008264603935930611">"Status"</string>
+ <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"Kamera"</string>
+ <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Media-kontroles"</string>
+ <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Herordening van legstuk begin."</string>
+ <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Herordening van legstuk beëindig."</string>
+ <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Legstuk <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> uitgevee."</string>
+ <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Vou ontsluitruimte uit."</string>
+ <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Sleep-ontsluit."</string>
+ <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Patroon ontsluit."</string>
+ <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Gesigslot."</string>
+ <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"PIN ontsluit."</string>
+ <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Wagwoord ontsluit."</string>
+ <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Patroonarea."</string>
+ <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Sleep-area."</string>
+ <!-- no translation found for keyguard_accessibility_transport_prev_description (1337286538318543555) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_next_description (7073928300444909320) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_pause_description (8455979545295224302) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_play_description (8146417789511154044) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_stop_description (7656358482980912216) -->
+ <skip />
+ <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+ <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+ <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+ <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Kanselleer"</string>
+ <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Vee uit"</string>
+ <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Klaar"</string>
+ <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Modus verander"</string>
+ <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
+ <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Invoersleutel"</string>
+ <string name="description_target_unlock" msgid="2228524900439801453">"Ontsluit"</string>
+ <string name="description_target_camera" msgid="969071997552486814">"Kamera"</string>
+ <string name="description_target_silent" msgid="893551287746522182">"Stil"</string>
+ <string name="description_target_soundon" msgid="30052466675500172">"Klank aan"</string>
+ <string name="description_target_search" msgid="3091587249776033139">"Soek"</string>
+ <string name="description_direction_up" msgid="7169032478259485180">"Gly op vir <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_down" msgid="5087739728639014595">"Gly af vir <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_left" msgid="7207478719805562165">"Gly links vir <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_right" msgid="8034433242579600980">"Gly regs vir <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="user_switched" msgid="3768006783166984410">"Huidige gebruiker <xliff:g id="NAME">%1$s</xliff:g> ."</string>
+ <string name="kg_emergency_call_label" msgid="684946192523830531">"Noodoproep"</string>
+ <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Het jy die patroon vergeet?"</string>
+ <string name="kg_wrong_pattern" msgid="1850806070801358830">"Verkeerde patroon"</string>
+ <string name="kg_wrong_password" msgid="2333281762128113157">"Verkeerde wagwoord"</string>
+ <string name="kg_wrong_pin" msgid="1131306510833563801">"Verkeerde PIN"</string>
+ <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Probeer weer oor <xliff:g id="NUMBER">%d</xliff:g> sekondes."</string>
+ <string name="kg_pattern_instructions" msgid="398978611683075868">"Teken jou patroon"</string>
+ <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Voer SIM-PIN in"</string>
+ <string name="kg_pin_instructions" msgid="2377242233495111557">"Voer PIN in"</string>
+ <string name="kg_password_instructions" msgid="5753646556186936819">"Voer wagwoord in"</string>
+ <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"SIM is nou gedeaktiveer. Voer PUK-kode in om voort te gaan. Kontak diensverskaffer vir details."</string>
+ <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Voer die gewenste PIN-kode in"</string>
+ <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Bevestig gewenste PIN-kode"</string>
+ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Ontsluit tans SIM-kaart…"</string>
+ <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Verkeerde PIN-kode."</string>
+ <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Tik \'n PIN in wat 4 tot 8 syfers lank is."</string>
+ <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK-kode moet 8 of meer syfers wees."</string>
+ <string name="kg_invalid_puk" msgid="3638289409676051243">"Voer weer die korrekte PUK-kode in. Herhaalde pogings sal die SIM permanent deaktiveer."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN-kodes stem nie ooreen nie"</string>
+ <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Te veel patroonpogings"</string>
+ <string name="kg_login_instructions" msgid="1100551261265506448">"Om te ontsluit, meld met jou Google-rekening aan."</string>
+ <string name="kg_login_username_hint" msgid="5718534272070920364">"Gebruikernaam (e-pos)"</string>
+ <string name="kg_login_password_hint" msgid="9057289103827298549">"Wagwoord"</string>
+ <string name="kg_login_submit_button" msgid="5355904582674054702">"Meld aan"</string>
+ <string name="kg_login_invalid_input" msgid="5754664119319872197">"Ongeldige gebruikernaam of wagwoord."</string>
+ <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Het jy jou gebruikernaam of wagwoord vergeet?"\n"Besoek "<b>"google.com/accounts/recovery"</b>"."</string>
+ <string name="kg_login_checking_password" msgid="1052685197710252395">"Kontroleer tans rekening..."</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Jy het jou PIN <xliff:g id="NUMBER_0">%d</xliff:g> keer verkeerd ingetik. "\n\n"Probeer weer oor <xliff:g id="NUMBER_1">%d</xliff:g> sekondes."</string>
+ <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Jy het <xliff:g id="NUMBER_0">%d</xliff:g> keer jou wagwoord verkeerdelik getik. "\n\n"Probeer weer oor <xliff:g id="NUMBER_1">%d</xliff:g> sekondes."</string>
+ <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Jy het jou ontsluitpatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer verkeerdelik geteken. "\n\n"Probeer weer oor <xliff:g id="NUMBER_1">%d</xliff:g> sekondes."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Jy het <xliff:g id="NUMBER_0">%d</xliff:g> keer verkeerdelik gepoog om die tablet te ontsluit. Na nog <xliff:g id="NUMBER_1">%d</xliff:g> onsuksesvolle pogings, sal die tablet na die fabrieksverstek teruggestel word en al die gebruikerdata sal verlore wees."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Jy het <xliff:g id="NUMBER_0">%d</xliff:g> keer verkeerdelik gepoog om die foon te ontsluit. Na nog <xliff:g id="NUMBER_1">%d</xliff:g> onsuksesvolle pogings, sal die foon na die fabrieksverstek teruggestel word en al die gebruikerdata sal verlore wees."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Jy het <xliff:g id="NUMBER">%d</xliff:g> keer verkeerdelik gepoog om die tablet te ontsluit. Die tablet sal nou na fabrieksverstek teruggestel word."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Jy het <xliff:g id="NUMBER">%d</xliff:g> keer verkeerdelik gepoog om die foon te ontsluit. Die foon sal nou na fabrieksverstek teruggestel word."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Jy het jou ontsluitpatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer verkeerdelik geteken. Na nog <xliff:g id="NUMBER_1">%d</xliff:g> onsuksesvolle pogings, sal jy gevra word om jou tablet te ontsluit deur middel van \'n e-posrekening."\n\n" Probeer weer oor <xliff:g id="NUMBER_2">%d</xliff:g> sekondes."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Jy het jou ontsluitpatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer verkeerdelik geteken. Na nog <xliff:g id="NUMBER_1">%d</xliff:g> onsuksesvolle pogings, sal jy gevra word om jou foon te ontsluit deur middel van \'n e-posrekening."\n\n" Probeer weer oor <xliff:g id="NUMBER_2">%d</xliff:g> sekondes."</string>
+ <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
+ <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Verwyder"</string>
+ <!-- no translation found for keyguard_transport_prev_description (8229108430245669854) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_next_description (4299258300283778305) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_pause_description (5093073338238310224) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_play_description (2924628863741150956) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_stop_description (3084179324810575787) -->
+ <skip />
+ <!-- no translation found for keyguard_carrier_default (8700650403054042153) -->
+ <skip />
+</resources>
diff --git a/packages/Keyguard/res/values-am/strings.xml b/packages/Keyguard/res/values-am/strings.xml
new file mode 100644
index 0000000..bf01123
--- /dev/null
+++ b/packages/Keyguard/res/values-am/strings.xml
@@ -0,0 +1,164 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/* //device/apps/common/assets/res/any/strings.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:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"ፒን ኮድ ተይብ"</string>
+ <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"PUK እና አዲስ ፒን ተይብ"</string>
+ <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"የPUK ኮድ"</string>
+ <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"አዲስ Pin ኮድ"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"የይለፍ ቃል ለመተየብ ንካ"</font></string>
+ <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"ለመክፈት የይለፍ ቃል ተይብ"</string>
+ <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"ለመክፈት ፒን ተይብ"</string>
+ <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"ትክክል ያልሆነ PIN ኮድ።"</string>
+ <string name="keyguard_label_text" msgid="861796461028298424">"ለመክፈት፣ምናሌ ተጫን ከዛ 0"</string>
+ <string name="faceunlock_multiple_failures" msgid="754137583022792429">"የመጨረሻውን የገጽ ክፈት ሙከራዎችን አልፏል"</string>
+ <!-- no translation found for keyguard_charged (3272223906073492454) -->
+ <skip />
+ <!-- no translation found for keyguard_plugged_in (8117572000639998388) -->
+ <skip />
+ <!-- no translation found for keyguard_low_battery (8143808018719173859) -->
+ <skip />
+ <!-- no translation found for keyguard_instructions_when_pattern_disabled (1332288268600329841) -->
+ <skip />
+ <!-- no translation found for keyguard_network_locked_message (9169717779058037168) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message_short (494980561304211931) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (1445849005909260039) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (3481110395508637643) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions (5210891509995942250) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions_long (5968985489463870358) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_message_short (8340813989586622356) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_instructions (5892940909699723544) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_locked_message (6875773413306380902) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_puk_locked_message (3747232467471801633) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_unlock_progress_dialog_message (7975221805033614426) -->
+ <skip />
+ <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s። ምግብር %2$d ከ%3$d።"</string>
+ <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"ንዑስ ፕሮግራም አክል"</string>
+ <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"ባዶ"</string>
+ <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"የመክፈቻ አካባቢ ተስፋፍቷል።"</string>
+ <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"የመክፈቻ አካባቢ ተሰብስቧል።"</string>
+ <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"የ<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> ንዑስ ፕሮግራም።"</string>
+ <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"ተጠቃሚ መራጭ"</string>
+ <string name="keyguard_accessibility_status" msgid="8008264603935930611">"ሁኔታ"</string>
+ <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"ካሜራ"</string>
+ <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"የሚዲያ መቆጣጠሪያዎች"</string>
+ <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"የንዑስ ፕሮግራም ዳግም መደርደር ተጀምሯል።"</string>
+ <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"የንዑስ ፕሮግራም ዳግም መደርደር አብቅቷል።"</string>
+ <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"ንዑስ ፕሮግራም <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> ተሰርዟል።"</string>
+ <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"የመክፈቻ አካባቢውን አስፋፋ።"</string>
+ <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"በማንሸራተት ክፈት።"</string>
+ <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"በስርዓተ-ጥለት መክፈት።"</string>
+ <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"በፊት መክፈት።"</string>
+ <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"በፒን መክፈት።"</string>
+ <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"በይለፍ ቃል መክፈት።"</string>
+ <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"የስርዓተ-ጥለት አካባቢ።"</string>
+ <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"የማንሸራተቻ አካባቢ።"</string>
+ <!-- no translation found for keyguard_accessibility_transport_prev_description (1337286538318543555) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_next_description (7073928300444909320) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_pause_description (8455979545295224302) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_play_description (8146417789511154044) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_stop_description (7656358482980912216) -->
+ <skip />
+ <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+ <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+ <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+ <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"ተወው"</string>
+ <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"ሰርዝ"</string>
+ <string name="keyboardview_keycode_done" msgid="1992571118466679775">"ተከናውኗል"</string>
+ <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"ሞድ ለውጥ"</string>
+ <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"ቀይር"</string>
+ <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"አስገባ"</string>
+ <string name="description_target_unlock" msgid="2228524900439801453">"ክፈት"</string>
+ <string name="description_target_camera" msgid="969071997552486814">"ካሜራ"</string>
+ <string name="description_target_silent" msgid="893551287746522182">"ፀጥታ"</string>
+ <string name="description_target_soundon" msgid="30052466675500172">"ድምፅ አብራ"</string>
+ <string name="description_target_search" msgid="3091587249776033139">"ፈልግ"</string>
+ <string name="description_direction_up" msgid="7169032478259485180">"ለ<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ወደ ላይ አንሸራትት።"</string>
+ <string name="description_direction_down" msgid="5087739728639014595">"ለ<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ወደ ታች አንሸራትት።"</string>
+ <string name="description_direction_left" msgid="7207478719805562165">"ለ<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ወደ ግራ አንሸራትት።"</string>
+ <string name="description_direction_right" msgid="8034433242579600980">"ለ<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ወደ ቀኝ አንሸራትት።"</string>
+ <string name="user_switched" msgid="3768006783166984410">"የአሁኑ ተጠቃሚ <xliff:g id="NAME">%1$s</xliff:g>።"</string>
+ <string name="kg_emergency_call_label" msgid="684946192523830531">"የአደጋ ጊዜ ጥሪ"</string>
+ <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"ስርዓተ ጥለቱን እርሳ"</string>
+ <string name="kg_wrong_pattern" msgid="1850806070801358830">"የተሳሳተ ስርዓተ ጥለት"</string>
+ <string name="kg_wrong_password" msgid="2333281762128113157">"የተሳሳተ ይለፍ ቃል"</string>
+ <string name="kg_wrong_pin" msgid="1131306510833563801">"የተሳሳተ ፒን"</string>
+ <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"በ<xliff:g id="NUMBER">%d</xliff:g> ሰከንዶች ውስጥ እንደገና ይሞክሩ።"</string>
+ <string name="kg_pattern_instructions" msgid="398978611683075868">"ስርዓተ ጥለትዎን ይሳሉ"</string>
+ <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"የሲም ፒን ያስገቡ"</string>
+ <string name="kg_pin_instructions" msgid="2377242233495111557">"ፒን ያስገቡ"</string>
+ <string name="kg_password_instructions" msgid="5753646556186936819">"የይለፍ ቃል ያስገቡ"</string>
+ <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"ሲም አሁን ተሰናክሏል። ለመቀጠል የPUK ኮድ ያስገቡ። ለዝርዝር ድምጸ ተያያዥ ሞደምን ያግኙ።"</string>
+ <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"የተፈለገውን የፒን ኮድ ያስገቡ"</string>
+ <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"የተፈለገውን የፒን ኮድ ያረጋግጡ"</string>
+ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"ሲም ካርዱን በመክፈት ላይ…"</string>
+ <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"ትክክል ያልሆነ ፒን ኮድ።"</string>
+ <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"ከ4 እስከ 8 ቁጥሮች የያዘ ፒን ይተይቡ።"</string>
+ <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"የPUK ኮድ 8 ወይም ከዚያ በላይ ቁጥሮች ሊኖረው ይገባል።"</string>
+ <string name="kg_invalid_puk" msgid="3638289409676051243">"ትክክለኛውን የPUK ኮድ እንደገና ያስገቡ። ተደጋጋሚ ሙከራዎች ሲም ካርዱን እስከመጨረሻው ያሰናክሉታል።"</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"ፒን ኮዶች አይገጣጠሙም"</string>
+ <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"በጣም ብዙ የስርዓተ ጥለት ሙከራዎች"</string>
+ <string name="kg_login_instructions" msgid="1100551261265506448">"ለመክፈት በGoogle መለያዎ ይግቡ።"</string>
+ <string name="kg_login_username_hint" msgid="5718534272070920364">"የተጠቃሚ ስም (ኢሜይል)"</string>
+ <string name="kg_login_password_hint" msgid="9057289103827298549">"የይለፍ ቃል"</string>
+ <string name="kg_login_submit_button" msgid="5355904582674054702">"ግባ"</string>
+ <string name="kg_login_invalid_input" msgid="5754664119319872197">"ልክ ያልሆነ የተጠቃሚ ስም ወይም የይለፍ ቃል።"</string>
+ <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"የተጠቃሚ ስምዎን ወይም የይለፍ ቃልዎን ረሱት?"\n<b>"google.com/accounts/recovery"</b>"ይጎብኙ።"</string>
+ <string name="kg_login_checking_password" msgid="1052685197710252395">"መለያውን በማረጋገጥ ላይ…"</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"ፒንዎን <xliff:g id="NUMBER_0">%d</xliff:g> ጊዜ በትክክል አልተየቡም። "\n\n"በ<xliff:g id="NUMBER_1">%d</xliff:g> ሰኮንዶች ውስጥ እንደገና ይሞክሩ።"</string>
+ <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"የይለፍ ቃልዎን <xliff:g id="NUMBER_0">%d</xliff:g> ጊዜ ትክክል ባልሆነ መንገድ ተይበዋል።"\n\n"በ<xliff:g id="NUMBER_1">%d</xliff:g> ሰኮንዶች ውስጥ እንደገና ይሞክሩ።"</string>
+ <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"የመክፈቻ ስርዓተ ጥለትዎን <xliff:g id="NUMBER_0">%d</xliff:g> ጊዜ በትክክል አልሳሉትም። "\n\n" ከ<xliff:g id="NUMBER_1">%d</xliff:g> ሰከንዶች በኋላ እንደገና ይሞክሩ።"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"ጡባዊ ቱኮውን <xliff:g id="NUMBER_0">%d</xliff:g> ጊዜ ትክክል ባልሆነ መንገድ ለመክፈት ሞክረዋል። ከ<xliff:g id="NUMBER_1">%d</xliff:g> ተጨማሪ ያልተሳኩ ሙከራዎች በኋላ ጡባዊ ቱኮው በፋብሪካ ነባሪ ቅንብር ዳግም ይጀመርና ሁሉም የተጠቃሚ ውሂብ ይጠፋል።"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"ስልኩን <xliff:g id="NUMBER_0">%d</xliff:g> ጊዜ ትክክል ባልሆነ መንገድ ለመክፈት ሞክረዋል። ከ<xliff:g id="NUMBER_1">%d</xliff:g> ተጨማሪ ያልተሳኩ ሙከራዎች በኋላ ስልኩ በፋብሪካ ነባሪ ቅንብር ዳግም ይጀመርና ሁሉም የተጠቃሚ ውሂብ ይጠፋል።"</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"ጡባዊ ቱኮዎን <xliff:g id="NUMBER">%d</xliff:g> ጊዜ ትክክል ባልሆነ መንገድ ለመክፈት ሞክረዋል። ጡባዊ ቱኮዎ አሁን በፋብሪካ ነባሪ ቅንብር ዳግም ይጀመራል።"</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"ስልኩን <xliff:g id="NUMBER">%d</xliff:g> ጊዜ ትክክል ባልሆነ መንገድ ለመክፈት ሞክረዋል። ስልኩ አሁን በፋብሪካ ነባሪ ቅንብር ዳግም ይጀመራል።"</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"የመክፈቻ ስርዓተ ጥለቱን <xliff:g id="NUMBER_0">%d</xliff:g> ጊዜ በትክክል አልሳሉትም። ከ<xliff:g id="NUMBER_1">%d</xliff:g> ተጨማሪ ያልተሳኩ ሙከራዎች በኋላ የኢሜይል መለያ ተጠቅመው ጡባዊ ቱኮዎን እንዲከፍቱ ይጠየቃሉ።"\n\n" ከ<xliff:g id="NUMBER_2">%d</xliff:g> ከሰከንዶች በኋላ እንደገና ይሞክሩ።"</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"የመክፈቻ ስርዓተ ጥለቱን <xliff:g id="NUMBER_0">%d</xliff:g> ጊዜ በትክክል አልሳሉትም። ከ<xliff:g id="NUMBER_1">%d</xliff:g> ተጨማሪ ያልተሳኩ ሙከራዎች በኋላ የኢሜይል መለያ ተጠቅመው ስልክዎን እንዲከፍቱ ይጠየቃሉ።"\n\n"እባክዎ ከ<xliff:g id="NUMBER_2">%d</xliff:g> ሰከንዶች በኋላ እንደገና ይሞክሩ።"</string>
+ <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
+ <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"አስወግድ"</string>
+ <!-- no translation found for keyguard_transport_prev_description (8229108430245669854) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_next_description (4299258300283778305) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_pause_description (5093073338238310224) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_play_description (2924628863741150956) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_stop_description (3084179324810575787) -->
+ <skip />
+ <!-- no translation found for keyguard_carrier_default (8700650403054042153) -->
+ <skip />
+</resources>
diff --git a/packages/Keyguard/res/values-ar/strings.xml b/packages/Keyguard/res/values-ar/strings.xml
new file mode 100644
index 0000000..1454758
--- /dev/null
+++ b/packages/Keyguard/res/values-ar/strings.xml
@@ -0,0 +1,164 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/* //device/apps/common/assets/res/any/strings.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:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"اكتب رمز رقم التعريف الشخصي"</string>
+ <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"اكتب رمز PUK ورمز رقم التعريف الشخصي الجديد"</string>
+ <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"رمز PUK"</string>
+ <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"رمز رقم التعريف الشخصي الجديد"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"المس لكتابة كلمة المرور"</font></string>
+ <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"اكتب كلمة المرور لإلغاء التأمين"</string>
+ <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"اكتب رقم التعريف الشخصي لإلغاء التأمين"</string>
+ <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"رقم التعريف الشخصي غير صحيح."</string>
+ <string name="keyguard_label_text" msgid="861796461028298424">"لإلغاء التأمين، اضغط على \"القائمة\" ثم على 0."</string>
+ <string name="faceunlock_multiple_failures" msgid="754137583022792429">"تم تجاوز الحد الأقصى لعدد محاولات تأمين الجهاز بالوجه"</string>
+ <!-- no translation found for keyguard_charged (3272223906073492454) -->
+ <skip />
+ <!-- no translation found for keyguard_plugged_in (8117572000639998388) -->
+ <skip />
+ <!-- no translation found for keyguard_low_battery (8143808018719173859) -->
+ <skip />
+ <!-- no translation found for keyguard_instructions_when_pattern_disabled (1332288268600329841) -->
+ <skip />
+ <!-- no translation found for keyguard_network_locked_message (9169717779058037168) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message_short (494980561304211931) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (1445849005909260039) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (3481110395508637643) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions (5210891509995942250) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions_long (5968985489463870358) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_message_short (8340813989586622356) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_instructions (5892940909699723544) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_locked_message (6875773413306380902) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_puk_locked_message (3747232467471801633) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_unlock_progress_dialog_message (7975221805033614426) -->
+ <skip />
+ <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. الأداة %2$d من %3$d."</string>
+ <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"إضافة أداة."</string>
+ <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"فارغة"</string>
+ <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"تم توسيع منطقة إلغاء القفل."</string>
+ <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"تم تصغير منطقة إلغاء القفل."</string>
+ <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"أداة <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>."</string>
+ <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"محدد المستخدم"</string>
+ <string name="keyguard_accessibility_status" msgid="8008264603935930611">"الحالة"</string>
+ <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"الكاميرا"</string>
+ <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"أدوات التحكم في الوسائط"</string>
+ <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"بدأت إعادة ترتيب الأدوات."</string>
+ <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"انتهت إعادة ترتيب الأدوات."</string>
+ <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"تم حذف أداة <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>."</string>
+ <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"توسيع منطقة إلغاء القفل."</string>
+ <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"إلغاء القفل باستخدام التمرير."</string>
+ <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"إلغاء القفل باستخدام النقش."</string>
+ <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"تأمين الجهاز بالوجه."</string>
+ <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"إلغاء القفل باستخدام رقم التعريف الشخصي."</string>
+ <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"إلغاء القفل باستخدام كلمة المرور."</string>
+ <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"منطقة النقش."</string>
+ <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"منطقة التمرير."</string>
+ <!-- no translation found for keyguard_accessibility_transport_prev_description (1337286538318543555) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_next_description (7073928300444909320) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_pause_description (8455979545295224302) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_play_description (8146417789511154044) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_stop_description (7656358482980912216) -->
+ <skip />
+ <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+ <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ب ت ث"</string>
+ <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+ <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"إلغاء"</string>
+ <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"حذف"</string>
+ <string name="keyboardview_keycode_done" msgid="1992571118466679775">"تم"</string>
+ <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"تغيير الوضع"</string>
+ <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"العالي"</string>
+ <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
+ <string name="description_target_unlock" msgid="2228524900439801453">"إلغاء تأمين"</string>
+ <string name="description_target_camera" msgid="969071997552486814">"الكاميرا"</string>
+ <string name="description_target_silent" msgid="893551287746522182">"صامت"</string>
+ <string name="description_target_soundon" msgid="30052466675500172">"تشغيل الصوت"</string>
+ <string name="description_target_search" msgid="3091587249776033139">"بحث"</string>
+ <string name="description_direction_up" msgid="7169032478259485180">"تمرير لأعلى لـ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_down" msgid="5087739728639014595">"تمرير لأسفل لـ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_left" msgid="7207478719805562165">"تمرير لليسار لـ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_right" msgid="8034433242579600980">"تمرير لليمين لـ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="user_switched" msgid="3768006783166984410">"المستخدم الحالي <xliff:g id="NAME">%1$s</xliff:g>."</string>
+ <string name="kg_emergency_call_label" msgid="684946192523830531">"الاتصال بالطوارئ"</string>
+ <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"نسيت النقش"</string>
+ <string name="kg_wrong_pattern" msgid="1850806070801358830">"نقش خاطئ"</string>
+ <string name="kg_wrong_password" msgid="2333281762128113157">"كلمة مرور خاطئة"</string>
+ <string name="kg_wrong_pin" msgid="1131306510833563801">"رقم تعريف شخصي خاطئ"</string>
+ <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"حاول مرة أخرى خلال <xliff:g id="NUMBER">%d</xliff:g> ثانية."</string>
+ <string name="kg_pattern_instructions" msgid="398978611683075868">"ارسم نقشك"</string>
+ <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"أدخل رقم التعريف الشخصي لبطاقة SIM"</string>
+ <string name="kg_pin_instructions" msgid="2377242233495111557">"أدخل رقم التعريف الشخصي"</string>
+ <string name="kg_password_instructions" msgid="5753646556186936819">"أدخل كلمة المرور"</string>
+ <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"بطاقة SIM معطلة الآن. أدخل رمز PUK للمتابعة. اتصل بمشغل شبكة الجوال للاطلاع على التفاصيل."</string>
+ <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"إدخال رمز رقم التعريف الشخصي المراد"</string>
+ <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"تأكيد رمز رقم التعريف الشخصي المراد"</string>
+ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"جارٍ إلغاء تأمين بطاقة SIM…"</string>
+ <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"رقم التعريف الشخصي غير صحيح."</string>
+ <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"اكتب رقم التعريف الشخصي المكون من 4 إلى 8 أرقام."</string>
+ <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"يجب أن يتضمن رمز PUK‏ 8 أرقام أو أكثر."</string>
+ <string name="kg_invalid_puk" msgid="3638289409676051243">"أعد إدخال رمز PUK الصحيح. وستؤدي المحاولات المتكررة إلى تعطيل بطاقة SIM نهائيًا."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"لا يتطابق رمزا رقم التعريف الشخصي"</string>
+ <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"محاولات النقش كثيرة جدًا"</string>
+ <string name="kg_login_instructions" msgid="1100551261265506448">"لإلغاء التأمين، سجّل الدخول بحسابك في Google."</string>
+ <string name="kg_login_username_hint" msgid="5718534272070920364">"اسم المستخدم (البريد إلكتروني)"</string>
+ <string name="kg_login_password_hint" msgid="9057289103827298549">"كلمة المرور"</string>
+ <string name="kg_login_submit_button" msgid="5355904582674054702">"تسجيل الدخول"</string>
+ <string name="kg_login_invalid_input" msgid="5754664119319872197">"اسم مستخدم غير صحيح أو كلمة مرور غير صالحة."</string>
+ <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"هل نسيت اسم المستخدم أو كلمة المرور؟"\n"انتقل إلى "<b>"google.com/accounts/recovery"</b>"."</string>
+ <string name="kg_login_checking_password" msgid="1052685197710252395">"جارٍ فحص الحساب…"</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"لقد كتبت رقم التعريف الشخصي بشكل غير صحيح <xliff:g id="NUMBER_0">%d</xliff:g> مرة. "\n\n"أعد المحاولة خلال <xliff:g id="NUMBER_1">%d</xliff:g> ثانية."</string>
+ <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"لقد كتبت كلمة المرور بشكل غير صحيح <xliff:g id="NUMBER_0">%d</xliff:g> مرة. "\n\n"أعد المحاولة خلال <xliff:g id="NUMBER_1">%d</xliff:g> ثانية."</string>
+ <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"لقد رسمت نقش إلغاء التأمين بطريقة غير صحيحة <xliff:g id="NUMBER_0">%d</xliff:g> مرة. "\n\n"أعد المحاولة خلال <xliff:g id="NUMBER_1">%d</xliff:g> ثانية."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"لقد حاولت إلغاء تأمين الجهاز اللوحي بشكل غير صحيح <xliff:g id="NUMBER_0">%d</xliff:g> مرة. بعد إجراء <xliff:g id="NUMBER_1">%d</xliff:g> من المحاولات غير الناجحة الأخرى، ستتم إعادة تعيين الجهاز اللوحي على الإعدادات الافتراضية للمصنع وسيتم فقد جميع بيانات المستخدم."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"لقد حاولت إلغاء تأمين الهاتف بشكل غير صحيح <xliff:g id="NUMBER_0">%d</xliff:g> مرة. بعد إجراء <xliff:g id="NUMBER_1">%d</xliff:g> من المحاولات غير الناجحة الأخرى، ستتم إعادة تعيين الهاتف على الإعدادات الافتراضية للمصنع وسيتم فقد جميع بيانات المستخدم."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"لقد حاولت إلغاء تأمين الجهاز اللوحي بشكل غير صحيح <xliff:g id="NUMBER">%d</xliff:g> مرة. سيتم الآن إعادة تعيين الجهاز اللوحي على الإعدادات الافتراضية للمصنع."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"لقد حاولت إلغاء تأمين الهاتف بشكل غير صحيح <xliff:g id="NUMBER">%d</xliff:g> مرة. سيتم الآن إعادة تعيين الهاتف على الإعدادات الافتراضية للمصنع."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"لقد رسمت نقش إلغاء التأمين بشكل غير صحيح <xliff:g id="NUMBER_0">%d</xliff:g> مرة. بعد إجراء <xliff:g id="NUMBER_1">%d</xliff:g> من المحاولات غير الناجحة الأخرى، ستطالَب بإلغاء تأمين الجهاز اللوحي باستخدام معلومات حساب بريد إلكتروني."\n\n" أعد المحاولة خلال <xliff:g id="NUMBER_2">%d</xliff:g> ثانية."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"لقد رسمت نقش إلغاء التأمين بشكل غير صحيح <xliff:g id="NUMBER_0">%d</xliff:g> مرة. بعد إجراء <xliff:g id="NUMBER_1">%d</xliff:g> من المحاولات غير الناجحة الأخرى، ستُطالب بإلغاء تأمين الهاتف باستخدام حساب بريد إلكتروني لإلغاء تأمين الهاتف."\n\n" أعد المحاولة خلال <xliff:g id="NUMBER_2">%d</xliff:g> ثانية."</string>
+ <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
+ <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"إزالة"</string>
+ <!-- no translation found for keyguard_transport_prev_description (8229108430245669854) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_next_description (4299258300283778305) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_pause_description (5093073338238310224) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_play_description (2924628863741150956) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_stop_description (3084179324810575787) -->
+ <skip />
+ <!-- no translation found for keyguard_carrier_default (8700650403054042153) -->
+ <skip />
+</resources>
diff --git a/packages/Keyguard/res/values-be/strings.xml b/packages/Keyguard/res/values-be/strings.xml
new file mode 100644
index 0000000..b003fa4
--- /dev/null
+++ b/packages/Keyguard/res/values-be/strings.xml
@@ -0,0 +1,164 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/* //device/apps/common/assets/res/any/strings.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:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Увядзіце PIN-код"</string>
+ <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Увядзіце PUK-код і новы PIN-код"</string>
+ <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK"</string>
+ <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Новы PIN-код"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Дакраніцеся, каб увесці пароль"</font></string>
+ <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Увядзіце пароль для разблакавання"</string>
+ <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Каб разблакаваць, увядзіце PIN-код"</string>
+ <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Няправільны PIN-код."</string>
+ <string name="keyguard_label_text" msgid="861796461028298424">"Каб разблакаваць, націсніце \"Меню\", затым 0."</string>
+ <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Перавышана максімальная колькасць спроб разблакоўкі праз Фэйскантроль"</string>
+ <!-- no translation found for keyguard_charged (3272223906073492454) -->
+ <skip />
+ <!-- no translation found for keyguard_plugged_in (8117572000639998388) -->
+ <skip />
+ <!-- no translation found for keyguard_low_battery (8143808018719173859) -->
+ <skip />
+ <!-- no translation found for keyguard_instructions_when_pattern_disabled (1332288268600329841) -->
+ <skip />
+ <!-- no translation found for keyguard_network_locked_message (9169717779058037168) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message_short (494980561304211931) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (1445849005909260039) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (3481110395508637643) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions (5210891509995942250) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions_long (5968985489463870358) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_message_short (8340813989586622356) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_instructions (5892940909699723544) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_locked_message (6875773413306380902) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_puk_locked_message (3747232467471801633) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_unlock_progress_dialog_message (7975221805033614426) -->
+ <skip />
+ <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. ВIджэт %2$d з %3$d."</string>
+ <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Дадаць віджэт"</string>
+ <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Пусты"</string>
+ <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Вобласць разблакіроўкі разгарнута."</string>
+ <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Вобласць разблакіроўкі згарнута."</string>
+ <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"Віджэт <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>."</string>
+ <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"Селектар карыстальнiка"</string>
+ <string name="keyguard_accessibility_status" msgid="8008264603935930611">"Стан"</string>
+ <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"Камера"</string>
+ <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Налады мультымедыя"</string>
+ <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Змяненне парадку віджэтаў пачалося."</string>
+ <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Змяненне парадку віджэтаў скончылася."</string>
+ <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Віджэт <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> выдалены."</string>
+ <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Разгарнуць вобласць разблакіроўкі."</string>
+ <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Разблакiроўка слайда."</string>
+ <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Узор разблакiроўкі."</string>
+ <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Фэйскантроль"</string>
+ <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"PIN-код разблакiроўкі."</string>
+ <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Пароль разблакiроўкі."</string>
+ <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Вобласць узора."</string>
+ <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Вобласць слайда."</string>
+ <!-- no translation found for keyguard_accessibility_transport_prev_description (1337286538318543555) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_next_description (7073928300444909320) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_pause_description (8455979545295224302) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_play_description (8146417789511154044) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_stop_description (7656358482980912216) -->
+ <skip />
+ <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"123"</string>
+ <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+ <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"Alt"</string>
+ <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+ <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Адмена"</string>
+ <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Выдаліць"</string>
+ <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Гатова"</string>
+ <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Змена рэжыму"</string>
+ <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
+ <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
+ <string name="description_target_unlock" msgid="2228524900439801453">"Разблакаваць"</string>
+ <string name="description_target_camera" msgid="969071997552486814">"Камера"</string>
+ <string name="description_target_silent" msgid="893551287746522182">"Ціхі рэжым"</string>
+ <string name="description_target_soundon" msgid="30052466675500172">"Гук уключаны"</string>
+ <string name="description_target_search" msgid="3091587249776033139">"Пошук"</string>
+ <string name="description_direction_up" msgid="7169032478259485180">"Правядзіце пальцам уверх, каб атрымаць <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_down" msgid="5087739728639014595">"Правядзіце пальцам уніз, каб атрымаць <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_left" msgid="7207478719805562165">"Правядзіце пальцам улева, каб атрымаць <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_right" msgid="8034433242579600980">"Правядзіце пальцам управа, каб атрымаць <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="user_switched" msgid="3768006783166984410">"Бягучы карыстальнік <xliff:g id="NAME">%1$s</xliff:g>."</string>
+ <string name="kg_emergency_call_label" msgid="684946192523830531">"Экстранны выклік"</string>
+ <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Забылі ключ"</string>
+ <string name="kg_wrong_pattern" msgid="1850806070801358830">"Няправільна ключ"</string>
+ <string name="kg_wrong_password" msgid="2333281762128113157">"Няправiльны пароль"</string>
+ <string name="kg_wrong_pin" msgid="1131306510833563801">"Няправільны PIN-код"</string>
+ <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Паўтарыце спробу праз <xliff:g id="NUMBER">%d</xliff:g> с."</string>
+ <string name="kg_pattern_instructions" msgid="398978611683075868">"Намалюйце ключ"</string>
+ <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Увядзіце PIN-код SIM-карты"</string>
+ <string name="kg_pin_instructions" msgid="2377242233495111557">"Увядзіце PIN-код"</string>
+ <string name="kg_password_instructions" msgid="5753646556186936819">"Увядзіце пароль"</string>
+ <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"SIM-карта зараз адключана. Увядзіце PUK-код, каб працягнуць. Звяжыцеся са сваiм аператарам, каб атрымаць дадатковую iнфармацыю."</string>
+ <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Увядзіце жаданы PIN-код"</string>
+ <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Пацвердзіце жадан PIN-код"</string>
+ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Разблакiроўка SIM-карты..."</string>
+ <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Няправільны PIN-код."</string>
+ <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Увядзіце PIN-код, які змяшчае ад 4 да 8 лічбаў."</string>
+ <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK-код павінен утрымлiваць 8 лiчбаў і больш."</string>
+ <string name="kg_invalid_puk" msgid="3638289409676051243">"Паўторна увядзіце правільны PUK-код. Неаднаразовыя спробы назаўжды адключаць SIM-карту."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN-коды не супадаюць"</string>
+ <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Занадта шмат спроб паўтарыць шаблон!"</string>
+ <string name="kg_login_instructions" msgid="1100551261265506448">"Каб разблакiраваць, увайдзіце ў свой уліковы запіс Google."</string>
+ <string name="kg_login_username_hint" msgid="5718534272070920364">"Імя карыстальніка (электронная пошта)"</string>
+ <string name="kg_login_password_hint" msgid="9057289103827298549">"Пароль"</string>
+ <string name="kg_login_submit_button" msgid="5355904582674054702">"Увайсцi"</string>
+ <string name="kg_login_invalid_input" msgid="5754664119319872197">"Няправільнае імя карыстальніка ці пароль."</string>
+ <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Забыліся на імя карыстальніка або пароль?"\n"Наведайце "<b>"google.com/accounts/recovery"</b></string>
+ <string name="kg_login_checking_password" msgid="1052685197710252395">"Праверка ўлiковага запiсу..."</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Вы няправільна ўвялі PIN-код пэўную колькасць разоў: <xliff:g id="NUMBER_0">%d</xliff:g>. "\n\n"Паўтарыце спробу праз <xliff:g id="NUMBER_1">%d</xliff:g> с."</string>
+ <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Вы няправільна ўвялі пароль пэўную колькасць разоў: <xliff:g id="NUMBER_0">%d</xliff:g>. "\n\n"Паўтарыце спробу праз <xliff:g id="NUMBER_1">%d</xliff:g> с."</string>
+ <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Вы няправільна ўвялі графічны ключ разблакiроўкi пэўную колькасць разоў: <xliff:g id="NUMBER_0">%d</xliff:g>. "\n\n"Паўтарыце спробу праз <xliff:g id="NUMBER_1">%d</xliff:g> с."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Вы няправільна спрабавалі разблакiраваць планшэт некалькi разоў (<xliff:g id="NUMBER_0">%d</xliff:g>). Пасля яшчэ некалькiх спроб (<xliff:g id="NUMBER_1">%d</xliff:g>) ён будзе скінуты да заводскіх налад i карыстальнiцкiя дадзеныя будуць згубленыя."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Вы няправільна спрабавалі разблакiраваць планшэт некалькi разоў (<xliff:g id="NUMBER_0">%d</xliff:g>). Пасля яшчэ некалькiх спроб (<xliff:g id="NUMBER_1">%d</xliff:g>) ён будзе скінуты да завадскіх налад i карыстальнiцкiя дадзеныя будуць згубленыя."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Вы няправільна спрабавалі разблакiраваць планшэт некалькi разоў (<xliff:g id="NUMBER">%d</xliff:g>). Цяпер ён будзе скінуты да завадскіх налад."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Вы няправільна спрабавалі разблакiраваць тэлефон некалькi разоў (<xliff:g id="NUMBER">%d</xliff:g>). Цяпер ён будзе скінуты да завадскіх налад."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Вы няправільна ўвялі графічны ключ разблакiроўкi пэўную колькасць разоў: <xliff:g id="NUMBER_0">%d</xliff:g>. Пасля яшчэ некалькiх няўдалых спроб (<xliff:g id="NUMBER_1">%d</xliff:g>) вам будзе прапанавана разблакiраваць тэлефон, увайшоўшы ў Google."\n\n" Паўтарыце спробу праз <xliff:g id="NUMBER_2">%d</xliff:g> с."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Вы няправільна ўвялі графічны ключ разблакiроўкi пэўную колькасць разоў: <xliff:g id="NUMBER_0">%d</xliff:g>. Пасля яшчэ некалькiх няўдалых спроб (<xliff:g id="NUMBER_1">%d</xliff:g>) вам будзе прапанавана разблакiраваць тэлефон, увайшоўшы ў Google."\n\n" Паўтарыце спробу праз <xliff:g id="NUMBER_2">%d</xliff:g> с."</string>
+ <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
+ <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Выдалiць"</string>
+ <!-- no translation found for keyguard_transport_prev_description (8229108430245669854) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_next_description (4299258300283778305) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_pause_description (5093073338238310224) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_play_description (2924628863741150956) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_stop_description (3084179324810575787) -->
+ <skip />
+ <!-- no translation found for keyguard_carrier_default (8700650403054042153) -->
+ <skip />
+</resources>
diff --git a/packages/Keyguard/res/values-bg/strings.xml b/packages/Keyguard/res/values-bg/strings.xml
new file mode 100644
index 0000000..c3c5905
--- /dev/null
+++ b/packages/Keyguard/res/values-bg/strings.xml
@@ -0,0 +1,164 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/* //device/apps/common/assets/res/any/strings.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:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Въведете ПИН кода"</string>
+ <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Въведете PUK и новия ПИН код"</string>
+ <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK код"</string>
+ <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Нов ПИН код"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Докоснете и въведете парола"</font></string>
+ <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Въведете парола, за да отключите"</string>
+ <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Въведете ПИН, за да отключите"</string>
+ <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Неправилен ПИН код."</string>
+ <string name="keyguard_label_text" msgid="861796461028298424">"За да отключите, натиснете „Меню“ и после 0."</string>
+ <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Максималният брой опити за отключване с лице е надвишен"</string>
+ <!-- no translation found for keyguard_charged (3272223906073492454) -->
+ <skip />
+ <!-- no translation found for keyguard_plugged_in (8117572000639998388) -->
+ <skip />
+ <!-- no translation found for keyguard_low_battery (8143808018719173859) -->
+ <skip />
+ <!-- no translation found for keyguard_instructions_when_pattern_disabled (1332288268600329841) -->
+ <skip />
+ <!-- no translation found for keyguard_network_locked_message (9169717779058037168) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message_short (494980561304211931) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (1445849005909260039) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (3481110395508637643) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions (5210891509995942250) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions_long (5968985489463870358) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_message_short (8340813989586622356) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_instructions (5892940909699723544) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_locked_message (6875773413306380902) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_puk_locked_message (3747232467471801633) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_unlock_progress_dialog_message (7975221805033614426) -->
+ <skip />
+ <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Приспособление %2$d от %3$d."</string>
+ <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Добавяне на приспособление."</string>
+ <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Празно"</string>
+ <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Областта за отключване е разгъната."</string>
+ <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Областта за отключване е свита."</string>
+ <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"Приспособление за <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>."</string>
+ <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"Инструмент за избор на потребители"</string>
+ <string name="keyguard_accessibility_status" msgid="8008264603935930611">"Състояние"</string>
+ <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"Камера"</string>
+ <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Контроли за мултимедията"</string>
+ <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Пренареждането на приспособленията започна."</string>
+ <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Пренареждането на приспособленията завърши."</string>
+ <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Приспособлението за <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> е изтрито."</string>
+ <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Разгъване на областта за отключване."</string>
+ <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Отключване с плъзгане."</string>
+ <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Отключване с фигура."</string>
+ <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Отключване с лице."</string>
+ <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Отключване с ПИН код."</string>
+ <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Отключване с парола."</string>
+ <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Област на фигурата."</string>
+ <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Област на плъзгане."</string>
+ <!-- no translation found for keyguard_accessibility_transport_prev_description (1337286538318543555) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_next_description (7073928300444909320) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_pause_description (8455979545295224302) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_play_description (8146417789511154044) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_stop_description (7656358482980912216) -->
+ <skip />
+ <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+ <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"АБВ"</string>
+ <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+ <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Отказ"</string>
+ <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Изтриване"</string>
+ <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Готово"</string>
+ <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Промяна на режима"</string>
+ <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
+ <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
+ <string name="description_target_unlock" msgid="2228524900439801453">"Отключване"</string>
+ <string name="description_target_camera" msgid="969071997552486814">"Камера"</string>
+ <string name="description_target_silent" msgid="893551287746522182">"Тих режим"</string>
+ <string name="description_target_soundon" msgid="30052466675500172">"Включване на звука"</string>
+ <string name="description_target_search" msgid="3091587249776033139">"Търсене"</string>
+ <string name="description_direction_up" msgid="7169032478259485180">"Плъзнете нагоре за <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_down" msgid="5087739728639014595">"Плъзнете надолу за <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_left" msgid="7207478719805562165">"Плъзнете наляво за <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_right" msgid="8034433242579600980">"Плъзнете надясно за <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="user_switched" msgid="3768006783166984410">"Текущ потребител <xliff:g id="NAME">%1$s</xliff:g>."</string>
+ <string name="kg_emergency_call_label" msgid="684946192523830531">"Спешно обаждане"</string>
+ <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Забравена фигура"</string>
+ <string name="kg_wrong_pattern" msgid="1850806070801358830">"Грешна фигура"</string>
+ <string name="kg_wrong_password" msgid="2333281762128113157">"Грешна парола"</string>
+ <string name="kg_wrong_pin" msgid="1131306510833563801">"Грешен ПИН код"</string>
+ <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Опитайте отново след <xliff:g id="NUMBER">%d</xliff:g> секунди."</string>
+ <string name="kg_pattern_instructions" msgid="398978611683075868">"Начертайте фигурата си"</string>
+ <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Въведете ПИН кода за SIM картата"</string>
+ <string name="kg_pin_instructions" msgid="2377242233495111557">"Въведете ПИН код"</string>
+ <string name="kg_password_instructions" msgid="5753646556186936819">"Въведете паролата"</string>
+ <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"SIM картата вече е деактивирана. Въведете PUK кода, за да продължите. Свържете се с оператора за подробности."</string>
+ <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Въведете желания ПИН код"</string>
+ <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Потвърдете желания ПИН код"</string>
+ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"SIM картата се отключва…"</string>
+ <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Неправилен ПИН код."</string>
+ <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Въведете ПИН код с четири до осем цифри."</string>
+ <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK кодът трябва да е с 8 или повече цифри."</string>
+ <string name="kg_invalid_puk" msgid="3638289409676051243">"Въведете отново правилния PUK код. Многократните опити ще деактивират за постоянно SIM картата."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"ПИН кодовете не съвпадат"</string>
+ <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Опитите за фигурата са твърде много"</string>
+ <string name="kg_login_instructions" msgid="1100551261265506448">"За да отключите, влезте с профила си в Google."</string>
+ <string name="kg_login_username_hint" msgid="5718534272070920364">"Потребителско име (имейл)"</string>
+ <string name="kg_login_password_hint" msgid="9057289103827298549">"Парола"</string>
+ <string name="kg_login_submit_button" msgid="5355904582674054702">"Вход"</string>
+ <string name="kg_login_invalid_input" msgid="5754664119319872197">"Невалидно потребителско име или парола."</string>
+ <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Забравили сте потребителското име или паролата си?"\n"Посетете "<b>"google.com/accounts/recovery"</b>"."</string>
+ <string name="kg_login_checking_password" msgid="1052685197710252395">"Профилът се проверява…"</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Въведохте неправилно ПИН кода си <xliff:g id="NUMBER_0">%d</xliff:g> пъти. "\n\n"Опитайте отново след <xliff:g id="NUMBER_1">%d</xliff:g> секунди."</string>
+ <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Въведохте неправилно паролата си <xliff:g id="NUMBER_0">%d</xliff:g> пъти. "\n\n"Опитайте отново след <xliff:g id="NUMBER_1">%d</xliff:g> секунди."</string>
+ <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Начертахте неправилно фигурата си за отключване <xliff:g id="NUMBER_0">%d</xliff:g> пъти. "\n\n"Опитайте отново след <xliff:g id="NUMBER_1">%d</xliff:g> секунди."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Направихте опит да отключите неправилно таблета <xliff:g id="NUMBER_0">%d</xliff:g> пъти. След още <xliff:g id="NUMBER_1">%d</xliff:g> неуспешни опита ще бъдат възстановени стандартните му фабрични настройки и всички потребителски данни ще бъдат заличени."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Направихте опит да отключите неправилно телефона <xliff:g id="NUMBER_0">%d</xliff:g> пъти. След още <xliff:g id="NUMBER_1">%d</xliff:g> неуспешни опита ще бъдат възстановени стандартните му фабрични настройки и всички потребителски данни ще бъдат заличени."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Направихте опит да отключите неправилно таблета <xliff:g id="NUMBER">%d</xliff:g> пъти. Сега ще бъдат възстановени стандартните му фабрични настройки."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Направихте опит да отключите неправилно телефона <xliff:g id="NUMBER">%d</xliff:g> пъти. Сега ще бъдат възстановени стандартните му фабрични настройки."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Начертахте неправилно фигурата си за отключване <xliff:g id="NUMBER_0">%d</xliff:g> пъти. След още <xliff:g id="NUMBER_1">%d</xliff:g> неуспешни опита ще бъдете помолени да отключите таблета посредством имейл адрес."\n\n" Опитайте отново след <xliff:g id="NUMBER_2">%d</xliff:g> секунди."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Начертахте неправилно фигурата си за отключване <xliff:g id="NUMBER_0">%d</xliff:g> пъти. След още <xliff:g id="NUMBER_1">%d</xliff:g> неуспешни опита ще бъдете помолени да отключите телефона посредством имейл адрес."\n\n" Опитайте отново след <xliff:g id="NUMBER_2">%d</xliff:g> секунди."</string>
+ <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" – "</string>
+ <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Премахване"</string>
+ <!-- no translation found for keyguard_transport_prev_description (8229108430245669854) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_next_description (4299258300283778305) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_pause_description (5093073338238310224) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_play_description (2924628863741150956) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_stop_description (3084179324810575787) -->
+ <skip />
+ <!-- no translation found for keyguard_carrier_default (8700650403054042153) -->
+ <skip />
+</resources>
diff --git a/packages/Keyguard/res/values-ca/strings.xml b/packages/Keyguard/res/values-ca/strings.xml
new file mode 100644
index 0000000..20e80cf
--- /dev/null
+++ b/packages/Keyguard/res/values-ca/strings.xml
@@ -0,0 +1,164 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/* //device/apps/common/assets/res/any/strings.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:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Introdueix el codi PIN"</string>
+ <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Introdueix el codi PUK i el codi PIN nou"</string>
+ <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"Codi PUK"</string>
+ <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Codi PIN nou"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Toca per introduir contrasenya"</font></string>
+ <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Introdueix la contrasenya per desbloquejar"</string>
+ <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Introdueix la contrasenya per desbloquejar"</string>
+ <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Codi PIN incorrecte."</string>
+ <string name="keyguard_label_text" msgid="861796461028298424">"Per desbloquejar-lo, premeu Menú i després 0."</string>
+ <string name="faceunlock_multiple_failures" msgid="754137583022792429">"S\'ha superat el nombre màxim d\'intents de desbloqueig facial"</string>
+ <!-- no translation found for keyguard_charged (3272223906073492454) -->
+ <skip />
+ <!-- no translation found for keyguard_plugged_in (8117572000639998388) -->
+ <skip />
+ <!-- no translation found for keyguard_low_battery (8143808018719173859) -->
+ <skip />
+ <!-- no translation found for keyguard_instructions_when_pattern_disabled (1332288268600329841) -->
+ <skip />
+ <!-- no translation found for keyguard_network_locked_message (9169717779058037168) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message_short (494980561304211931) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (1445849005909260039) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (3481110395508637643) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions (5210891509995942250) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions_long (5968985489463870358) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_message_short (8340813989586622356) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_instructions (5892940909699723544) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_locked_message (6875773413306380902) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_puk_locked_message (3747232467471801633) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_unlock_progress_dialog_message (7975221805033614426) -->
+ <skip />
+ <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d de %3$d."</string>
+ <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Afegeix un widget"</string>
+ <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Buit"</string>
+ <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"S\'ha ampliat l\'àrea de desbloqueig."</string>
+ <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"L\'àrea de desbloqueig està replegada."</string>
+ <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"Widget de <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>."</string>
+ <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"Selector d\'usuaris"</string>
+ <string name="keyguard_accessibility_status" msgid="8008264603935930611">"Estat"</string>
+ <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"Càmera"</string>
+ <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Controls multimèdia"</string>
+ <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"S\'ha iniciat la reorganització del widget."</string>
+ <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Ha finalitzat la reorganització del widget."</string>
+ <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"S\'ha suprimit el widget de <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>."</string>
+ <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Amplia l\'àrea de desbloqueig."</string>
+ <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Desbloqueig lliscant el dit"</string>
+ <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Desbloqueig mitjançant patró"</string>
+ <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Desbloqueig facial"</string>
+ <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Desbloqueig mitjançant PIN"</string>
+ <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Desbloqueig mitjançant contrasenya"</string>
+ <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Àrea de patró"</string>
+ <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Àrea per lliscar el dit"</string>
+ <!-- no translation found for keyguard_accessibility_transport_prev_description (1337286538318543555) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_next_description (7073928300444909320) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_pause_description (8455979545295224302) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_play_description (8146417789511154044) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_stop_description (7656358482980912216) -->
+ <skip />
+ <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+ <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+ <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+ <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Cancel·la"</string>
+ <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Suprimeix"</string>
+ <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Fet"</string>
+ <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Canvi de mode"</string>
+ <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Maj"</string>
+ <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Retorn"</string>
+ <string name="description_target_unlock" msgid="2228524900439801453">"Desbloqueja"</string>
+ <string name="description_target_camera" msgid="969071997552486814">"Càmera"</string>
+ <string name="description_target_silent" msgid="893551287746522182">"Silenci"</string>
+ <string name="description_target_soundon" msgid="30052466675500172">"Activa el so"</string>
+ <string name="description_target_search" msgid="3091587249776033139">"Cerca"</string>
+ <string name="description_direction_up" msgid="7169032478259485180">"Fes lliscar el dit cap amunt per <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_down" msgid="5087739728639014595">"Fes lliscar el dit cap avall per <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_left" msgid="7207478719805562165">"Fes lliscar el dit cap a l\'esquerra per <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_right" msgid="8034433242579600980">"Fes lliscar el dit cap a la dreta per <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="user_switched" msgid="3768006783166984410">"Usuari actual: <xliff:g id="NAME">%1$s</xliff:g>."</string>
+ <string name="kg_emergency_call_label" msgid="684946192523830531">"Trucada d\'emergència"</string>
+ <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Patró oblidat"</string>
+ <string name="kg_wrong_pattern" msgid="1850806070801358830">"Patró incorrecte"</string>
+ <string name="kg_wrong_password" msgid="2333281762128113157">"Contrasenya incorrecta"</string>
+ <string name="kg_wrong_pin" msgid="1131306510833563801">"PIN incorrecte"</string>
+ <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Torna-ho a provar d\'aquí a <xliff:g id="NUMBER">%d</xliff:g> segons."</string>
+ <string name="kg_pattern_instructions" msgid="398978611683075868">"Dibuixa el patró"</string>
+ <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Introdueix el PIN de la SIM"</string>
+ <string name="kg_pin_instructions" msgid="2377242233495111557">"Introdueix el PIN"</string>
+ <string name="kg_password_instructions" msgid="5753646556186936819">"Introdueix la contrasenya"</string>
+ <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"La SIM està desactivada. Introdueix el codi PUK per continuar. Contacta amb l\'operador de telefonia mòbil per obtenir detalls."</string>
+ <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Introdueix el codi PIN"</string>
+ <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Confirma el codi PIN"</string>
+ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"S\'està desbloquejant la targeta SIM..."</string>
+ <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Codi PIN incorrecte."</string>
+ <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Escriu un PIN que tingui de 4 a 8 números."</string>
+ <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"El codi PUK ha de tenir 8 números o més."</string>
+ <string name="kg_invalid_puk" msgid="3638289409676051243">"Torna a introduir el codi PUK correcte. Els intents repetits faran que es desactivi la SIM de manera permanent."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"Els codis PIN no coincideixen"</string>
+ <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Massa intents incorrectes"</string>
+ <string name="kg_login_instructions" msgid="1100551261265506448">"Per desbloquejar el telèfon, inicia la sessió amb el compte de Google."</string>
+ <string name="kg_login_username_hint" msgid="5718534272070920364">"Nom d\'usuari (correu electrònic)"</string>
+ <string name="kg_login_password_hint" msgid="9057289103827298549">"Contrasenya"</string>
+ <string name="kg_login_submit_button" msgid="5355904582674054702">"Inicia la sessió"</string>
+ <string name="kg_login_invalid_input" msgid="5754664119319872197">"Nom d\'usuari o contrasenya no vàlids."</string>
+ <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Has oblidat el teu nom d\'usuari o la contrasenya?"\n"Visita "<b>"google.com/accounts/recovery"</b>"."</string>
+ <string name="kg_login_checking_password" msgid="1052685197710252395">"S\'està comprovant el compte…"</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Has escrit malament el PIN <xliff:g id="NUMBER_0">%d</xliff:g> vegades. "\n\n"Torna-ho a provar d\'aquí a <xliff:g id="NUMBER_1">%d</xliff:g> segons."</string>
+ <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Has escrit malament la contrasenya <xliff:g id="NUMBER_0">%d</xliff:g> vegades. "\n\n"Torna-ho a provar d\'aquí a <xliff:g id="NUMBER_1">%d</xliff:g> segons."</string>
+ <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Has dibuixat el patró de desbloqueig de manera incorrecta <xliff:g id="NUMBER_0">%d</xliff:g> vegades. "\n\n"Torna-ho a provar d\'aquí a <xliff:g id="NUMBER_1">%d</xliff:g> segons."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Has provat de desbloquejar la tauleta <xliff:g id="NUMBER_0">%d</xliff:g> vegades de manera incorrecta. D\'aquí a <xliff:g id="NUMBER_1">%d</xliff:g> intents incorrectes més, la tauleta es restablirà a la configuració predeterminada de fàbrica i es perdran totes les dades dels usuaris."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Has provat de desbloquejar el telèfon <xliff:g id="NUMBER_0">%d</xliff:g> vegades de manera incorrecta. D\'aquí a <xliff:g id="NUMBER_1">%d</xliff:g> intents incorrectes més, el telèfon es restablirà a la configuració predeterminada de fàbrica i es perdran totes les dades dels usuaris."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Has provat de desbloquejar la tauleta <xliff:g id="NUMBER">%d</xliff:g> vegades de manera incorrecta. Ara la tauleta es restablirà a la configuració predeterminada de fàbrica."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Has provat de desbloquejar el telèfon <xliff:g id="NUMBER">%d</xliff:g> vegades de manera incorrecta. Ara el telèfon es restablirà a la configuració predeterminada de fàbrica."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Has dibuixat el patró de desbloqueig <xliff:g id="NUMBER_0">%d</xliff:g> vegades de manera incorrecta. Després de <xliff:g id="NUMBER_1">%d</xliff:g> intents incorrectes més, se\'t demanarà que desbloquegis la tauleta amb un compte de correu electrònic."\n\n" Torna-ho a provar d\'aquí a <xliff:g id="NUMBER_2">%d</xliff:g> segons."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Has dibuixat el patró de desbloqueig <xliff:g id="NUMBER_0">%d</xliff:g> vegades de manera incorrecta. Després de <xliff:g id="NUMBER_1">%d</xliff:g> intents incorrectes més, se\'t demanarà que desbloquegis el telèfon amb un compte de correu electrònic."\n\n" Torna-ho a provar d\'aquí a <xliff:g id="NUMBER_2">%d</xliff:g> segons."</string>
+ <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
+ <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Elimina"</string>
+ <!-- no translation found for keyguard_transport_prev_description (8229108430245669854) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_next_description (4299258300283778305) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_pause_description (5093073338238310224) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_play_description (2924628863741150956) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_stop_description (3084179324810575787) -->
+ <skip />
+ <!-- no translation found for keyguard_carrier_default (8700650403054042153) -->
+ <skip />
+</resources>
diff --git a/packages/Keyguard/res/values-cs/strings.xml b/packages/Keyguard/res/values-cs/strings.xml
new file mode 100644
index 0000000..ad4e042
--- /dev/null
+++ b/packages/Keyguard/res/values-cs/strings.xml
@@ -0,0 +1,164 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/* //device/apps/common/assets/res/any/strings.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:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Zadejte kód PIN"</string>
+ <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Zadejte kód PUK a nový kód PIN."</string>
+ <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"Kód PUK"</string>
+ <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Nový kód PIN"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Dotykem zadáte heslo"</font></string>
+ <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Zadejte heslo pro odemknutí"</string>
+ <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Zadejte kód PIN pro odemknutí"</string>
+ <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Nesprávný kód PIN."</string>
+ <string name="keyguard_label_text" msgid="861796461028298424">"Chcete-li telefon odemknout, stiskněte Menu a poté 0."</string>
+ <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Překročili jste maximální povolený počet pokusů o odemknutí obličejem."</string>
+ <!-- no translation found for keyguard_charged (3272223906073492454) -->
+ <skip />
+ <!-- no translation found for keyguard_plugged_in (8117572000639998388) -->
+ <skip />
+ <!-- no translation found for keyguard_low_battery (8143808018719173859) -->
+ <skip />
+ <!-- no translation found for keyguard_instructions_when_pattern_disabled (1332288268600329841) -->
+ <skip />
+ <!-- no translation found for keyguard_network_locked_message (9169717779058037168) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message_short (494980561304211931) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (1445849005909260039) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (3481110395508637643) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions (5210891509995942250) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions_long (5968985489463870358) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_message_short (8340813989586622356) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_instructions (5892940909699723544) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_locked_message (6875773413306380902) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_puk_locked_message (3747232467471801633) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_unlock_progress_dialog_message (7975221805033614426) -->
+ <skip />
+ <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d z %3$d."</string>
+ <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Přidat widget"</string>
+ <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Prázdné"</string>
+ <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Oblast odemknutí byla rozšířena."</string>
+ <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Oblast odemknutí byla sbalena."</string>
+ <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"Widget <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>"</string>
+ <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"Výběr uživatele"</string>
+ <string name="keyguard_accessibility_status" msgid="8008264603935930611">"Stav"</string>
+ <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"Fotoaparát"</string>
+ <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Ovládání médií"</string>
+ <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Přeuspořádání widgetů bylo zahájeno."</string>
+ <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Přeuspořádání widgetů bylo dokončeno."</string>
+ <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Widget <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> byl smazán."</string>
+ <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Rozšířit oblast odemknutí"</string>
+ <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Odemknutí přejetím prstem."</string>
+ <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Odemknutí gestem."</string>
+ <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Odemknutí obličejem."</string>
+ <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Odemknutí kódem PIN."</string>
+ <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Odemknutí heslem."</string>
+ <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Oblast pro zadání bezpečnostního gesta."</string>
+ <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Oblast pro přejetí prstem."</string>
+ <!-- no translation found for keyguard_accessibility_transport_prev_description (1337286538318543555) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_next_description (7073928300444909320) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_pause_description (8455979545295224302) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_play_description (8146417789511154044) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_stop_description (7656358482980912216) -->
+ <skip />
+ <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+ <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+ <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"Alt"</string>
+ <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+ <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Zrušit"</string>
+ <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Smazat"</string>
+ <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Hotovo"</string>
+ <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Změna režimu"</string>
+ <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
+ <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
+ <string name="description_target_unlock" msgid="2228524900439801453">"Odemknout"</string>
+ <string name="description_target_camera" msgid="969071997552486814">"Fotoaparát"</string>
+ <string name="description_target_silent" msgid="893551287746522182">"Tichý"</string>
+ <string name="description_target_soundon" msgid="30052466675500172">"Zapnout zvuk"</string>
+ <string name="description_target_search" msgid="3091587249776033139">"Vyhledávání"</string>
+ <string name="description_direction_up" msgid="7169032478259485180">"Přejeďte prstem nahoru: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
+ <string name="description_direction_down" msgid="5087739728639014595">"Přejeďte prstem dolů: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
+ <string name="description_direction_left" msgid="7207478719805562165">"Přejeďte prstem doleva: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
+ <string name="description_direction_right" msgid="8034433242579600980">"Přejeďte prstem doprava: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
+ <string name="user_switched" msgid="3768006783166984410">"Aktuální uživatel je <xliff:g id="NAME">%1$s</xliff:g>."</string>
+ <string name="kg_emergency_call_label" msgid="684946192523830531">"Tísňové volání"</string>
+ <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Zapomenuté gesto"</string>
+ <string name="kg_wrong_pattern" msgid="1850806070801358830">"Nesprávné gesto"</string>
+ <string name="kg_wrong_password" msgid="2333281762128113157">"Nesprávné heslo"</string>
+ <string name="kg_wrong_pin" msgid="1131306510833563801">"Nesprávný kód PIN"</string>
+ <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Zkuste to znovu za <xliff:g id="NUMBER">%d</xliff:g> s."</string>
+ <string name="kg_pattern_instructions" msgid="398978611683075868">"Nakreslete gesto"</string>
+ <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Zadejte kód PIN SIM karty"</string>
+ <string name="kg_pin_instructions" msgid="2377242233495111557">"Zadejte kód PIN"</string>
+ <string name="kg_password_instructions" msgid="5753646556186936819">"Zadejte heslo"</string>
+ <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"SIM karta byla deaktivována. Chcete-li pokračovat, je třeba zadat kód PUK. Podrobné informace získáte od operátora."</string>
+ <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Zadejte požadovaný kód PIN."</string>
+ <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Potvrďte požadovaný kód PIN."</string>
+ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Odblokování SIM karty..."</string>
+ <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Nesprávný kód PIN."</string>
+ <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Zadejte kód PIN o délce 4–8 číslic."</string>
+ <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"Minimální délka kódu PUK je 8 číslic."</string>
+ <string name="kg_invalid_puk" msgid="3638289409676051243">"Znovu zadejte správný kód PUK. Opakovanými pokusy SIM kartu trvale deaktivujete."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"Kódy PIN se neshodují."</string>
+ <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Příliš mnoho pokusů o nakreslení gesta"</string>
+ <string name="kg_login_instructions" msgid="1100551261265506448">"Chcete-li telefon odemknout, přihlaste se pomocí svého účtu Google."</string>
+ <string name="kg_login_username_hint" msgid="5718534272070920364">"Uživatelské jméno (e-mail)"</string>
+ <string name="kg_login_password_hint" msgid="9057289103827298549">"Heslo"</string>
+ <string name="kg_login_submit_button" msgid="5355904582674054702">"Přihlásit se"</string>
+ <string name="kg_login_invalid_input" msgid="5754664119319872197">"Neplatné uživatelské jméno nebo heslo."</string>
+ <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Zapomněli jste uživatelské jméno nebo heslo?"\n"Přejděte na stránku "<b>"google.com/accounts/recovery"</b>"."</string>
+ <string name="kg_login_checking_password" msgid="1052685197710252395">"Kontrola účtu…"</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Již <xliff:g id="NUMBER_0">%d</xliff:g>krát jste zadali nesprávný kód PIN. "\n\n"Zkuste to znovu za <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
+ <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Již <xliff:g id="NUMBER_0">%d</xliff:g>krát jste nesprávně zadali heslo. "\n\n"Zkuste to znovu za <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
+ <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Již <xliff:g id="NUMBER_0">%d</xliff:g>krát jste zadali nesprávné bezpečnostní gesto. "\n\n"Zkuste to znovu za <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Již jste se <xliff:g id="NUMBER_0">%d</xliff:g>krát pokusili odemknout tablet nesprávným způsobem. Po <xliff:g id="NUMBER_1">%d</xliff:g> dalších neúspěšných pokusech se v tabletu obnoví tovární nastavení a veškerá uživatelská data budou ztracena."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Již jste se <xliff:g id="NUMBER_0">%d</xliff:g>krát pokusili odemknout telefon nesprávným způsobem. Po <xliff:g id="NUMBER_1">%d</xliff:g> dalších neúspěšných pokusech se v telefonu obnoví tovární nastavení a veškerá uživatelská data budou ztracena."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Již jste se <xliff:g id="NUMBER">%d</xliff:g>krát pokusili odemknout tablet nesprávným způsobem. V tabletu se nyní obnoví výchozí tovární nastavení."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Již jste se <xliff:g id="NUMBER">%d</xliff:g>krát pokusili odemknout telefon nesprávným způsobem. V telefonu se nyní obnoví výchozí tovární nastavení."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Již <xliff:g id="NUMBER_0">%d</xliff:g>krát jste nesprávně nakreslili své heslo odemknutí. Po <xliff:g id="NUMBER_1">%d</xliff:g>dalších neúspěšných pokusech budete požádáni o odemčení tabletu pomocí e-mailového účtu."\n\n" Zkuste to znovu za <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Již <xliff:g id="NUMBER_0">%d</xliff:g>krát jste nesprávně nakreslili své heslo odemknutí. Po <xliff:g id="NUMBER_1">%d</xliff:g> dalších neúspěšných pokusech budete požádáni o odemčení telefonu pomocí e-mailového účtu."\n\n" Zkuste to znovu za <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
+ <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" – "</string>
+ <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Odebrat"</string>
+ <!-- no translation found for keyguard_transport_prev_description (8229108430245669854) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_next_description (4299258300283778305) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_pause_description (5093073338238310224) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_play_description (2924628863741150956) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_stop_description (3084179324810575787) -->
+ <skip />
+ <!-- no translation found for keyguard_carrier_default (8700650403054042153) -->
+ <skip />
+</resources>
diff --git a/packages/Keyguard/res/values-da/strings.xml b/packages/Keyguard/res/values-da/strings.xml
new file mode 100644
index 0000000..cc1a971
--- /dev/null
+++ b/packages/Keyguard/res/values-da/strings.xml
@@ -0,0 +1,164 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/* //device/apps/common/assets/res/any/strings.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:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Indtast pinkode"</string>
+ <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Indtast PUK- og pinkode"</string>
+ <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK-kode"</string>
+ <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Ny pinkode"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Tryk for at angive adgangskode"</font></string>
+ <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Indtast adgangskoden for at låse op"</string>
+ <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Indtast pinkode for at låse op"</string>
+ <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Forkert pinkode."</string>
+ <string name="keyguard_label_text" msgid="861796461028298424">"Tryk på Menu og dernæst på 0 for at låse op."</string>
+ <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Det maksimale antal forsøg på at bruge Ansigtslås er overskredet"</string>
+ <!-- no translation found for keyguard_charged (3272223906073492454) -->
+ <skip />
+ <!-- no translation found for keyguard_plugged_in (8117572000639998388) -->
+ <skip />
+ <!-- no translation found for keyguard_low_battery (8143808018719173859) -->
+ <skip />
+ <!-- no translation found for keyguard_instructions_when_pattern_disabled (1332288268600329841) -->
+ <skip />
+ <!-- no translation found for keyguard_network_locked_message (9169717779058037168) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message_short (494980561304211931) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (1445849005909260039) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (3481110395508637643) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions (5210891509995942250) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions_long (5968985489463870358) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_message_short (8340813989586622356) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_instructions (5892940909699723544) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_locked_message (6875773413306380902) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_puk_locked_message (3747232467471801633) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_unlock_progress_dialog_message (7975221805033614426) -->
+ <skip />
+ <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d af %3$d."</string>
+ <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Tilføj widget."</string>
+ <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Tom"</string>
+ <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Oplåsningsområdet er udvidet."</string>
+ <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Oplåsningsområdet er skjult."</string>
+ <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"Widget til <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>."</string>
+ <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"Brugervælger"</string>
+ <string name="keyguard_accessibility_status" msgid="8008264603935930611">"Status"</string>
+ <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"Kamera"</string>
+ <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Mediekontrolelementer"</string>
+ <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Omrokering af widgets er påbegyndt."</string>
+ <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Omrokering af widgets er afsluttet."</string>
+ <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Widgetten <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> er slettet."</string>
+ <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Udvid oplåsningsområdet."</string>
+ <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Lås op ved at stryge."</string>
+ <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Lås op med mønster."</string>
+ <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Lås op med ansigt."</string>
+ <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Lås op med pinkode."</string>
+ <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Lås op med adgangskode."</string>
+ <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Mønsterområde."</string>
+ <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Strygeområde."</string>
+ <!-- no translation found for keyguard_accessibility_transport_prev_description (1337286538318543555) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_next_description (7073928300444909320) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_pause_description (8455979545295224302) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_play_description (8146417789511154044) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_stop_description (7656358482980912216) -->
+ <skip />
+ <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+ <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+ <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+ <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Annuller"</string>
+ <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Slet"</string>
+ <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Udført"</string>
+ <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Ændring af tilstand"</string>
+ <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
+ <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Angiv"</string>
+ <string name="description_target_unlock" msgid="2228524900439801453">"Lås op"</string>
+ <string name="description_target_camera" msgid="969071997552486814">"Kamera"</string>
+ <string name="description_target_silent" msgid="893551287746522182">"Lydløs"</string>
+ <string name="description_target_soundon" msgid="30052466675500172">"Lyd slået til"</string>
+ <string name="description_target_search" msgid="3091587249776033139">"Søgning"</string>
+ <string name="description_direction_up" msgid="7169032478259485180">"Glid op for at <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_down" msgid="5087739728639014595">"Glid ned for at <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_left" msgid="7207478719805562165">"Glid til venstre for at <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_right" msgid="8034433242579600980">"Glid til højre for at <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="user_switched" msgid="3768006783166984410">"Nuværende bruger <xliff:g id="NAME">%1$s</xliff:g>."</string>
+ <string name="kg_emergency_call_label" msgid="684946192523830531">"Nødopkald"</string>
+ <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Glemt mønster"</string>
+ <string name="kg_wrong_pattern" msgid="1850806070801358830">"Forkert mønster"</string>
+ <string name="kg_wrong_password" msgid="2333281762128113157">"Forkert adgangskode"</string>
+ <string name="kg_wrong_pin" msgid="1131306510833563801">"Forkert pinkode"</string>
+ <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Prøv igen om <xliff:g id="NUMBER">%d</xliff:g> sekunder."</string>
+ <string name="kg_pattern_instructions" msgid="398978611683075868">"Tegn dit mønster"</string>
+ <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Indtast pinkode til SIM"</string>
+ <string name="kg_pin_instructions" msgid="2377242233495111557">"Indtast pinkode"</string>
+ <string name="kg_password_instructions" msgid="5753646556186936819">"Angiv adgangskode"</string>
+ <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"SIM-kortet er nu deaktiveret. Indtast PUK-koden for at fortsætte. Kontakt mobiloperatøren for at få flere oplysninger."</string>
+ <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Indtast den ønskede pinkode"</string>
+ <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Bekræft den ønskede pinkode"</string>
+ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"SIM-kortet låses op…"</string>
+ <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Forkert pinkode."</string>
+ <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Indtast en pinkode på mellem 4 og 8 tal."</string>
+ <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK-koden skal være på 8 tal eller mere."</string>
+ <string name="kg_invalid_puk" msgid="3638289409676051243">"Indtast den korrekte PUK-kode. Gentagne forsøg vil permanent deaktivere SIM-kortet."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"Pinkoderne stemmer ikke overens"</string>
+ <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"For mange forsøg på at tegne mønstret korrekt"</string>
+ <string name="kg_login_instructions" msgid="1100551261265506448">"Lås op ved at logge ind med din Google-konto."</string>
+ <string name="kg_login_username_hint" msgid="5718534272070920364">"Brugernavn (e-mail)"</string>
+ <string name="kg_login_password_hint" msgid="9057289103827298549">"Adgangskode"</string>
+ <string name="kg_login_submit_button" msgid="5355904582674054702">"Log ind"</string>
+ <string name="kg_login_invalid_input" msgid="5754664119319872197">"Ugyldigt brugernavn eller ugyldig adgangskode."</string>
+ <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Har du glemt dit brugernavn eller din adgangskode?"\n"Gå til "<b>"google.com/accounts/recovery"</b>"."</string>
+ <string name="kg_login_checking_password" msgid="1052685197710252395">"Kontoen kontrolleres…"</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Du har indtastet en forkert pinkode <xliff:g id="NUMBER_0">%d</xliff:g> gange. "\n\n"Prøv igen om <xliff:g id="NUMBER_1">%d</xliff:g> sekunder."</string>
+ <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Du har indtastet din adgangskode forkert <xliff:g id="NUMBER_0">%d</xliff:g> gange. "\n\n"Prøv igen om <xliff:g id="NUMBER_1">%d</xliff:g> sekunder."</string>
+ <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Du har tegnet dit oplåsningsmønster forkert <xliff:g id="NUMBER_0">%d</xliff:g> gange. "\n\n"Prøv igen om <xliff:g id="NUMBER_1">%d</xliff:g> sekunder."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Du har forsøgt at låse tabletten op forkert <xliff:g id="NUMBER_0">%d</xliff:g> gange. Efter <xliff:g id="NUMBER_1">%d</xliff:g> yderligere mislykkede forsøg nulstilles tabletten til fabriksindstillingerne, og alle brugerdata mistes."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Du har forsøgt at låse telefonen op forkert <xliff:g id="NUMBER_0">%d</xliff:g> gange. Efter <xliff:g id="NUMBER_1">%d</xliff:g> yderligere mislykkede forsøg, nulstilles telefonen til fabriksindstillingerne, og alle brugerdata mistes."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Du har forsøgt at låse tabletten op forkert <xliff:g id="NUMBER">%d</xliff:g> gange. Tabletten nulstilles til fabriksindstillingerne."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Du har forsøgt at låse telefonen op forkert <xliff:g id="NUMBER">%d</xliff:g> gange. Telefonen nulstilles til fabriksindstillingerne."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Du har tegnet dit oplåsningsmønster forkert <xliff:g id="NUMBER_0">%d</xliff:g> gange. Efter <xliff:g id="NUMBER_1">%d</xliff:g> yderligere mislykkede forsøg vil du blive bedt om at låse din tablet op ved hjælp af en e-mailkonto"\n\n" Prøv igen om <xliff:g id="NUMBER_2">%d</xliff:g> sekunder."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Du har tegnet dit oplåsningsmønster forkert <xliff:g id="NUMBER_0">%d</xliff:g> gange. Efter <xliff:g id="NUMBER_1">%d</xliff:g> yderligere mislykkede forsøg til vil du blive bedt om at låse din telefon op ved hjælp af en e-mailkonto."\n\n" Prøv igen om <xliff:g id="NUMBER_2">%d</xliff:g> sekunder."</string>
+ <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" – "</string>
+ <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Fjern"</string>
+ <!-- no translation found for keyguard_transport_prev_description (8229108430245669854) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_next_description (4299258300283778305) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_pause_description (5093073338238310224) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_play_description (2924628863741150956) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_stop_description (3084179324810575787) -->
+ <skip />
+ <!-- no translation found for keyguard_carrier_default (8700650403054042153) -->
+ <skip />
+</resources>
diff --git a/packages/Keyguard/res/values-de/strings.xml b/packages/Keyguard/res/values-de/strings.xml
new file mode 100644
index 0000000..5aa9641
--- /dev/null
+++ b/packages/Keyguard/res/values-de/strings.xml
@@ -0,0 +1,164 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/* //device/apps/common/assets/res/any/strings.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:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"PIN-Code eingeben"</string>
+ <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"PUK und neuen PIN-Code eingeben"</string>
+ <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK-Code"</string>
+ <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Neuer PIN-Code"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Zur Passworteingabe berühren"</font></string>
+ <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Passwort zum Entsperren eingeben"</string>
+ <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"PIN zum Entsperren eingeben"</string>
+ <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Falscher PIN-Code"</string>
+ <string name="keyguard_label_text" msgid="861796461028298424">"Drücken Sie zum Entsperren die Menütaste und dann auf \"0\"."</string>
+ <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Die maximal zulässige Anzahl an Face Unlock-Versuchen wurde überschritten."</string>
+ <!-- no translation found for keyguard_charged (3272223906073492454) -->
+ <skip />
+ <!-- no translation found for keyguard_plugged_in (8117572000639998388) -->
+ <skip />
+ <!-- no translation found for keyguard_low_battery (8143808018719173859) -->
+ <skip />
+ <!-- no translation found for keyguard_instructions_when_pattern_disabled (1332288268600329841) -->
+ <skip />
+ <!-- no translation found for keyguard_network_locked_message (9169717779058037168) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message_short (494980561304211931) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (1445849005909260039) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (3481110395508637643) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions (5210891509995942250) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions_long (5968985489463870358) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_message_short (8340813989586622356) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_instructions (5892940909699723544) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_locked_message (6875773413306380902) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_puk_locked_message (3747232467471801633) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_unlock_progress_dialog_message (7975221805033614426) -->
+ <skip />
+ <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d von %3$d."</string>
+ <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Widget hinzufügen"</string>
+ <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Leer"</string>
+ <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Entsperr-Bereich maximiert"</string>
+ <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Entsperr-Bereich mminimiert"</string>
+ <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"Widget <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>"</string>
+ <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"Nutzerauswahl"</string>
+ <string name="keyguard_accessibility_status" msgid="8008264603935930611">"Status"</string>
+ <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"Kamera"</string>
+ <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Mediensteuerelemente"</string>
+ <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Neuordnung der Widgets gestartet"</string>
+ <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Neuordnung der Widgets abgeschlossen"</string>
+ <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Widget <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> gelöscht"</string>
+ <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Entsperr-Bereich maximieren"</string>
+ <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Entsperrung mit Fingerbewegung"</string>
+ <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Entsperrung mit Muster"</string>
+ <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Face Unlock"</string>
+ <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Entsperrung mit PIN"</string>
+ <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Entsperrung mit Passwort"</string>
+ <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Bereich für Muster"</string>
+ <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Bereich für Fingerbewegung"</string>
+ <!-- no translation found for keyguard_accessibility_transport_prev_description (1337286538318543555) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_next_description (7073928300444909320) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_pause_description (8455979545295224302) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_play_description (8146417789511154044) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_stop_description (7656358482980912216) -->
+ <skip />
+ <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+ <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+ <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+ <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Abbrechen"</string>
+ <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Löschen"</string>
+ <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Fertig"</string>
+ <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Modusänderung"</string>
+ <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Umschalttaste"</string>
+ <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Eingabetaste"</string>
+ <string name="description_target_unlock" msgid="2228524900439801453">"Entsperren"</string>
+ <string name="description_target_camera" msgid="969071997552486814">"Kamera"</string>
+ <string name="description_target_silent" msgid="893551287746522182">"Lautlos"</string>
+ <string name="description_target_soundon" msgid="30052466675500172">"Ton ein"</string>
+ <string name="description_target_search" msgid="3091587249776033139">"Suche"</string>
+ <string name="description_direction_up" msgid="7169032478259485180">"Zum <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> nach oben schieben"</string>
+ <string name="description_direction_down" msgid="5087739728639014595">"Zum <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> nach unten schieben"</string>
+ <string name="description_direction_left" msgid="7207478719805562165">"Zum <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> nach links schieben"</string>
+ <string name="description_direction_right" msgid="8034433242579600980">"Zum <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> nach rechts schieben"</string>
+ <string name="user_switched" msgid="3768006783166984410">"Aktueller Nutzer <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="kg_emergency_call_label" msgid="684946192523830531">"Notruf"</string>
+ <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Muster vergessen"</string>
+ <string name="kg_wrong_pattern" msgid="1850806070801358830">"Falsches Muster"</string>
+ <string name="kg_wrong_password" msgid="2333281762128113157">"Falsches Passwort"</string>
+ <string name="kg_wrong_pin" msgid="1131306510833563801">"Falsche PIN"</string>
+ <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Versuchen Sie es in <xliff:g id="NUMBER">%d</xliff:g> Sekunden erneut."</string>
+ <string name="kg_pattern_instructions" msgid="398978611683075868">"Muster zeichnen"</string>
+ <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"SIM-PIN eingeben"</string>
+ <string name="kg_pin_instructions" msgid="2377242233495111557">"PIN eingeben"</string>
+ <string name="kg_password_instructions" msgid="5753646556186936819">"Passwort eingeben"</string>
+ <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"Die SIM-Karte ist jetzt deaktiviert. Geben Sie den PUK-Code ein, um fortzufahren. Weitere Informationen erhalten Sie von Ihrem Mobilfunkanbieter."</string>
+ <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Gewünschten PIN-Code eingeben"</string>
+ <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Gewünschten PIN-Code bestätigen"</string>
+ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"SIM-Karte wird entsperrt…"</string>
+ <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Falscher PIN-Code"</string>
+ <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Geben Sie eine 4- bis 8-stellige PIN ein."</string>
+ <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"Der PUK-Code muss mindestens 8 Ziffern betragen."</string>
+ <string name="kg_invalid_puk" msgid="3638289409676051243">"Geben Sie den richtigen PUK-Code ein. Bei wiederholten Versuchen wird die SIM-Karte dauerhaft deaktiviert."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN-Codes stimmen nicht überein"</string>
+ <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Zu viele Musterversuche"</string>
+ <string name="kg_login_instructions" msgid="1100551261265506448">"Melden Sie sich zum Entsperren mit Ihrem Google-Konto an."</string>
+ <string name="kg_login_username_hint" msgid="5718534272070920364">"Nutzername (E-Mail)"</string>
+ <string name="kg_login_password_hint" msgid="9057289103827298549">"Passwort"</string>
+ <string name="kg_login_submit_button" msgid="5355904582674054702">"Anmelden"</string>
+ <string name="kg_login_invalid_input" msgid="5754664119319872197">"Ungültiger Nutzername oder ungültiges Passwort"</string>
+ <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Nutzernamen oder Passwort vergessen?"\n"Besuchen Sie "<b>"google.com/accounts/recovery"</b>"."</string>
+ <string name="kg_login_checking_password" msgid="1052685197710252395">"Konto wird geprüft…"</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Sie haben Ihre PIN <xliff:g id="NUMBER_0">%d</xliff:g>-mal falsch eingegeben."\n\n"Versuchen Sie es in <xliff:g id="NUMBER_1">%d</xliff:g> Sekunden erneut."</string>
+ <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Sie haben Ihr Passwort <xliff:g id="NUMBER_0">%d</xliff:g>-mal falsch eingegeben."\n\n"Versuchen Sie es in <xliff:g id="NUMBER_1">%d</xliff:g> Sekunden erneut."</string>
+ <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Sie haben Ihr Entsperrungsmuster <xliff:g id="NUMBER_0">%d</xliff:g>-mal falsch gezeichnet. "\n\n"Versuchen Sie es in <xliff:g id="NUMBER_1">%d</xliff:g> Sekunden erneut."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Sie haben <xliff:g id="NUMBER_0">%d</xliff:g>-mal erfolglos versucht, das Tablet zu entsperren. Nach <xliff:g id="NUMBER_1">%d</xliff:g> weiteren erfolglosen Versuchen wird das Tablet auf die Werkseinstellungen zurückgesetzt und alle Nutzerdaten gehen verloren."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Sie haben <xliff:g id="NUMBER_0">%d</xliff:g>-mal erfolglos versucht, das Telefon zu entsperren. Nach <xliff:g id="NUMBER_1">%d</xliff:g> weiteren erfolglosen Versuchen wird das Telefon auf die Werkseinstellungen zurückgesetzt und alle Nutzerdaten gehen verloren."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Sie haben <xliff:g id="NUMBER">%d</xliff:g>-mal erfolglos versucht, das Tablet zu entsperren. Das Tablet wird nun auf die Werkseinstellungen zurückgesetzt."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Sie haben <xliff:g id="NUMBER">%d</xliff:g>-mal erfolglos versucht, das Telefon zu entsperren. Das Telefon wird nun auf die Werkseinstellungen zurückgesetzt."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Sie haben Ihr Entsperrungsmuster <xliff:g id="NUMBER_0">%d</xliff:g>-mal falsch gezeichnet. Nach <xliff:g id="NUMBER_1">%d</xliff:g> weiteren erfolglosen Versuchen werden Sie aufgefordert, Ihr Tablet mithilfe eines E-Mail-Kontos zu entsperren."\n\n" Versuchen Sie es in <xliff:g id="NUMBER_2">%d</xliff:g> Sekunden erneut."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Sie haben Ihr Entsperrungsmuster <xliff:g id="NUMBER_0">%d</xliff:g>-mal falsch gezeichnet. Nach <xliff:g id="NUMBER_1">%d</xliff:g> weiteren erfolglosen Versuchen werden Sie aufgefordert, Ihr Telefon mithilfe eines E-Mail-Kontos zu entsperren."\n\n" Versuchen Sie es in <xliff:g id="NUMBER_2">%d</xliff:g> Sekunden erneut."</string>
+ <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" – "</string>
+ <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Entfernen"</string>
+ <!-- no translation found for keyguard_transport_prev_description (8229108430245669854) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_next_description (4299258300283778305) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_pause_description (5093073338238310224) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_play_description (2924628863741150956) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_stop_description (3084179324810575787) -->
+ <skip />
+ <!-- no translation found for keyguard_carrier_default (8700650403054042153) -->
+ <skip />
+</resources>
diff --git a/packages/Keyguard/res/values-el/strings.xml b/packages/Keyguard/res/values-el/strings.xml
new file mode 100644
index 0000000..0380969
--- /dev/null
+++ b/packages/Keyguard/res/values-el/strings.xml
@@ -0,0 +1,164 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/* //device/apps/common/assets/res/any/strings.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:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Πληκτρολογήστε τον κωδικό αριθμό PIN"</string>
+ <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Πληκτρολογήστε τον κωδικό PUK και τον νέο κωδικό PIN"</string>
+ <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"Κωδικός PUK"</string>
+ <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Νέος κωδικός PIN"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Αγγίξτε για εισαγ. κωδ. πρόσβ."</font></string>
+ <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Πληκτρολογήστε τον κωδικό πρόσβασης για ξεκλείδωμα"</string>
+ <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Πληκτρολογήστε τον αριθμό PIN για ξεκλείδωμα"</string>
+ <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Εσφαλμένος κωδικός PIN."</string>
+ <string name="keyguard_label_text" msgid="861796461028298424">"Για ξεκλείδωμα, πατήστε το πλήκτρο Menu και, στη συνέχεια, το πλήκτρο 0."</string>
+ <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Έγινε υπέρβαση του μέγιστου αριθμού προσπαθειών Face Unlock"</string>
+ <!-- no translation found for keyguard_charged (3272223906073492454) -->
+ <skip />
+ <!-- no translation found for keyguard_plugged_in (8117572000639998388) -->
+ <skip />
+ <!-- no translation found for keyguard_low_battery (8143808018719173859) -->
+ <skip />
+ <!-- no translation found for keyguard_instructions_when_pattern_disabled (1332288268600329841) -->
+ <skip />
+ <!-- no translation found for keyguard_network_locked_message (9169717779058037168) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message_short (494980561304211931) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (1445849005909260039) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (3481110395508637643) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions (5210891509995942250) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions_long (5968985489463870358) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_message_short (8340813989586622356) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_instructions (5892940909699723544) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_locked_message (6875773413306380902) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_puk_locked_message (3747232467471801633) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_unlock_progress_dialog_message (7975221805033614426) -->
+ <skip />
+ <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Γραφικό στοιχείο %2$d από %3$d."</string>
+ <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Προσθήκη γραφικού στοιχείου"</string>
+ <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Κενή"</string>
+ <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Ανάπτυξη της περιοχής ξεκλειδώματος."</string>
+ <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Σύμπτυξη της περιοχής ξεκλειδώματος."</string>
+ <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"Γραφικό στοιχείο <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>."</string>
+ <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"Επιλογέας χρήστη"</string>
+ <string name="keyguard_accessibility_status" msgid="8008264603935930611">"Κατάσταση"</string>
+ <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"Φωτογραφική μηχανή"</string>
+ <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Στοιχεία ελέγχου μέσων"</string>
+ <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Έχει ξεκινήσει η αναδιάταξη των γραφικών στοιχείων."</string>
+ <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Έχει ολοκληρωθεί η αναδιάταξη των γραφικών στοιχείων."</string>
+ <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Το γραφικό στοιχείο <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> έχει διαγραφεί."</string>
+ <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Ανάπτυξη περιοχής ξεκλειδώματος."</string>
+ <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Ξεκλείδωμα ολίσθησης."</string>
+ <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Ξεκλείδωμα μοτίβου."</string>
+ <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Face unlock."</string>
+ <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Ξεκλείδωμα κωδικού ασφαλείας"</string>
+ <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Ξεκλείδωμα κωδικού πρόσβασης."</string>
+ <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Περιοχή μοτίβου."</string>
+ <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Περιοχή ολίσθησης"</string>
+ <!-- no translation found for keyguard_accessibility_transport_prev_description (1337286538318543555) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_next_description (7073928300444909320) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_pause_description (8455979545295224302) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_play_description (8146417789511154044) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_stop_description (7656358482980912216) -->
+ <skip />
+ <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+ <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ΑΒΓ"</string>
+ <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+ <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Ακύρωση"</string>
+ <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Διαγραφή"</string>
+ <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Τέλος"</string>
+ <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Αλλαγή τρόπου"</string>
+ <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
+ <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
+ <string name="description_target_unlock" msgid="2228524900439801453">"Ξεκλείδωμα"</string>
+ <string name="description_target_camera" msgid="969071997552486814">"Φωτογραφική μηχανή"</string>
+ <string name="description_target_silent" msgid="893551287746522182">"Αθόρυβο"</string>
+ <string name="description_target_soundon" msgid="30052466675500172">"Ενεργοποίηση ήχου"</string>
+ <string name="description_target_search" msgid="3091587249776033139">"Αναζήτηση"</string>
+ <string name="description_direction_up" msgid="7169032478259485180">"Κύλιση προς τα επάνω για <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_down" msgid="5087739728639014595">"Κύλιση προς τα κάτω για <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_left" msgid="7207478719805562165">"Κύλιση προς τα αριστερά για <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_right" msgid="8034433242579600980">"Κύλιση προς τα δεξιά για <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="user_switched" msgid="3768006783166984410">"Τρέχων χρήστης <xliff:g id="NAME">%1$s</xliff:g>."</string>
+ <string name="kg_emergency_call_label" msgid="684946192523830531">"Κλήσεις επείγουσας ανάγκης"</string>
+ <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Ξεχάσατε το μοτίβο"</string>
+ <string name="kg_wrong_pattern" msgid="1850806070801358830">"Εσφαλμένο μοτίβο"</string>
+ <string name="kg_wrong_password" msgid="2333281762128113157">"Εσφαλμένος κωδικός πρόσβασης"</string>
+ <string name="kg_wrong_pin" msgid="1131306510833563801">"Εσφαλμένος κωδικός PIN"</string>
+ <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Δοκιμάστε ξανά σε <xliff:g id="NUMBER">%d</xliff:g> δευτερόλεπτα."</string>
+ <string name="kg_pattern_instructions" msgid="398978611683075868">"Σχεδιάστε το μοτίβο σας"</string>
+ <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Εισαγωγή PIN SIM"</string>
+ <string name="kg_pin_instructions" msgid="2377242233495111557">"Πληκτρολογήστε το PIN"</string>
+ <string name="kg_password_instructions" msgid="5753646556186936819">"Εισαγάγετε κωδικό πρόσβασης"</string>
+ <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"Η κάρτα SIM είναι απενεργοποιημένη αυτή τη στιγμή. Εισαγάγετε τον κωδικό PUK για να συνεχίσετε. Επικοινωνήστε με την εταιρεία κινητής τηλεφωνίας σας για λεπτομέρειες."</string>
+ <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Εισαγάγετε τον απαιτούμενο κωδικό PIN"</string>
+ <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Επιβεβαιώστε τον απαιτούμενο κωδικό PIN"</string>
+ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Ξεκλείδωμα κάρτας SIM..."</string>
+ <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Εσφαλμένος κωδικός PIN."</string>
+ <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Πληκτρολογήστε έναν αριθμό PIN που να αποτελείται από 4 έως 8 αριθμούς."</string>
+ <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"Ο κωδικός PUK θα πρέπει να περιέχει τουλάχιστον 8 αριθμούς."</string>
+ <string name="kg_invalid_puk" msgid="3638289409676051243">"Εισαγάγετε ξανά τον κωδικό PUK. Οι επαναλαμβανόμενες προσπάθειες θα απενεργοποιήσουν οριστικά την κάρτα SIM."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"Δεν υπάρχει αντιστοιχία των κωδικών PIN"</string>
+ <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Πάρα πολλές προσπάθειες μοτίβου"</string>
+ <string name="kg_login_instructions" msgid="1100551261265506448">"Για ξεκλείδωμα, συνδεθείτε με τον λογαριασμό σας Google."</string>
+ <string name="kg_login_username_hint" msgid="5718534272070920364">"Όνομα χρήστη (διεύθυνση ηλεκτρονικού ταχυδρομείου)"</string>
+ <string name="kg_login_password_hint" msgid="9057289103827298549">"Κωδικός πρόσβασης"</string>
+ <string name="kg_login_submit_button" msgid="5355904582674054702">"Σύνδεση"</string>
+ <string name="kg_login_invalid_input" msgid="5754664119319872197">"Μη έγκυρο όνομα χρήστη ή κωδικός πρόσβασης."</string>
+ <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Ξεχάσατε το όνομα χρήστη ή τον κωδικό πρόσβασής σας;"\n"Επισκεφτείτε τη διεύθυνση "<b>"google.com/accounts/recovery"</b>"."</string>
+ <string name="kg_login_checking_password" msgid="1052685197710252395">"Έλεγχος λογαριασμού…"</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Έχετε πληκτρολογήσει εσφαλμένα τον κωδικό σας PIN <xliff:g id="NUMBER_0">%d</xliff:g> φορές. "\n\n"Δοκιμάστε ξανά σε <xliff:g id="NUMBER_1">%d</xliff:g> δευτερόλεπτα."</string>
+ <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Έχετε πληκτρολογήσει τον κωδικό πρόσβασης εσφαλμένα <xliff:g id="NUMBER_0">%d</xliff:g> φορές. "\n\n"Δοκιμάστε ξανά σε <xliff:g id="NUMBER_1">%d</xliff:g> δευτερόλεπτα."</string>
+ <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Σχεδιάσατε εσφαλμένα το μοτίβο ξεκλειδώματος <xliff:g id="NUMBER_0">%d</xliff:g> φορές. "\n\n"Δοκιμάστε ξανά σε <xliff:g id="NUMBER_1">%d</xliff:g> δευτερόλετπα."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Προσπαθήσατε να ξεκλειδώσετε εσφαλμένα το tablet <xliff:g id="NUMBER_0">%d</xliff:g> φορές. Μετά από <xliff:g id="NUMBER_1">%d</xliff:g> προσπάθειες, το tablet θα επαναφερθεί στις εργοστασιακές ρυθμίσεις και όλα τα δεδομένα χρήστη θα χαθούν."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Προσπαθήσατε να ξεκλειδώσετε εσφαλμένα το τηλέφωνο <xliff:g id="NUMBER_0">%d</xliff:g> φορές. Μετά από <xliff:g id="NUMBER_1">%d</xliff:g> προσπάθειες, το τηλέφωνο θα επαναφερθεί στις εργοστασιακές ρυθμίσεις και όλα τα δεδομένα χρήστη θα χαθούν."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Προσπαθήσατε να ξεκλειδώσετε εσφαλμένα το tablet <xliff:g id="NUMBER">%d</xliff:g> φορές. Το tablet θα επαναφερθεί στις εργοστασιακές ρυθμίσεις."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Προσπαθήσατε να ξεκλειδώσετε εσφαλμένα το τηλέφωνο <xliff:g id="NUMBER">%d</xliff:g> φορές. Το τηλέφωνο θα επαναφερθεί στις εργοστασιακές ρυθμίσεις."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Σχεδιάσατε το μοτίβο ξεκλειδώματος εσφαλμένα <xliff:g id="NUMBER_0">%d</xliff:g> φορές. Μετά από <xliff:g id="NUMBER_1">%d</xliff:g> ανεπιτυχείς προσπάθειες ακόμη, θα σας ζητηθεί να ξεκλειδώσετε το tablet σας με τη χρήση ενός λογαριασμού ηλεκτρονικού ταχυδρομείου."\n\n" Δοκιμάστε να συνδεθείτε ξανά σε <xliff:g id="NUMBER_2">%d</xliff:g> δευτερόλεπτα."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Σχεδιάσατε το μοτίβο ξεκλειδώματος εσφαλμένα <xliff:g id="NUMBER_0">%d</xliff:g> φορές. Μετά από <xliff:g id="NUMBER_1">%d</xliff:g> ανεπιτυχείς προσπάθειες ακόμη, θα σας ζητηθεί να ξεκλειδώσετε το τηλέφωνό σας με τη χρήση ενός λογαριασμού ηλεκτρονικού ταχυδρομείου."\n\n" Δοκιμάστε ξανά σε <xliff:g id="NUMBER_2">%d</xliff:g> δευτερόλεπτα."</string>
+ <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
+ <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Κατάργηση"</string>
+ <!-- no translation found for keyguard_transport_prev_description (8229108430245669854) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_next_description (4299258300283778305) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_pause_description (5093073338238310224) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_play_description (2924628863741150956) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_stop_description (3084179324810575787) -->
+ <skip />
+ <!-- no translation found for keyguard_carrier_default (8700650403054042153) -->
+ <skip />
+</resources>
diff --git a/packages/Keyguard/res/values-en-rGB/strings.xml b/packages/Keyguard/res/values-en-rGB/strings.xml
new file mode 100644
index 0000000..7053d02
--- /dev/null
+++ b/packages/Keyguard/res/values-en-rGB/strings.xml
@@ -0,0 +1,164 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/* //device/apps/common/assets/res/any/strings.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:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Type PIN code"</string>
+ <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Type PUK and new PIN code"</string>
+ <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK code"</string>
+ <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"New PIN Code"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Touch to type password"</font></string>
+ <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Type password to unlock"</string>
+ <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Type PIN to unlock"</string>
+ <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Incorrect PIN code."</string>
+ <string name="keyguard_label_text" msgid="861796461028298424">"To unlock, press Menu, then 0."</string>
+ <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Maximum Face Unlock attempts exceeded"</string>
+ <!-- no translation found for keyguard_charged (3272223906073492454) -->
+ <skip />
+ <!-- no translation found for keyguard_plugged_in (8117572000639998388) -->
+ <skip />
+ <!-- no translation found for keyguard_low_battery (8143808018719173859) -->
+ <skip />
+ <!-- no translation found for keyguard_instructions_when_pattern_disabled (1332288268600329841) -->
+ <skip />
+ <!-- no translation found for keyguard_network_locked_message (9169717779058037168) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message_short (494980561304211931) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (1445849005909260039) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (3481110395508637643) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions (5210891509995942250) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions_long (5968985489463870358) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_message_short (8340813989586622356) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_instructions (5892940909699723544) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_locked_message (6875773413306380902) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_puk_locked_message (3747232467471801633) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_unlock_progress_dialog_message (7975221805033614426) -->
+ <skip />
+ <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d of %3$d."</string>
+ <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Add widget"</string>
+ <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Empty"</string>
+ <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Unlock area expanded."</string>
+ <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Unlock area collapsed."</string>
+ <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> widget."</string>
+ <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"User selector"</string>
+ <string name="keyguard_accessibility_status" msgid="8008264603935930611">"Status"</string>
+ <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"Camera"</string>
+ <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Media controls"</string>
+ <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Widget reordering started."</string>
+ <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Widget reordering ended."</string>
+ <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Widget <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> deleted."</string>
+ <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Expand unlock area."</string>
+ <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Slide unlock."</string>
+ <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Pattern unlock."</string>
+ <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Face unlock."</string>
+ <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Pin unlock."</string>
+ <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Password unlock."</string>
+ <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Pattern area."</string>
+ <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Slide area."</string>
+ <!-- no translation found for keyguard_accessibility_transport_prev_description (1337286538318543555) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_next_description (7073928300444909320) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_pause_description (8455979545295224302) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_play_description (8146417789511154044) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_stop_description (7656358482980912216) -->
+ <skip />
+ <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+ <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+ <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+ <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Cancel"</string>
+ <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Delete"</string>
+ <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Done"</string>
+ <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Mode change"</string>
+ <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
+ <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
+ <string name="description_target_unlock" msgid="2228524900439801453">"Unlock"</string>
+ <string name="description_target_camera" msgid="969071997552486814">"Camera"</string>
+ <string name="description_target_silent" msgid="893551287746522182">"Silent"</string>
+ <string name="description_target_soundon" msgid="30052466675500172">"Sound on"</string>
+ <string name="description_target_search" msgid="3091587249776033139">"Search"</string>
+ <string name="description_direction_up" msgid="7169032478259485180">"Slide up for <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_down" msgid="5087739728639014595">"Slide down for <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_left" msgid="7207478719805562165">"Slide left for <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_right" msgid="8034433242579600980">"Slide right for <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="user_switched" msgid="3768006783166984410">"Current user <xliff:g id="NAME">%1$s</xliff:g>."</string>
+ <string name="kg_emergency_call_label" msgid="684946192523830531">"Emergency call"</string>
+ <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Forgot Pattern"</string>
+ <string name="kg_wrong_pattern" msgid="1850806070801358830">"Wrong Pattern"</string>
+ <string name="kg_wrong_password" msgid="2333281762128113157">"Wrong Password"</string>
+ <string name="kg_wrong_pin" msgid="1131306510833563801">"Wrong PIN"</string>
+ <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Try again in <xliff:g id="NUMBER">%d</xliff:g> seconds."</string>
+ <string name="kg_pattern_instructions" msgid="398978611683075868">"Draw your pattern"</string>
+ <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Enter SIM PIN"</string>
+ <string name="kg_pin_instructions" msgid="2377242233495111557">"Enter PIN"</string>
+ <string name="kg_password_instructions" msgid="5753646556186936819">"Enter Password"</string>
+ <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"SIM is now disabled. Enter PUK code to continue. Contact carrier for details."</string>
+ <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Enter desired PIN code"</string>
+ <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Confirm desired PIN code"</string>
+ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Unlocking SIM card…"</string>
+ <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Incorrect PIN code."</string>
+ <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Type a PIN that is 4 to 8 numbers."</string>
+ <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK code should be 8 numbers or more."</string>
+ <string name="kg_invalid_puk" msgid="3638289409676051243">"Re-enter the correct PUK code. Repeated attempts will permanently disable the SIM."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN codes do not match"</string>
+ <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Too many pattern attempts"</string>
+ <string name="kg_login_instructions" msgid="1100551261265506448">"To unlock, sign in with your Google account."</string>
+ <string name="kg_login_username_hint" msgid="5718534272070920364">"Username (email)"</string>
+ <string name="kg_login_password_hint" msgid="9057289103827298549">"Password"</string>
+ <string name="kg_login_submit_button" msgid="5355904582674054702">"Sign in"</string>
+ <string name="kg_login_invalid_input" msgid="5754664119319872197">"Invalid username or password."</string>
+ <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Forgot your username or password?"\n"Visit "<b>"google.com/accounts/recovery"</b>"."</string>
+ <string name="kg_login_checking_password" msgid="1052685197710252395">"Checking account…"</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"You have incorrectly typed your PIN <xliff:g id="NUMBER_0">%d</xliff:g> times. "\n\n"Try again in <xliff:g id="NUMBER_1">%d</xliff:g> seconds."</string>
+ <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"You have incorrectly typed your password <xliff:g id="NUMBER_0">%d</xliff:g> times. "\n\n"Try again in <xliff:g id="NUMBER_1">%d</xliff:g> seconds."</string>
+ <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%d</xliff:g> times. "\n\n"Try again in <xliff:g id="NUMBER_1">%d</xliff:g> seconds."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, the tablet will be reset to factory default and all user data will be lost."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, the phone will be reset to factory default and all user data will be lost."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"You have incorrectly attempted to unlock the tablet <xliff:g id="NUMBER">%d</xliff:g> times. The tablet will now be reset to factory default."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER">%d</xliff:g> times. The phone will now be reset to factory default."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, you will be asked to unlock your tablet using an email account."\n\n" Try again in <xliff:g id="NUMBER_2">%d</xliff:g> seconds."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, you will be asked to unlock your phone using an email account."\n\n" Try again in <xliff:g id="NUMBER_2">%d</xliff:g> seconds."</string>
+ <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
+ <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Remove"</string>
+ <!-- no translation found for keyguard_transport_prev_description (8229108430245669854) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_next_description (4299258300283778305) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_pause_description (5093073338238310224) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_play_description (2924628863741150956) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_stop_description (3084179324810575787) -->
+ <skip />
+ <!-- no translation found for keyguard_carrier_default (8700650403054042153) -->
+ <skip />
+</resources>
diff --git a/packages/Keyguard/res/values-es-rUS/strings.xml b/packages/Keyguard/res/values-es-rUS/strings.xml
new file mode 100644
index 0000000..0e47bdd
--- /dev/null
+++ b/packages/Keyguard/res/values-es-rUS/strings.xml
@@ -0,0 +1,164 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/* //device/apps/common/assets/res/any/strings.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:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Ingresa el código PIN"</string>
+ <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Escribe el código PUK y un nuevo código PIN."</string>
+ <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"Código PUK"</string>
+ <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Nuevo código PIN"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Toca para ingresar la contraseña"</font></string>
+ <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Ingresar contraseña para desbloquear"</string>
+ <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Ingresa el PIN para desbloquear"</string>
+ <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Código PIN incorrecto"</string>
+ <string name="keyguard_label_text" msgid="861796461028298424">"Para desbloquear, presiona el menú y luego 0."</string>
+ <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Se superó el máximo de intentos permitido para el desbloqueo facial del dispositivo."</string>
+ <!-- no translation found for keyguard_charged (3272223906073492454) -->
+ <skip />
+ <!-- no translation found for keyguard_plugged_in (8117572000639998388) -->
+ <skip />
+ <!-- no translation found for keyguard_low_battery (8143808018719173859) -->
+ <skip />
+ <!-- no translation found for keyguard_instructions_when_pattern_disabled (1332288268600329841) -->
+ <skip />
+ <!-- no translation found for keyguard_network_locked_message (9169717779058037168) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message_short (494980561304211931) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (1445849005909260039) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (3481110395508637643) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions (5210891509995942250) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions_long (5968985489463870358) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_message_short (8340813989586622356) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_instructions (5892940909699723544) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_locked_message (6875773413306380902) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_puk_locked_message (3747232467471801633) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_unlock_progress_dialog_message (7975221805033614426) -->
+ <skip />
+ <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d de %3$d"</string>
+ <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Agregar widget"</string>
+ <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Vacío"</string>
+ <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Área desbloqueada expandida."</string>
+ <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"El área desbloqueada se contrajo."</string>
+ <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> widget"</string>
+ <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"Selector de usuarios"</string>
+ <string name="keyguard_accessibility_status" msgid="8008264603935930611">"Estado"</string>
+ <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"Cámara"</string>
+ <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Controles de medios"</string>
+ <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Se comenzaron a reordenar los widgets."</string>
+ <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Se terminaron de reordenar los widgets."</string>
+ <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Widget <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> eliminado"</string>
+ <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Expandir el área desbloqueada"</string>
+ <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Desbloqueo por deslizamiento"</string>
+ <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Desbloqueo por patrón"</string>
+ <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Desbloqueo facial"</string>
+ <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Desbloqueo por PIN"</string>
+ <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Desbloqueo por contraseña"</string>
+ <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Área de patrón"</string>
+ <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Área de deslizamiento"</string>
+ <!-- no translation found for keyguard_accessibility_transport_prev_description (1337286538318543555) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_next_description (7073928300444909320) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_pause_description (8455979545295224302) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_play_description (8146417789511154044) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_stop_description (7656358482980912216) -->
+ <skip />
+ <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+ <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+ <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+ <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Cancelar"</string>
+ <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Eliminar"</string>
+ <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Listo"</string>
+ <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Cambio de modo"</string>
+ <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Mayúscula"</string>
+ <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Ingresar"</string>
+ <string name="description_target_unlock" msgid="2228524900439801453">"Desbloquear"</string>
+ <string name="description_target_camera" msgid="969071997552486814">"Cámara"</string>
+ <string name="description_target_silent" msgid="893551287746522182">"Silencioso"</string>
+ <string name="description_target_soundon" msgid="30052466675500172">"Sonido activado"</string>
+ <string name="description_target_search" msgid="3091587249776033139">"Buscar"</string>
+ <string name="description_direction_up" msgid="7169032478259485180">"Desliza el dedo hacia arriba para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_down" msgid="5087739728639014595">"Desliza el dedo hacia abajo para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_left" msgid="7207478719805562165">"Desliza el dedo hacia la izquierda para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_right" msgid="8034433242579600980">"Desliza el dedo hacia la derecha para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="user_switched" msgid="3768006783166984410">"Usuario actual: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="kg_emergency_call_label" msgid="684946192523830531">"Llamada de emergencia"</string>
+ <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"¿Olvidaste el patrón?"</string>
+ <string name="kg_wrong_pattern" msgid="1850806070801358830">"Patrón incorrecto"</string>
+ <string name="kg_wrong_password" msgid="2333281762128113157">"Contraseña incorrecta"</string>
+ <string name="kg_wrong_pin" msgid="1131306510833563801">"PIN incorrecto"</string>
+ <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Vuelve a intentarlo en <xliff:g id="NUMBER">%d</xliff:g> segundos."</string>
+ <string name="kg_pattern_instructions" msgid="398978611683075868">"Dibuja tu patrón."</string>
+ <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Ingresa el PIN de la tarjeta SIM."</string>
+ <string name="kg_pin_instructions" msgid="2377242233495111557">"Ingresa el PIN."</string>
+ <string name="kg_password_instructions" msgid="5753646556186936819">"Ingresa tu contraseña."</string>
+ <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"La tarjeta SIM está inhabilitada. Para continuar, ingresa el código PUK. Si quieres obtener más información, ponte en contacto con el proveedor."</string>
+ <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Ingresa el código PIN deseado"</string>
+ <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Confirmar código PIN deseado"</string>
+ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Desbloqueando tarjeta SIM…"</string>
+ <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Código PIN incorrecto"</string>
+ <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Escribe un PIN que tenga de cuatro a ocho números."</string>
+ <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"El código PUK debe tener ocho números como mínimo."</string>
+ <string name="kg_invalid_puk" msgid="3638289409676051243">"Vuelve a ingresar el código PUK correcto. Si ingresas un código incorrecto varias veces, se inhabilitará la tarjeta SIM."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"Los códigos PIN no coinciden."</string>
+ <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Demasiados intentos incorrectos de ingresar el patrón"</string>
+ <string name="kg_login_instructions" msgid="1100551261265506448">"Para desbloquear, accede con tu cuenta de Google."</string>
+ <string name="kg_login_username_hint" msgid="5718534272070920364">"Nombre de usuario (correo)"</string>
+ <string name="kg_login_password_hint" msgid="9057289103827298549">"Contraseña"</string>
+ <string name="kg_login_submit_button" msgid="5355904582674054702">"Acceder"</string>
+ <string name="kg_login_invalid_input" msgid="5754664119319872197">"Nombre de usuario o contraseña incorrectos"</string>
+ <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"¿Olvidaste tu nombre de usuario o contraseña?"\n"Accede a "<b>"google.com/accounts/recovery"</b>"."</string>
+ <string name="kg_login_checking_password" msgid="1052685197710252395">"Comprobando la cuenta…"</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Escribiste incorrectamente tu PIN <xliff:g id="NUMBER_0">%d</xliff:g> veces. "\n\n"Vuelve a intentarlo en <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
+ <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Escribiste incorrectamente tu contraseña <xliff:g id="NUMBER_0">%d</xliff:g> veces. "\n\n"Vuelve a intentarlo en <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
+ <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Dibujaste incorrectamente tu patrón de desbloqueo <xliff:g id="NUMBER_0">%d</xliff:g> veces. "\n\n"Vuelve a intentarlo en <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Intentaste desbloquear la tableta <xliff:g id="NUMBER_0">%d</xliff:g> veces, pero no lo lograste. Puedes intentarlo <xliff:g id="NUMBER_1">%d</xliff:g> veces más antes de que se restablezcan los valores predeterminados de fábrica de la tableta y se pierdan todos los datos del usuario."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Intentaste desbloquear el dispositivo <xliff:g id="NUMBER_0">%d</xliff:g> veces, pero no lo lograste. Puedes intentarlo <xliff:g id="NUMBER_1">%d</xliff:g> veces más antes de que se restablezcan los valores predeterminados de fábrica del dispositivo y se pierdan todos los datos del usuario."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Intentaste desbloquear la tableta <xliff:g id="NUMBER">%d</xliff:g> veces, pero no lo lograste. Se restablecerán los valores predeterminados de fábrica de la tableta."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Intentaste desbloquear el dispositivo <xliff:g id="NUMBER">%d</xliff:g> veces, pero no lo lograste. Se restablecerán los valores predeterminados de fábrica del dispositivo."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Dibujaste incorrectamente tu patrón de desbloqueo <xliff:g id="NUMBER_0">%d</xliff:g> veces. Luego de <xliff:g id="NUMBER_1">%d</xliff:g> intentos incorrectos más, se te solicitará que desbloquees tu tableta mediante el uso de una cuenta de correo."\n\n" Vuelve a intentarlo en <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Dibujaste incorrectamente tu patrón de desbloqueo <xliff:g id="NUMBER_0">%d</xliff:g> veces. Luego de <xliff:g id="NUMBER_1">%d</xliff:g> intentos incorrectos más, se te solicitará que desbloquees tu dispositivo mediante el uso de una cuenta de correo."\n\n" Vuelve a intentarlo en <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
+ <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
+ <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Eliminar"</string>
+ <!-- no translation found for keyguard_transport_prev_description (8229108430245669854) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_next_description (4299258300283778305) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_pause_description (5093073338238310224) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_play_description (2924628863741150956) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_stop_description (3084179324810575787) -->
+ <skip />
+ <!-- no translation found for keyguard_carrier_default (8700650403054042153) -->
+ <skip />
+</resources>
diff --git a/packages/Keyguard/res/values-es/strings.xml b/packages/Keyguard/res/values-es/strings.xml
new file mode 100644
index 0000000..35924b3
--- /dev/null
+++ b/packages/Keyguard/res/values-es/strings.xml
@@ -0,0 +1,164 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/* //device/apps/common/assets/res/any/strings.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:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Introduce el código PIN."</string>
+ <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Introduce el código PUK y un nuevo código PIN."</string>
+ <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"Código PUK"</string>
+ <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Nuevo código PIN"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Toca para introducir contraseña"</font></string>
+ <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Introduce la contraseña para desbloquear."</string>
+ <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Introduce el código PIN para desbloquear."</string>
+ <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Código PIN incorrecto"</string>
+ <string name="keyguard_label_text" msgid="861796461028298424">"Para desbloquear el teléfono, pulsa la tecla de menú y, a continuación, pulsa 0."</string>
+ <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Se ha superado el número máximo de intentos de desbloqueo facial."</string>
+ <!-- no translation found for keyguard_charged (3272223906073492454) -->
+ <skip />
+ <!-- no translation found for keyguard_plugged_in (8117572000639998388) -->
+ <skip />
+ <!-- no translation found for keyguard_low_battery (8143808018719173859) -->
+ <skip />
+ <!-- no translation found for keyguard_instructions_when_pattern_disabled (1332288268600329841) -->
+ <skip />
+ <!-- no translation found for keyguard_network_locked_message (9169717779058037168) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message_short (494980561304211931) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (1445849005909260039) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (3481110395508637643) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions (5210891509995942250) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions_long (5968985489463870358) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_message_short (8340813989586622356) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_instructions (5892940909699723544) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_locked_message (6875773413306380902) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_puk_locked_message (3747232467471801633) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_unlock_progress_dialog_message (7975221805033614426) -->
+ <skip />
+ <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d de %3$d"</string>
+ <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Añadir widget"</string>
+ <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Vacío"</string>
+ <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Área de desbloqueo ampliada"</string>
+ <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Área de desbloqueo contraída"</string>
+ <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"Widget de <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>"</string>
+ <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"Selector de usuarios"</string>
+ <string name="keyguard_accessibility_status" msgid="8008264603935930611">"Estado"</string>
+ <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"Cámara"</string>
+ <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Controles multimedia"</string>
+ <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Se ha empezado a cambiar el orden de los widgets."</string>
+ <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Se ha terminado de cambiar el orden de los widgets."</string>
+ <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Widget <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> eliminado"</string>
+ <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Ampliar área de desbloqueo"</string>
+ <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Desbloqueo deslizando el dedo"</string>
+ <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Desbloqueo por patrón"</string>
+ <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Desbloqueo facial"</string>
+ <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Desbloqueo por PIN"</string>
+ <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Desbloqueo por contraseña"</string>
+ <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Área de patrón"</string>
+ <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Área para deslizar"</string>
+ <!-- no translation found for keyguard_accessibility_transport_prev_description (1337286538318543555) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_next_description (7073928300444909320) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_pause_description (8455979545295224302) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_play_description (8146417789511154044) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_stop_description (7656358482980912216) -->
+ <skip />
+ <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+ <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+ <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+ <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Cancelar"</string>
+ <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Eliminar"</string>
+ <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Listo"</string>
+ <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Cambio de modo"</string>
+ <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Mayús"</string>
+ <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Intro"</string>
+ <string name="description_target_unlock" msgid="2228524900439801453">"Desbloquear"</string>
+ <string name="description_target_camera" msgid="969071997552486814">"Cámara"</string>
+ <string name="description_target_silent" msgid="893551287746522182">"Silencio"</string>
+ <string name="description_target_soundon" msgid="30052466675500172">"Sonido activado"</string>
+ <string name="description_target_search" msgid="3091587249776033139">"Buscar"</string>
+ <string name="description_direction_up" msgid="7169032478259485180">"Desliza el dedo hacia arriba para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_down" msgid="5087739728639014595">"Desliza el dedo hacia abajo para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_left" msgid="7207478719805562165">"Desliza el dedo hacia la izquierda para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_right" msgid="8034433242579600980">"Desliza el dedo hacia la derecha para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="user_switched" msgid="3768006783166984410">"Usuario actual: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="kg_emergency_call_label" msgid="684946192523830531">"Llamada de emergencia"</string>
+ <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"¿Has olvidado el patrón?"</string>
+ <string name="kg_wrong_pattern" msgid="1850806070801358830">"El patrón es incorrecto."</string>
+ <string name="kg_wrong_password" msgid="2333281762128113157">"Contraseña incorrecta"</string>
+ <string name="kg_wrong_pin" msgid="1131306510833563801">"PIN incorrecto"</string>
+ <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Inténtalo de nuevo en <xliff:g id="NUMBER">%d</xliff:g> segundos."</string>
+ <string name="kg_pattern_instructions" msgid="398978611683075868">"Dibuja tu patrón de desbloqueo."</string>
+ <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Introduce el PIN de la tarjeta SIM."</string>
+ <string name="kg_pin_instructions" msgid="2377242233495111557">"Introduce el PIN."</string>
+ <string name="kg_password_instructions" msgid="5753646556186936819">"Escribe tu contraseña."</string>
+ <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"La tarjeta SIM está inhabilitada. Para continuar, introduce el código PUK. Si quieres obtener más información, ponte en contacto con el operador"</string>
+ <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Introduce el código PIN deseado"</string>
+ <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Confirma el código PIN"</string>
+ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Desbloqueando tarjeta SIM…"</string>
+ <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Código PIN incorrecto"</string>
+ <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Introduce un código PIN con una longitud comprendida entre cuatro y ocho dígitos."</string>
+ <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"El código PUK debe tener ocho números como mínimo."</string>
+ <string name="kg_invalid_puk" msgid="3638289409676051243">"Vuelve a introducir el código PUK correcto. Si introduces un código incorrecto varias veces, se inhabilitará la tarjeta SIM."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"Los códigos PIN no coinciden."</string>
+ <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Demasiados intentos incorrectos de crear el patrón"</string>
+ <string name="kg_login_instructions" msgid="1100551261265506448">"Para desbloquear el teléfono, inicia sesión con tu cuenta de Google."</string>
+ <string name="kg_login_username_hint" msgid="5718534272070920364">"Nombre de usuario (correo electrónico)"</string>
+ <string name="kg_login_password_hint" msgid="9057289103827298549">"Contraseña"</string>
+ <string name="kg_login_submit_button" msgid="5355904582674054702">"Iniciar sesión"</string>
+ <string name="kg_login_invalid_input" msgid="5754664119319872197">"El nombre de usuario o la contraseña no son válidos."</string>
+ <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Si has olvidado tu nombre de usuario o tu contraseña,"\n"accede a la página "<b>"google.com/accounts/recovery"</b>"."</string>
+ <string name="kg_login_checking_password" msgid="1052685197710252395">"Comprobando cuenta…"</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Has introducido un código PIN incorrecto <xliff:g id="NUMBER_0">%d</xliff:g> veces. "\n\n"Inténtalo de nuevo en <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
+ <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Has introducido una contraseña incorrecta <xliff:g id="NUMBER_0">%d</xliff:g> veces. "\n\n"Inténtalo de nuevo en <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
+ <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Has fallado <xliff:g id="NUMBER_0">%d</xliff:g> veces al dibujar tu patrón de desbloqueo. "\n\n"Inténtalo de nuevo en <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Has intentado desbloquear el tablet <xliff:g id="NUMBER_0">%d</xliff:g> veces, pero no lo has conseguido. Si fallas otras <xliff:g id="NUMBER_1">%d</xliff:g> veces, se restablecerán los datos de fábrica y se perderán todos los datos del usuario."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Has intentado desbloquear el teléfono <xliff:g id="NUMBER_0">%d</xliff:g> veces, pero no lo has conseguido. Si fallas otras <xliff:g id="NUMBER_1">%d</xliff:g> veces, se restablecerán los datos de fábrica y se perderán todos los datos del usuario."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Has intentado desbloquear el tablet <xliff:g id="NUMBER">%d</xliff:g> veces, pero no lo has conseguido. Se restablecerán los datos de fábrica del dispositivo."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Has intentado desbloquear el teléfono <xliff:g id="NUMBER">%d</xliff:g> veces, pero no lo has conseguido. Se restablecerán los datos de fábrica del dispositivo."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Has fallado <xliff:g id="NUMBER_0">%d</xliff:g> veces al dibujar el patrón de desbloqueo. Si fallas otras <xliff:g id="NUMBER_1">%d</xliff:g> veces, deberás usar una cuenta de correo electrónico para desbloquear el tablet."\n\n" Inténtalo de nuevo en <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Has fallado <xliff:g id="NUMBER_0">%d</xliff:g> veces al dibujar el patrón de desbloqueo. Si fallas otras <xliff:g id="NUMBER_1">%d</xliff:g> veces, deberás usar una cuenta de correo electrónico para desbloquear el teléfono."\n\n" Inténtalo de nuevo en <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
+ <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
+ <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Eliminar"</string>
+ <!-- no translation found for keyguard_transport_prev_description (8229108430245669854) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_next_description (4299258300283778305) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_pause_description (5093073338238310224) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_play_description (2924628863741150956) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_stop_description (3084179324810575787) -->
+ <skip />
+ <!-- no translation found for keyguard_carrier_default (8700650403054042153) -->
+ <skip />
+</resources>
diff --git a/packages/Keyguard/res/values-et/strings.xml b/packages/Keyguard/res/values-et/strings.xml
new file mode 100644
index 0000000..c83b55c
--- /dev/null
+++ b/packages/Keyguard/res/values-et/strings.xml
@@ -0,0 +1,164 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/* //device/apps/common/assets/res/any/strings.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:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Sisestage PIN-kood"</string>
+ <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Sisestage PUK-kood ja uus PIN-kood"</string>
+ <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK-kood"</string>
+ <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Uus PIN-kood"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Puudutage parooli sisestamiseks"</font></string>
+ <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Avamiseks sisestage parool"</string>
+ <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Avamiseks sisestage PIN-kood"</string>
+ <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Vale PIN-kood."</string>
+ <string name="keyguard_label_text" msgid="861796461028298424">"Avamiseks vajutage menüüklahvi, seejärel klahvi 0."</string>
+ <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Maksimaalne teenusega Face Unlock avamise katsete arv on ületatud"</string>
+ <!-- no translation found for keyguard_charged (3272223906073492454) -->
+ <skip />
+ <!-- no translation found for keyguard_plugged_in (8117572000639998388) -->
+ <skip />
+ <!-- no translation found for keyguard_low_battery (8143808018719173859) -->
+ <skip />
+ <!-- no translation found for keyguard_instructions_when_pattern_disabled (1332288268600329841) -->
+ <skip />
+ <!-- no translation found for keyguard_network_locked_message (9169717779058037168) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message_short (494980561304211931) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (1445849005909260039) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (3481110395508637643) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions (5210891509995942250) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions_long (5968985489463870358) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_message_short (8340813989586622356) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_instructions (5892940909699723544) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_locked_message (6875773413306380902) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_puk_locked_message (3747232467471801633) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_unlock_progress_dialog_message (7975221805033614426) -->
+ <skip />
+ <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Vidin %2$d/%3$d."</string>
+ <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Vidina lisamine."</string>
+ <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Tühi"</string>
+ <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Avamisala on laiendatud."</string>
+ <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Avamisala on ahendatud."</string>
+ <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"Vidin <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>."</string>
+ <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"Kasutaja valija"</string>
+ <string name="keyguard_accessibility_status" msgid="8008264603935930611">"Olek"</string>
+ <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"Kaamera"</string>
+ <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Meedia juhtnupud"</string>
+ <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Vidina ümberkorraldamine algas."</string>
+ <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Vidina ümberkorraldamine lõppes."</string>
+ <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Vidin <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> on kustutatud."</string>
+ <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Avamisala laiendamine."</string>
+ <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Lohistamisega avamine."</string>
+ <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Mustriga avamine."</string>
+ <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Näoga avamine."</string>
+ <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"PIN-koodiga avamine."</string>
+ <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Parooliga avamine."</string>
+ <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Mustri ala."</string>
+ <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Lohistamisala."</string>
+ <!-- no translation found for keyguard_accessibility_transport_prev_description (1337286538318543555) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_next_description (7073928300444909320) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_pause_description (8455979545295224302) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_play_description (8146417789511154044) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_stop_description (7656358482980912216) -->
+ <skip />
+ <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+ <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+ <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+ <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Tühista"</string>
+ <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Kustuta"</string>
+ <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Valmis"</string>
+ <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Režiimi muutmine"</string>
+ <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Tõstuklahv"</string>
+ <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Sisestusklahv"</string>
+ <string name="description_target_unlock" msgid="2228524900439801453">"Luku avamine"</string>
+ <string name="description_target_camera" msgid="969071997552486814">"Kaamera"</string>
+ <string name="description_target_silent" msgid="893551287746522182">"Hääletu"</string>
+ <string name="description_target_soundon" msgid="30052466675500172">"Heli on sees"</string>
+ <string name="description_target_search" msgid="3091587249776033139">"Otsing"</string>
+ <string name="description_direction_up" msgid="7169032478259485180">"Lohistage üles: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_down" msgid="5087739728639014595">"Lohistage alla: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_left" msgid="7207478719805562165">"Lohistage vasakule: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_right" msgid="8034433242579600980">"Lohistage paremale: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="user_switched" msgid="3768006783166984410">"Praegune kasutaja <xliff:g id="NAME">%1$s</xliff:g>."</string>
+ <string name="kg_emergency_call_label" msgid="684946192523830531">"Hädaabikõne"</string>
+ <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Unustasin mustri"</string>
+ <string name="kg_wrong_pattern" msgid="1850806070801358830">"Vale muster"</string>
+ <string name="kg_wrong_password" msgid="2333281762128113157">"Vale parool"</string>
+ <string name="kg_wrong_pin" msgid="1131306510833563801">"Vale PIN-kood"</string>
+ <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Proovige uuesti <xliff:g id="NUMBER">%d</xliff:g> sekundi pärast."</string>
+ <string name="kg_pattern_instructions" msgid="398978611683075868">"Joonistage oma muster"</string>
+ <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Sisestage SIM-i PIN-kood"</string>
+ <string name="kg_pin_instructions" msgid="2377242233495111557">"Sisestage PIN-kood"</string>
+ <string name="kg_password_instructions" msgid="5753646556186936819">"Sisestage parool"</string>
+ <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"SIM on nüüd keelatud. Jätkamiseks sisestage PUK-kood. Üksikasju küsige operaatorilt."</string>
+ <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Sisestage soovitud PIN-kood"</string>
+ <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Kinnitage soovitud PIN-kood"</string>
+ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"SIM-kaardi avamine ..."</string>
+ <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Vale PIN-kood."</string>
+ <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Sisestage 4–8-numbriline PIN-kood."</string>
+ <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK-koodi pikkus peab olema vähemalt 8 numbrit."</string>
+ <string name="kg_invalid_puk" msgid="3638289409676051243">"Sisestage uuesti õige PUK-kood. Korduvkatsete korral keelatakse SIM jäädavalt."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN-koodid ei ole vastavuses"</string>
+ <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Liiga palju mustrikatseid"</string>
+ <string name="kg_login_instructions" msgid="1100551261265506448">"Avamiseks logige sisse oma Google\'i kontoga."</string>
+ <string name="kg_login_username_hint" msgid="5718534272070920364">"Kasutajanimi (e-post)"</string>
+ <string name="kg_login_password_hint" msgid="9057289103827298549">"Parool"</string>
+ <string name="kg_login_submit_button" msgid="5355904582674054702">"Logi sisse"</string>
+ <string name="kg_login_invalid_input" msgid="5754664119319872197">"Vale kasutajanimi või parool."</string>
+ <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Kas unustasite kasutajanime või parooli?"\n"Külastage aadressi "<b>"google.com/accounts/recovery"</b>"."</string>
+ <string name="kg_login_checking_password" msgid="1052685197710252395">"Konto kontrollimine ..."</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Olete PIN-koodi <xliff:g id="NUMBER_0">%d</xliff:g> korda valesti sisestanud."\n\n"Proovige <xliff:g id="NUMBER_1">%d</xliff:g> sekundi pärast uuesti."</string>
+ <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Olete parooli <xliff:g id="NUMBER_0">%d</xliff:g> korda valesti sisestanud. "\n\n"Proovige uuesti <xliff:g id="NUMBER_1">%d</xliff:g> sekundi pärast."</string>
+ <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Joonistasite oma avamismustri <xliff:g id="NUMBER_0">%d</xliff:g> korda valesti."\n\n"Proovige <xliff:g id="NUMBER_1">%d</xliff:g> sekundi pärast uuesti."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Olete üritanud <xliff:g id="NUMBER_0">%d</xliff:g> korda tahvelarvutit valesti avada. Pärast veel <xliff:g id="NUMBER_1">%d</xliff:g> ebaõnnestunud katset lähtestatakse tahvelarvuti tehase vaikeseadetele ja kõik kasutajaandmed lähevad kaotsi."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Olete üritanud <xliff:g id="NUMBER_0">%d</xliff:g> korda telefoni valesti avada. Pärast veel <xliff:g id="NUMBER_1">%d</xliff:g> ebaõnnestunud katset lähtestatakse telefon tehase vaikeseadetele ja kõik kasutajaandmed lähevad kaotsi."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Olete püüdnud tahvelarvutit <xliff:g id="NUMBER">%d</xliff:g> korda valesti avada. Tahvelarvuti lähtestatakse nüüd tehase vaikeseadetele."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Olete püüdnud telefoni <xliff:g id="NUMBER">%d</xliff:g> korda valesti avada. Telefon lähtestatakse nüüd tehase vaikeseadetele."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Joonistasite oma avamismustri <xliff:g id="NUMBER_0">%d</xliff:g> korda valesti. Pärast veel <xliff:g id="NUMBER_1">%d</xliff:g> ebaõnnestunud katset palutakse teil tahvelarvuti avada meilikontoga."\n\n" Proovige uuesti <xliff:g id="NUMBER_2">%d</xliff:g> sekundi pärast."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Joonistasite oma avamismustri <xliff:g id="NUMBER_0">%d</xliff:g> korda valesti. Pärast veel <xliff:g id="NUMBER_1">%d</xliff:g> ebaõnnestunud katset palutakse teil telefon avada meilikontoga."\n\n" Proovige uuesti <xliff:g id="NUMBER_2">%d</xliff:g> sekundi pärast."</string>
+ <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
+ <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Eemalda"</string>
+ <!-- no translation found for keyguard_transport_prev_description (8229108430245669854) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_next_description (4299258300283778305) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_pause_description (5093073338238310224) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_play_description (2924628863741150956) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_stop_description (3084179324810575787) -->
+ <skip />
+ <!-- no translation found for keyguard_carrier_default (8700650403054042153) -->
+ <skip />
+</resources>
diff --git a/packages/Keyguard/res/values-fa/strings.xml b/packages/Keyguard/res/values-fa/strings.xml
new file mode 100644
index 0000000..f0b83c1
--- /dev/null
+++ b/packages/Keyguard/res/values-fa/strings.xml
@@ -0,0 +1,164 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/* //device/apps/common/assets/res/any/strings.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:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"پین کد را وارد کنید"</string>
+ <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"PUK و پین کد جدید را تایپ کنید"</string>
+ <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"کد PUK"</string>
+ <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"پین کد جدید"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"برای تایپ گذرواژه لمس کنید"</font></string>
+ <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"برای بازکردن قفل، گذرواژه را وارد کنید"</string>
+ <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"برای بازکردن قفل، پین را تایپ کنید"</string>
+ <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"پین کد اشتباه است."</string>
+ <string name="keyguard_label_text" msgid="861796461028298424">"برای بازگشایی قفل، منو را فشار دهید و سپس 0 را فشار دهید."</string>
+ <string name="faceunlock_multiple_failures" msgid="754137583022792429">"دفعات تلاش برای Face Unlock از حداکثر مجاز بیشتر شد"</string>
+ <!-- no translation found for keyguard_charged (3272223906073492454) -->
+ <skip />
+ <!-- no translation found for keyguard_plugged_in (8117572000639998388) -->
+ <skip />
+ <!-- no translation found for keyguard_low_battery (8143808018719173859) -->
+ <skip />
+ <!-- no translation found for keyguard_instructions_when_pattern_disabled (1332288268600329841) -->
+ <skip />
+ <!-- no translation found for keyguard_network_locked_message (9169717779058037168) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message_short (494980561304211931) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (1445849005909260039) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (3481110395508637643) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions (5210891509995942250) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions_long (5968985489463870358) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_message_short (8340813989586622356) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_instructions (5892940909699723544) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_locked_message (6875773413306380902) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_puk_locked_message (3747232467471801633) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_unlock_progress_dialog_message (7975221805033614426) -->
+ <skip />
+ <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. ابزارک %2$d از %3$d."</string>
+ <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"ابزارک اضافه کنید."</string>
+ <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"خالی"</string>
+ <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"منطقه بازگشایی گسترده شد."</string>
+ <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"منطقه بازگشایی کوچک شد."</string>
+ <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"ابزارک <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>."</string>
+ <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"انتخابگر کاربر"</string>
+ <string name="keyguard_accessibility_status" msgid="8008264603935930611">"وضعیت"</string>
+ <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"دوربین"</string>
+ <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"کنترل‌های رسانه"</string>
+ <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"مرتب سازی مجدد ابزارک آغاز شد."</string>
+ <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"مرتب‌سازی مجدد ابزارک به پایان رسید."</string>
+ <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"ابزارک <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> حذف شد.‍"</string>
+ <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"گسترده کردن منطقه بازگشایی شده."</string>
+ <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"باز کردن قفل با کشیدن انگشت روی صفحه."</string>
+ <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"باز کردن قفل با الگو."</string>
+ <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"باز کردن قفل با چهره."</string>
+ <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"باز کردن قفل با پین."</string>
+ <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"باز کردن قفل با گذرواژه."</string>
+ <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"ناحیه الگو."</string>
+ <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"ناحیه کشیدن انگشت روی صفحه."</string>
+ <!-- no translation found for keyguard_accessibility_transport_prev_description (1337286538318543555) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_next_description (7073928300444909320) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_pause_description (8455979545295224302) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_play_description (8146417789511154044) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_stop_description (7656358482980912216) -->
+ <skip />
+ <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+ <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+ <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+ <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"لغو"</string>
+ <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Delete"</string>
+ <string name="keyboardview_keycode_done" msgid="1992571118466679775">"انجام شد"</string>
+ <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"تغییر حالت"</string>
+ <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
+ <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
+ <string name="description_target_unlock" msgid="2228524900439801453">"بازکردن قفل"</string>
+ <string name="description_target_camera" msgid="969071997552486814">"دوربین"</string>
+ <string name="description_target_silent" msgid="893551287746522182">"ساکت"</string>
+ <string name="description_target_soundon" msgid="30052466675500172">"صدا روشن"</string>
+ <string name="description_target_search" msgid="3091587249776033139">"جستجو"</string>
+ <string name="description_direction_up" msgid="7169032478259485180">"لغزاندن به بالا برای <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_down" msgid="5087739728639014595">"لغزاندن به پایین برای <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_left" msgid="7207478719805562165">"لغزاندن به چپ برای <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_right" msgid="8034433242579600980">"لغزاندن به راست برای <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="user_switched" msgid="3768006783166984410">"کاربر کنونی <xliff:g id="NAME">%1$s</xliff:g>."</string>
+ <string name="kg_emergency_call_label" msgid="684946192523830531">"تماس اضطراری"</string>
+ <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"الگو را فراموش کرده‌اید"</string>
+ <string name="kg_wrong_pattern" msgid="1850806070801358830">"الگوی اشتباه"</string>
+ <string name="kg_wrong_password" msgid="2333281762128113157">"گذرواژه اشتباه"</string>
+ <string name="kg_wrong_pin" msgid="1131306510833563801">"پین اشتباه"</string>
+ <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"پس از <xliff:g id="NUMBER">%d</xliff:g> ثانیه دوباره امتحان کنید."</string>
+ <string name="kg_pattern_instructions" msgid="398978611683075868">"الگوی خود را رسم کنید"</string>
+ <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"پین سیم کارت را وارد کنید"</string>
+ <string name="kg_pin_instructions" msgid="2377242233495111557">"پین را وارد کنید"</string>
+ <string name="kg_password_instructions" msgid="5753646556186936819">"گذرواژه را وارد کنید"</string>
+ <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"اکنون سیم کارت غیرفعال است. پین کد را برای ادامه وارد کنید. برای جزئیات با شرکت مخابراتی خود تماس بگیرید."</string>
+ <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"پین کد دلخواه را وارد کنید"</string>
+ <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"تأیید پین کد دلخواه"</string>
+ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"بازگشایی قفل سیم کارت..."</string>
+ <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"پین کد اشتباه است."</string>
+ <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"یک پین ۴ تا ۸ رقمی را تایپ کنید."</string>
+ <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"پین کد باید ۸ عدد یا بیشتر باشد."</string>
+ <string name="kg_invalid_puk" msgid="3638289409676051243">"پین کد صحیح را دوباره وارد کنید. تلاش‌های مکرر به‌طور دائم سیم کارت را غیرفعال خواهد کرد."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"پین کدها منطبق نیستند"</string>
+ <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"تلاش‎های زیادی برای کشیدن الگو صورت گرفته است"</string>
+ <string name="kg_login_instructions" msgid="1100551261265506448">"برای بازگشایی قفل، با حساب Google خود وارد سیستم شوید."</string>
+ <string name="kg_login_username_hint" msgid="5718534272070920364">"نام کاربری (ایمیل)"</string>
+ <string name="kg_login_password_hint" msgid="9057289103827298549">"گذرواژه"</string>
+ <string name="kg_login_submit_button" msgid="5355904582674054702">"ورود به سیستم"</string>
+ <string name="kg_login_invalid_input" msgid="5754664119319872197">"نام کاربری یا گذرواژه نامعتبر."</string>
+ <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"نام کاربری یا گذرواژه خود را فراموش کردید؟"\n"از "<b>"google.com/accounts/recovery"</b>" بازدید کنید."</string>
+ <string name="kg_login_checking_password" msgid="1052685197710252395">"درحال بررسی حساب..."</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"پین خود را <xliff:g id="NUMBER_0">%d</xliff:g> بار اشتباه تایپ کردید. "\n\n"پس از <xliff:g id="NUMBER_1">%d</xliff:g> ثانیه دوباره امتحان کنید."</string>
+ <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"گذرواژه خود را <xliff:g id="NUMBER_0">%d</xliff:g> بار اشتباه تایپ کردید. "\n\n"پس از <xliff:g id="NUMBER_1">%d</xliff:g> ثانیه دوباره امتحان کنید."</string>
+ <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"الگوی بازگشایی قفل خود را <xliff:g id="NUMBER_0">%d</xliff:g> بار اشتباه کشیدید. "\n\n"لطفاً پس از <xliff:g id="NUMBER_1">%d</xliff:g> ثانیه دوباره امتحان کنید."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"شما به اشتباه <xliff:g id="NUMBER_0">%d</xliff:g> بار اقدام به باز کردن قفل رایانه لوحی کرده‌اید. پس از <xliff:g id="NUMBER_1">%d</xliff:g> تلاش ناموفق دیگر، رایانهٔ لوحی به پیش‌فرض کارخانه بازنشانی می‌شود و تمام داده‌های کاربر از دست خواهد رفت."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"شما به اشتباه <xliff:g id="NUMBER_0">%d</xliff:g> بار اقدام به باز کردن قفل تلفن کرده‌اید. پس از <xliff:g id="NUMBER_1">%d</xliff:g> تلاش ناموفق دیگر، تلفن به پیش‌فرض کارخانه بازنشانی می‌شود و تمام داده‌های کاربر از دست خواهد رفت."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"شما به اشتباه <xliff:g id="NUMBER">%d</xliff:g> بار اقدام به باز کردن قفل رایانه لوحی کرده‌اید. رایانه لوحی اکنون به پیش‌فرض کارخانه بازنشانی می‌شود."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"شما به اشتباه <xliff:g id="NUMBER">%d</xliff:g> بار اقدام به باز کردن قفل تلفن کرده‌اید. این تلفن اکنون به پیش‌فرض کارخانه بازنشانی می‌شود."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"شما الگوی بازگشایی قفل خود را <xliff:g id="NUMBER_0">%d</xliff:g> بار اشتباه کشیده‎اید. بعد از <xliff:g id="NUMBER_1">%d</xliff:g> تلاش ناموفق، از شما خواسته می‎شود که با استفاده از یک حساب ایمیل قفل رایانه لوحی خود را باز کنید."\n\n" لطفاً پس از <xliff:g id="NUMBER_2">%d</xliff:g> ثانیه دوباره امتحان کنید."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"شما الگوی بازگشایی قفل خود را <xliff:g id="NUMBER_0">%d</xliff:g> بار اشتباه کشیده‌اید. پس از <xliff:g id="NUMBER_1">%d</xliff:g> تلاش ناموفق، از شما خواسته می‎شود که با استفاده از یک حساب ایمیل قفل تلفن خود را باز کنید."\n\n" لطفاً پس از <xliff:g id="NUMBER_2">%d</xliff:g> ثانیه دوباره امتحان کنید."</string>
+ <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
+ <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"حذف"</string>
+ <!-- no translation found for keyguard_transport_prev_description (8229108430245669854) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_next_description (4299258300283778305) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_pause_description (5093073338238310224) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_play_description (2924628863741150956) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_stop_description (3084179324810575787) -->
+ <skip />
+ <!-- no translation found for keyguard_carrier_default (8700650403054042153) -->
+ <skip />
+</resources>
diff --git a/packages/Keyguard/res/values-fi/strings.xml b/packages/Keyguard/res/values-fi/strings.xml
new file mode 100644
index 0000000..15eac4b
--- /dev/null
+++ b/packages/Keyguard/res/values-fi/strings.xml
@@ -0,0 +1,164 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/* //device/apps/common/assets/res/any/strings.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:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Anna PIN-koodi"</string>
+ <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Anna PUK-koodi ja uusi PIN-koodi"</string>
+ <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK-koodi"</string>
+ <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Uusi PIN-koodi"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Kosketa ja anna salasana"</font></string>
+ <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Poista lukitus antamalla salasana"</string>
+ <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Poista lukitus antamalla PIN-koodi"</string>
+ <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"PIN-koodi väärin."</string>
+ <string name="keyguard_label_text" msgid="861796461028298424">"Poista lukitus painamalla Valikko-painiketta ja 0-näppäintä."</string>
+ <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Face Unlock -yrityksiä tehty suurin sallittu määrä."</string>
+ <!-- no translation found for keyguard_charged (3272223906073492454) -->
+ <skip />
+ <!-- no translation found for keyguard_plugged_in (8117572000639998388) -->
+ <skip />
+ <!-- no translation found for keyguard_low_battery (8143808018719173859) -->
+ <skip />
+ <!-- no translation found for keyguard_instructions_when_pattern_disabled (1332288268600329841) -->
+ <skip />
+ <!-- no translation found for keyguard_network_locked_message (9169717779058037168) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message_short (494980561304211931) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (1445849005909260039) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (3481110395508637643) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions (5210891509995942250) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions_long (5968985489463870358) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_message_short (8340813989586622356) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_instructions (5892940909699723544) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_locked_message (6875773413306380902) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_puk_locked_message (3747232467471801633) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_unlock_progress_dialog_message (7975221805033614426) -->
+ <skip />
+ <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d/%3$d."</string>
+ <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Lisää widget."</string>
+ <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Tyhjä"</string>
+ <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Lukituksen poiston alue laajennettu."</string>
+ <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Lukituksen poiston alue tiivistetty."</string>
+ <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g>-widget."</string>
+ <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"Käyttäjävalitsin"</string>
+ <string name="keyguard_accessibility_status" msgid="8008264603935930611">"Tila"</string>
+ <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"Kamera"</string>
+ <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Mediaohjaimet"</string>
+ <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Widgetien järjestely aloitettu."</string>
+ <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Widgetien järjestely päättyi."</string>
+ <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Widget <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> poistettu."</string>
+ <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Laajenna lukituksen poiston aluetta."</string>
+ <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Lukituksen poisto liu\'uttamalla."</string>
+ <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Lukituksen poisto salasanalla."</string>
+ <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Face Unlock"</string>
+ <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Lukituksen poisto PIN-koodilla."</string>
+ <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Lukituksen poisto salasanalla."</string>
+ <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Kuvioalue."</string>
+ <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Liu\'utusalue."</string>
+ <!-- no translation found for keyguard_accessibility_transport_prev_description (1337286538318543555) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_next_description (7073928300444909320) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_pause_description (8455979545295224302) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_play_description (8146417789511154044) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_stop_description (7656358482980912216) -->
+ <skip />
+ <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+ <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+ <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+ <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Peruuta"</string>
+ <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Poista"</string>
+ <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Valmis"</string>
+ <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Tilan muutos"</string>
+ <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
+ <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
+ <string name="description_target_unlock" msgid="2228524900439801453">"Poista lukitus"</string>
+ <string name="description_target_camera" msgid="969071997552486814">"Kamera"</string>
+ <string name="description_target_silent" msgid="893551287746522182">"Äänetön"</string>
+ <string name="description_target_soundon" msgid="30052466675500172">"Ääni käytössä"</string>
+ <string name="description_target_search" msgid="3091587249776033139">"Haku"</string>
+ <string name="description_direction_up" msgid="7169032478259485180">"Liu\'uta ylös ja <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_down" msgid="5087739728639014595">"Liu\'uta alas ja <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_left" msgid="7207478719805562165">"Liu\'uta vasemmalle ja <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_right" msgid="8034433242579600980">"Liu\'uta oikealle ja <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="user_switched" msgid="3768006783166984410">"Nykyinen käyttäjä: <xliff:g id="NAME">%1$s</xliff:g>."</string>
+ <string name="kg_emergency_call_label" msgid="684946192523830531">"Hätäpuhelu"</string>
+ <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Unohtunut kuvio"</string>
+ <string name="kg_wrong_pattern" msgid="1850806070801358830">"Väärä kuvio"</string>
+ <string name="kg_wrong_password" msgid="2333281762128113157">"Väärä salasana"</string>
+ <string name="kg_wrong_pin" msgid="1131306510833563801">"Väärä PIN-koodi"</string>
+ <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Yritä uudelleen <xliff:g id="NUMBER">%d</xliff:g> sekunnin kuluttua."</string>
+ <string name="kg_pattern_instructions" msgid="398978611683075868">"Piirrä kuvio"</string>
+ <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Anna SIM-kortin PIN-koodi"</string>
+ <string name="kg_pin_instructions" msgid="2377242233495111557">"Anna PIN-koodi"</string>
+ <string name="kg_password_instructions" msgid="5753646556186936819">"Anna salasana"</string>
+ <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"SIM-kortti on nyt poistettu käytöstä. Jatka antamalla PUK-koodi. Saat lisätietoja ottamalla yhteyttä operaattoriin."</string>
+ <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Anna haluamasi PIN-koodi"</string>
+ <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Vahvista haluamasi PIN-koodi"</string>
+ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"SIM-kortin lukitusta poistetaan…"</string>
+ <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Virheellinen PIN-koodi."</string>
+ <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Anna 4–8-numeroinen PIN-koodi."</string>
+ <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK-koodissa tulee olla vähintään 8 numeroa."</string>
+ <string name="kg_invalid_puk" msgid="3638289409676051243">"Anna uudelleen oikea PUK-koodi. Jos teet liian monta yritystä, SIM-kortti poistetaan käytöstä pysyvästi."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN-koodit eivät täsmää"</string>
+ <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Liikaa kuvionpiirtoyrityksiä"</string>
+ <string name="kg_login_instructions" msgid="1100551261265506448">"Poista lukitus kirjautumalla sisään Google-tililläsi."</string>
+ <string name="kg_login_username_hint" msgid="5718534272070920364">"Käyttäjänimi (sähköposti)"</string>
+ <string name="kg_login_password_hint" msgid="9057289103827298549">"Salasana"</string>
+ <string name="kg_login_submit_button" msgid="5355904582674054702">"Kirjaudu sisään"</string>
+ <string name="kg_login_invalid_input" msgid="5754664119319872197">"Virheellinen käyttäjänimi tai salasana."</string>
+ <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Unohditko käyttäjänimesi tai salasanasi?"\n"Käy osoitteessa "<b>"google.com/accounts/recovery"</b>"."</string>
+ <string name="kg_login_checking_password" msgid="1052685197710252395">"Tarkistetaan tiliä..."</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Olet kirjoittanut PIN-koodin väärin <xliff:g id="NUMBER_0">%d</xliff:g> kertaa. "\n\n"Yritä uudelleen <xliff:g id="NUMBER_1">%d</xliff:g> sekunnin kuluttua."</string>
+ <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Olet kirjoittanut salasanan väärin <xliff:g id="NUMBER_0">%d</xliff:g> kertaa. "\n\n"Yritä uudelleen <xliff:g id="NUMBER_1">%d</xliff:g> sekunnin kuluttua."</string>
+ <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Olet piirtänyt lukituksenpoistokuvion väärin <xliff:g id="NUMBER_0">%d</xliff:g> kertaa. "\n\n"Yritä uudelleen <xliff:g id="NUMBER_1">%d</xliff:g> sekunnin kuluttua."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Tablet-laitteen lukituksen poisto epäonnistui <xliff:g id="NUMBER_0">%d</xliff:g> kertaa. Jos teet vielä <xliff:g id="NUMBER_1">%d</xliff:g> epäonnistunutta yritystä, tablet-laitteeseen palautetaan tehdasasetukset ja kaikki käyttäjätiedot häviävät."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Puhelimen lukituksen poisto epäonnistui <xliff:g id="NUMBER_0">%d</xliff:g> kertaa. Jos teet vielä <xliff:g id="NUMBER_1">%d</xliff:g> epäonnistunutta yritystä, puhelimeen palautetaan tehdasasetukset ja kaikki käyttäjätiedot häviävät."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Tablet-laitteen lukituksen poisto epäonnistui <xliff:g id="NUMBER">%d</xliff:g> kertaa. Laitteeseen palautetaan nyt tehdasasetukset."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Puhelimen lukituksen poisto epäonnistui <xliff:g id="NUMBER">%d</xliff:g> kertaa. Puhelimeen palautetaan nyt tehdasasetukset."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Piirsit lukituksenpoistokuvion väärin <xliff:g id="NUMBER_0">%d</xliff:g> kertaa. Jos piirrät kuvion väärin vielä <xliff:g id="NUMBER_1">%d</xliff:g> kertaa, sinua pyydetään poistamaan tablet-laitteesi lukitus sähköpostitilin avulla."\n\n" Yritä uudelleen <xliff:g id="NUMBER_2">%d</xliff:g> sekunnin kuluttua."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Piirsit lukituksenpoistokuvion väärin <xliff:g id="NUMBER_0">%d</xliff:g> kertaa. Jos piirrät kuvion väärin vielä <xliff:g id="NUMBER_1">%d</xliff:g> kertaa, sinua pyydetään poistamaan puhelimesi lukitus sähköpostitilin avulla."\n\n" Yritä uudelleen <xliff:g id="NUMBER_2">%d</xliff:g> sekunnin kuluttua."</string>
+ <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" – "</string>
+ <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Poista"</string>
+ <!-- no translation found for keyguard_transport_prev_description (8229108430245669854) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_next_description (4299258300283778305) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_pause_description (5093073338238310224) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_play_description (2924628863741150956) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_stop_description (3084179324810575787) -->
+ <skip />
+ <!-- no translation found for keyguard_carrier_default (8700650403054042153) -->
+ <skip />
+</resources>
diff --git a/packages/Keyguard/res/values-fr/strings.xml b/packages/Keyguard/res/values-fr/strings.xml
new file mode 100644
index 0000000..219ab91
--- /dev/null
+++ b/packages/Keyguard/res/values-fr/strings.xml
@@ -0,0 +1,164 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/* //device/apps/common/assets/res/any/strings.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:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Saisissez le code PIN."</string>
+ <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Saisissez la clé PUK et le nouveau code PIN."</string>
+ <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"Code PUK"</string>
+ <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Nouveau code PIN"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Appuyez pour saisir mot passe"</font></string>
+ <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Saisissez le mot de passe pour déverrouiller le clavier."</string>
+ <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Saisissez le code PIN pour déverrouiller le clavier."</string>
+ <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Le code PIN est erroné."</string>
+ <string name="keyguard_label_text" msgid="861796461028298424">"Pour déverrouiller le clavier, appuyez sur \"Menu\" puis sur 0."</string>
+ <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Nombre maximal autorisé de tentatives Face Unlock atteint."</string>
+ <!-- no translation found for keyguard_charged (3272223906073492454) -->
+ <skip />
+ <!-- no translation found for keyguard_plugged_in (8117572000639998388) -->
+ <skip />
+ <!-- no translation found for keyguard_low_battery (8143808018719173859) -->
+ <skip />
+ <!-- no translation found for keyguard_instructions_when_pattern_disabled (1332288268600329841) -->
+ <skip />
+ <!-- no translation found for keyguard_network_locked_message (9169717779058037168) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message_short (494980561304211931) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (1445849005909260039) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (3481110395508637643) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions (5210891509995942250) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions_long (5968985489463870358) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_message_short (8340813989586622356) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_instructions (5892940909699723544) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_locked_message (6875773413306380902) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_puk_locked_message (3747232467471801633) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_unlock_progress_dialog_message (7975221805033614426) -->
+ <skip />
+ <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d sur %3$d."</string>
+ <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Ajouter un widget"</string>
+ <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Vide"</string>
+ <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Zone de déverrouillage développée."</string>
+ <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Zone de déverrouillage réduite."</string>
+ <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"Widget <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>"</string>
+ <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"Sélecteur d\'utilisateur"</string>
+ <string name="keyguard_accessibility_status" msgid="8008264603935930611">"État"</string>
+ <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"Caméra"</string>
+ <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Commandes multimédias"</string>
+ <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Début de la réorganisation des widgets"</string>
+ <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Réorganisation des widgets terminée."</string>
+ <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Le widget <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> a été supprimé."</string>
+ <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Développer la zone de déverrouillage"</string>
+ <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Déverrouillage en faisant glisser votre doigt sur l\'écran"</string>
+ <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Déverrouillage par schéma"</string>
+ <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Déverrouillage par reconnaissance faciale"</string>
+ <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Déverrouillage par code PIN"</string>
+ <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Déverrouillage par mot de passe"</string>
+ <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Zone du schéma"</string>
+ <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Zone où faire glisser votre doigt sur l\'écran"</string>
+ <!-- no translation found for keyguard_accessibility_transport_prev_description (1337286538318543555) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_next_description (7073928300444909320) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_pause_description (8455979545295224302) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_play_description (8146417789511154044) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_stop_description (7656358482980912216) -->
+ <skip />
+ <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+ <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+ <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+ <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Annuler"</string>
+ <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Supprimer"</string>
+ <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Terminé"</string>
+ <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Changement de mode"</string>
+ <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Maj"</string>
+ <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Entrée"</string>
+ <string name="description_target_unlock" msgid="2228524900439801453">"Déverrouiller"</string>
+ <string name="description_target_camera" msgid="969071997552486814">"Appareil photo"</string>
+ <string name="description_target_silent" msgid="893551287746522182">"Mode silencieux"</string>
+ <string name="description_target_soundon" msgid="30052466675500172">"Son activé"</string>
+ <string name="description_target_search" msgid="3091587249776033139">"Rechercher"</string>
+ <string name="description_direction_up" msgid="7169032478259485180">"Faites glisser vers le haut pour <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_down" msgid="5087739728639014595">"Faites glisser vers le bas pour <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_left" msgid="7207478719805562165">"Faites glisser vers la gauche pour <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_right" msgid="8034433242579600980">"Faites glisser vers la droite pour <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="user_switched" msgid="3768006783166984410">"Utilisateur actuel : <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="kg_emergency_call_label" msgid="684946192523830531">"Appel d\'urgence"</string>
+ <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"J\'ai oublié le schéma"</string>
+ <string name="kg_wrong_pattern" msgid="1850806070801358830">"Schéma incorrect."</string>
+ <string name="kg_wrong_password" msgid="2333281762128113157">"Mot de passe incorrect."</string>
+ <string name="kg_wrong_pin" msgid="1131306510833563801">"Code PIN incorrect."</string>
+ <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Réessayez dans <xliff:g id="NUMBER">%d</xliff:g> secondes."</string>
+ <string name="kg_pattern_instructions" msgid="398978611683075868">"Dessinez votre schéma."</string>
+ <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Saisissez le code PIN de la carte SIM."</string>
+ <string name="kg_pin_instructions" msgid="2377242233495111557">"Saisissez le code PIN."</string>
+ <string name="kg_password_instructions" msgid="5753646556186936819">"Saisissez votre mot de passe."</string>
+ <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"La carte SIM est maintenant désactivée. Saisissez le code PUK pour continuer. Contactez votre opérateur pour en savoir plus."</string>
+ <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Saisir le code PIN souhaité"</string>
+ <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Confirmer le code PIN souhaité"</string>
+ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Déblocage de la carte SIM en cours…"</string>
+ <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Le code PIN est erroné."</string>
+ <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Veuillez saisir un code PIN comprenant entre quatre et huit chiffres."</string>
+ <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"Le code PUK doit contenir au moins 8 chiffres."</string>
+ <string name="kg_invalid_puk" msgid="3638289409676051243">"Veuillez saisir de nouveau le code PUK correct. Des tentatives répétées désactivent définitivement la carte SIM."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"Les codes PIN ne correspondent pas."</string>
+ <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Trop de tentatives."</string>
+ <string name="kg_login_instructions" msgid="1100551261265506448">"Pour déverrouiller le téléphone, veuillez vous connecter avec votre compte Google."</string>
+ <string name="kg_login_username_hint" msgid="5718534272070920364">"Nom d\'utilisateur (e-mail)"</string>
+ <string name="kg_login_password_hint" msgid="9057289103827298549">"Mot de passe"</string>
+ <string name="kg_login_submit_button" msgid="5355904582674054702">"Connexion"</string>
+ <string name="kg_login_invalid_input" msgid="5754664119319872197">"Nom d\'utilisateur ou mot de passe non valide."</string>
+ <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Vous avez oublié votre nom d\'utilisateur ou votre mot de passe ?"\n"Rendez-vous sur la page "<b>"google.com/accounts/recovery"</b>"."</string>
+ <string name="kg_login_checking_password" msgid="1052685197710252395">"Vérification du compte en cours…"</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Vous avez saisi un code PIN incorrect à <xliff:g id="NUMBER_0">%d</xliff:g> reprises. "\n\n"Veuillez réessayer dans <xliff:g id="NUMBER_1">%d</xliff:g> secondes."</string>
+ <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Vous avez saisi un mot de passe incorrect à <xliff:g id="NUMBER_0">%d</xliff:g> reprises. "\n\n"Veuillez réessayer dans <xliff:g id="NUMBER_1">%d</xliff:g> secondes."</string>
+ <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%d</xliff:g> reprises."\n\n"Veuillez réessayer dans <xliff:g id="NUMBER_1">%d</xliff:g> secondes."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Vous avez tenté de déverrouiller la tablette de façon incorrecte à <xliff:g id="NUMBER_0">%d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%d</xliff:g> fois, sa configuration d\'usine sera rétablie, et toutes les données utilisateur seront perdues."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Vous avez tenté de déverrouiller le téléphone de façon incorrecte à <xliff:g id="NUMBER_0">%d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%d</xliff:g> fois, sa configuration d\'usine sera rétablie, et toutes les données utilisateur seront perdues."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Vous avez tenté de déverrouiller la tablette de façon incorrecte à <xliff:g id="NUMBER">%d</xliff:g> reprises. Sa configuration d\'usine va être rétablie."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Vous avez tenté de déverrouiller le téléphone de façon incorrecte à <xliff:g id="NUMBER">%d</xliff:g> reprises. Sa configuration d\'usine va être rétablie."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%d</xliff:g> fois, vous devrez déverrouiller votre tablette à l\'aide d\'un compte de messagerie électronique."\n\n" Veuillez réessayer dans <xliff:g id="NUMBER_2">%d</xliff:g> secondes."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%d</xliff:g> fois, vous devrez déverrouiller votre téléphone à l\'aide d\'un compte de messagerie électronique."\n\n" Veuillez réessayer dans <xliff:g id="NUMBER_2">%d</xliff:g> secondes."</string>
+ <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
+ <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Supprimer"</string>
+ <!-- no translation found for keyguard_transport_prev_description (8229108430245669854) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_next_description (4299258300283778305) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_pause_description (5093073338238310224) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_play_description (2924628863741150956) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_stop_description (3084179324810575787) -->
+ <skip />
+ <!-- no translation found for keyguard_carrier_default (8700650403054042153) -->
+ <skip />
+</resources>
diff --git a/packages/Keyguard/res/values-hi/strings.xml b/packages/Keyguard/res/values-hi/strings.xml
new file mode 100644
index 0000000..39378c7
--- /dev/null
+++ b/packages/Keyguard/res/values-hi/strings.xml
@@ -0,0 +1,164 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/* //device/apps/common/assets/res/any/strings.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:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"पिन कोड लिखें"</string>
+ <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"PUK और नया पिन कोड लिखें"</string>
+ <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK कोड"</string>
+ <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"नया पिन कोड"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"पासवर्ड लिखने के लिए स्पर्श करें"</font></string>
+ <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"अनलॉक करने के लिए पासवर्ड लिखें"</string>
+ <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"अनलॉक करने के लिए पिन लिखें"</string>
+ <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"गलत पिन कोड."</string>
+ <string name="keyguard_label_text" msgid="861796461028298424">"अनलॉक करने के लिए, मेनू दबाएं और फिर 0 दबाएं."</string>
+ <string name="faceunlock_multiple_failures" msgid="754137583022792429">"फेस अनलॉक के अधिकतम प्रयासों की सीमा पार हो गई"</string>
+ <!-- no translation found for keyguard_charged (3272223906073492454) -->
+ <skip />
+ <!-- no translation found for keyguard_plugged_in (8117572000639998388) -->
+ <skip />
+ <!-- no translation found for keyguard_low_battery (8143808018719173859) -->
+ <skip />
+ <!-- no translation found for keyguard_instructions_when_pattern_disabled (1332288268600329841) -->
+ <skip />
+ <!-- no translation found for keyguard_network_locked_message (9169717779058037168) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message_short (494980561304211931) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (1445849005909260039) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (3481110395508637643) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions (5210891509995942250) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions_long (5968985489463870358) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_message_short (8340813989586622356) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_instructions (5892940909699723544) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_locked_message (6875773413306380902) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_puk_locked_message (3747232467471801633) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_unlock_progress_dialog_message (7975221805033614426) -->
+ <skip />
+ <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. %3$d विजेट में से %2$d."</string>
+ <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"विजेट जोड़ें"</string>
+ <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"रिक्त"</string>
+ <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"अनलॉक क्षेत्र को विस्तृत कर दिया गया."</string>
+ <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"अनलॉक क्षेत्र को संक्षिप्त कर दिया गया."</string>
+ <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> विजेट."</string>
+ <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"उपयोगकर्ता चयनकर्ता"</string>
+ <string name="keyguard_accessibility_status" msgid="8008264603935930611">"स्थिति"</string>
+ <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"कैमरा"</string>
+ <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"मीडिया नियंत्रण"</string>
+ <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"विजेट पुनः क्रमित करना प्रारंभ."</string>
+ <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"विजेट पुनः क्रमित करना समाप्त."</string>
+ <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"विजेट <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> को हटा दिया गया."</string>
+ <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"अनलॉक क्षेत्र विस्तृत करें."</string>
+ <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"स्लाइड अनलॉक."</string>
+ <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"प्रतिमान अनलॉक."</string>
+ <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"फेस अनलॉक."</string>
+ <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"पिन अनलॉक."</string>
+ <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"पासवर्ड अनलॉक."</string>
+ <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"प्रतिमान क्षेत्र."</string>
+ <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"स्लाइड क्षेत्र."</string>
+ <!-- no translation found for keyguard_accessibility_transport_prev_description (1337286538318543555) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_next_description (7073928300444909320) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_pause_description (8455979545295224302) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_play_description (8146417789511154044) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_stop_description (7656358482980912216) -->
+ <skip />
+ <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+ <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+ <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+ <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"रद्द करें"</string>
+ <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"हटाएं"</string>
+ <string name="keyboardview_keycode_done" msgid="1992571118466679775">"पूर्ण"</string>
+ <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Mode change"</string>
+ <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
+ <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
+ <string name="description_target_unlock" msgid="2228524900439801453">"अनलॉक करें"</string>
+ <string name="description_target_camera" msgid="969071997552486814">"कैमरा"</string>
+ <string name="description_target_silent" msgid="893551287746522182">"मौन"</string>
+ <string name="description_target_soundon" msgid="30052466675500172">"ध्‍वनि चालू करें"</string>
+ <string name="description_target_search" msgid="3091587249776033139">"खोजें"</string>
+ <string name="description_direction_up" msgid="7169032478259485180">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> के लिए ऊपर स्‍लाइड करें."</string>
+ <string name="description_direction_down" msgid="5087739728639014595">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> के लिए नीचे स्‍लाइड करें."</string>
+ <string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> के लिए बाएं स्‍लाइड करें."</string>
+ <string name="description_direction_right" msgid="8034433242579600980">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> के लिए दाएं स्‍लाइड करें."</string>
+ <string name="user_switched" msgid="3768006783166984410">"वर्तमान उपयोगकर्ता <xliff:g id="NAME">%1$s</xliff:g>."</string>
+ <string name="kg_emergency_call_label" msgid="684946192523830531">"आपातकालीन कॉल"</string>
+ <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"प्रतिमान भूल गए"</string>
+ <string name="kg_wrong_pattern" msgid="1850806070801358830">"गलत प्रतिमान"</string>
+ <string name="kg_wrong_password" msgid="2333281762128113157">"गलत पासवर्ड"</string>
+ <string name="kg_wrong_pin" msgid="1131306510833563801">"गलत PIN"</string>
+ <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"<xliff:g id="NUMBER">%d</xliff:g> सेकंड में पुन: प्रयास करें."</string>
+ <string name="kg_pattern_instructions" msgid="398978611683075868">"अपना प्रतिमान आरेखित करें"</string>
+ <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"सिम PIN डालें"</string>
+ <string name="kg_pin_instructions" msgid="2377242233495111557">"PIN डालें"</string>
+ <string name="kg_password_instructions" msgid="5753646556186936819">"पासवर्ड डालें"</string>
+ <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"सिम अब अक्षम हो गई है. जारी रखने के लिए PUK कोड डालें. विवरण के लिए वाहक से संपर्क करें."</string>
+ <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"इच्छित पिन कोड डालें"</string>
+ <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"इच्छित पिन कोड की पुष्टि करें"</string>
+ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"SIM कार्ड अनलॉक कर रहा है…"</string>
+ <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"गलत PIN कोड."</string>
+ <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"ऐसा PIN लिखें, जो 4 से 8 अंकों का हो."</string>
+ <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK कोड 8 या अधिक संख्या वाला होना चाहिए."</string>
+ <string name="kg_invalid_puk" msgid="3638289409676051243">"सही PUK कोड पुन: डालें. बार-बार प्रयास करने से सिम स्थायी रूप से अक्षम हो जाएगी."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"पिन कोड का मिलान नहीं होता"</string>
+ <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"बहुत अधिक प्रतिमान प्रयास"</string>
+ <string name="kg_login_instructions" msgid="1100551261265506448">"अनलॉक करने के लिए, अपने Google खाते से साइन इन करें."</string>
+ <string name="kg_login_username_hint" msgid="5718534272070920364">"उपयोगकर्ता नाम (ईमेल)"</string>
+ <string name="kg_login_password_hint" msgid="9057289103827298549">"पासवर्ड"</string>
+ <string name="kg_login_submit_button" msgid="5355904582674054702">"साइन इन करें"</string>
+ <string name="kg_login_invalid_input" msgid="5754664119319872197">"अमान्य उपयोगकर्ता नाम या पासवर्ड."</string>
+ <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"अपना उपयोगकर्ता नाम या पासवर्ड भूल गए?"\n" "<b>"google.com/accounts/recovery"</b>" पर जाएं."</string>
+ <string name="kg_login_checking_password" msgid="1052685197710252395">"खाते की जांच की जा रही है…"</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"आप अपना PIN <xliff:g id="NUMBER_0">%d</xliff:g> बार गलत तरीके से लिख चुके हैं. "\n\n" <xliff:g id="NUMBER_1">%d</xliff:g> सेकंड में पुन: प्रयास करें."</string>
+ <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"आप अपना पासवर्ड <xliff:g id="NUMBER_0">%d</xliff:g> बार गलत तरीके से लिख चुके हैं. "\n\n" <xliff:g id="NUMBER_1">%d</xliff:g> सेकंड में पुन: प्रयास करें."</string>
+ <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"आपने अपना अनलॉक प्रतिमान <xliff:g id="NUMBER_0">%d</xliff:g> बार गलत तरीके से आरेखित किया है. "\n\n" <xliff:g id="NUMBER_1">%d</xliff:g> सेकंड में पुन: प्रयास करें."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"आप टेबलेट को अनलॉक करने के लिए <xliff:g id="NUMBER_0">%d</xliff:g> बार गलत तरीके से प्रयास कर चुके हैं. <xliff:g id="NUMBER_1">%d</xliff:g> और असफल प्रयासों के बाद, टेबलेट फ़ैक्टरी डिफ़ॉल्ट पर रीसेट हो जाएगा और सभी उपयोगकर्ता डेटा खो जाएगा."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"आप फ़ोन को अनलॉक करने के लिए <xliff:g id="NUMBER_0">%d</xliff:g> बार गलत तरीके से प्रयास कर चुके हैं. <xliff:g id="NUMBER_1">%d</xliff:g> और असफल प्रयासों के बाद, फ़ोन फ़ैक्टरी डिफ़ॉल्ट पर रीसेट हो जाएगा और सभी उपयोगकर्ता डेटा खो जाएगा."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"आप टेबलेट को अनलॉक करने के लिए <xliff:g id="NUMBER">%d</xliff:g> बार गलत तरीके से प्रयास कर चुके हैं. टेबलेट अब फ़ैक्‍टरी डिफ़ॉल्‍ट पर रीसेट हो जाएगा."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"आप फ़ोन को अनलॉक करने के लिए <xliff:g id="NUMBER">%d</xliff:g> बार गलत तरीके से प्रयास कर चुके हैं. फ़ोन अब फ़ैक्टरी डिफ़ॉल्ट पर रीसेट हो जाएगा."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"आपने अपने अनलॉक प्रतिमान को <xliff:g id="NUMBER_0">%d</xliff:g> बार गलत तरीके से आरेखित किया है. <xliff:g id="NUMBER_1">%d</xliff:g> और असफल प्रयासों के बाद, आपसे अपने टेबलेट को किसी ईमेल खाते के उपयोग से अनलॉक करने के लिए कहा जाएगा."\n\n" <xliff:g id="NUMBER_2">%d</xliff:g> सेकंड में पुन: प्रयास करें."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"आपने अपने अनलॉक प्रतिमान को <xliff:g id="NUMBER_0">%d</xliff:g> बार गलत तरीके से आरेखित किया है. <xliff:g id="NUMBER_1">%d</xliff:g> और असफल प्रयासों के बाद, आपसे अपने फ़ोन को किसी ईमेल खाते का उपयोग करके अनलॉक करने के लिए कहा जाएगा."\n\n" <xliff:g id="NUMBER_2">%d</xliff:g> सेकंड में पुन: प्रयास करें."</string>
+ <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
+ <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"निकालें"</string>
+ <!-- no translation found for keyguard_transport_prev_description (8229108430245669854) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_next_description (4299258300283778305) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_pause_description (5093073338238310224) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_play_description (2924628863741150956) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_stop_description (3084179324810575787) -->
+ <skip />
+ <!-- no translation found for keyguard_carrier_default (8700650403054042153) -->
+ <skip />
+</resources>
diff --git a/packages/Keyguard/res/values-hr/strings.xml b/packages/Keyguard/res/values-hr/strings.xml
new file mode 100644
index 0000000..36b738a
--- /dev/null
+++ b/packages/Keyguard/res/values-hr/strings.xml
@@ -0,0 +1,164 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/* //device/apps/common/assets/res/any/strings.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:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Unesite PIN kôd"</string>
+ <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Unesite PUK i novi PIN kôd"</string>
+ <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK kôd"</string>
+ <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Novi PIN kôd"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Dodirnite za tipkanje zaporke"</font></string>
+ <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Unesite zaporku za otključavanje"</string>
+ <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Unesite PIN za otključavanje"</string>
+ <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Netočan PIN kôd."</string>
+ <string name="keyguard_label_text" msgid="861796461028298424">"Za otključavanje pritisnite Izbornik pa 0."</string>
+ <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Premašen je maksimalni broj Otključavanja licem"</string>
+ <!-- no translation found for keyguard_charged (3272223906073492454) -->
+ <skip />
+ <!-- no translation found for keyguard_plugged_in (8117572000639998388) -->
+ <skip />
+ <!-- no translation found for keyguard_low_battery (8143808018719173859) -->
+ <skip />
+ <!-- no translation found for keyguard_instructions_when_pattern_disabled (1332288268600329841) -->
+ <skip />
+ <!-- no translation found for keyguard_network_locked_message (9169717779058037168) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message_short (494980561304211931) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (1445849005909260039) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (3481110395508637643) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions (5210891509995942250) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions_long (5968985489463870358) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_message_short (8340813989586622356) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_instructions (5892940909699723544) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_locked_message (6875773413306380902) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_puk_locked_message (3747232467471801633) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_unlock_progress_dialog_message (7975221805033614426) -->
+ <skip />
+ <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d od %3$d."</string>
+ <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Dodavanje widgeta."</string>
+ <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Prazno"</string>
+ <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Područje za otključavanje prošireno je."</string>
+ <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Područje za otključavanje sažeto je."</string>
+ <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> widget."</string>
+ <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"Birač korisnika"</string>
+ <string name="keyguard_accessibility_status" msgid="8008264603935930611">"Status"</string>
+ <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"Fotoaparat"</string>
+ <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Nadzor medija"</string>
+ <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Pokrenuta je promjena redoslijeda widgeta."</string>
+ <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Završena je promjena redoslijeda widgeta."</string>
+ <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Widget <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> izbrisan je."</string>
+ <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Proširivanje područja za otključavanje."</string>
+ <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Otključavanje klizanjem."</string>
+ <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Uzorak za otključavanje."</string>
+ <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Otključavanje licem."</string>
+ <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Otključavanje PIN-om."</string>
+ <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Otključavanje zaporkom."</string>
+ <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Područje uzorka."</string>
+ <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Područje klizanja."</string>
+ <!-- no translation found for keyguard_accessibility_transport_prev_description (1337286538318543555) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_next_description (7073928300444909320) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_pause_description (8455979545295224302) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_play_description (8146417789511154044) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_stop_description (7656358482980912216) -->
+ <skip />
+ <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+ <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+ <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+ <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Odustani"</string>
+ <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Izbriši"</string>
+ <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Gotovo"</string>
+ <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Promjena načina"</string>
+ <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
+ <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
+ <string name="description_target_unlock" msgid="2228524900439801453">"Otključaj"</string>
+ <string name="description_target_camera" msgid="969071997552486814">"Fotoaparat"</string>
+ <string name="description_target_silent" msgid="893551287746522182">"Bešumno"</string>
+ <string name="description_target_soundon" msgid="30052466675500172">"Zvuk je uključen"</string>
+ <string name="description_target_search" msgid="3091587249776033139">"Pretraživanje"</string>
+ <string name="description_direction_up" msgid="7169032478259485180">"Kliznite prema gore za <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_down" msgid="5087739728639014595">"Kliznite prema dolje za <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_left" msgid="7207478719805562165">"Kliznite lijevo za <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_right" msgid="8034433242579600980">"Kliznite desno za <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="user_switched" msgid="3768006783166984410">"Trenutačni korisnik <xliff:g id="NAME">%1$s</xliff:g>."</string>
+ <string name="kg_emergency_call_label" msgid="684946192523830531">"Hitan poziv"</string>
+ <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Zaboravili ste obrazac"</string>
+ <string name="kg_wrong_pattern" msgid="1850806070801358830">"Pogrešan obrazac"</string>
+ <string name="kg_wrong_password" msgid="2333281762128113157">"Pogrešna zaporka"</string>
+ <string name="kg_wrong_pin" msgid="1131306510833563801">"Pogrešan PIN"</string>
+ <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Pokušajte ponovo za <xliff:g id="NUMBER">%d</xliff:g> s."</string>
+ <string name="kg_pattern_instructions" msgid="398978611683075868">"Iscrtajte svoj obrazac"</string>
+ <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Unesite PIN za SIM"</string>
+ <string name="kg_pin_instructions" msgid="2377242233495111557">"Unesite PIN"</string>
+ <string name="kg_password_instructions" msgid="5753646556186936819">"Unesite zaporku"</string>
+ <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"SIM je sad onemogućen. Unesite PUK kôd da biste nastavili. Kontaktirajte operatera za pojedinosti."</string>
+ <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Upišite željeni PIN kôd"</string>
+ <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Potvrdite željeni PIN kôd"</string>
+ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Otključavanje SIM kartice…"</string>
+ <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Netočan PIN kôd."</string>
+ <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Unesite PIN koji ima od 4 do 8 brojeva."</string>
+ <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK kôd treba imati 8 brojeva ili više."</string>
+ <string name="kg_invalid_puk" msgid="3638289409676051243">"Ponovo unesite ispravan PUK kôd. Ponovljeni pokušaji trajno će onemogućiti SIM."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN kodovi nisu jednaki"</string>
+ <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Previše pokušaja iscrtavanja obrasca"</string>
+ <string name="kg_login_instructions" msgid="1100551261265506448">"Za otključavanje prijavite se Google računom."</string>
+ <string name="kg_login_username_hint" msgid="5718534272070920364">"Korisničko ime (e-pošta)"</string>
+ <string name="kg_login_password_hint" msgid="9057289103827298549">"Zaporka"</string>
+ <string name="kg_login_submit_button" msgid="5355904582674054702">"Prijava"</string>
+ <string name="kg_login_invalid_input" msgid="5754664119319872197">"Nevažeće korisničko ime ili zaporka."</string>
+ <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Zaboravili ste korisničko ime ili zaporku?"\n"Posjetite "<b>"google.com/accounts/recovery"</b>"."</string>
+ <string name="kg_login_checking_password" msgid="1052685197710252395">"Provjera računa..."</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Netočno ste napisali PIN <xliff:g id="NUMBER_0">%d</xliff:g> puta. "\n\n"Pokušajte ponovo za <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
+ <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Netočno ste napisali zaporku <xliff:g id="NUMBER_0">%d</xliff:g> puta. "\n\n"Pokušajte ponovo za <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
+ <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Netočno ste iscrtali obrazac za otključavanje <xliff:g id="NUMBER_0">%d</xliff:g> puta. "\n\n"Pokušajte ponovo za <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Netočno ste pokušali otključati tabletno računalo <xliff:g id="NUMBER_0">%d</xliff:g> puta. Ono će se vratiti na tvorničke postavke i svi korisnički podaci bit će izgubljeni nakon još ovoliko neuspjelih pokušaja: <xliff:g id="NUMBER_1">%d</xliff:g>."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Netočno ste pokušali otključati telefon <xliff:g id="NUMBER_0">%d</xliff:g> puta. On će se vratiti na tvorničke postavke i svi korisnički podaci bit će izgubljeni nakon još ovoliko neuspjelih pokušaja: <xliff:g id="NUMBER_1">%d</xliff:g>."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Netočno ste pokušali otključati tabletno računalo <xliff:g id="NUMBER">%d</xliff:g> puta. Sada će se vratiti na tvorničke postavke."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Netočno ste pokušali otključati telefon <xliff:g id="NUMBER">%d</xliff:g> puta. Sada će se vratiti na tvorničke postavke."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Netočno ste iscrtali obrazac za otključavanje <xliff:g id="NUMBER_0">%d</xliff:g> puta. Nakon još ovoliko neuspješnih pokušaja: <xliff:g id="NUMBER_1">%d</xliff:g> morat ćete otključati tabletno računalo pomoću računa e-pošte."\n\n" Pokušajte ponovo za <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Netočno ste iscrtali obrazac za otključavanje <xliff:g id="NUMBER_0">%d</xliff:g> puta. Nakon još ovoliko neuspješnih pokušaja: <xliff:g id="NUMBER_1">%d</xliff:g> morat ćete otključati telefon pomoću računa e-pošte."\n\n" Pokušajte ponovo za <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
+ <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" – "</string>
+ <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Ukloni"</string>
+ <!-- no translation found for keyguard_transport_prev_description (8229108430245669854) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_next_description (4299258300283778305) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_pause_description (5093073338238310224) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_play_description (2924628863741150956) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_stop_description (3084179324810575787) -->
+ <skip />
+ <!-- no translation found for keyguard_carrier_default (8700650403054042153) -->
+ <skip />
+</resources>
diff --git a/packages/Keyguard/res/values-hu/strings.xml b/packages/Keyguard/res/values-hu/strings.xml
new file mode 100644
index 0000000..07bcb25
--- /dev/null
+++ b/packages/Keyguard/res/values-hu/strings.xml
@@ -0,0 +1,164 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/* //device/apps/common/assets/res/any/strings.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:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Írja be a PIN kódot"</string>
+ <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Írja be a PUK kódot, majd az új PIN kódot"</string>
+ <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK kód"</string>
+ <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Új PIN kód"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Érintsen jelszó megadásához"</font></string>
+ <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"A feloldáshoz írja be a jelszót"</string>
+ <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Feloldáshoz írja be a PIN kódot"</string>
+ <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Helytelen PIN kód."</string>
+ <string name="keyguard_label_text" msgid="861796461028298424">"A feloldáshoz nyomja meg a Menü, majd a 0 gombot."</string>
+ <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Elérte az arcalapú feloldási kísérletek maximális számát"</string>
+ <!-- no translation found for keyguard_charged (3272223906073492454) -->
+ <skip />
+ <!-- no translation found for keyguard_plugged_in (8117572000639998388) -->
+ <skip />
+ <!-- no translation found for keyguard_low_battery (8143808018719173859) -->
+ <skip />
+ <!-- no translation found for keyguard_instructions_when_pattern_disabled (1332288268600329841) -->
+ <skip />
+ <!-- no translation found for keyguard_network_locked_message (9169717779058037168) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message_short (494980561304211931) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (1445849005909260039) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (3481110395508637643) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions (5210891509995942250) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions_long (5968985489463870358) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_message_short (8340813989586622356) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_instructions (5892940909699723544) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_locked_message (6875773413306380902) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_puk_locked_message (3747232467471801633) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_unlock_progress_dialog_message (7975221805033614426) -->
+ <skip />
+ <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Modul %3$d/%2$d"</string>
+ <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Modul hozzáadása."</string>
+ <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Üres"</string>
+ <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Feloldási terület kiterjesztve."</string>
+ <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Feloldási terület összecsukva."</string>
+ <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> modul."</string>
+ <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"Felhasználóválasztó"</string>
+ <string name="keyguard_accessibility_status" msgid="8008264603935930611">"Állapot"</string>
+ <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"Kamera"</string>
+ <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Médiaelemek vezérlője"</string>
+ <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"A modulátrendezés elkezdődött."</string>
+ <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"A modulátrendezés véget ért."</string>
+ <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> modul törölve."</string>
+ <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"A feloldási terület kiterjesztése."</string>
+ <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Feloldás csúsztatással"</string>
+ <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Feloldás mintával"</string>
+ <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Arcalapú feloldás"</string>
+ <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Feloldás PIN kóddal"</string>
+ <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Feloldás jelszóval"</string>
+ <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Mintaterület"</string>
+ <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Csúsztatási terület"</string>
+ <!-- no translation found for keyguard_accessibility_transport_prev_description (1337286538318543555) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_next_description (7073928300444909320) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_pause_description (8455979545295224302) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_play_description (8146417789511154044) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_stop_description (7656358482980912216) -->
+ <skip />
+ <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+ <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+ <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+ <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Mégse"</string>
+ <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Delete"</string>
+ <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Kész"</string>
+ <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Mód váltása"</string>
+ <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
+ <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
+ <string name="description_target_unlock" msgid="2228524900439801453">"Feloldás"</string>
+ <string name="description_target_camera" msgid="969071997552486814">"Kamera"</string>
+ <string name="description_target_silent" msgid="893551287746522182">"Némítás"</string>
+ <string name="description_target_soundon" msgid="30052466675500172">"Hang bekapcsolása"</string>
+ <string name="description_target_search" msgid="3091587249776033139">"Keresés"</string>
+ <string name="description_direction_up" msgid="7169032478259485180">"A(z) <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> művelethez csúsztassa felfelé."</string>
+ <string name="description_direction_down" msgid="5087739728639014595">"A(z) <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> művelethez csúsztassa lefelé."</string>
+ <string name="description_direction_left" msgid="7207478719805562165">"A(z) <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> művelethez csúsztassa balra."</string>
+ <string name="description_direction_right" msgid="8034433242579600980">"A(z) <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> művelethez csúsztassa jobbra."</string>
+ <string name="user_switched" msgid="3768006783166984410">"<xliff:g id="NAME">%1$s</xliff:g> az aktuális felhasználó."</string>
+ <string name="kg_emergency_call_label" msgid="684946192523830531">"Segélyhívás"</string>
+ <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Elfelejtett minta"</string>
+ <string name="kg_wrong_pattern" msgid="1850806070801358830">"Helytelen minta"</string>
+ <string name="kg_wrong_password" msgid="2333281762128113157">"Helytelen jelszó"</string>
+ <string name="kg_wrong_pin" msgid="1131306510833563801">"Helytelen PIN kód"</string>
+ <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Próbálkozzon újra <xliff:g id="NUMBER">%d</xliff:g> másodperc múlva."</string>
+ <string name="kg_pattern_instructions" msgid="398978611683075868">"Rajzolja le a mintát"</string>
+ <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Adja meg a SIM kártya PIN kódját"</string>
+ <string name="kg_pin_instructions" msgid="2377242233495111557">"Adja meg a PIN kódot"</string>
+ <string name="kg_password_instructions" msgid="5753646556186936819">"Írja be a jelszót"</string>
+ <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"A SIM kártya le van tiltva. A folytatáshoz adja meg a PUK kódot. A részletekért vegye fel a kapcsolatot szolgáltatójával."</string>
+ <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Kívánt PIN kód megadása"</string>
+ <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Kívánt PIN kód megerősítése"</string>
+ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"SIM kártya feloldása..."</string>
+ <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Helytelen PIN kód."</string>
+ <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"4–8 számjegyű PIN kódot írjon be."</string>
+ <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"A PUK kód legalább 8 számjegyből kell, hogy álljon."</string>
+ <string name="kg_invalid_puk" msgid="3638289409676051243">"Adja meg újra a helyes PUK kódot. Az ismételt próbálkozással véglegesen letiltja a SIM kártyát."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"A PIN kódok nem egyeznek."</string>
+ <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Túl sok mintarajzolási próbálkozás"</string>
+ <string name="kg_login_instructions" msgid="1100551261265506448">"A feloldáshoz jelentkezzen be Google Fiókjával."</string>
+ <string name="kg_login_username_hint" msgid="5718534272070920364">"Felhasználónév (e-mail cím)"</string>
+ <string name="kg_login_password_hint" msgid="9057289103827298549">"Jelszó"</string>
+ <string name="kg_login_submit_button" msgid="5355904582674054702">"Bejelentkezés"</string>
+ <string name="kg_login_invalid_input" msgid="5754664119319872197">"Érvénytelen felhasználónév vagy jelszó."</string>
+ <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Elfelejtette a felhasználónevét vagy jelszavát?"\n"Keresse fel a "<b>"google.com/accounts/recovery"</b>" webhelyet."</string>
+ <string name="kg_login_checking_password" msgid="1052685197710252395">"Fiók ellenőrzése..."</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"<xliff:g id="NUMBER_0">%d</xliff:g> alkalommal helytelenül adta meg PIN kódját. "\n\n"Próbálja újra <xliff:g id="NUMBER_1">%d</xliff:g> másodperc múlva."</string>
+ <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"<xliff:g id="NUMBER_0">%d</xliff:g> alkalommal helytelenül adta meg a jelszót. "\n\n" Próbálja újra <xliff:g id="NUMBER_1">%d</xliff:g> másodperc múlva."</string>
+ <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"<xliff:g id="NUMBER_0">%d</xliff:g> alkalommal rosszul rajzolta le feloldási mintát. "\n\n"Próbálja újra <xliff:g id="NUMBER_1">%d</xliff:g> másodperc múlva."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"A táblagépet <xliff:g id="NUMBER_0">%d</xliff:g> alkalommal próbálta meg sikertelenül feloldani. <xliff:g id="NUMBER_1">%d</xliff:g> további sikertelen próbálkozás után a rendszer visszaállítja a táblagép gyári alapértelmezett beállításait, és minden felhasználói adat elvész."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"A telefont <xliff:g id="NUMBER_0">%d</xliff:g> alkalommal próbálta meg sikertelenül feloldani. <xliff:g id="NUMBER_1">%d</xliff:g> további sikertelen próbálkozás után a rendszer visszaállítja a telefon gyári alapértelmezett beállításait, és minden felhasználói adat elvész."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"A táblagépet <xliff:g id="NUMBER">%d</xliff:g> alkalommal próbálta meg sikertelenül feloldani. A rendszer visszaállítja a táblagép gyári alapértelmezett beállításait."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"A telefont <xliff:g id="NUMBER">%d</xliff:g> alkalommal próbálta meg sikertelenül feloldani. A rendszer visszaállítja a telefon gyári alapértelmezett beállításait."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"<xliff:g id="NUMBER_0">%d</xliff:g> alkalommal helytelenül rajzolta le a feloldási mintát. További <xliff:g id="NUMBER_1">%d</xliff:g> sikertelen kísérlet után egy e-mail fiók használatával kell feloldania a táblagépét."\n\n" Kérjük, próbálja újra <xliff:g id="NUMBER_2">%d</xliff:g> másodperc múlva."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"<xliff:g id="NUMBER_0">%d</xliff:g> alkalommal helytelenül rajzolta le a feloldási mintát. További <xliff:g id="NUMBER_1">%d</xliff:g> sikertelen kísérlet után egy e-mail fiók használatával kell feloldania a telefonját."\n\n" Kérjük, próbálja újra <xliff:g id="NUMBER_2">%d</xliff:g> másodperc múlva."</string>
+ <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" – "</string>
+ <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Eltávolítás"</string>
+ <!-- no translation found for keyguard_transport_prev_description (8229108430245669854) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_next_description (4299258300283778305) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_pause_description (5093073338238310224) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_play_description (2924628863741150956) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_stop_description (3084179324810575787) -->
+ <skip />
+ <!-- no translation found for keyguard_carrier_default (8700650403054042153) -->
+ <skip />
+</resources>
diff --git a/packages/Keyguard/res/values-in/strings.xml b/packages/Keyguard/res/values-in/strings.xml
new file mode 100644
index 0000000..108e390
--- /dev/null
+++ b/packages/Keyguard/res/values-in/strings.xml
@@ -0,0 +1,164 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/* //device/apps/common/assets/res/any/strings.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:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Ketik kode PIN"</string>
+ <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Ketik kode PUK dan PIN baru"</string>
+ <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"Kode PUK"</string>
+ <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Kode Pin baru"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Sentuh untuk mengetikkan sandi"</font></string>
+ <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Ketik sandi untuk membuka kunci"</string>
+ <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Ketik PIN untuk membuka kunci"</string>
+ <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Kode PIN salah."</string>
+ <string name="keyguard_label_text" msgid="861796461028298424">"Untuk membuka, tekan Menu lalu 0."</string>
+ <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Percobaan Face Unlock melebihi batas maksimum"</string>
+ <!-- no translation found for keyguard_charged (3272223906073492454) -->
+ <skip />
+ <!-- no translation found for keyguard_plugged_in (8117572000639998388) -->
+ <skip />
+ <!-- no translation found for keyguard_low_battery (8143808018719173859) -->
+ <skip />
+ <!-- no translation found for keyguard_instructions_when_pattern_disabled (1332288268600329841) -->
+ <skip />
+ <!-- no translation found for keyguard_network_locked_message (9169717779058037168) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message_short (494980561304211931) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (1445849005909260039) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (3481110395508637643) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions (5210891509995942250) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions_long (5968985489463870358) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_message_short (8340813989586622356) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_instructions (5892940909699723544) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_locked_message (6875773413306380902) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_puk_locked_message (3747232467471801633) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_unlock_progress_dialog_message (7975221805033614426) -->
+ <skip />
+ <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d dari %3$d."</string>
+ <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Tambahkan widget."</string>
+ <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Kosong"</string>
+ <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Area buka kunci diluaskan."</string>
+ <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Area buka kunci diciutkan."</string>
+ <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"Widget <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>."</string>
+ <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"Pemilih pengguna"</string>
+ <string name="keyguard_accessibility_status" msgid="8008264603935930611">"Status"</string>
+ <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"Kamera"</string>
+ <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Kontrol media"</string>
+ <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Pengurutan ulang widget dimulai."</string>
+ <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Pengurutan ulang widget berakhir."</string>
+ <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Widget <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> dihapus."</string>
+ <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Luaskan area buka kunci."</string>
+ <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Buka kunci dengan menggeser."</string>
+ <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Buka kunci dengan pola."</string>
+ <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Buka kunci dengan face unlock."</string>
+ <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Buka kunci dengan PIN."</string>
+ <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Buka kunci dengan sandi."</string>
+ <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Area pola."</string>
+ <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Area geser."</string>
+ <!-- no translation found for keyguard_accessibility_transport_prev_description (1337286538318543555) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_next_description (7073928300444909320) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_pause_description (8455979545295224302) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_play_description (8146417789511154044) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_stop_description (7656358482980912216) -->
+ <skip />
+ <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+ <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+ <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+ <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Batal"</string>
+ <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Hapus"</string>
+ <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Selesai"</string>
+ <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Pengubahan mode"</string>
+ <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
+ <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
+ <string name="description_target_unlock" msgid="2228524900439801453">"Membuka gembok"</string>
+ <string name="description_target_camera" msgid="969071997552486814">"Kamera"</string>
+ <string name="description_target_silent" msgid="893551287746522182">"Senyap"</string>
+ <string name="description_target_soundon" msgid="30052466675500172">"Suara hidup"</string>
+ <string name="description_target_search" msgid="3091587249776033139">"Telusuri"</string>
+ <string name="description_direction_up" msgid="7169032478259485180">"Geser ke atas untuk <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_down" msgid="5087739728639014595">"Geser ke bawah untuk <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_left" msgid="7207478719805562165">"Geser ke kiri untuk <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_right" msgid="8034433242579600980">"Geser ke kanan untuk <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="user_switched" msgid="3768006783166984410">"Pengguna saat ini <xliff:g id="NAME">%1$s</xliff:g>."</string>
+ <string name="kg_emergency_call_label" msgid="684946192523830531">"Panggilan darurat"</string>
+ <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Lupa Pola?"</string>
+ <string name="kg_wrong_pattern" msgid="1850806070801358830">"Pola Salah"</string>
+ <string name="kg_wrong_password" msgid="2333281762128113157">"Sandi Salah"</string>
+ <string name="kg_wrong_pin" msgid="1131306510833563801">"PIN Salah"</string>
+ <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Coba lagi dalam <xliff:g id="NUMBER">%d</xliff:g> detik."</string>
+ <string name="kg_pattern_instructions" msgid="398978611683075868">"Gambar pola Anda"</string>
+ <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Masukkan PIN SIM"</string>
+ <string name="kg_pin_instructions" msgid="2377242233495111557">"Masukkan PIN"</string>
+ <string name="kg_password_instructions" msgid="5753646556186936819">"Masukkan Sandi"</string>
+ <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"SIM telah dinonaktifkan. Masukkan kode PUK untuk melanjutkan. Hubungi operator untuk keterangan selengkapnya."</string>
+ <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Masukkan kode PIN yang diinginkan"</string>
+ <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Konfirmasi kode PIN yang diinginkan"</string>
+ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Membuka kunci kartu SIM…"</string>
+ <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Kode PIN salah."</string>
+ <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Ketik PIN yang terdiri dari 4 sampai 8 angka."</string>
+ <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"Kode PUK harus terdiri dari 8 angka atau lebih."</string>
+ <string name="kg_invalid_puk" msgid="3638289409676051243">"Masukkan kembali kode PUK yang benar. Jika berulang kali gagal, SIM akan dinonaktifkan secara permanen."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"Kode PIN tidak cocok"</string>
+ <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Terlalu banyak upaya pola"</string>
+ <string name="kg_login_instructions" msgid="1100551261265506448">"Untuk membuka kunci, masuk dengan akun Google Anda."</string>
+ <string name="kg_login_username_hint" msgid="5718534272070920364">"Nama pengguna (email)"</string>
+ <string name="kg_login_password_hint" msgid="9057289103827298549">"Sandi"</string>
+ <string name="kg_login_submit_button" msgid="5355904582674054702">"Masuk"</string>
+ <string name="kg_login_invalid_input" msgid="5754664119319872197">"Nama pengguna atau sandi tidak valid."</string>
+ <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Lupa nama pengguna atau sandi Anda?"\n"Kunjungi "<b>"google.com/accounts/recovery"</b>"."</string>
+ <string name="kg_login_checking_password" msgid="1052685197710252395">"Memeriksa akun…"</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Anda telah <xliff:g id="NUMBER_0">%d</xliff:g> kali salah mengetik PIN. "\n\n"Coba lagi dalam <xliff:g id="NUMBER_1">%d</xliff:g> detik."</string>
+ <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Anda telah <xliff:g id="NUMBER_0">%d</xliff:g> kali salah mengetik sandi. "\n\n"Coba lagi dalam <xliff:g id="NUMBER_1">%d</xliff:g> detik."</string>
+ <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Anda telah <xliff:g id="NUMBER_0">%d</xliff:g> kali salah menggambar pola pembuka kunci. "\n\n"Coba lagi dalam <xliff:g id="NUMBER_1">%d</xliff:g> detik."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Anda telah <xliff:g id="NUMBER_0">%d</xliff:g> kali gagal saat berusaha membuka kunci tablet. Setelah <xliff:g id="NUMBER_1">%d</xliff:g> lagi upaya gagal, tablet akan disetel ulang ke setelan default pabrik dan semua data pengguna akan hilang."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Anda telah <xliff:g id="NUMBER_0">%d</xliff:g> kali gagal saat berusaha membuka kunci ponsel. Setelah <xliff:g id="NUMBER_1">%d</xliff:g> lagi upaya gagal, ponsel akan disetel ulang ke setelan default pabrik dan semua data pengguna akan hilang."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Anda telah <xliff:g id="NUMBER">%d</xliff:g> kali gagal saat berusaha membuka kunci tablet. Kini tablet akan disetel ulang ke setelan default pabrik."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Anda telah <xliff:g id="NUMBER">%d</xliff:g> kali gagal saat berusaha untuk membuka kunci ponsel. Kini ponsel akan disetel ulang ke setelan default pabrik."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Anda telah <xliff:g id="NUMBER_0">%d</xliff:g> kali salah menggambar pola pembuka kunci. Setelah <xliff:g id="NUMBER_1">%d</xliff:g> lagi upaya gagal, Anda akan diminta membuka kunci tablet menggunakan akun email."\n\n"Coba lagi dalam <xliff:g id="NUMBER_2">%d</xliff:g> detik."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Anda telah <xliff:g id="NUMBER_0">%d</xliff:g> kali salah menggambar pola pembuka kunci. Setelah <xliff:g id="NUMBER_1">%d</xliff:g> lagi upaya gagal, Anda akan diminta membuka kunci ponsel menggunakan akun email."\n\n"Coba lagi dalam <xliff:g id="NUMBER_2">%d</xliff:g> detik."</string>
+ <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
+ <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Hapus"</string>
+ <!-- no translation found for keyguard_transport_prev_description (8229108430245669854) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_next_description (4299258300283778305) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_pause_description (5093073338238310224) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_play_description (2924628863741150956) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_stop_description (3084179324810575787) -->
+ <skip />
+ <!-- no translation found for keyguard_carrier_default (8700650403054042153) -->
+ <skip />
+</resources>
diff --git a/packages/Keyguard/res/values-it/strings.xml b/packages/Keyguard/res/values-it/strings.xml
new file mode 100644
index 0000000..b066ba1
--- /dev/null
+++ b/packages/Keyguard/res/values-it/strings.xml
@@ -0,0 +1,164 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/* //device/apps/common/assets/res/any/strings.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:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Inserisci il codice PIN"</string>
+ <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Inserisci il PUK e il nuovo codice PIN"</string>
+ <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"Codice PUK"</string>
+ <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Nuovo codice PIN"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Tocca per inserire la password"</font></string>
+ <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Inserisci password per sbloccare"</string>
+ <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Inserisci PIN per sbloccare"</string>
+ <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Codice PIN errato."</string>
+ <string name="keyguard_label_text" msgid="861796461028298424">"Per sbloccare, premi Menu, poi 0."</string>
+ <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Numero massimo di tentativi di Sblocco col sorriso superato"</string>
+ <!-- no translation found for keyguard_charged (3272223906073492454) -->
+ <skip />
+ <!-- no translation found for keyguard_plugged_in (8117572000639998388) -->
+ <skip />
+ <!-- no translation found for keyguard_low_battery (8143808018719173859) -->
+ <skip />
+ <!-- no translation found for keyguard_instructions_when_pattern_disabled (1332288268600329841) -->
+ <skip />
+ <!-- no translation found for keyguard_network_locked_message (9169717779058037168) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message_short (494980561304211931) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (1445849005909260039) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (3481110395508637643) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions (5210891509995942250) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions_long (5968985489463870358) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_message_short (8340813989586622356) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_instructions (5892940909699723544) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_locked_message (6875773413306380902) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_puk_locked_message (3747232467471801633) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_unlock_progress_dialog_message (7975221805033614426) -->
+ <skip />
+ <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d di %3$d."</string>
+ <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Aggiungi widget."</string>
+ <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Vuoto"</string>
+ <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Area di sblocco estesa."</string>
+ <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Area di sblocco compressa."</string>
+ <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> widget."</string>
+ <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"Selettore utente"</string>
+ <string name="keyguard_accessibility_status" msgid="8008264603935930611">"Stato"</string>
+ <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"Fotocamera"</string>
+ <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Controlli media"</string>
+ <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Riordino dei widget iniziato."</string>
+ <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Riordino dei widget terminato."</string>
+ <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Widget <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> eliminato."</string>
+ <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Espandi area di sblocco."</string>
+ <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Sblocco con scorrimento."</string>
+ <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Sblocco con sequenza."</string>
+ <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Sblocco col sorriso."</string>
+ <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Sblocco con PIN."</string>
+ <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Sblocco con password."</string>
+ <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Area sequenza."</string>
+ <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Area di scorrimento."</string>
+ <!-- no translation found for keyguard_accessibility_transport_prev_description (1337286538318543555) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_next_description (7073928300444909320) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_pause_description (8455979545295224302) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_play_description (8146417789511154044) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_stop_description (7656358482980912216) -->
+ <skip />
+ <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+ <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+ <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+ <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Annulla"</string>
+ <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Canc"</string>
+ <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Fine"</string>
+ <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Cambio modalità"</string>
+ <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Maiuscolo"</string>
+ <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Invio"</string>
+ <string name="description_target_unlock" msgid="2228524900439801453">"Sblocca"</string>
+ <string name="description_target_camera" msgid="969071997552486814">"Fotocamera"</string>
+ <string name="description_target_silent" msgid="893551287746522182">"Silenzioso"</string>
+ <string name="description_target_soundon" msgid="30052466675500172">"Audio attivato"</string>
+ <string name="description_target_search" msgid="3091587249776033139">"Ricerca"</string>
+ <string name="description_direction_up" msgid="7169032478259485180">"Su per <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_down" msgid="5087739728639014595">"Giù per <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_left" msgid="7207478719805562165">"A sinistra per <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_right" msgid="8034433242579600980">"A destra per <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="user_switched" msgid="3768006783166984410">"Utente corrente <xliff:g id="NAME">%1$s</xliff:g>."</string>
+ <string name="kg_emergency_call_label" msgid="684946192523830531">"Chiamata di emergenza"</string>
+ <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Sequenza dimenticata"</string>
+ <string name="kg_wrong_pattern" msgid="1850806070801358830">"Sequenza sbagliata"</string>
+ <string name="kg_wrong_password" msgid="2333281762128113157">"Password sbagliata"</string>
+ <string name="kg_wrong_pin" msgid="1131306510833563801">"PIN errato"</string>
+ <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Riprova fra <xliff:g id="NUMBER">%d</xliff:g> secondi."</string>
+ <string name="kg_pattern_instructions" msgid="398978611683075868">"Inserisci la sequenza"</string>
+ <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Inserisci il PIN della SIM"</string>
+ <string name="kg_pin_instructions" msgid="2377242233495111557">"Inserisci PIN"</string>
+ <string name="kg_password_instructions" msgid="5753646556186936819">"Inserisci la password"</string>
+ <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"La scheda SIM è disattivata. Inserisci il codice PUK per continuare. Contatta l\'operatore per avere informazioni dettagliate."</string>
+ <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Inserisci il codice PIN desiderato"</string>
+ <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Conferma il codice PIN desiderato"</string>
+ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Sblocco scheda SIM..."</string>
+ <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Codice PIN errato."</string>
+ <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Il PIN deve essere di 4-8 numeri."</string>
+ <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"Il codice PUK dovrebbe avere almeno otto numeri."</string>
+ <string name="kg_invalid_puk" msgid="3638289409676051243">"Inserisci di nuovo il codice PUK corretto. Ripetuti tentativi comportano la disattivazione definitiva della scheda SIM."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"I codici PIN non corrispondono"</string>
+ <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Troppi tentativi di inserimento della sequenza"</string>
+ <string name="kg_login_instructions" msgid="1100551261265506448">"Per sbloccare, accedi con il tuo account Google."</string>
+ <string name="kg_login_username_hint" msgid="5718534272070920364">"Nome utente (email)"</string>
+ <string name="kg_login_password_hint" msgid="9057289103827298549">"Password"</string>
+ <string name="kg_login_submit_button" msgid="5355904582674054702">"Accedi"</string>
+ <string name="kg_login_invalid_input" msgid="5754664119319872197">"Nome utente o password non validi."</string>
+ <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Hai dimenticato il nome utente o la password?"\n"Visita "<b>"google.com/accounts/recovery"</b>"."</string>
+ <string name="kg_login_checking_password" msgid="1052685197710252395">"Controllo account…"</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Hai digitato il tuo PIN <xliff:g id="NUMBER_0">%d</xliff:g> volte in modo errato. "\n\n"Riprova tra <xliff:g id="NUMBER_1">%d</xliff:g> secondi."</string>
+ <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Hai digitato la tua password <xliff:g id="NUMBER_0">%d</xliff:g> volte in modo errato. "\n\n"Riprova tra <xliff:g id="NUMBER_1">%d</xliff:g> secondi."</string>
+ <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"<xliff:g id="NUMBER_0">%d</xliff:g> tentativi errati di inserimento della sequenza di sblocco. "\n\n"Riprova tra <xliff:g id="NUMBER_1">%d</xliff:g> secondi."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"<xliff:g id="NUMBER_0">%d</xliff:g> tentativi errati di sblocco del tablet. Dopo altri <xliff:g id="NUMBER_1">%d</xliff:g> tentativi falliti, il tablet verrà sottoposto a un ripristino dei dati di fabbrica e tutti i dati utente andranno persi."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"<xliff:g id="NUMBER_0">%d</xliff:g> tentativi errati di sblocco del telefono. Dopo altri <xliff:g id="NUMBER_1">%d</xliff:g> tentativi falliti, il telefono verrà sottoposto a un ripristino dei dati di fabbrica e tutti i dati utente andranno persi."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"<xliff:g id="NUMBER">%d</xliff:g> tentativi errati di sblocco del tablet. Il tablet verrà sottoposto a un ripristino dei dati di fabbrica."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"<xliff:g id="NUMBER">%d</xliff:g> tentativi errati di sblocco del telefono. Il telefono verrà sottoposto a un ripristino dei dati di fabbrica."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"<xliff:g id="NUMBER_0">%d</xliff:g> tentativi errati di inserimento della sequenza di sblocco. Dopo altri <xliff:g id="NUMBER_1">%d</xliff:g> tentativi falliti, ti verrà chiesto di sbloccare il tablet con un account email."\n\n" Riprova tra <xliff:g id="NUMBER_2">%d</xliff:g> secondi."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"<xliff:g id="NUMBER_0">%d</xliff:g> tentativi errati di inserimento della sequenza di sblocco. Dopo altri <xliff:g id="NUMBER_1">%d</xliff:g> tentativi falliti, ti verrà chiesto di sbloccare il telefono con un account email."\n\n" Riprova tra <xliff:g id="NUMBER_2">%d</xliff:g> secondi."</string>
+ <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" – "</string>
+ <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Rimuovi"</string>
+ <!-- no translation found for keyguard_transport_prev_description (8229108430245669854) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_next_description (4299258300283778305) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_pause_description (5093073338238310224) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_play_description (2924628863741150956) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_stop_description (3084179324810575787) -->
+ <skip />
+ <!-- no translation found for keyguard_carrier_default (8700650403054042153) -->
+ <skip />
+</resources>
diff --git a/packages/Keyguard/res/values-iw/strings.xml b/packages/Keyguard/res/values-iw/strings.xml
new file mode 100644
index 0000000..956a48e
--- /dev/null
+++ b/packages/Keyguard/res/values-iw/strings.xml
@@ -0,0 +1,164 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/* //device/apps/common/assets/res/any/strings.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:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"הקלד קוד PIN"</string>
+ <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"הקלד את קוד ה-PUK וקוד ה-PIN החדש"</string>
+ <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"קוד PUK"</string>
+ <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"קוד PIN חדש"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"גע כדי להקליד את הסיסמה"</font></string>
+ <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"הקלד סיסמה לביטול הנעילה"</string>
+ <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"הקלד קוד PIN לביטול הנעילה"</string>
+ <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"קוד PIN שגוי"</string>
+ <string name="keyguard_label_text" msgid="861796461028298424">"כדי לבטל את הנעילה, לחץ על \'תפריט\' ולאחר מכן על 0."</string>
+ <string name="faceunlock_multiple_failures" msgid="754137583022792429">"חרגת ממספר הניסיונות המרבי של זיהוי פרצוף"</string>
+ <!-- no translation found for keyguard_charged (3272223906073492454) -->
+ <skip />
+ <!-- no translation found for keyguard_plugged_in (8117572000639998388) -->
+ <skip />
+ <!-- no translation found for keyguard_low_battery (8143808018719173859) -->
+ <skip />
+ <!-- no translation found for keyguard_instructions_when_pattern_disabled (1332288268600329841) -->
+ <skip />
+ <!-- no translation found for keyguard_network_locked_message (9169717779058037168) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message_short (494980561304211931) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (1445849005909260039) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (3481110395508637643) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions (5210891509995942250) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions_long (5968985489463870358) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_message_short (8340813989586622356) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_instructions (5892940909699723544) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_locked_message (6875773413306380902) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_puk_locked_message (3747232467471801633) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_unlock_progress_dialog_message (7975221805033614426) -->
+ <skip />
+ <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d מתוך %3$d."</string>
+ <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"הוסף Widget."</string>
+ <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"ריק"</string>
+ <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"אזור ביטול הנעילה הורחב."</string>
+ <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"אזור ביטול הנעילה כווץ."</string>
+ <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"Widget ‏<xliff:g id="WIDGET_INDEX">%1$s</xliff:g>."</string>
+ <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"בוחר משתמשים"</string>
+ <string name="keyguard_accessibility_status" msgid="8008264603935930611">"סטטוס"</string>
+ <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"מצלמה"</string>
+ <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"פקדי מדיה"</string>
+ <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"סידור מחדש של Widgets התחיל."</string>
+ <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"סידור מחדש של Widgets הסתיים."</string>
+ <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Widget ‏<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> נמחק."</string>
+ <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"הרחב את אזור ביטול הנעילה."</string>
+ <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"ביטול נעילה באמצעות הסטה."</string>
+ <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"ביטול נעילה באמצעות ציור קו."</string>
+ <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"ביטול נעילה באמצעות זיהוי פרצוף."</string>
+ <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"ביטול נעילה באמצעות מספר PIN."</string>
+ <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"ביטול נעילה באמצעות סיסמה."</string>
+ <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"אזור ציור קו."</string>
+ <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"אזור הסטה."</string>
+ <!-- no translation found for keyguard_accessibility_transport_prev_description (1337286538318543555) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_next_description (7073928300444909320) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_pause_description (8455979545295224302) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_play_description (8146417789511154044) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_stop_description (7656358482980912216) -->
+ <skip />
+ <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+ <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"אבג"</string>
+ <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+ <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"ביטול"</string>
+ <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"מחק"</string>
+ <string name="keyboardview_keycode_done" msgid="1992571118466679775">"סיום"</string>
+ <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"שינוי מצב"</string>
+ <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
+ <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
+ <string name="description_target_unlock" msgid="2228524900439801453">"בטל נעילה"</string>
+ <string name="description_target_camera" msgid="969071997552486814">"מצלמה"</string>
+ <string name="description_target_silent" msgid="893551287746522182">"שקט"</string>
+ <string name="description_target_soundon" msgid="30052466675500172">"הקול פועל"</string>
+ <string name="description_target_search" msgid="3091587249776033139">"חיפוש"</string>
+ <string name="description_direction_up" msgid="7169032478259485180">"הסט למעלה כדי להציג <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_down" msgid="5087739728639014595">"הסט למטה כדי להציג <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_left" msgid="7207478719805562165">"הסט שמאלה כדי להציג <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_right" msgid="8034433242579600980">"הסט ימינה כדי להציג <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="user_switched" msgid="3768006783166984410">"המשתמש הנוכחי <xliff:g id="NAME">%1$s</xliff:g>."</string>
+ <string name="kg_emergency_call_label" msgid="684946192523830531">"שיחת חירום"</string>
+ <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"שכחת את הקו"</string>
+ <string name="kg_wrong_pattern" msgid="1850806070801358830">"קו ביטול נעילה שגוי"</string>
+ <string name="kg_wrong_password" msgid="2333281762128113157">"סיסמה שגויה"</string>
+ <string name="kg_wrong_pin" msgid="1131306510833563801">"מספר PIN שגוי"</string>
+ <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"נסה שוב בעוד <xliff:g id="NUMBER">%d</xliff:g> שניות."</string>
+ <string name="kg_pattern_instructions" msgid="398978611683075868">"שרטט את קו ביטול הנעילה"</string>
+ <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"הזן מספר PIN ל-SIM"</string>
+ <string name="kg_pin_instructions" msgid="2377242233495111557">"הזן מספר PIN"</string>
+ <string name="kg_password_instructions" msgid="5753646556186936819">"הזן את הסיסמה"</string>
+ <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"כרטיס ה-SIM מושבת כעת. הזן קוד PUK כדי להמשיך. פנה אל הספק לפרטים."</string>
+ <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"הזן את קוד ה-PIN הרצוי"</string>
+ <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"אשר את קוד ה-PIN הרצוי"</string>
+ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"מבטל נעילה של כרטיס SIM…"</string>
+ <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"קוד PIN שגוי."</string>
+ <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"הקלד מספר PIN שאורכו 4 עד 8 ספרות."</string>
+ <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"קוד PUK צריך להיות בן 8 ספרות או יותר."</string>
+ <string name="kg_invalid_puk" msgid="3638289409676051243">"הזן מחדש את קוד PUK הנכון. ניסיונות חוזרים ישביתו לצמיתות את כרטיס ה-SIM."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"קודי ה-PIN אינם תואמים"</string>
+ <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"ניסיונות רבים מדי לשרטוט קו ביטול נעילה."</string>
+ <string name="kg_login_instructions" msgid="1100551261265506448">"כדי לבטל את הנעילה, היכנס באמצעות חשבון Google שלך."</string>
+ <string name="kg_login_username_hint" msgid="5718534272070920364">"שם משתמש (דוא\"ל)"</string>
+ <string name="kg_login_password_hint" msgid="9057289103827298549">"סיסמה"</string>
+ <string name="kg_login_submit_button" msgid="5355904582674054702">"היכנס"</string>
+ <string name="kg_login_invalid_input" msgid="5754664119319872197">"שם משתמש או סיסמה לא חוקיים."</string>
+ <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"שכחת את שם המשתמש או הסיסמה?"\n"בקר בכתובת "<b>"google.com/accounts/recovery"</b></string>
+ <string name="kg_login_checking_password" msgid="1052685197710252395">"בודק חשבון…"</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"הקלדת מספר PIN שגוי <xliff:g id="NUMBER_0">%d</xliff:g> פעמים. "\n\n"נסה שוב בעוד <xliff:g id="NUMBER_1">%d</xliff:g> שניות."</string>
+ <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"הקלדת סיסמה שגויה <xliff:g id="NUMBER_0">%d</xliff:g> פעמים."\n\n"נסה שוב בעוד <xliff:g id="NUMBER_1">%d</xliff:g> שניות."</string>
+ <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"שרטטת את קו ביטול הנעילה באופן שגוי <xliff:g id="NUMBER_0">%d</xliff:g> פעמים. "\n\n"נסה שוב בעוד <xliff:g id="NUMBER_1">%d</xliff:g> שניות."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"ביצעת <xliff:g id="NUMBER_0">%d</xliff:g> ניסיונות שגויים לביטול נעילת הטלפון. לאחר <xliff:g id="NUMBER_1">%d</xliff:g> ניסיונות כושלים נוספים, הטאבלט יעבור איפוס לברירת המחדל של היצרן וכל נתוני המשתמש יאבדו."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"ביצעת <xliff:g id="NUMBER_0">%d</xliff:g> ניסיונות שגויים לביטול נעילת הטלפון. לאחר <xliff:g id="NUMBER_1">%d</xliff:g> ניסיונות כושלים נוספים, הטלפון יעבור איפוס לברירת המחדל של היצרן וכל נתוני המשתמש יאבדו."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"ביצעת <xliff:g id="NUMBER">%d</xliff:g> ניסיונות שגויים לביטול נעילת הטאבלט. הטאבלט יעבור כעת איפוס לברירת המחדל של היצרן."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"ביצעת <xliff:g id="NUMBER">%d</xliff:g> ניסיונות שגויים לביטול נעילת הטלפון. הטלפון יעבור כעת איפוס לברירת המחדל של היצרן."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"שרטטת את קו ביטול הנעילה באופן שגוי <xliff:g id="NUMBER_0">%d</xliff:g> פעמים. לאחר <xliff:g id="NUMBER_1">%d</xliff:g> ניסיונות כושלים נוספים, תתבקש לבטל את נעילת הטאבלט באמצעות חשבון דוא\"ל‏."\n\n"נסה שוב בעוד <xliff:g id="NUMBER_2">%d</xliff:g> שניות."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"שרטטת את קו ביטול הנעילה באופן שגוי <xliff:g id="NUMBER_0">%d</xliff:g> פעמים. לאחר <xliff:g id="NUMBER_1">%d</xliff:g> ניסיונות כושלים נוספים, תתבקש לבטל את נעילת הטלפון באמצעות חשבון דוא\"ל‏."\n\n"נסה שוב בעוד <xliff:g id="NUMBER_2">%d</xliff:g> שניות."</string>
+ <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
+ <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"הסר"</string>
+ <!-- no translation found for keyguard_transport_prev_description (8229108430245669854) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_next_description (4299258300283778305) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_pause_description (5093073338238310224) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_play_description (2924628863741150956) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_stop_description (3084179324810575787) -->
+ <skip />
+ <!-- no translation found for keyguard_carrier_default (8700650403054042153) -->
+ <skip />
+</resources>
diff --git a/packages/Keyguard/res/values-ja/strings.xml b/packages/Keyguard/res/values-ja/strings.xml
new file mode 100644
index 0000000..b80b7af
--- /dev/null
+++ b/packages/Keyguard/res/values-ja/strings.xml
@@ -0,0 +1,164 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/* //device/apps/common/assets/res/any/strings.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:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"PINコードを入力"</string>
+ <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"PUKと新しいPINコードを入力"</string>
+ <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUKコード"</string>
+ <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"新しいPINコード"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"タップしてパスワードを入力"</font></string>
+ <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"ロックを解除するにはパスワードを入力"</string>
+ <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"ロックを解除するにはPINを入力"</string>
+ <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"PINコードが正しくありません。"</string>
+ <string name="keyguard_label_text" msgid="861796461028298424">"MENU、0キーでロック解除"</string>
+ <string name="faceunlock_multiple_failures" msgid="754137583022792429">"フェイスアンロックの最大試行回数を超えました"</string>
+ <!-- no translation found for keyguard_charged (3272223906073492454) -->
+ <skip />
+ <!-- no translation found for keyguard_plugged_in (8117572000639998388) -->
+ <skip />
+ <!-- no translation found for keyguard_low_battery (8143808018719173859) -->
+ <skip />
+ <!-- no translation found for keyguard_instructions_when_pattern_disabled (1332288268600329841) -->
+ <skip />
+ <!-- no translation found for keyguard_network_locked_message (9169717779058037168) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message_short (494980561304211931) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (1445849005909260039) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (3481110395508637643) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions (5210891509995942250) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions_long (5968985489463870358) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_message_short (8340813989586622356) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_instructions (5892940909699723544) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_locked_message (6875773413306380902) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_puk_locked_message (3747232467471801633) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_unlock_progress_dialog_message (7975221805033614426) -->
+ <skip />
+ <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s。ウィジェット%2$d/%3$d。"</string>
+ <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"ウィジェットを追加します。"</string>
+ <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"なし"</string>
+ <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"ロック解除エリアを拡大しました。"</string>
+ <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"ロック解除エリアを縮小しました。"</string>
+ <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g>ウィジェットです。"</string>
+ <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"ユーザー切り替え"</string>
+ <string name="keyguard_accessibility_status" msgid="8008264603935930611">"ステータス"</string>
+ <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"カメラ"</string>
+ <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"メディアコントロール"</string>
+ <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"ウィジェットの並べ替えを開始しました。"</string>
+ <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"ウィジェットの並べ替えを終了しました。"</string>
+ <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g>ウィジェットを削除しました。"</string>
+ <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"ロック解除エリアを拡大します。"</string>
+ <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"スライドロックを解除します。"</string>
+ <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"パターンロックを解除します。"</string>
+ <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"フェイスアンロックを行います。"</string>
+ <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"PINロックを解除します。"</string>
+ <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"パスワードロックを解除します。"</string>
+ <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"パターンエリアです。"</string>
+ <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"スライドエリアです。"</string>
+ <!-- no translation found for keyguard_accessibility_transport_prev_description (1337286538318543555) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_next_description (7073928300444909320) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_pause_description (8455979545295224302) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_play_description (8146417789511154044) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_stop_description (7656358482980912216) -->
+ <skip />
+ <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+ <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+ <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+ <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"キャンセル"</string>
+ <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"削除"</string>
+ <string name="keyboardview_keycode_done" msgid="1992571118466679775">"完了"</string>
+ <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"モードを変更"</string>
+ <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
+ <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
+ <string name="description_target_unlock" msgid="2228524900439801453">"ロックを解除"</string>
+ <string name="description_target_camera" msgid="969071997552486814">"カメラ"</string>
+ <string name="description_target_silent" msgid="893551287746522182">"マナーモード"</string>
+ <string name="description_target_soundon" msgid="30052466675500172">"サウンドON"</string>
+ <string name="description_target_search" msgid="3091587249776033139">"検索します"</string>
+ <string name="description_direction_up" msgid="7169032478259485180">"上にスライドして<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>を行います。"</string>
+ <string name="description_direction_down" msgid="5087739728639014595">"下にスライドして<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>を行います。"</string>
+ <string name="description_direction_left" msgid="7207478719805562165">"左にスライドして<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>を行います。"</string>
+ <string name="description_direction_right" msgid="8034433242579600980">"右にスライドして<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>を行います。"</string>
+ <string name="user_switched" msgid="3768006783166984410">"現在のユーザーは<xliff:g id="NAME">%1$s</xliff:g>です。"</string>
+ <string name="kg_emergency_call_label" msgid="684946192523830531">"緊急通報"</string>
+ <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"パターンを忘れた場合"</string>
+ <string name="kg_wrong_pattern" msgid="1850806070801358830">"パターンが正しくありません"</string>
+ <string name="kg_wrong_password" msgid="2333281762128113157">"パスワードが正しくありません"</string>
+ <string name="kg_wrong_pin" msgid="1131306510833563801">"PINが正しくありません"</string>
+ <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"<xliff:g id="NUMBER">%d</xliff:g>秒後にもう一度お試しください。"</string>
+ <string name="kg_pattern_instructions" msgid="398978611683075868">"パターンを入力"</string>
+ <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"SIM PINを入力"</string>
+ <string name="kg_pin_instructions" msgid="2377242233495111557">"PINを入力"</string>
+ <string name="kg_password_instructions" msgid="5753646556186936819">"パスワードを入力"</string>
+ <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"SIMが無効になりました。続行するにはPUKコードを入力してください。詳しくは携帯通信会社にお問い合わせください。"</string>
+ <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"希望のPINコードを入力してください"</string>
+ <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"希望のPINコードを確認してください"</string>
+ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"SIMカードのロック解除中…"</string>
+ <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"PINコードが正しくありません。"</string>
+ <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"PINは4~8桁の数字で入力してください。"</string>
+ <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUKコードは8桁以上の番号です。"</string>
+ <string name="kg_invalid_puk" msgid="3638289409676051243">"正しいPUKコードを再入力してください。誤入力を繰り返すと、SIMが永久に無効になるおそれがあります。"</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PINコードが一致しません"</string>
+ <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"パターンの入力を所定の回数以上間違えました。"</string>
+ <string name="kg_login_instructions" msgid="1100551261265506448">"ロックを解除するにはGoogleアカウントでログインしてください。"</string>
+ <string name="kg_login_username_hint" msgid="5718534272070920364">"ユーザー名(メール)"</string>
+ <string name="kg_login_password_hint" msgid="9057289103827298549">"パスワード"</string>
+ <string name="kg_login_submit_button" msgid="5355904582674054702">"ログイン"</string>
+ <string name="kg_login_invalid_input" msgid="5754664119319872197">"ユーザー名またはパスワードが無効です。"</string>
+ <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"ユーザー名またはパスワードを忘れた場合は"\n" "<b>"google.com/accounts/recovery"</b>" にアクセスしてください。"</string>
+ <string name="kg_login_checking_password" msgid="1052685197710252395">"アカウントをチェックしています…"</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"PINの入力を<xliff:g id="NUMBER_0">%d</xliff:g>回間違えました。"\n\n"<xliff:g id="NUMBER_1">%d</xliff:g>秒後にもう一度お試しください。"</string>
+ <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"パスワードの入力を<xliff:g id="NUMBER_0">%d</xliff:g>回間違えました。"\n\n"<xliff:g id="NUMBER_1">%d</xliff:g>秒後にもう一度お試しください。"</string>
+ <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"ロック解除パターンの入力を<xliff:g id="NUMBER_0">%d</xliff:g>回間違えました。"\n\n"<xliff:g id="NUMBER_1">%d</xliff:g>秒後にもう一度お試しください。"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"タブレットのロック解除に<xliff:g id="NUMBER_0">%d</xliff:g>回失敗しました。あと<xliff:g id="NUMBER_1">%d</xliff:g>回失敗すると、タブレットは出荷時設定にリセットされ、ユーザーのデータはすべて失われます。"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"携帯端末のロック解除に<xliff:g id="NUMBER_0">%d</xliff:g>回失敗しました。あと<xliff:g id="NUMBER_1">%d</xliff:g>回失敗すると、端末は出荷時設定にリセットされ、ユーザーのデータはすべて失われます。"</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"タブレットのロック解除を<xliff:g id="NUMBER">%d</xliff:g>回失敗しました。タブレットは出荷時設定にリセットされます。"</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"携帯端末のロック解除を<xliff:g id="NUMBER">%d</xliff:g>回失敗しました。端末は出荷時設定にリセットされます。"</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"ロック解除パターンの入力を<xliff:g id="NUMBER_0">%d</xliff:g>回間違えました。あと<xliff:g id="NUMBER_1">%d</xliff:g>回間違えると、タブレットのロック解除にメールアカウントが必要になります。"\n\n"<xliff:g id="NUMBER_2">%d</xliff:g>秒後にもう一度お試しください。"</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"ロック解除パターンの入力を<xliff:g id="NUMBER_0">%d</xliff:g>回間違えました。あと<xliff:g id="NUMBER_1">%d</xliff:g>回間違えると、携帯端末のロック解除にメールアカウントが必要になります。"\n\n"<xliff:g id="NUMBER_2">%d</xliff:g>秒後にもう一度お試しください。"</string>
+ <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" - "</string>
+ <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"削除"</string>
+ <!-- no translation found for keyguard_transport_prev_description (8229108430245669854) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_next_description (4299258300283778305) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_pause_description (5093073338238310224) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_play_description (2924628863741150956) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_stop_description (3084179324810575787) -->
+ <skip />
+ <!-- no translation found for keyguard_carrier_default (8700650403054042153) -->
+ <skip />
+</resources>
diff --git a/packages/Keyguard/res/values-ko/strings.xml b/packages/Keyguard/res/values-ko/strings.xml
new file mode 100644
index 0000000..3f8b441
--- /dev/null
+++ b/packages/Keyguard/res/values-ko/strings.xml
@@ -0,0 +1,164 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/* //device/apps/common/assets/res/any/strings.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:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"PIN 코드 입력"</string>
+ <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"PUK 및 새 PIN 코드 입력"</string>
+ <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK 코드"</string>
+ <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"새 PIN 코드"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"비밀번호를 입력하려면 터치"</font></string>
+ <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"잠금 해제하려면 비밀번호 입력"</string>
+ <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"잠금을 해제하려면 PIN 입력"</string>
+ <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"PIN 코드가 잘못되었습니다."</string>
+ <string name="keyguard_label_text" msgid="861796461028298424">"잠금해제하려면 메뉴를 누른 다음 0을 누릅니다."</string>
+ <string name="faceunlock_multiple_failures" msgid="754137583022792429">"얼굴 인식 잠금해제 최대 시도 횟수를 초과했습니다."</string>
+ <!-- no translation found for keyguard_charged (3272223906073492454) -->
+ <skip />
+ <!-- no translation found for keyguard_plugged_in (8117572000639998388) -->
+ <skip />
+ <!-- no translation found for keyguard_low_battery (8143808018719173859) -->
+ <skip />
+ <!-- no translation found for keyguard_instructions_when_pattern_disabled (1332288268600329841) -->
+ <skip />
+ <!-- no translation found for keyguard_network_locked_message (9169717779058037168) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message_short (494980561304211931) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (1445849005909260039) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (3481110395508637643) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions (5210891509995942250) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions_long (5968985489463870358) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_message_short (8340813989586622356) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_instructions (5892940909699723544) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_locked_message (6875773413306380902) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_puk_locked_message (3747232467471801633) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_unlock_progress_dialog_message (7975221805033614426) -->
+ <skip />
+ <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. %3$d의 위젯 %2$d."</string>
+ <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"위젯 추가"</string>
+ <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"비어 있음"</string>
+ <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"잠금 해제 영역 확장됨"</string>
+ <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"잠금 해제 영역 축소됨"</string>
+ <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> 위젯"</string>
+ <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"사용자 선택기"</string>
+ <string name="keyguard_accessibility_status" msgid="8008264603935930611">"상태"</string>
+ <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"카메라"</string>
+ <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"미디어 조정"</string>
+ <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"위젯 재정렬 시작됨"</string>
+ <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"위젯 재정렬 완료됨"</string>
+ <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> 위젯이 삭제됨"</string>
+ <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"잠금 해제 영역 확장"</string>
+ <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"슬라이드하여 잠금해제합니다."</string>
+ <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"패턴을 사용하여 잠금해제합니다."</string>
+ <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"얼굴 인식을 사용하여 잠금해제합니다."</string>
+ <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"핀을 사용하여 잠금해제합니다."</string>
+ <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"비밀번호를 사용하여 잠금해제합니다."</string>
+ <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"패턴을 그리는 부분입니다."</string>
+ <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"슬라이드하는 부분입니다."</string>
+ <!-- no translation found for keyguard_accessibility_transport_prev_description (1337286538318543555) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_next_description (7073928300444909320) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_pause_description (8455979545295224302) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_play_description (8146417789511154044) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_stop_description (7656358482980912216) -->
+ <skip />
+ <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+ <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+ <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt 키"</string>
+ <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"취소"</string>
+ <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Delete 키"</string>
+ <string name="keyboardview_keycode_done" msgid="1992571118466679775">"완료"</string>
+ <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"모드 변경"</string>
+ <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift 키"</string>
+ <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter 키"</string>
+ <string name="description_target_unlock" msgid="2228524900439801453">"잠금 해제"</string>
+ <string name="description_target_camera" msgid="969071997552486814">"카메라"</string>
+ <string name="description_target_silent" msgid="893551287746522182">"무음"</string>
+ <string name="description_target_soundon" msgid="30052466675500172">"사운드 켜기"</string>
+ <string name="description_target_search" msgid="3091587249776033139">"검색"</string>
+ <string name="description_direction_up" msgid="7169032478259485180">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>하려면 위로 슬라이드"</string>
+ <string name="description_direction_down" msgid="5087739728639014595">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>하려면 아래로 슬라이드"</string>
+ <string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>하려면 왼쪽으로 슬라이드"</string>
+ <string name="description_direction_right" msgid="8034433242579600980">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>하려면 오른쪽으로 슬라이드"</string>
+ <string name="user_switched" msgid="3768006783166984410">"현재 사용자는 <xliff:g id="NAME">%1$s</xliff:g>님입니다."</string>
+ <string name="kg_emergency_call_label" msgid="684946192523830531">"긴급 통화"</string>
+ <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"패턴을 잊음"</string>
+ <string name="kg_wrong_pattern" msgid="1850806070801358830">"잘못된 패턴"</string>
+ <string name="kg_wrong_password" msgid="2333281762128113157">"잘못된 비밀번호"</string>
+ <string name="kg_wrong_pin" msgid="1131306510833563801">"잘못된 PIN"</string>
+ <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"<xliff:g id="NUMBER">%d</xliff:g>초 후에 다시 시도해 주세요."</string>
+ <string name="kg_pattern_instructions" msgid="398978611683075868">"패턴 그리기"</string>
+ <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"SIM PIN 입력"</string>
+ <string name="kg_pin_instructions" msgid="2377242233495111557">"PIN 입력"</string>
+ <string name="kg_password_instructions" msgid="5753646556186936819">"비밀번호 입력"</string>
+ <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"이제 SIM을 사용할 수 없습니다. 계속하려면 PUK 코드를 입력합니다. 자세한 내용은 이동통신사에 문의하세요."</string>
+ <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"원하는 PIN 코드 입력"</string>
+ <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"원하는 PIN 코드 확인"</string>
+ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"SIM 카드 잠금해제 중..."</string>
+ <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"PIN 코드가 잘못되었습니다."</string>
+ <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"4~8자리 숫자로 된 PIN을 입력하세요."</string>
+ <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK 코드는 8자리 이상의 숫자여야 합니다."</string>
+ <string name="kg_invalid_puk" msgid="3638289409676051243">"올바른 PUK 코드를 다시 입력하세요. 입력을 반복해서 시도하면 SIM을 영구적으로 사용할 수 없게 됩니다."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN 코드가 일치하지 않음"</string>
+ <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"패턴 시도 횟수가 너무 많음"</string>
+ <string name="kg_login_instructions" msgid="1100551261265506448">"잠금해제하려면 Google 계정으로 로그인하세요."</string>
+ <string name="kg_login_username_hint" msgid="5718534272070920364">"사용자 이름(이메일)"</string>
+ <string name="kg_login_password_hint" msgid="9057289103827298549">"비밀번호"</string>
+ <string name="kg_login_submit_button" msgid="5355904582674054702">"로그인"</string>
+ <string name="kg_login_invalid_input" msgid="5754664119319872197">"사용자 이름 또는 비밀번호가 잘못되었습니다."</string>
+ <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"사용자 이름이나 비밀번호를 잊어버렸습니까?"\n<b>"google.com/accounts/recovery"</b>" 페이지를 방문하세요."</string>
+ <string name="kg_login_checking_password" msgid="1052685197710252395">"계정 확인 중…"</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"PIN을 <xliff:g id="NUMBER_0">%d</xliff:g>회 잘못 입력했습니다. "\n\n"<xliff:g id="NUMBER_1">%d</xliff:g>초 후에 다시 시도해 주세요."</string>
+ <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"비밀번호를 <xliff:g id="NUMBER_0">%d</xliff:g>회 잘못 입력했습니다. "\n\n"<xliff:g id="NUMBER_1">%d</xliff:g>초 후에 다시 시도해 주세요."</string>
+ <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"잠금해제 패턴을 <xliff:g id="NUMBER_0">%d</xliff:g>회 잘못 그렸습니다. "\n\n"<xliff:g id="NUMBER_1">%d</xliff:g>초 후에 다시 시도해 주세요."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"태블릿을 잠금해제하려는 시도가 <xliff:g id="NUMBER_0">%d</xliff:g>회 잘못되었습니다. <xliff:g id="NUMBER_1">%d</xliff:g>회 더 실패하면 태블릿이 초기화되고 사용자 데이터가 모두 사라집니다."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"휴대전화를 잠금해제하려는 시도가 <xliff:g id="NUMBER_0">%d</xliff:g>회 잘못되었습니다. <xliff:g id="NUMBER_1">%d</xliff:g>회 더 실패하면 휴대전화가 초기화되고 사용자 데이터가 모두 사라집니다."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"태블릿을 잠금해제하려는 시도가 <xliff:g id="NUMBER">%d</xliff:g>회 잘못되었습니다. 태블릿이 초기화됩니다."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"휴대전화를 잠금해제하려는 시도가 <xliff:g id="NUMBER">%d</xliff:g>회 잘못되었습니다. 휴대전화가 초기화됩니다."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"잠금해제 패턴을 <xliff:g id="NUMBER_0">%d</xliff:g>회 잘못 그렸습니다. <xliff:g id="NUMBER_1">%d</xliff:g>회 더 실패하면 이메일 계정을 사용하여 태블릿을 잠금해제해야 합니다."\n\n" <xliff:g id="NUMBER_2">%d</xliff:g>초 후에 다시 시도해 주세요."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"잠금해제 패턴을 <xliff:g id="NUMBER_0">%d</xliff:g>회 잘못 그렸습니다. <xliff:g id="NUMBER_1">%d</xliff:g>회 더 실패하면 이메일 계정을 사용하여 휴대전화를 잠금해제해야 합니다."\n\n" <xliff:g id="NUMBER_2">%d</xliff:g>초 후에 다시 시도해 주세요."</string>
+ <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
+ <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"삭제"</string>
+ <!-- no translation found for keyguard_transport_prev_description (8229108430245669854) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_next_description (4299258300283778305) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_pause_description (5093073338238310224) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_play_description (2924628863741150956) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_stop_description (3084179324810575787) -->
+ <skip />
+ <!-- no translation found for keyguard_carrier_default (8700650403054042153) -->
+ <skip />
+</resources>
diff --git a/packages/Keyguard/res/values-land/alias.xml b/packages/Keyguard/res/values-land/alias.xml
new file mode 100644
index 0000000..7aac5b4
--- /dev/null
+++ b/packages/Keyguard/res/values-land/alias.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/assets/res/any/colors.xml
+**
+** 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.
+*/
+-->
+<resources>
+ <!-- Alias used to reference one of two possible layouts in keyguard. -->
+ <item type="layout" name="keyguard_eca">@layout/keyguard_emergency_carrier_area_empty</item>
+</resources>
diff --git a/packages/Keyguard/res/values-land/arrays.xml b/packages/Keyguard/res/values-land/arrays.xml
new file mode 100644
index 0000000..240b9e4
--- /dev/null
+++ b/packages/Keyguard/res/values-land/arrays.xml
@@ -0,0 +1,72 @@
+<?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">
+
+ <!-- Resources for GlowPadView in LockScreen -->
+ <array name="lockscreen_targets_when_silent">
+ <item>@null</item>"
+ <item>@drawable/ic_action_assist_generic</item>
+ <item>@drawable/ic_lockscreen_soundon</item>
+ <item>@drawable/ic_lockscreen_unlock</item>
+ </array>
+
+ <array name="lockscreen_target_descriptions_when_silent">
+ <item>@null</item>
+ <item>@string/description_target_search</item>
+ <item>@string/description_target_soundon</item>
+ <item>@string/description_target_unlock</item>
+ </array>
+
+ <array name="lockscreen_direction_descriptions">
+ <item>@null</item>
+ <item>@string/description_direction_up</item>
+ <item>@string/description_direction_left</item>
+ <item>@string/description_direction_down</item>
+ </array>
+
+ <array name="lockscreen_targets_when_soundon">
+ <item>@null</item>
+ <item>@drawable/ic_action_assist_generic</item>
+ <item>@drawable/ic_lockscreen_silent</item>
+ <item>@drawable/ic_lockscreen_unlock</item>
+ </array>
+
+ <array name="lockscreen_target_descriptions_when_soundon">
+ <item>@null</item>
+ <item>@string/description_target_search</item>
+ <item>@string/description_target_silent</item>
+ <item>@string/description_target_unlock</item>
+ </array>
+
+ <array name="lockscreen_targets_with_camera">
+ <item>@null</item>
+ <item>@drawable/ic_action_assist_generic</item>
+ <item>@drawable/ic_lockscreen_camera</item>
+ <item>@drawable/ic_lockscreen_unlock</item>
+ </array>
+
+ <array name="lockscreen_target_descriptions_with_camera">
+ <item>@null</item>
+ <item>@string/description_target_search</item>
+ <item>@string/description_target_camera</item>
+ <item>@string/description_target_unlock</item>
+ </array>
+
+</resources>
diff --git a/packages/Keyguard/res/values-land/bools.xml b/packages/Keyguard/res/values-land/bools.xml
new file mode 100644
index 0000000..a1dd2e4
--- /dev/null
+++ b/packages/Keyguard/res/values-land/bools.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<resources>
+ <bool name="kg_enable_camera_default_widget">false</bool>
+ <bool name="kg_top_align_page_shrink_on_bouncer_visible">true</bool>
+ <bool name="kg_share_status_area">false</bool>
+ <bool name="kg_sim_puk_account_full_screen">false</bool>
+</resources>
diff --git a/packages/Keyguard/res/values-land/dimens.xml b/packages/Keyguard/res/values-land/dimens.xml
new file mode 100644
index 0000000..64e043c
--- /dev/null
+++ b/packages/Keyguard/res/values-land/dimens.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 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.
+*/
+-->
+
+<resources>
+ <!-- Default height of a key in the password keyboard for alpha -->
+ <dimen name="password_keyboard_key_height_alpha">47dip</dimen>
+ <!-- Default height of a key in the password keyboard for numeric -->
+ <dimen name="password_keyboard_key_height_numeric">50dip</dimen>
+ <!-- Default correction for the space key in the password keyboard -->
+ <dimen name="password_keyboard_spacebar_vertical_correction">2dip</dimen>
+ <dimen name="preference_widget_width">72dp</dimen>
+
+ <!-- Size of clock font in LockScreen on Unsecure unlock screen. -->
+ <dimen name="keyguard_lockscreen_clock_font_size">70sp</dimen>
+
+ <!-- Shift emergency button from the left edge by this amount. Used by landscape layout on
+ phones -->
+ <dimen name="kg_emergency_button_shift">30dp</dimen>
+
+ <!-- Space reserved at the bottom of secure views (pin/pattern/password/SIM pin/SIM puk) -->
+ <dimen name="kg_secure_padding_height">0dp</dimen>
+
+ <!-- Top padding for the widget pager -->
+ <dimen name="kg_widget_pager_top_padding">0dp</dimen>
+
+ <!-- Bottom padding for the widget pager -->
+ <dimen name="kg_widget_pager_bottom_padding">0dp</dimen>
+
+ <!-- If the height if keyguard drops below this threshold (most likely
+ due to the appearance of the IME), then drop the multiuser selector.
+ Landscape's layout allows this to be smaller than for portrait. -->
+ <dimen name="kg_squashed_layout_threshold">400dp</dimen>
+
+</resources>
diff --git a/packages/Keyguard/res/values-land/integers.xml b/packages/Keyguard/res/values-land/integers.xml
new file mode 100644
index 0000000..020fd23
--- /dev/null
+++ b/packages/Keyguard/res/values-land/integers.xml
@@ -0,0 +1,26 @@
+<?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.
+*/
+-->
+<resources>
+ <!-- Gravity to make KeyguardSelectorView work in multiple orientations
+ 0x13 == "left|center_vertical" -->
+ <integer name="kg_selector_gravity">0x13</integer>
+ <integer name="kg_widget_region_weight">45</integer>
+ <integer name="kg_security_flipper_weight">55</integer>
+ <integer name="kg_glowpad_rotation_offset">-90</integer>
+</resources>
diff --git a/packages/Keyguard/res/values-large/dimens.xml b/packages/Keyguard/res/values-large/dimens.xml
new file mode 100644
index 0000000..8cd614d
--- /dev/null
+++ b/packages/Keyguard/res/values-large/dimens.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2011, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<resources>
+ <!-- Default height of a key in the password keyboard for alpha -->
+ <dimen name="password_keyboard_key_height_alpha">75dip</dimen>
+ <!-- Default height of a key in the password keyboard for numeric -->
+ <dimen name="password_keyboard_key_height_numeric">75dip</dimen>
+ <!-- keyboardHeight = key_height*4 + key_bottom_gap*3 -->
+ <dimen name="password_keyboard_height">48.0mm</dimen>
+
+ <!-- Minimum width of the search view text entry area. -->
+ <dimen name="search_view_text_min_width">192dip</dimen>
+
+ <item type="dimen" name="dialog_min_width_major">55%</item>
+ <item type="dimen" name="dialog_min_width_minor">80%</item>
+
+ <!-- Preference UI dimensions for larger screens. -->
+ <dimen name="preference_widget_width">56dp</dimen>
+</resources>
diff --git a/packages/Keyguard/res/values-lt/strings.xml b/packages/Keyguard/res/values-lt/strings.xml
new file mode 100644
index 0000000..acaf0f7
--- /dev/null
+++ b/packages/Keyguard/res/values-lt/strings.xml
@@ -0,0 +1,164 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/* //device/apps/common/assets/res/any/strings.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:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Įveskite PIN kodą"</string>
+ <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Įveskite PUK ir naują PIN kodus"</string>
+ <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK kodas"</string>
+ <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Naujas PIN kodas"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Palieskite, kad įves. slaptaž."</font></string>
+ <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Jei norite atrakinti, įveskite slaptažodį"</string>
+ <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Jei norite atrakinti, įveskite PIN kodą"</string>
+ <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Neteisingas PIN kodas."</string>
+ <string name="keyguard_label_text" msgid="861796461028298424">"Jei norite atrakinti, paspauskite „Meniu“ ir 0."</string>
+ <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Viršijote maksimalų atrakinimo pagal veidą bandymų skaičių"</string>
+ <!-- no translation found for keyguard_charged (3272223906073492454) -->
+ <skip />
+ <!-- no translation found for keyguard_plugged_in (8117572000639998388) -->
+ <skip />
+ <!-- no translation found for keyguard_low_battery (8143808018719173859) -->
+ <skip />
+ <!-- no translation found for keyguard_instructions_when_pattern_disabled (1332288268600329841) -->
+ <skip />
+ <!-- no translation found for keyguard_network_locked_message (9169717779058037168) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message_short (494980561304211931) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (1445849005909260039) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (3481110395508637643) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions (5210891509995942250) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions_long (5968985489463870358) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_message_short (8340813989586622356) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_instructions (5892940909699723544) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_locked_message (6875773413306380902) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_puk_locked_message (3747232467471801633) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_unlock_progress_dialog_message (7975221805033614426) -->
+ <skip />
+ <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. %2$d valdiklis iš %3$d."</string>
+ <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Pridėti valdiklį."</string>
+ <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Tuščia"</string>
+ <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Atrakinimo sritis išplėsta."</string>
+ <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Atrakinimo sritis sutraukta."</string>
+ <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"Valdiklis <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>."</string>
+ <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"Naudotojo pasirinkimo valdiklis"</string>
+ <string name="keyguard_accessibility_status" msgid="8008264603935930611">"Būsena"</string>
+ <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"Fotoaparatas"</string>
+ <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Medijos valdikliai"</string>
+ <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Valdiklių pertvarkymas pradėtas."</string>
+ <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Valdiklių pertvarkymas baigtas."</string>
+ <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Valdiklis <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> ištrintas."</string>
+ <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Išplėsti atrakinimo sritį."</string>
+ <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Atrakinimas slystant."</string>
+ <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Atrakinimas pagal piešinį."</string>
+ <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Atrakinimas pagal veidą."</string>
+ <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Atrakinimas įvedus PIN kodą."</string>
+ <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Atrakinimas įvedus slaptažodį."</string>
+ <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Atrakinimo pagal piešinį sritis."</string>
+ <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Slydimo sritis."</string>
+ <!-- no translation found for keyguard_accessibility_transport_prev_description (1337286538318543555) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_next_description (7073928300444909320) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_pause_description (8455979545295224302) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_play_description (8146417789511154044) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_stop_description (7656358482980912216) -->
+ <skip />
+ <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+ <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+ <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+ <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Atšaukti"</string>
+ <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Ištrinti"</string>
+ <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Atlikta"</string>
+ <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Režimo keitimas"</string>
+ <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
+ <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Įvesti"</string>
+ <string name="description_target_unlock" msgid="2228524900439801453">"Atrakinti"</string>
+ <string name="description_target_camera" msgid="969071997552486814">"Vaizdo kamera"</string>
+ <string name="description_target_silent" msgid="893551287746522182">"Begarsis"</string>
+ <string name="description_target_soundon" msgid="30052466675500172">"Garsas įjungtas"</string>
+ <string name="description_target_search" msgid="3091587249776033139">"Paieška"</string>
+ <string name="description_direction_up" msgid="7169032478259485180">"Slyskite aukštyn link <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_down" msgid="5087739728639014595">"Slyskite žemyn link <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_left" msgid="7207478719805562165">"Slyskite į kairę link <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_right" msgid="8034433242579600980">"Slyskite į dešinę link <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="user_switched" msgid="3768006783166984410">"Dabartinis naudotojas: <xliff:g id="NAME">%1$s</xliff:g>."</string>
+ <string name="kg_emergency_call_label" msgid="684946192523830531">"Skambutis pagalbos numeriu"</string>
+ <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Pamiršau atrakinimo piešinį"</string>
+ <string name="kg_wrong_pattern" msgid="1850806070801358830">"Netinkamas atrakinimo piešinys"</string>
+ <string name="kg_wrong_password" msgid="2333281762128113157">"Netinkamas slaptažodis"</string>
+ <string name="kg_wrong_pin" msgid="1131306510833563801">"Netinkamas PIN kodas"</string>
+ <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Bandyti dar kartą po <xliff:g id="NUMBER">%d</xliff:g> sek."</string>
+ <string name="kg_pattern_instructions" msgid="398978611683075868">"Nupieškite atrakinimo piešinį"</string>
+ <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Įveskite SIM PIN kodą"</string>
+ <string name="kg_pin_instructions" msgid="2377242233495111557">"Įveskite PIN kodą"</string>
+ <string name="kg_password_instructions" msgid="5753646556186936819">"Įveskite slaptažodį"</string>
+ <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"Dabar SIM neleidžiama. Jei norite tęsti, įveskite PUK kodą. Jei reikia išsamios informacijos, susisiekite su operatoriumi."</string>
+ <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Įveskite pageidaujamą PIN kodą"</string>
+ <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Patvirtinkite pageidaujamą PIN kodą"</string>
+ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Atrakinama SIM kortelė…"</string>
+ <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Netinkamas PIN kodas."</string>
+ <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Įveskite PIN kodą, sudarytą iš 4–8 skaičių."</string>
+ <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK kodas turėtų būti mažiausiai 8 skaitmenų."</string>
+ <string name="kg_invalid_puk" msgid="3638289409676051243">"Pakartotinai įveskite tinkamą PUK kodą. Pakartotinai bandant SIM bus neleidžiama visam laikui."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN kodai neatitinka"</string>
+ <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Per daug atrakinimo piešinių bandymų"</string>
+ <string name="kg_login_instructions" msgid="1100551261265506448">"Jei norite atrakinti, prisijunkite naudodami „Google“ paskyrą."</string>
+ <string name="kg_login_username_hint" msgid="5718534272070920364">"Naudotojo vardas (el. paštas)"</string>
+ <string name="kg_login_password_hint" msgid="9057289103827298549">"Slaptažodis"</string>
+ <string name="kg_login_submit_button" msgid="5355904582674054702">"Prisijungti"</string>
+ <string name="kg_login_invalid_input" msgid="5754664119319872197">"Netinkamas naudotojo vardas ar slaptažodis."</string>
+ <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Pamiršote naudotojo vardą ar slaptažodį?"\n"Apsilankykite šiuo adresu: "<b>"google.com/accounts/recovery"</b></string>
+ <string name="kg_login_checking_password" msgid="1052685197710252395">"Tikrinama paskyra…"</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"PIN kodą netinkamai įvedėte <xliff:g id="NUMBER_0">%d</xliff:g> k. "\n\n"Bandykite dar kartą po <xliff:g id="NUMBER_1">%d</xliff:g> sek."</string>
+ <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Neteisingai įvedėte slaptažodį <xliff:g id="NUMBER_0">%d</xliff:g> k. "\n\n"Bandykite dar kartą po <xliff:g id="NUMBER_1">%d</xliff:g> sek."</string>
+ <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Netinkamai nupiešėte atrakinimo piešinį <xliff:g id="NUMBER_0">%d</xliff:g> k. "\n\n"Bandykite dar kartą po <xliff:g id="NUMBER_1">%d</xliff:g> sek."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"<xliff:g id="NUMBER_0">%d</xliff:g> k. bandėte netinkamai atrakinti planšetinį kompiuterį. Po dar <xliff:g id="NUMBER_1">%d</xliff:g> nesėkm. band. planšetiniame kompiuteryje bus iš naujo nustatyti numatytieji gamyklos nustatymai ir bus prarasti visi naudotojo duomenys."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"<xliff:g id="NUMBER_0">%d</xliff:g> k. bandėte netinkamai atrakinti telefoną. Po dar <xliff:g id="NUMBER_1">%d</xliff:g> nesėkm. band. telefone bus iš naujo nustatyti numatytieji gamyklos nustatymai ir bus prarasti visi naudotojo duomenys."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"<xliff:g id="NUMBER">%d</xliff:g> k. bandėte netinkamai atrakinti planšetinį kompiuterį. Planšetiniame kompiuteryje bus iš naujo nustatyti numatytieji gamyklos nustatymai."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"<xliff:g id="NUMBER">%d</xliff:g> k. bandėte netinkamai atrakinti telefoną. Telefone bus iš naujo nustatyti numatytieji gamyklos nustatymai."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Netinkamai nupiešėte atrakinimo piešinį <xliff:g id="NUMBER_0">%d</xliff:g> k. Po dar <xliff:g id="NUMBER_1">%d</xliff:g> nesėkm. band. būsite paprašyti atrakinti planšetinį kompiuterį naudodami „Google“ prisijungimo duomenis."\n\n" Bandykite dar kartą po <xliff:g id="NUMBER_2">%d</xliff:g> sek."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Netinkamai nupiešėte atrakinimo piešinį <xliff:g id="NUMBER_0">%d</xliff:g> k. Po dar <xliff:g id="NUMBER_1">%d</xliff:g> nesėkm. band. būsite paprašyti atrakinti telefoną naudodami „Google“ prisijungimo duomenis."\n\n" Bandykite dar kartą po <xliff:g id="NUMBER_2">%d</xliff:g> sek."</string>
+ <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" – "</string>
+ <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Pašalinti"</string>
+ <!-- no translation found for keyguard_transport_prev_description (8229108430245669854) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_next_description (4299258300283778305) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_pause_description (5093073338238310224) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_play_description (2924628863741150956) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_stop_description (3084179324810575787) -->
+ <skip />
+ <!-- no translation found for keyguard_carrier_default (8700650403054042153) -->
+ <skip />
+</resources>
diff --git a/packages/Keyguard/res/values-lv/strings.xml b/packages/Keyguard/res/values-lv/strings.xml
new file mode 100644
index 0000000..94cae47
--- /dev/null
+++ b/packages/Keyguard/res/values-lv/strings.xml
@@ -0,0 +1,164 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/* //device/apps/common/assets/res/any/strings.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:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Ievadiet PIN kodu."</string>
+ <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Ievadiet PUK kodu un jaunu PIN kodu."</string>
+ <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK kods"</string>
+ <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Jauns PIN kods"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Pieskarieties, lai ievadītu paroli"</font>"."</string>
+ <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Ievadiet paroli, lai atbloķētu."</string>
+ <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Lai atbloķētu, ievadiet PIN."</string>
+ <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"PIN kods nav pareizs."</string>
+ <string name="keyguard_label_text" msgid="861796461028298424">"Lai atbloķētu, nospiediet Izvēlne, pēc tam 0."</string>
+ <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Ir pārsniegts maksimālais Autorizācijas pēc sejas mēģinājumu skaits."</string>
+ <!-- no translation found for keyguard_charged (3272223906073492454) -->
+ <skip />
+ <!-- no translation found for keyguard_plugged_in (8117572000639998388) -->
+ <skip />
+ <!-- no translation found for keyguard_low_battery (8143808018719173859) -->
+ <skip />
+ <!-- no translation found for keyguard_instructions_when_pattern_disabled (1332288268600329841) -->
+ <skip />
+ <!-- no translation found for keyguard_network_locked_message (9169717779058037168) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message_short (494980561304211931) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (1445849005909260039) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (3481110395508637643) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions (5210891509995942250) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions_long (5968985489463870358) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_message_short (8340813989586622356) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_instructions (5892940909699723544) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_locked_message (6875773413306380902) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_puk_locked_message (3747232467471801633) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_unlock_progress_dialog_message (7975221805033614426) -->
+ <skip />
+ <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. %2$d. logrīks no %3$d."</string>
+ <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Pievienot logrīku."</string>
+ <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Tukšs"</string>
+ <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Atbloķēšanas apgabals ir izvērsts."</string>
+ <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Atbloķēšanas apgabals ir sakļauts."</string>
+ <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"Logrīks <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>."</string>
+ <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"Lietotāju atlasītājs"</string>
+ <string name="keyguard_accessibility_status" msgid="8008264603935930611">"Statuss"</string>
+ <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"Kamera"</string>
+ <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Multivides vadīklas"</string>
+ <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Logrīku pārkārtošana ir sākta."</string>
+ <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Logrīku pārkārtošana ir pabeigta."</string>
+ <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Logrīks <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> ir izdzēsts."</string>
+ <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Izvērst atbloķēšanas apgabalu."</string>
+ <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Autorizācija, velkot ar pirkstu."</string>
+ <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Autorizācija ar kombināciju."</string>
+ <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Autorizācija pēc sejas."</string>
+ <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Autorizācija ar PIN kodu."</string>
+ <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Autorizācija ar paroli."</string>
+ <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Kombinācijas ievades apgabals."</string>
+ <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Apgabals, kur vilkt ar pirkstu."</string>
+ <!-- no translation found for keyguard_accessibility_transport_prev_description (1337286538318543555) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_next_description (7073928300444909320) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_pause_description (8455979545295224302) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_play_description (8146417789511154044) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_stop_description (7656358482980912216) -->
+ <skip />
+ <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+ <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+ <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alternēšanas taustiņš"</string>
+ <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Atcelt"</string>
+ <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Dzēšanas taustiņš"</string>
+ <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Gatavs"</string>
+ <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Režīma maiņa"</string>
+ <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Pārslēgšanas taustiņš"</string>
+ <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Ievadīšanas taustiņš"</string>
+ <string name="description_target_unlock" msgid="2228524900439801453">"Atbloķēt"</string>
+ <string name="description_target_camera" msgid="969071997552486814">"Kamera"</string>
+ <string name="description_target_silent" msgid="893551287746522182">"Klusums"</string>
+ <string name="description_target_soundon" msgid="30052466675500172">"Skaņa ieslēgta"</string>
+ <string name="description_target_search" msgid="3091587249776033139">"Meklēt"</string>
+ <string name="description_direction_up" msgid="7169032478259485180">"Velciet uz augšu, lai veiktu šādu darbību: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_down" msgid="5087739728639014595">"Velciet uz leju, lai veiktu šādu darbību: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_left" msgid="7207478719805562165">"Velciet pa kreisi, lai veiktu šādu darbību: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_right" msgid="8034433242579600980">"Velciet pa labi, lai veiktu šādu darbību: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="user_switched" msgid="3768006783166984410">"Pašreizējais lietotājs: <xliff:g id="NAME">%1$s</xliff:g>."</string>
+ <string name="kg_emergency_call_label" msgid="684946192523830531">"Ārkārtas izsaukums"</string>
+ <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Aizmirsu kombināciju"</string>
+ <string name="kg_wrong_pattern" msgid="1850806070801358830">"Nepareiza kombinācija"</string>
+ <string name="kg_wrong_password" msgid="2333281762128113157">"Nepareiza parole"</string>
+ <string name="kg_wrong_pin" msgid="1131306510833563801">"Nepareizs PIN"</string>
+ <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Mēģiniet vēlreiz pēc <xliff:g id="NUMBER">%d</xliff:g> sekundēm."</string>
+ <string name="kg_pattern_instructions" msgid="398978611683075868">"Norādiet savu kombināciju"</string>
+ <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Ievadiet SIM kartes PIN"</string>
+ <string name="kg_pin_instructions" msgid="2377242233495111557">"Ievadiet PIN"</string>
+ <string name="kg_password_instructions" msgid="5753646556186936819">"Ievadiet paroli"</string>
+ <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"SIM karte ir atspējota. Lai turpinātu, ievadiet PUK kodu. Lai iegūtu detalizētu informāciju, sazinieties ar mobilo sakaru operatoru."</string>
+ <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Ievadiet vēlamo PIN kodu."</string>
+ <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Apstipriniet vēlamo PIN."</string>
+ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Notiek SIM kartes atbloķēšana..."</string>
+ <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"PIN kods nav pareizs."</string>
+ <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Ievadiet PIN, kas sastāv no 4 līdz 8 cipariem."</string>
+ <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK kodam ir jābūt vismaz 8 ciparus garam."</string>
+ <string name="kg_invalid_puk" msgid="3638289409676051243">"Atkārtoti ievadiet pareizo PUK kodu. Ja vairākas reizes ievadīsiet to nepareizi, SIM karte tiks neatgriezeniski atspējota."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN kodi neatbilst."</string>
+ <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Pārāk daudz kombinācijas mēģinājumu"</string>
+ <string name="kg_login_instructions" msgid="1100551261265506448">"Lai atbloķētu, pierakstieties, izmantojot savu Google kontu."</string>
+ <string name="kg_login_username_hint" msgid="5718534272070920364">"Lietotājvārds (e-pasts)"</string>
+ <string name="kg_login_password_hint" msgid="9057289103827298549">"Parole"</string>
+ <string name="kg_login_submit_button" msgid="5355904582674054702">"Pierakstīties"</string>
+ <string name="kg_login_invalid_input" msgid="5754664119319872197">"Nederīgs lietotājvārds vai parole."</string>
+ <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Vai aizmirsāt lietotājvārdu vai paroli?"\n"Apmeklējiet vietni "<b>"google.com/accounts/recovery"</b>"."</string>
+ <string name="kg_login_checking_password" msgid="1052685197710252395">"Notiek konta pārbaude…"</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Jūs nepareizi ievadījāt PIN <xliff:g id="NUMBER_0">%d</xliff:g> reizes."\n\n"Mēģiniet vēlreiz pēc <xliff:g id="NUMBER_1">%d</xliff:g> sekundēm."</string>
+ <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Jūs nepareizi ievadījāt paroli <xliff:g id="NUMBER_0">%d</xliff:g> reizes."\n\n"Mēģiniet vēlreiz pēc <xliff:g id="NUMBER_1">%d</xliff:g> sekundēm."</string>
+ <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Jūs nepareizi norādījāt atbloķēšanas kombināciju <xliff:g id="NUMBER_0">%d</xliff:g> reizes."\n\n"Mēģiniet vēlreiz pēc <xliff:g id="NUMBER_1">%d</xliff:g> sekundēm."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Jūs nepareizi veicāt planšetdatora atbloķēšanu <xliff:g id="NUMBER_0">%d</xliff:g> reizes. Pēc vēl <xliff:g id="NUMBER_1">%d</xliff:g> neveiksmīgiem mēģinājumiem planšetdatorā tiks atiestatīti rūpnīcas noklusējuma iestatījumi un lietotāja dati tiks zaudēti."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Jūs nepareizi veicāt tālruņa atbloķēšanu <xliff:g id="NUMBER_0">%d</xliff:g> reizes. Pēc vēl <xliff:g id="NUMBER_1">%d</xliff:g> neveiksmīgiem mēģinājumiem tālrunī tiks atiestatīti rūpnīcas noklusējuma iestatījumi un lietotāja dati tiks zaudēti."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Jūs nepareizi veicāt planšetdatora atbloķēšanu <xliff:g id="NUMBER">%d</xliff:g> reizes. Planšetdatorā tiks atiestatīti rūpnīcas noklusējuma iestatījumi."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Jūs nepareizi veicāt tālruņa atbloķēšanu <xliff:g id="NUMBER">%d</xliff:g> reizes. Tālrunī tiks atiestatīti rūpnīcas noklusējuma iestatījumi."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Jūs nepareizi norādījāt atbloķēšanas kombināciju <xliff:g id="NUMBER_0">%d</xliff:g> reizes. Pēc vēl <xliff:g id="NUMBER_1">%d</xliff:g> neveiksmīgiem mēģinājumiem planšetdators būs jāatbloķē, izmantojot e-pasta kontu."\n\n"Mēģiniet vēlreiz pēc <xliff:g id="NUMBER_2">%d</xliff:g> sekundēm."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Jūs nepareizi norādījāt atbloķēšanas kombināciju <xliff:g id="NUMBER_0">%d</xliff:g> reizes. Pēc vēl <xliff:g id="NUMBER_1">%d</xliff:g> neveiksmīgiem mēģinājumiem tālrunis būs jāatbloķē, izmantojot e-pasta kontu."\n\n"Mēģiniet vēlreiz pēc <xliff:g id="NUMBER_2">%d</xliff:g> sekundēm."</string>
+ <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">"  — "</string>
+ <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Noņemt"</string>
+ <!-- no translation found for keyguard_transport_prev_description (8229108430245669854) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_next_description (4299258300283778305) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_pause_description (5093073338238310224) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_play_description (2924628863741150956) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_stop_description (3084179324810575787) -->
+ <skip />
+ <!-- no translation found for keyguard_carrier_default (8700650403054042153) -->
+ <skip />
+</resources>
diff --git a/packages/Keyguard/res/values-ms/strings.xml b/packages/Keyguard/res/values-ms/strings.xml
new file mode 100644
index 0000000..99efc11
--- /dev/null
+++ b/packages/Keyguard/res/values-ms/strings.xml
@@ -0,0 +1,164 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/* //device/apps/common/assets/res/any/strings.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:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Taip kod PIN"</string>
+ <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Taip PUK dan kod PIN baharu"</string>
+ <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"Kod PUK"</string>
+ <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Kod PIN Baharu"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Sentuh untuk menaip kata laluan"</font></string>
+ <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Taip kata laluan untuk membuka kunci"</string>
+ <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Taip PIN untuk membuka kunci"</string>
+ <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Kod PIN salah."</string>
+ <string name="keyguard_label_text" msgid="861796461028298424">"Untuk membuka kunci, tekan Menu, kemudian 0."</string>
+ <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Telah melepasi had cubaan Buka Kunci Wajah"</string>
+ <!-- no translation found for keyguard_charged (3272223906073492454) -->
+ <skip />
+ <!-- no translation found for keyguard_plugged_in (8117572000639998388) -->
+ <skip />
+ <!-- no translation found for keyguard_low_battery (8143808018719173859) -->
+ <skip />
+ <!-- no translation found for keyguard_instructions_when_pattern_disabled (1332288268600329841) -->
+ <skip />
+ <!-- no translation found for keyguard_network_locked_message (9169717779058037168) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message_short (494980561304211931) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (1445849005909260039) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (3481110395508637643) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions (5210891509995942250) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions_long (5968985489463870358) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_message_short (8340813989586622356) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_instructions (5892940909699723544) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_locked_message (6875773413306380902) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_puk_locked_message (3747232467471801633) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_unlock_progress_dialog_message (7975221805033614426) -->
+ <skip />
+ <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d dari %3$d."</string>
+ <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Tambah widget."</string>
+ <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Kosong"</string>
+ <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Bahagian buka kunci dikembangkan."</string>
+ <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Bahagian buka kunci diruntuhkan."</string>
+ <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"Widget <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>."</string>
+ <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"Pemilih pengguna"</string>
+ <string name="keyguard_accessibility_status" msgid="8008264603935930611">"Status"</string>
+ <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"Kamera"</string>
+ <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Kawalan media"</string>
+ <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Penyusunan semula widget dimulakan."</string>
+ <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Penyusunan semula widget tamat."</string>
+ <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Widget <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> dipadamkan."</string>
+ <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Kembangkan bahagian buka kunci."</string>
+ <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Buka kunci luncur."</string>
+ <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Buka kunci corak."</string>
+ <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Wajah Buka Kunci"</string>
+ <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Buka kunci pin."</string>
+ <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Buka kunci kata laluan."</string>
+ <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Kawasan corak."</string>
+ <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Kawasan luncur."</string>
+ <!-- no translation found for keyguard_accessibility_transport_prev_description (1337286538318543555) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_next_description (7073928300444909320) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_pause_description (8455979545295224302) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_play_description (8146417789511154044) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_stop_description (7656358482980912216) -->
+ <skip />
+ <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+ <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+ <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+ <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Batal"</string>
+ <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Padam"</string>
+ <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Selesai"</string>
+ <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Perubahan mod"</string>
+ <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
+ <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Masuk"</string>
+ <string name="description_target_unlock" msgid="2228524900439801453">"Buka kunci"</string>
+ <string name="description_target_camera" msgid="969071997552486814">"Kamera"</string>
+ <string name="description_target_silent" msgid="893551287746522182">"Senyap"</string>
+ <string name="description_target_soundon" msgid="30052466675500172">"Bunyi dihidupkan"</string>
+ <string name="description_target_search" msgid="3091587249776033139">"Carian"</string>
+ <string name="description_direction_up" msgid="7169032478259485180">"Luncurkan ke atas untuk <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_down" msgid="5087739728639014595">"Luncurkan ke bawah untuk <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_left" msgid="7207478719805562165">"Luncurkan ke kiri untuk <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_right" msgid="8034433242579600980">"Luncurkan ke kanan untuk <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="user_switched" msgid="3768006783166984410">"Pengguna semasa <xliff:g id="NAME">%1$s</xliff:g>."</string>
+ <string name="kg_emergency_call_label" msgid="684946192523830531">"Panggilan kecemasan"</string>
+ <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Lupa Corak"</string>
+ <string name="kg_wrong_pattern" msgid="1850806070801358830">"Corak Salah"</string>
+ <string name="kg_wrong_password" msgid="2333281762128113157">"Kata Laluan Salah"</string>
+ <string name="kg_wrong_pin" msgid="1131306510833563801">"PIN salah"</string>
+ <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Cuba lagi dalam <xliff:g id="NUMBER">%d</xliff:g> saat."</string>
+ <string name="kg_pattern_instructions" msgid="398978611683075868">"Lukiskan corak anda"</string>
+ <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Masukkan PIN SIM"</string>
+ <string name="kg_pin_instructions" msgid="2377242233495111557">"Masukkan PIN"</string>
+ <string name="kg_password_instructions" msgid="5753646556186936819">"Masukkan Kata Laluan"</string>
+ <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"Kini SIM dilumpuhkan. Masukkan kod PUK untuk meneruskan. Hubungi pembawa untuk butiran."</string>
+ <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Masukkan kod PIN yang diingini"</string>
+ <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Sahkan kod PIN yang diingini"</string>
+ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Membuka kunci kad SIM..."</string>
+ <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Kod PIN salah."</string>
+ <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Taipkan PIN yang mengandungi 4 hingga 8 nombor."</string>
+ <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"Kod PUK mestilah 8 nombor atau lebih."</string>
+ <string name="kg_invalid_puk" msgid="3638289409676051243">"Masukkan semula kod PIN yang betul. Percubaan berulang akan melumpuhkan SIM secara kekal."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"Kod PIN tidak sepadan"</string>
+ <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Terlalu banyak percubaan melukis corak"</string>
+ <string name="kg_login_instructions" msgid="1100551261265506448">"Untuk membuka kunci, log masuk dengan akaun Google anda."</string>
+ <string name="kg_login_username_hint" msgid="5718534272070920364">"Nama Pengguna (E-mel)"</string>
+ <string name="kg_login_password_hint" msgid="9057289103827298549">"Kata laluan"</string>
+ <string name="kg_login_submit_button" msgid="5355904582674054702">"Log masuk"</string>
+ <string name="kg_login_invalid_input" msgid="5754664119319872197">"Nama pengguna atau kata laluan tidak sah."</string>
+ <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Lupa nama pengguna atau kata laluan anda?"\n"Lawati"<b>"google.com/accounts/recovery"</b>"."</string>
+ <string name="kg_login_checking_password" msgid="1052685197710252395">"Menyemak akaun…"</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Anda telah menaip PIN anda secara salah sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. "\n\n"Cuba lagi dalam <xliff:g id="NUMBER_1">%d</xliff:g> saat."</string>
+ <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Anda telah menaip kata laluan anda secara salah sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. "\n\n"Cuba lagi dalam <xliff:g id="NUMBER_1">%d</xliff:g> saat."</string>
+ <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Anda telah tersilap melukis corak buka kunci anda sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. "\n\n"Cuba lagi dalam <xliff:g id="NUMBER_1">%d</xliff:g> saat."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Anda telah mencuba untuk membuka kunci tablet dengan salah sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%d</xliff:g> lagi percubaan yang tidak berjaya, tablet akan ditetapkan semula kepada tetapan lalai kilang dan semua data pengguna akan hilang."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Anda telah mencuba untuk membuka kunci telefon dengan salah sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%d</xliff:g> lagi percubaan yang tidak berjaya, telefon akan ditetapkan semula kepada tetapan lalai kilang dan semua data pengguna akan hilang."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Anda telah mencuba untuk membuka kunci tablet secara salah sebanyak <xliff:g id="NUMBER">%d</xliff:g> kali. Tablet kini akan ditetapkan semula ke tetapan lalai kilang."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Anda telah mencuba untuk membuka kunci telefon secara salah sebanyak <xliff:g id="NUMBER">%d</xliff:g> kali. Telefon kini akan ditetapkan semula ke tetapan lalai kilang."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Anda telah tersilap melukis corak buka kunci sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%d</xliff:g> lagi percubaan yang tidak berjaya, anda akan diminta membuka kunci tablet anda menggunakan log masuk Google anda."\n\n" Cuba lagi dalam <xliff:g id="NUMBER_2">%d</xliff:g> saat."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Anda telah tersilap lukis corak buka kunci sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%d</xliff:g> lagi percubaan yang tidak berjaya, anda akan diminta membuka kunci telefon anda menggunakan log masuk Google anda."\n\n" Cuba lagi dalam <xliff:g id="NUMBER_2">%d</xliff:g> saat."</string>
+ <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
+ <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Alih keluar"</string>
+ <!-- no translation found for keyguard_transport_prev_description (8229108430245669854) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_next_description (4299258300283778305) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_pause_description (5093073338238310224) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_play_description (2924628863741150956) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_stop_description (3084179324810575787) -->
+ <skip />
+ <!-- no translation found for keyguard_carrier_default (8700650403054042153) -->
+ <skip />
+</resources>
diff --git a/packages/Keyguard/res/values-nb/strings.xml b/packages/Keyguard/res/values-nb/strings.xml
new file mode 100644
index 0000000..b8e3be3
--- /dev/null
+++ b/packages/Keyguard/res/values-nb/strings.xml
@@ -0,0 +1,164 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/* //device/apps/common/assets/res/any/strings.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:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Skriv inn PIN-kode"</string>
+ <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Skriv inn PUK-kode og ny personlig kode"</string>
+ <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK-kode"</string>
+ <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Ny PIN-kode"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Trykk for å skrive inn passord"</font></string>
+ <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Skriv inn passord for å låse opp"</string>
+ <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Skriv inn PIN-kode for å låse opp"</string>
+ <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Feil personlig kode."</string>
+ <string name="keyguard_label_text" msgid="861796461028298424">"For å låse opp, trykk på menyknappen og deretter 0."</string>
+ <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Du har overskredet grensen for opplåsingsforsøk med Ansiktslås"</string>
+ <!-- no translation found for keyguard_charged (3272223906073492454) -->
+ <skip />
+ <!-- no translation found for keyguard_plugged_in (8117572000639998388) -->
+ <skip />
+ <!-- no translation found for keyguard_low_battery (8143808018719173859) -->
+ <skip />
+ <!-- no translation found for keyguard_instructions_when_pattern_disabled (1332288268600329841) -->
+ <skip />
+ <!-- no translation found for keyguard_network_locked_message (9169717779058037168) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message_short (494980561304211931) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (1445849005909260039) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (3481110395508637643) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions (5210891509995942250) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions_long (5968985489463870358) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_message_short (8340813989586622356) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_instructions (5892940909699723544) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_locked_message (6875773413306380902) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_puk_locked_message (3747232467471801633) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_unlock_progress_dialog_message (7975221805033614426) -->
+ <skip />
+ <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Modul %2$d av %3$d."</string>
+ <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Legg til modul."</string>
+ <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Tom"</string>
+ <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Opplåsingsfeltet vises."</string>
+ <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Opplåsingsfeltet skjules."</string>
+ <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g>-modul."</string>
+ <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"Brukervelgeren"</string>
+ <string name="keyguard_accessibility_status" msgid="8008264603935930611">"Status"</string>
+ <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"Kamera"</string>
+ <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Mediekontroll"</string>
+ <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Endring av modulplasseringen har startet."</string>
+ <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Endringen av modulplasseringen er ferdig."</string>
+ <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Modulen <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> ble slettet."</string>
+ <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Vis opplåsingsfeltet."</string>
+ <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Opplåsning ved å dra med fingeren."</string>
+ <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Mønsteropplåsning."</string>
+ <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Ansiktsopplåsning."</string>
+ <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"PIN-opplåsning."</string>
+ <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Passordopplåsning."</string>
+ <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Mønsterområde."</string>
+ <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Dra-felt."</string>
+ <!-- no translation found for keyguard_accessibility_transport_prev_description (1337286538318543555) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_next_description (7073928300444909320) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_pause_description (8455979545295224302) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_play_description (8146417789511154044) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_stop_description (7656358482980912216) -->
+ <skip />
+ <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+ <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+ <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+ <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Avbryt"</string>
+ <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Slett"</string>
+ <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Ferdig"</string>
+ <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Modusendring"</string>
+ <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
+ <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
+ <string name="description_target_unlock" msgid="2228524900439801453">"Lås opp"</string>
+ <string name="description_target_camera" msgid="969071997552486814">"Kamera"</string>
+ <string name="description_target_silent" msgid="893551287746522182">"Stille"</string>
+ <string name="description_target_soundon" msgid="30052466675500172">"Lyd på"</string>
+ <string name="description_target_search" msgid="3091587249776033139">"Søk"</string>
+ <string name="description_direction_up" msgid="7169032478259485180">"Dra opp for å <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_down" msgid="5087739728639014595">"Dra ned for å <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_left" msgid="7207478719805562165">"Dra til venstre for å <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_right" msgid="8034433242579600980">"Dra til høyre for å <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="user_switched" msgid="3768006783166984410">"Gjeldende bruker: <xliff:g id="NAME">%1$s</xliff:g>."</string>
+ <string name="kg_emergency_call_label" msgid="684946192523830531">"Nødnummer"</string>
+ <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Har du glemt mønsteret?"</string>
+ <string name="kg_wrong_pattern" msgid="1850806070801358830">"Feil mønster"</string>
+ <string name="kg_wrong_password" msgid="2333281762128113157">"Feil passord"</string>
+ <string name="kg_wrong_pin" msgid="1131306510833563801">"Feil PIN-kode"</string>
+ <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Prøv på nytt om <xliff:g id="NUMBER">%d</xliff:g> sekunder."</string>
+ <string name="kg_pattern_instructions" msgid="398978611683075868">"Tegn mønsteret ditt"</string>
+ <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Skriv inn PIN-koden for SIM-kortet"</string>
+ <string name="kg_pin_instructions" msgid="2377242233495111557">"Skriv inn PIN-koden"</string>
+ <string name="kg_password_instructions" msgid="5753646556186936819">"Skriv inn passordet"</string>
+ <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"SIM-kortet er nå deaktivert. Skriv inn PUK-koden for å fortsette. Ta kontakt med operatøren for mer informasjon."</string>
+ <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Tast inn ønsket PIN-kode"</string>
+ <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Bekreft ønsket PIN-kode"</string>
+ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Låser opp SIM-kortet ..."</string>
+ <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Feil PIN-kode."</string>
+ <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Skriv inn en PIN-kode på fire til åtte sifre."</string>
+ <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK-koden skal være på åtte eller flere siffer."</string>
+ <string name="kg_invalid_puk" msgid="3638289409676051243">"Skriv inn den korrekte PUK-koden på nytt. Gjentatte forsøk kommer til å deaktivere SIM-kortet."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN-kodene stemmer ikke overens"</string>
+ <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"For mange forsøk på tegning av mønster"</string>
+ <string name="kg_login_instructions" msgid="1100551261265506448">"Logg deg på med Google-kontoen din for å låse opp."</string>
+ <string name="kg_login_username_hint" msgid="5718534272070920364">"Brukernavn (e-postadresse)"</string>
+ <string name="kg_login_password_hint" msgid="9057289103827298549">"Passord"</string>
+ <string name="kg_login_submit_button" msgid="5355904582674054702">"Logg på"</string>
+ <string name="kg_login_invalid_input" msgid="5754664119319872197">"Ugyldig brukernavn eller passord."</string>
+ <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Har du glemt brukernavnet eller passordet?"\n"Gå til "<b>"google.com/accounts/recovery"</b>"."</string>
+ <string name="kg_login_checking_password" msgid="1052685197710252395">"Sjekker kontoen ..."</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Du har oppgitt feil PIN-kode <xliff:g id="NUMBER_0">%d</xliff:g> ganger. "\n\n"Prøv på nytt om <xliff:g id="NUMBER_1">%d</xliff:g> sekunder."</string>
+ <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Du har tastet inn passordet ditt feil <xliff:g id="NUMBER_0">%d</xliff:g> ganger. "\n\n"Prøv på nytt om <xliff:g id="NUMBER_1">%d</xliff:g> sekunder."</string>
+ <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Du har tegnet opplåsningsmønsteret ditt feil <xliff:g id="NUMBER_0">%d</xliff:g> ganger. "\n\n"Prøv på nytt om <xliff:g id="NUMBER_1">%d</xliff:g> sekunder."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Du har oppgitt feil opplåsningspassord for nettbrettet <xliff:g id="NUMBER_0">%d</xliff:g> ganger. Etter ytterligere <xliff:g id="NUMBER_1">%d</xliff:g> gale forsøk, tilbakestilles nettbrettet til fabrikkstandard og all data går tapt."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Du har oppgitt feil opplåsningspassord for telefonen <xliff:g id="NUMBER_0">%d</xliff:g> ganger. Etter ytterligere <xliff:g id="NUMBER_1">%d</xliff:g> gale forsøk, tilbakestilles telefonen til fabrikkstandard og all data går tapt."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Du har oppgitt feil opplåsningspassord for nettbrettet <xliff:g id="NUMBER">%d</xliff:g> ganger. Telefonen tilbakestilles nå til fabrikkstandard."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Du har oppgitt feil opplåsningspassord for telefonen <xliff:g id="NUMBER">%d</xliff:g> ganger. Telefonen tilbakestilles nå til fabrikkstandard."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Du har tegnet opplåsningsmønsteret feil <xliff:g id="NUMBER_0">%d</xliff:g> ganger. Etter ytterligere <xliff:g id="NUMBER_1">%d</xliff:g> gale forsøk, blir du bedt om å låse opp nettbrettet via en e-postkonto."\n\n" Prøv på nytt om <xliff:g id="NUMBER_2">%d</xliff:g> sekunder."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Du har tegnet opplåsningsmønsteret feil <xliff:g id="NUMBER_0">%d</xliff:g> ganger. Etter ytterligere <xliff:g id="NUMBER_1">%d</xliff:g> gale forsøk, blir du bedt om å låse opp telefonen via en e-postkonto."\n\n" Prøv på nytt om <xliff:g id="NUMBER_2">%d</xliff:g> sekunder."</string>
+ <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
+ <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Fjern"</string>
+ <!-- no translation found for keyguard_transport_prev_description (8229108430245669854) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_next_description (4299258300283778305) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_pause_description (5093073338238310224) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_play_description (2924628863741150956) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_stop_description (3084179324810575787) -->
+ <skip />
+ <!-- no translation found for keyguard_carrier_default (8700650403054042153) -->
+ <skip />
+</resources>
diff --git a/packages/Keyguard/res/values-nl/strings.xml b/packages/Keyguard/res/values-nl/strings.xml
new file mode 100644
index 0000000..250e7c9
--- /dev/null
+++ b/packages/Keyguard/res/values-nl/strings.xml
@@ -0,0 +1,164 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/* //device/apps/common/assets/res/any/strings.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:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Pincode typen"</string>
+ <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Geef de PUK-code en de nieuwe pincode op"</string>
+ <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK-code"</string>
+ <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Nieuwe pincode"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Raak aan om wachtwoord in te voeren"</font></string>
+ <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Typ het wachtwoord om te ontgrendelen"</string>
+ <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Typ pincode om te ontgrendelen"</string>
+ <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Onjuiste pincode."</string>
+ <string name="keyguard_label_text" msgid="861796461028298424">"Druk op \'Menu\' en vervolgens op 0 om te ontgrendelen."</string>
+ <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Maximaal aantal pogingen voor Face Unlock overschreden"</string>
+ <!-- no translation found for keyguard_charged (3272223906073492454) -->
+ <skip />
+ <!-- no translation found for keyguard_plugged_in (8117572000639998388) -->
+ <skip />
+ <!-- no translation found for keyguard_low_battery (8143808018719173859) -->
+ <skip />
+ <!-- no translation found for keyguard_instructions_when_pattern_disabled (1332288268600329841) -->
+ <skip />
+ <!-- no translation found for keyguard_network_locked_message (9169717779058037168) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message_short (494980561304211931) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (1445849005909260039) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (3481110395508637643) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions (5210891509995942250) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions_long (5968985489463870358) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_message_short (8340813989586622356) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_instructions (5892940909699723544) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_locked_message (6875773413306380902) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_puk_locked_message (3747232467471801633) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_unlock_progress_dialog_message (7975221805033614426) -->
+ <skip />
+ <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d van %3$d."</string>
+ <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Widget toevoegen."</string>
+ <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Leeg"</string>
+ <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Ontgrendelingsgebied uitgevouwen."</string>
+ <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Ontgrendelingsgebied samengevouwen."</string>
+ <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"Widget <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>."</string>
+ <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"Gebruikersselectie"</string>
+ <string name="keyguard_accessibility_status" msgid="8008264603935930611">"Status"</string>
+ <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"Camera"</string>
+ <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Mediabediening"</string>
+ <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Opnieuw indelen van widget gestart."</string>
+ <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Opnieuw indelen van widget beëindigd."</string>
+ <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Widget <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> verwijderd."</string>
+ <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Ontgrendelingsgebied uitvouwen."</string>
+ <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Ontgrendeling via schuiven."</string>
+ <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Ontgrendeling via patroon."</string>
+ <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Ontgrendeling via gezichtsherkenning."</string>
+ <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Ontgrendeling via pincode."</string>
+ <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Ontgrendeling via wachtwoord."</string>
+ <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Tekengebied voor patroon."</string>
+ <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Schuifgebied."</string>
+ <!-- no translation found for keyguard_accessibility_transport_prev_description (1337286538318543555) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_next_description (7073928300444909320) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_pause_description (8455979545295224302) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_play_description (8146417789511154044) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_stop_description (7656358482980912216) -->
+ <skip />
+ <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+ <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+ <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"Alt"</string>
+ <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+ <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Annuleren"</string>
+ <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Delete"</string>
+ <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Gereed"</string>
+ <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Modus wijzigen"</string>
+ <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
+ <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
+ <string name="description_target_unlock" msgid="2228524900439801453">"Ontgrendelen"</string>
+ <string name="description_target_camera" msgid="969071997552486814">"Camera"</string>
+ <string name="description_target_silent" msgid="893551287746522182">"Stil"</string>
+ <string name="description_target_soundon" msgid="30052466675500172">"Geluid aan"</string>
+ <string name="description_target_search" msgid="3091587249776033139">"Zoeken"</string>
+ <string name="description_direction_up" msgid="7169032478259485180">"Veeg omhoog voor <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_down" msgid="5087739728639014595">"Veeg omlaag voor <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_left" msgid="7207478719805562165">"Veeg naar links voor <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_right" msgid="8034433242579600980">"Veeg naar rechts voor <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="user_switched" msgid="3768006783166984410">"Huidige gebruiker <xliff:g id="NAME">%1$s</xliff:g>."</string>
+ <string name="kg_emergency_call_label" msgid="684946192523830531">"Noodoproep"</string>
+ <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Patroon vergeten"</string>
+ <string name="kg_wrong_pattern" msgid="1850806070801358830">"Onjuist patroon"</string>
+ <string name="kg_wrong_password" msgid="2333281762128113157">"Onjuist wachtwoord"</string>
+ <string name="kg_wrong_pin" msgid="1131306510833563801">"Onjuiste pincode"</string>
+ <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Probeer het over <xliff:g id="NUMBER">%d</xliff:g> seconden opnieuw."</string>
+ <string name="kg_pattern_instructions" msgid="398978611683075868">"Teken uw patroon"</string>
+ <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Geef de pincode van de simkaart op"</string>
+ <string name="kg_pin_instructions" msgid="2377242233495111557">"Pincode opgeven"</string>
+ <string name="kg_password_instructions" msgid="5753646556186936819">"Wachtwoord invoeren"</string>
+ <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"De simkaart is nu uitgeschakeld. Geef de PUK-code op om door te gaan. Neem contact op met de provider voor informatie."</string>
+ <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Gewenste pincode opgeven"</string>
+ <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Gewenste pincode bevestigen"</string>
+ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Simkaart ontgrendelen..."</string>
+ <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Onjuiste pincode."</string>
+ <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Voer een pincode van 4 tot 8 cijfers in."</string>
+ <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"De PUK-code is minimaal acht nummers lang."</string>
+ <string name="kg_invalid_puk" msgid="3638289409676051243">"Geef de juiste PUK-code opnieuw op. Bij herhaalde pogingen wordt de simkaart permanent uitgeschakeld."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"Pincodes komen niet overeen"</string>
+ <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Te veel patroonpogingen"</string>
+ <string name="kg_login_instructions" msgid="1100551261265506448">"Als u wilt ontgrendelen, moet u zich aanmelden bij uw Google-account."</string>
+ <string name="kg_login_username_hint" msgid="5718534272070920364">"Gebruikersnaam (e-mail)"</string>
+ <string name="kg_login_password_hint" msgid="9057289103827298549">"Wachtwoord"</string>
+ <string name="kg_login_submit_button" msgid="5355904582674054702">"Aanmelden"</string>
+ <string name="kg_login_invalid_input" msgid="5754664119319872197">"Ongeldige gebruikersnaam of wachtwoord."</string>
+ <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Bent u uw gebruikersnaam of wachtwoord vergeten?"\n"Ga naar "<b>"google.com/accounts/recovery"</b>"."</string>
+ <string name="kg_login_checking_password" msgid="1052685197710252395">"Account controleren…"</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"U heeft uw pincode <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getypt. "\n\n"Probeer het over <xliff:g id="NUMBER_1">%d</xliff:g> seconden opnieuw."</string>
+ <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"U heeft uw wachtwoord <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getypt. "\n\n"Probeer het over <xliff:g id="NUMBER_1">%d</xliff:g> seconden opnieuw."</string>
+ <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"U heeft uw ontgrendelingspatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getekend. "\n\n"Probeer het over <xliff:g id="NUMBER_1">%d</xliff:g> seconden opnieuw."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"U heeft <xliff:g id="NUMBER_0">%d</xliff:g> keer geprobeerd de tablet op een onjuiste manier te ontgrendelen. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen worden de fabrieksinstellingen hersteld op de tablet en gaan alle gebruikersgegevens verloren."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"U heeft nu <xliff:g id="NUMBER_0">%d</xliff:g> keer geprobeerd de telefoon op een onjuiste manier te ontgrendelen. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen worden de fabrieksinstellingen hersteld op de telefoon en gaan alle gebruikersgegevens verloren."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"U heeft <xliff:g id="NUMBER">%d</xliff:g> keer geprobeerd de tablet op een onjuiste manier te ontgrendelen. De fabrieksinstellingen worden nu hersteld op de tablet."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"U heeft <xliff:g id="NUMBER">%d</xliff:g> keer geprobeerd de telefoon op een onjuiste manier te ontgrendelen. De fabrieksinstellingen worden nu hersteld op de telefoon."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"U heeft uw ontgrendelingspatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getekend. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen wordt u gevraagd uw tablet te ontgrendelen via een e-mailaccount."\n\n" Probeer het over <xliff:g id="NUMBER_2">%d</xliff:g> seconden opnieuw."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"U heeft uw ontgrendelingspatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getekend. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen wordt u gevraagd uw telefoon te ontgrendelen via een e-mailaccount."\n\n" Probeer het over <xliff:g id="NUMBER_2">%d</xliff:g> seconden opnieuw."</string>
+ <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
+ <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Verwijderen"</string>
+ <!-- no translation found for keyguard_transport_prev_description (8229108430245669854) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_next_description (4299258300283778305) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_pause_description (5093073338238310224) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_play_description (2924628863741150956) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_stop_description (3084179324810575787) -->
+ <skip />
+ <!-- no translation found for keyguard_carrier_default (8700650403054042153) -->
+ <skip />
+</resources>
diff --git a/packages/Keyguard/res/values-pl/strings.xml b/packages/Keyguard/res/values-pl/strings.xml
new file mode 100644
index 0000000..6bb237a
--- /dev/null
+++ b/packages/Keyguard/res/values-pl/strings.xml
@@ -0,0 +1,164 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/* //device/apps/common/assets/res/any/strings.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:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Wpisz kod PIN."</string>
+ <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Wpisz kod PUK i nowy kod PIN."</string>
+ <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"Kod PUK"</string>
+ <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Nowy PIN"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Dotknij, aby wpisać hasło."</font></string>
+ <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Wpisz hasło, aby odblokować."</string>
+ <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Wpisz kod PIN, aby odblokować."</string>
+ <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Błędny kod PIN"</string>
+ <string name="keyguard_label_text" msgid="861796461028298424">"Aby odblokować, naciśnij Menu, a następnie 0."</string>
+ <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Przekroczono maksymalną liczbę prób rozpoznania twarzy."</string>
+ <!-- no translation found for keyguard_charged (3272223906073492454) -->
+ <skip />
+ <!-- no translation found for keyguard_plugged_in (8117572000639998388) -->
+ <skip />
+ <!-- no translation found for keyguard_low_battery (8143808018719173859) -->
+ <skip />
+ <!-- no translation found for keyguard_instructions_when_pattern_disabled (1332288268600329841) -->
+ <skip />
+ <!-- no translation found for keyguard_network_locked_message (9169717779058037168) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message_short (494980561304211931) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (1445849005909260039) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (3481110395508637643) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions (5210891509995942250) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions_long (5968985489463870358) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_message_short (8340813989586622356) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_instructions (5892940909699723544) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_locked_message (6875773413306380902) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_puk_locked_message (3747232467471801633) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_unlock_progress_dialog_message (7975221805033614426) -->
+ <skip />
+ <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widżet %2$d z %3$d."</string>
+ <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Dodaj widżet."</string>
+ <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Puste"</string>
+ <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Rozwinięto obszar odblokowania."</string>
+ <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Zwinięto obszar odblokowania."</string>
+ <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"Widżet <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>."</string>
+ <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"Wybór użytkownika"</string>
+ <string name="keyguard_accessibility_status" msgid="8008264603935930611">"Stan"</string>
+ <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"Aparat"</string>
+ <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Elementy sterujące multimediów"</string>
+ <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Rozpoczęto zmienianie kolejności widżetów."</string>
+ <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Zakończono zmienianie kolejności widżetów."</string>
+ <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Usunięto widżet <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>."</string>
+ <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Rozwiń obszar odblokowania."</string>
+ <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Odblokowanie przesunięciem."</string>
+ <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Odblokowanie wzorem."</string>
+ <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Rozpoznanie twarzy"</string>
+ <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Odblokowanie kodem PIN."</string>
+ <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Odblokowanie hasłem."</string>
+ <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Obszar wzoru."</string>
+ <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Obszar przesuwania."</string>
+ <!-- no translation found for keyguard_accessibility_transport_prev_description (1337286538318543555) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_next_description (7073928300444909320) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_pause_description (8455979545295224302) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_play_description (8146417789511154044) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_stop_description (7656358482980912216) -->
+ <skip />
+ <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+ <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+ <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+ <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Anuluj"</string>
+ <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Delete"</string>
+ <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Gotowe"</string>
+ <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Zmiana trybu"</string>
+ <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
+ <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
+ <string name="description_target_unlock" msgid="2228524900439801453">"Odblokuj"</string>
+ <string name="description_target_camera" msgid="969071997552486814">"Aparat"</string>
+ <string name="description_target_silent" msgid="893551287746522182">"Wyciszenie"</string>
+ <string name="description_target_soundon" msgid="30052466675500172">"Włącz dźwięk"</string>
+ <string name="description_target_search" msgid="3091587249776033139">"Szukaj"</string>
+ <string name="description_direction_up" msgid="7169032478259485180">"Przesuń w górę: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_down" msgid="5087739728639014595">"Przesuń w dół: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_left" msgid="7207478719805562165">"Przesuń w lewo: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_right" msgid="8034433242579600980">"Przesuń w prawo: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="user_switched" msgid="3768006783166984410">"Bieżący użytkownik: <xliff:g id="NAME">%1$s</xliff:g>."</string>
+ <string name="kg_emergency_call_label" msgid="684946192523830531">"Połączenie alarmowe"</string>
+ <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Nie pamiętam wzoru"</string>
+ <string name="kg_wrong_pattern" msgid="1850806070801358830">"Nieprawidłowy wzór"</string>
+ <string name="kg_wrong_password" msgid="2333281762128113157">"Nieprawidłowe hasło"</string>
+ <string name="kg_wrong_pin" msgid="1131306510833563801">"Nieprawidłowy PIN"</string>
+ <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Spróbuj ponownie za <xliff:g id="NUMBER">%d</xliff:g> s."</string>
+ <string name="kg_pattern_instructions" msgid="398978611683075868">"Narysuj wzór"</string>
+ <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Podaj PIN karty SIM"</string>
+ <string name="kg_pin_instructions" msgid="2377242233495111557">"Podaj PIN"</string>
+ <string name="kg_password_instructions" msgid="5753646556186936819">"Wpisz hasło"</string>
+ <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"Karta SIM została wyłączona. Podaj kod PUK, by przejść dalej. Szczegóły uzyskasz od operatora."</string>
+ <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Podaj wybrany kod PIN"</string>
+ <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Potwierdź wybrany kod PIN"</string>
+ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Odblokowuję kartę SIM…"</string>
+ <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Nieprawidłowy PIN."</string>
+ <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Wpisz PIN o długości od 4 do 8 cyfr."</string>
+ <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"Kod PUK musi mieć co najmniej 8 cyfr."</string>
+ <string name="kg_invalid_puk" msgid="3638289409676051243">"Ponownie podaj poprawny kod PUK. Nieudane próby spowodują trwałe wyłączenie karty SIM."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"Kody PIN nie pasują"</string>
+ <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Zbyt wiele prób narysowania wzoru"</string>
+ <string name="kg_login_instructions" msgid="1100551261265506448">"Aby odblokować, zaloguj się na konto Google."</string>
+ <string name="kg_login_username_hint" msgid="5718534272070920364">"Nazwa użytkownika (e-mail)"</string>
+ <string name="kg_login_password_hint" msgid="9057289103827298549">"Hasło"</string>
+ <string name="kg_login_submit_button" msgid="5355904582674054702">"Zaloguj się"</string>
+ <string name="kg_login_invalid_input" msgid="5754664119319872197">"Nieprawidłowa nazwa użytkownika lub hasło."</string>
+ <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Nie pamiętasz nazwy użytkownika lub hasła?"\n"Wejdź na "<b>"google.com/accounts/recovery"</b>"."</string>
+ <string name="kg_login_checking_password" msgid="1052685197710252395">"Sprawdzam konto"</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Po raz <xliff:g id="NUMBER_0">%d</xliff:g> wpisałeś nieprawidłowy PIN. "\n\n"Spróbuj ponownie za <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
+ <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Po raz <xliff:g id="NUMBER_0">%d</xliff:g> wpisałeś nieprawidłowe hasło. "\n\n"Spróbuj ponownie za <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
+ <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Po raz <xliff:g id="NUMBER_0">%d</xliff:g> narysowałeś nieprawidłowy wzór odblokowania. "\n\n"Spróbuj ponownie za <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Po raz <xliff:g id="NUMBER_0">%d</xliff:g> próbowałeś nieprawidłowo odblokować tablet. Po kolejnych <xliff:g id="NUMBER_1">%d</xliff:g> nieudanych próbach tablet zostanie zresetowany do ustawień fabrycznych, a wszystkie dane użytkownika zostaną utracone."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Po raz <xliff:g id="NUMBER_0">%d</xliff:g> próbowałeś nieprawidłowo odblokować telefon. Po kolejnych <xliff:g id="NUMBER_1">%d</xliff:g> nieudanych próbach telefon zostanie zresetowany do ustawień fabrycznych, a wszystkie dane użytkownika zostaną utracone."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Po raz <xliff:g id="NUMBER">%d</xliff:g> próbowałeś nieprawidłowo odblokować tablet. Tablet zostanie teraz zresetowany do ustawień fabrycznych."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Po raz <xliff:g id="NUMBER">%d</xliff:g> próbowałeś nieprawidłowo odblokować telefon. Telefon zostanie teraz zresetowany do ustawień fabrycznych."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Po raz <xliff:g id="NUMBER_0">%d</xliff:g> nieprawidłowo narysowałeś wzór odblokowania. Po kolejnych <xliff:g id="NUMBER_1">%d</xliff:g> nieudanych próbach konieczne będzie odblokowanie tabletu przy użyciu danych logowania na konto Google."\n\n" Spróbuj ponownie za <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Po raz <xliff:g id="NUMBER_0">%d</xliff:g> nieprawidłowo narysowałeś wzór odblokowania. Po kolejnych <xliff:g id="NUMBER_1">%d</xliff:g> nieudanych próbach konieczne będzie odblokowanie telefonu przy użyciu danych logowania na konto Google."\n\n" Spróbuj ponownie za <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
+ <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" – "</string>
+ <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Usuń"</string>
+ <!-- no translation found for keyguard_transport_prev_description (8229108430245669854) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_next_description (4299258300283778305) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_pause_description (5093073338238310224) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_play_description (2924628863741150956) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_stop_description (3084179324810575787) -->
+ <skip />
+ <!-- no translation found for keyguard_carrier_default (8700650403054042153) -->
+ <skip />
+</resources>
diff --git a/packages/Keyguard/res/values-port/alias.xml b/packages/Keyguard/res/values-port/alias.xml
new file mode 100644
index 0000000..c3ecbb9
--- /dev/null
+++ b/packages/Keyguard/res/values-port/alias.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/assets/res/any/colors.xml
+**
+** 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.
+*/
+-->
+<resources>
+ <!-- Alias used to reference one of two possible layouts in keyguard. -->
+ <item type="layout" name="keyguard_eca">@layout/keyguard_emergency_carrier_area</item>
+</resources>
diff --git a/packages/Keyguard/res/values-port/bools.xml b/packages/Keyguard/res/values-port/bools.xml
new file mode 100644
index 0000000..1e2a4f2
--- /dev/null
+++ b/packages/Keyguard/res/values-port/bools.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<resources>
+ <bool name="action_bar_embed_tabs">false</bool>
+ <bool name="kg_share_status_area">true</bool>
+ <bool name="kg_sim_puk_account_full_screen">true</bool>
+</resources>
diff --git a/packages/Keyguard/res/values-port/integers.xml b/packages/Keyguard/res/values-port/integers.xml
new file mode 100644
index 0000000..ef7e4da
--- /dev/null
+++ b/packages/Keyguard/res/values-port/integers.xml
@@ -0,0 +1,23 @@
+<?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.
+*/
+-->
+<resources>
+ <!-- Gravity to make KeyguardSelectorView work in multiple orientations
+ 0x31 == "top|center_horizontal" -->
+ <integer name="kg_selector_gravity">0x31</integer>
+</resources> \ No newline at end of file
diff --git a/packages/Keyguard/res/values-pt-rPT/strings.xml b/packages/Keyguard/res/values-pt-rPT/strings.xml
new file mode 100644
index 0000000..300ce43
--- /dev/null
+++ b/packages/Keyguard/res/values-pt-rPT/strings.xml
@@ -0,0 +1,164 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/* //device/apps/common/assets/res/any/strings.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:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Escreva o código PIN"</string>
+ <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Escreva o PUK e o novo código PIN"</string>
+ <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"Código PUK"</string>
+ <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Novo código PIN"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Toque para escrever a palavra-passe"</font></string>
+ <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Escreva a palavra-passe para desbloquear"</string>
+ <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Escreva o PIN para desbloquear"</string>
+ <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Código PIN incorreto."</string>
+ <string name="keyguard_label_text" msgid="861796461028298424">"Para desbloquear, prima Menu e, em seguida, 0."</string>
+ <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Excedido o n.º máximo de tentativas de Desbloqueio Através do Rosto"</string>
+ <!-- no translation found for keyguard_charged (3272223906073492454) -->
+ <skip />
+ <!-- no translation found for keyguard_plugged_in (8117572000639998388) -->
+ <skip />
+ <!-- no translation found for keyguard_low_battery (8143808018719173859) -->
+ <skip />
+ <!-- no translation found for keyguard_instructions_when_pattern_disabled (1332288268600329841) -->
+ <skip />
+ <!-- no translation found for keyguard_network_locked_message (9169717779058037168) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message_short (494980561304211931) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (1445849005909260039) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (3481110395508637643) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions (5210891509995942250) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions_long (5968985489463870358) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_message_short (8340813989586622356) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_instructions (5892940909699723544) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_locked_message (6875773413306380902) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_puk_locked_message (3747232467471801633) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_unlock_progress_dialog_message (7975221805033614426) -->
+ <skip />
+ <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d de %3$d."</string>
+ <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Adicionar widget."</string>
+ <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Vazio"</string>
+ <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Área de desbloqueio expandida."</string>
+ <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Área de desbloqueio minimizada."</string>
+ <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> widget."</string>
+ <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"Seletor de utilizadores"</string>
+ <string name="keyguard_accessibility_status" msgid="8008264603935930611">"Estado"</string>
+ <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"Câmara"</string>
+ <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Controlos de multimédia"</string>
+ <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Reordenação de widgets iniciada."</string>
+ <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Reordenação de widgets concluída."</string>
+ <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Widget <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> eliminado."</string>
+ <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Expandir área de desbloqueio."</string>
+ <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Desbloqueio através de deslize."</string>
+ <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Desbloqueio através de sequência."</string>
+ <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Desbloqueio através do rosto."</string>
+ <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Desbloqueio através de PIN."</string>
+ <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Desbloqueio através de palavra-passe."</string>
+ <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Área da sequência."</string>
+ <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Área de deslize."</string>
+ <!-- no translation found for keyguard_accessibility_transport_prev_description (1337286538318543555) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_next_description (7073928300444909320) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_pause_description (8455979545295224302) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_play_description (8146417789511154044) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_stop_description (7656358482980912216) -->
+ <skip />
+ <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+ <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+ <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+ <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Cancelar"</string>
+ <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Delete"</string>
+ <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Concluído"</string>
+ <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Alteração do modo"</string>
+ <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
+ <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
+ <string name="description_target_unlock" msgid="2228524900439801453">"Desbloquear"</string>
+ <string name="description_target_camera" msgid="969071997552486814">"Câmara"</string>
+ <string name="description_target_silent" msgid="893551287746522182">"Silencioso"</string>
+ <string name="description_target_soundon" msgid="30052466675500172">"Som ativado"</string>
+ <string name="description_target_search" msgid="3091587249776033139">"Pesquisar"</string>
+ <string name="description_direction_up" msgid="7169032478259485180">"Deslize para cima para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string>
+ <string name="description_direction_down" msgid="5087739728639014595">"Deslize para baixo para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string>
+ <string name="description_direction_left" msgid="7207478719805562165">"Deslize para a esquerda para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string>
+ <string name="description_direction_right" msgid="8034433242579600980">"Deslize para a direita para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string>
+ <string name="user_switched" msgid="3768006783166984410">"<xliff:g id="NAME">%1$s</xliff:g> do utilizador atual."</string>
+ <string name="kg_emergency_call_label" msgid="684946192523830531">"Chamada de emergência"</string>
+ <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Esqueceu-se da Sequência"</string>
+ <string name="kg_wrong_pattern" msgid="1850806070801358830">"Sequência Incorreta"</string>
+ <string name="kg_wrong_password" msgid="2333281762128113157">"Palavra-passe Incorreta"</string>
+ <string name="kg_wrong_pin" msgid="1131306510833563801">"PIN Incorreto"</string>
+ <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Tente novamente dentro de <xliff:g id="NUMBER">%d</xliff:g> segundos."</string>
+ <string name="kg_pattern_instructions" msgid="398978611683075868">"Desenhe a sua sequência"</string>
+ <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Introduzir PIN do cartão SIM"</string>
+ <string name="kg_pin_instructions" msgid="2377242233495111557">"Introduzir PIN"</string>
+ <string name="kg_password_instructions" msgid="5753646556186936819">"Introduzir Palavra-passe"</string>
+ <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"O SIM está agora desativado. Introduza o código PUK para continuar. Contacte o operador para obter detalhes."</string>
+ <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Introduza o código PIN pretendido"</string>
+ <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Confirme o código PIN pretendido"</string>
+ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"A desbloquear cartão SIM..."</string>
+ <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Código PIN incorreto."</string>
+ <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Introduza um PIN entre 4 e 8 números."</string>
+ <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"O código PUK deve ter 8 ou mais números."</string>
+ <string name="kg_invalid_puk" msgid="3638289409676051243">"Volte a introduzir o código PUK correto. Demasiadas tentativas consecutivas irão desativar permanentemente o SIM."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"Os códigos PIN não correspondem"</string>
+ <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Demasiadas tentativas para desenhar sequência"</string>
+ <string name="kg_login_instructions" msgid="1100551261265506448">"Para desbloquear, inicie sessão com a sua Conta do Google."</string>
+ <string name="kg_login_username_hint" msgid="5718534272070920364">"Nome de utilizador (email)"</string>
+ <string name="kg_login_password_hint" msgid="9057289103827298549">"Palavra-passe"</string>
+ <string name="kg_login_submit_button" msgid="5355904582674054702">"Iniciar sessão"</string>
+ <string name="kg_login_invalid_input" msgid="5754664119319872197">"Nome de utilizador ou palavra-passe inválidos."</string>
+ <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Esqueceu-se do nome de utilizador ou da palavra-passe?"\n"Aceda a "<b>"google.com/accounts/recovery"</b>"."</string>
+ <string name="kg_login_checking_password" msgid="1052685197710252395">"A verificar a conta…"</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Escreveu o PIN incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. "\n\n"Tente novamente dentro de <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
+ <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Escreveu a palavra-passe incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. "\n\n"Tente novamente dentro de <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
+ <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Desenhou a sua sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. "\n\n"Tente novamente dentro de <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Tentou desbloquear o tablet <xliff:g id="NUMBER_0">%d</xliff:g> vezes de forma incorreta. Depois de mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas sem êxito, as definições de origem do telemóvel serão repostas e todos os dados do utilizador serão perdidos."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Tentou desbloquear o telemóvel <xliff:g id="NUMBER_0">%d</xliff:g> vezes de forma incorreta. Depois de mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas sem êxito, as definições de origem do telemóvel serão repostas e todos os dados do utilizador serão perdidos."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Tentou desbloquear o tablet <xliff:g id="NUMBER">%d</xliff:g> vezes de forma incorreta, pelo que será reposta a predefinição de fábrica."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Tentou desbloquear o telemóvel <xliff:g id="NUMBER">%d</xliff:g> vezes de forma incorreta, pelo que será reposta a predefinição de fábrica."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Desenhou a sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Depois de mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas sem sucesso, ser-lhe-á pedido para desbloquear o tablet através de uma conta de email."\n\n" Tente novamente dentro de <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Desenhou a sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Depois de mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas sem sucesso, ser-lhe-á pedido para desbloquear o telemóvel através de uma conta de email."\n\n" Tente novamente dentro de <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
+ <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" - "</string>
+ <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Remover"</string>
+ <!-- no translation found for keyguard_transport_prev_description (8229108430245669854) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_next_description (4299258300283778305) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_pause_description (5093073338238310224) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_play_description (2924628863741150956) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_stop_description (3084179324810575787) -->
+ <skip />
+ <!-- no translation found for keyguard_carrier_default (8700650403054042153) -->
+ <skip />
+</resources>
diff --git a/packages/Keyguard/res/values-pt/strings.xml b/packages/Keyguard/res/values-pt/strings.xml
new file mode 100644
index 0000000..cf3d64c
--- /dev/null
+++ b/packages/Keyguard/res/values-pt/strings.xml
@@ -0,0 +1,164 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/* //device/apps/common/assets/res/any/strings.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:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Insira o código PIN"</string>
+ <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Insira o PUK e o novo código PIN"</string>
+ <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"Código PUK"</string>
+ <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Novo código PIN"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Toque para inserir a senha"</font></string>
+ <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Digite a senha para desbloquear"</string>
+ <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Insira o PIN para desbloquear"</string>
+ <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Código PIN incorreto."</string>
+ <string name="keyguard_label_text" msgid="861796461028298424">"Para desbloquear, pressione Menu e, em seguida, 0."</string>
+ <string name="faceunlock_multiple_failures" msgid="754137583022792429">"O número máximo de tentativas de Desbloqueio por reconhecimento facial foi excedido"</string>
+ <!-- no translation found for keyguard_charged (3272223906073492454) -->
+ <skip />
+ <!-- no translation found for keyguard_plugged_in (8117572000639998388) -->
+ <skip />
+ <!-- no translation found for keyguard_low_battery (8143808018719173859) -->
+ <skip />
+ <!-- no translation found for keyguard_instructions_when_pattern_disabled (1332288268600329841) -->
+ <skip />
+ <!-- no translation found for keyguard_network_locked_message (9169717779058037168) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message_short (494980561304211931) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (1445849005909260039) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (3481110395508637643) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions (5210891509995942250) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions_long (5968985489463870358) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_message_short (8340813989586622356) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_instructions (5892940909699723544) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_locked_message (6875773413306380902) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_puk_locked_message (3747232467471801633) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_unlock_progress_dialog_message (7975221805033614426) -->
+ <skip />
+ <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d de %3$d."</string>
+ <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Adicionar widget"</string>
+ <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Vazio"</string>
+ <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Área de desbloqueio expandida."</string>
+ <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Área de desbloqueio recolhida."</string>
+ <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"Widget de <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>."</string>
+ <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"Seletor de usuários"</string>
+ <string name="keyguard_accessibility_status" msgid="8008264603935930611">"Status"</string>
+ <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"Câmera"</string>
+ <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Controles de mídia"</string>
+ <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Reordenação de widgets iniciada."</string>
+ <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Reordenação de widgets concluída."</string>
+ <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Widget <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> excluído."</string>
+ <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Expandir a área de desbloqueio."</string>
+ <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Desbloqueio com deslize."</string>
+ <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Desbloqueio com padrão."</string>
+ <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Desbloqueio facial."</string>
+ <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Desbloqueio com PIN."</string>
+ <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Desbloqueio com senha."</string>
+ <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Área do padrão."</string>
+ <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Área de deslize."</string>
+ <!-- no translation found for keyguard_accessibility_transport_prev_description (1337286538318543555) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_next_description (7073928300444909320) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_pause_description (8455979545295224302) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_play_description (8146417789511154044) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_stop_description (7656358482980912216) -->
+ <skip />
+ <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+ <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+ <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+ <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Cancelar"</string>
+ <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Excluir"</string>
+ <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Concluído"</string>
+ <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Alteração do modo"</string>
+ <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
+ <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
+ <string name="description_target_unlock" msgid="2228524900439801453">"Desbloquear"</string>
+ <string name="description_target_camera" msgid="969071997552486814">"Câmera"</string>
+ <string name="description_target_silent" msgid="893551287746522182">"Silencioso"</string>
+ <string name="description_target_soundon" msgid="30052466675500172">"Som ativado"</string>
+ <string name="description_target_search" msgid="3091587249776033139">"Pesquisar"</string>
+ <string name="description_direction_up" msgid="7169032478259485180">"Para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>, deslize para cima."</string>
+ <string name="description_direction_down" msgid="5087739728639014595">"Para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>, deslize para baixo."</string>
+ <string name="description_direction_left" msgid="7207478719805562165">"Para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>, deslize para a esquerda."</string>
+ <string name="description_direction_right" msgid="8034433242579600980">"Para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>, deslize para a direita."</string>
+ <string name="user_switched" msgid="3768006783166984410">"Usuário atual <xliff:g id="NAME">%1$s</xliff:g>."</string>
+ <string name="kg_emergency_call_label" msgid="684946192523830531">"Chamada de emergência"</string>
+ <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Esqueci o padrão"</string>
+ <string name="kg_wrong_pattern" msgid="1850806070801358830">"Padrão incorreto"</string>
+ <string name="kg_wrong_password" msgid="2333281762128113157">"Senha incorreta"</string>
+ <string name="kg_wrong_pin" msgid="1131306510833563801">"PIN incorreto"</string>
+ <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Tente novamente em <xliff:g id="NUMBER">%d</xliff:g> segundos."</string>
+ <string name="kg_pattern_instructions" msgid="398978611683075868">"Desenhe seu padrão"</string>
+ <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Digite o PIN do cartão SIM"</string>
+ <string name="kg_pin_instructions" msgid="2377242233495111557">"Digite o PIN"</string>
+ <string name="kg_password_instructions" msgid="5753646556186936819">"Digite a senha"</string>
+ <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"O SIM foi desativado. Insira o código PUK para continuar. Entre em contato com a operadora para obter mais detalhes."</string>
+ <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Digite o código PIN desejado"</string>
+ <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Confirme o código PIN desejado"</string>
+ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Desbloqueando o cartão SIM…"</string>
+ <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Código PIN incorreto."</string>
+ <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Digite um PIN com quatro a oito números."</string>
+ <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"O código PUK deve ter 8 números ou mais."</string>
+ <string name="kg_invalid_puk" msgid="3638289409676051243">"Introduza novamente o código PUK correto. Muitas tentativas malsucedidas desativarão permanentemente o SIM."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"Os códigos PIN não coincidem"</string>
+ <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Muitas tentativas de padrão"</string>
+ <string name="kg_login_instructions" msgid="1100551261265506448">"Para desbloquear, faça login usando sua Conta do Google."</string>
+ <string name="kg_login_username_hint" msgid="5718534272070920364">"Nome de usuário (e-mail)"</string>
+ <string name="kg_login_password_hint" msgid="9057289103827298549">"Senha"</string>
+ <string name="kg_login_submit_button" msgid="5355904582674054702">"Fazer login"</string>
+ <string name="kg_login_invalid_input" msgid="5754664119319872197">"Nome de usuário ou senha inválidos."</string>
+ <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Esqueceu seu nome de usuário ou senha?"\n"Acesse "<b>"google.com.br/accounts/recovery"</b>"."</string>
+ <string name="kg_login_checking_password" msgid="1052685197710252395">"Verificando a conta..."</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Você digitou seu PIN incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. "\n\n"Tente novamente em <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
+ <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Você digitou sua senha incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. "\n\n"Tente novamente em <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
+ <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Você desenhou sua sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. "\n\n"Tente novamente em <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Você tentou desbloquear incorretamente o tablet <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Após mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas malsucedidas, o tablet será redefinido para o padrão de fábrica e todos os dados do usuário serão perdidos."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Você tentou desbloquear incorretamente o telefone <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Após mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas malsucedidas, o telefone será redefinido para o padrão de fábrica e todos os dados do usuário serão perdidos."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Você tentou desbloquear incorretamente o tablet <xliff:g id="NUMBER">%d</xliff:g> vezes. O tablet será redefinido para o padrão de fábrica."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Você tentou desbloquear incorretamente o telefone <xliff:g id="NUMBER">%d</xliff:g> vezes. O telefone será redefinido para o padrão de fábrica."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Você desenhou sua sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Se fizer mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas incorretas, será solicitado que você use o login do Google para desbloquear seu tablet."\n\n" Tente novamente em <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Você desenhou sua sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Se fizer mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas incorretas, será solicitado que você use o login do Google para desbloquear."\n\n" Tente novamente em <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
+ <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
+ <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Remover"</string>
+ <!-- no translation found for keyguard_transport_prev_description (8229108430245669854) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_next_description (4299258300283778305) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_pause_description (5093073338238310224) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_play_description (2924628863741150956) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_stop_description (3084179324810575787) -->
+ <skip />
+ <!-- no translation found for keyguard_carrier_default (8700650403054042153) -->
+ <skip />
+</resources>
diff --git a/packages/Keyguard/res/values-rm/strings.xml b/packages/Keyguard/res/values-rm/strings.xml
new file mode 100644
index 0000000..8dda055
--- /dev/null
+++ b/packages/Keyguard/res/values-rm/strings.xml
@@ -0,0 +1,249 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/* //device/apps/common/assets/res/any/strings.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:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- no translation found for keyguard_password_enter_pin_code (3037685796058495017) -->
+ <skip />
+ <!-- no translation found for keyguard_password_enter_puk_code (4800725266925845333) -->
+ <skip />
+ <!-- no translation found for keyguard_password_enter_puk_prompt (1341112146710087048) -->
+ <skip />
+ <!-- no translation found for keyguard_password_enter_pin_prompt (8027680321614196258) -->
+ <skip />
+ <!-- no translation found for keyguard_password_entry_touch_hint (7858547464982981384) -->
+ <skip />
+ <!-- no translation found for keyguard_password_enter_password_code (1054721668279049780) -->
+ <skip />
+ <!-- no translation found for keyguard_password_enter_pin_password_code (6391755146112503443) -->
+ <skip />
+ <!-- no translation found for keyguard_password_wrong_pin_code (2422225591006134936) -->
+ <skip />
+ <string name="keyguard_label_text" msgid="861796461028298424">"Smatgai per debloccar sin la tasta Menu e lura sin 0."</string>
+ <!-- no translation found for faceunlock_multiple_failures (754137583022792429) -->
+ <skip />
+ <!-- no translation found for keyguard_charged (3272223906073492454) -->
+ <skip />
+ <!-- no translation found for keyguard_plugged_in (8117572000639998388) -->
+ <skip />
+ <!-- no translation found for keyguard_low_battery (8143808018719173859) -->
+ <skip />
+ <!-- no translation found for keyguard_instructions_when_pattern_disabled (1332288268600329841) -->
+ <skip />
+ <!-- no translation found for keyguard_network_locked_message (9169717779058037168) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message_short (494980561304211931) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (1445849005909260039) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (3481110395508637643) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions (5210891509995942250) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions_long (5968985489463870358) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_message_short (8340813989586622356) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_instructions (5892940909699723544) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_locked_message (6875773413306380902) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_puk_locked_message (3747232467471801633) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_unlock_progress_dialog_message (7975221805033614426) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_widget_changed (5678624624681400191) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_add_widget (8273277058724924654) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_widget_empty_slot (1281505703307930757) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_unlock_area_expanded (2278106022311170299) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_unlock_area_collapsed (6366992066936076396) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_widget (6527131039741808240) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_user_selector (1226798370913698896) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_status (8008264603935930611) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_camera (8904231194181114603) -->
+ <skip />
+ <!-- no translation found for keygaurd_accessibility_media_controls (262209654292161806) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_widget_reorder_start (8736853615588828197) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_widget_reorder_end (7170190950870468320) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_widget_deleted (4426204263929224434) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_expand_lock_area (519859720934178024) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_slide_unlock (2959928478764697254) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_pattern_unlock (1490840706075246612) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_face_unlock (4817282543351718535) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_pin_unlock (2469687111784035046) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_password_unlock (7675777623912155089) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_pattern_area (7679891324509597904) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_slide_area (6736064494019979544) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_prev_description (1337286538318543555) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_next_description (7073928300444909320) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_pause_description (8455979545295224302) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_play_description (8146417789511154044) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_stop_description (7656358482980912216) -->
+ <skip />
+ <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+ <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+ <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <!-- no translation found for keyboardview_keycode_alt (4856868820040051939) -->
+ <skip />
+ <!-- no translation found for keyboardview_keycode_cancel (1203984017245783244) -->
+ <skip />
+ <!-- no translation found for keyboardview_keycode_delete (3337914833206635744) -->
+ <skip />
+ <!-- no translation found for keyboardview_keycode_done (1992571118466679775) -->
+ <skip />
+ <!-- no translation found for keyboardview_keycode_mode_change (4547387741906537519) -->
+ <skip />
+ <!-- no translation found for keyboardview_keycode_shift (2270748814315147690) -->
+ <skip />
+ <!-- no translation found for keyboardview_keycode_enter (2985864015076059467) -->
+ <skip />
+ <!-- no translation found for description_target_unlock (2228524900439801453) -->
+ <skip />
+ <!-- no translation found for description_target_camera (969071997552486814) -->
+ <skip />
+ <!-- no translation found for description_target_silent (893551287746522182) -->
+ <skip />
+ <!-- no translation found for description_target_soundon (30052466675500172) -->
+ <skip />
+ <!-- no translation found for description_target_search (3091587249776033139) -->
+ <skip />
+ <!-- no translation found for description_direction_up (7169032478259485180) -->
+ <skip />
+ <!-- no translation found for description_direction_down (5087739728639014595) -->
+ <skip />
+ <!-- no translation found for description_direction_left (7207478719805562165) -->
+ <skip />
+ <!-- no translation found for description_direction_right (8034433242579600980) -->
+ <skip />
+ <!-- no translation found for user_switched (3768006783166984410) -->
+ <skip />
+ <!-- no translation found for kg_emergency_call_label (684946192523830531) -->
+ <skip />
+ <!-- no translation found for kg_forgot_pattern_button_text (8852021467868220608) -->
+ <skip />
+ <!-- no translation found for kg_wrong_pattern (1850806070801358830) -->
+ <skip />
+ <!-- no translation found for kg_wrong_password (2333281762128113157) -->
+ <skip />
+ <!-- no translation found for kg_wrong_pin (1131306510833563801) -->
+ <skip />
+ <!-- no translation found for kg_too_many_failed_attempts_countdown (6358110221603297548) -->
+ <skip />
+ <!-- no translation found for kg_pattern_instructions (398978611683075868) -->
+ <skip />
+ <!-- no translation found for kg_sim_pin_instructions (2319508550934557331) -->
+ <skip />
+ <!-- no translation found for kg_pin_instructions (2377242233495111557) -->
+ <skip />
+ <!-- no translation found for kg_password_instructions (5753646556186936819) -->
+ <skip />
+ <!-- no translation found for kg_puk_enter_puk_hint (453227143861735537) -->
+ <skip />
+ <!-- no translation found for kg_puk_enter_pin_hint (7871604527429602024) -->
+ <skip />
+ <!-- no translation found for kg_enter_confirm_pin_hint (325676184762529976) -->
+ <skip />
+ <!-- no translation found for kg_sim_unlock_progress_dialog_message (8950398016976865762) -->
+ <skip />
+ <!-- no translation found for kg_password_wrong_pin_code (1139324887413846912) -->
+ <skip />
+ <!-- no translation found for kg_invalid_sim_pin_hint (8795159358110620001) -->
+ <skip />
+ <!-- no translation found for kg_invalid_sim_puk_hint (7553388325654369575) -->
+ <skip />
+ <!-- no translation found for kg_invalid_puk (3638289409676051243) -->
+ <skip />
+ <!-- no translation found for kg_invalid_confirm_pin_hint (7003469261464593516) -->
+ <skip />
+ <!-- no translation found for kg_login_too_many_attempts (6486842094005698475) -->
+ <skip />
+ <!-- no translation found for kg_login_instructions (1100551261265506448) -->
+ <skip />
+ <!-- no translation found for kg_login_username_hint (5718534272070920364) -->
+ <skip />
+ <!-- no translation found for kg_login_password_hint (9057289103827298549) -->
+ <skip />
+ <!-- no translation found for kg_login_submit_button (5355904582674054702) -->
+ <skip />
+ <!-- no translation found for kg_login_invalid_input (5754664119319872197) -->
+ <skip />
+ <!-- no translation found for kg_login_account_recovery_hint (5690709132841752974) -->
+ <skip />
+ <!-- no translation found for kg_login_checking_password (1052685197710252395) -->
+ <skip />
+ <!-- no translation found for kg_too_many_failed_pin_attempts_dialog_message (8276745642049502550) -->
+ <skip />
+ <!-- no translation found for kg_too_many_failed_password_attempts_dialog_message (7813713389422226531) -->
+ <skip />
+ <!-- no translation found for kg_too_many_failed_pattern_attempts_dialog_message (74089475965050805) -->
+ <skip />
+ <!-- no translation found for kg_failed_attempts_almost_at_wipe (1575557200627128949) -->
+ <skip />
+ <!-- no translation found for kg_failed_attempts_almost_at_wipe (4051015943038199910) -->
+ <skip />
+ <!-- no translation found for kg_failed_attempts_now_wiping (2072996269148483637) -->
+ <skip />
+ <!-- no translation found for kg_failed_attempts_now_wiping (4817627474419471518) -->
+ <skip />
+ <!-- no translation found for kg_failed_attempts_almost_at_login (3253575572118914370) -->
+ <skip />
+ <!-- no translation found for kg_failed_attempts_almost_at_login (1437638152015574839) -->
+ <skip />
+ <!-- no translation found for kg_text_message_separator (4160700433287233771) -->
+ <skip />
+ <!-- no translation found for kg_reordering_delete_drop_target_text (7899202978204438708) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_prev_description (8229108430245669854) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_next_description (4299258300283778305) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_pause_description (5093073338238310224) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_play_description (2924628863741150956) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_stop_description (3084179324810575787) -->
+ <skip />
+ <!-- no translation found for keyguard_carrier_default (8700650403054042153) -->
+ <skip />
+</resources>
diff --git a/packages/Keyguard/res/values-ro/strings.xml b/packages/Keyguard/res/values-ro/strings.xml
new file mode 100644
index 0000000..a251c22
--- /dev/null
+++ b/packages/Keyguard/res/values-ro/strings.xml
@@ -0,0 +1,164 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/* //device/apps/common/assets/res/any/strings.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:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Introduceţi codul PIN"</string>
+ <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Introduceţi codul PUK şi noul cod PIN"</string>
+ <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"Codul PUK"</string>
+ <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Noul cod PIN"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Atingeţi şi introduceţi parola"</font></string>
+ <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Introduceţi parola pentru a debloca"</string>
+ <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Introduceţi codul PIN pentru a debloca"</string>
+ <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Cod PIN incorect."</string>
+ <string name="keyguard_label_text" msgid="861796461028298424">"Pentru a debloca, apăsaţi Meniu, apoi 0."</string>
+ <string name="faceunlock_multiple_failures" msgid="754137583022792429">"S-a depăşit numărul maxim de încercări pentru Deblocare facială"</string>
+ <!-- no translation found for keyguard_charged (3272223906073492454) -->
+ <skip />
+ <!-- no translation found for keyguard_plugged_in (8117572000639998388) -->
+ <skip />
+ <!-- no translation found for keyguard_low_battery (8143808018719173859) -->
+ <skip />
+ <!-- no translation found for keyguard_instructions_when_pattern_disabled (1332288268600329841) -->
+ <skip />
+ <!-- no translation found for keyguard_network_locked_message (9169717779058037168) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message_short (494980561304211931) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (1445849005909260039) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (3481110395508637643) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions (5210891509995942250) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions_long (5968985489463870358) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_message_short (8340813989586622356) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_instructions (5892940909699723544) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_locked_message (6875773413306380902) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_puk_locked_message (3747232467471801633) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_unlock_progress_dialog_message (7975221805033614426) -->
+ <skip />
+ <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d din %3$d."</string>
+ <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Adăugaţi un widget."</string>
+ <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Gol"</string>
+ <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Zona de deblocare a fost extinsă."</string>
+ <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Zona de deblocare a fost restrânsă."</string>
+ <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"Widget <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>."</string>
+ <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"Selector utilizator"</string>
+ <string name="keyguard_accessibility_status" msgid="8008264603935930611">"Stare"</string>
+ <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"Cameră foto"</string>
+ <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Comenzi media"</string>
+ <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"A început reordonarea widgeturilor."</string>
+ <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Reordonarea widgeturilor s-a încheiat."</string>
+ <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Widgetul <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> a fost eliminat."</string>
+ <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Extindeţi zona de deblocare."</string>
+ <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Deblocare prin glisare."</string>
+ <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Deblocare cu model."</string>
+ <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Deblocare facială."</string>
+ <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Deblocare cu PIN."</string>
+ <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Deblocare cu parolă."</string>
+ <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Zonă model."</string>
+ <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Zonă glisare."</string>
+ <!-- no translation found for keyguard_accessibility_transport_prev_description (1337286538318543555) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_next_description (7073928300444909320) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_pause_description (8455979545295224302) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_play_description (8146417789511154044) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_stop_description (7656358482980912216) -->
+ <skip />
+ <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+ <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+ <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+ <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Anulaţi"</string>
+ <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Ştergeţi"</string>
+ <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Terminat"</string>
+ <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Schimbarea modului"</string>
+ <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
+ <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
+ <string name="description_target_unlock" msgid="2228524900439801453">"Deblocaţi"</string>
+ <string name="description_target_camera" msgid="969071997552486814">"Cameră foto"</string>
+ <string name="description_target_silent" msgid="893551287746522182">"Silenţios"</string>
+ <string name="description_target_soundon" msgid="30052466675500172">"Sunet activat"</string>
+ <string name="description_target_search" msgid="3091587249776033139">"Căutaţi"</string>
+ <string name="description_direction_up" msgid="7169032478259485180">"Glisaţi în sus pentru <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_down" msgid="5087739728639014595">"Glisaţi în jos pentru <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_left" msgid="7207478719805562165">"Glisaţi spre stânga pentru <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_right" msgid="8034433242579600980">"Glisaţi spre dreapta pentru <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="user_switched" msgid="3768006783166984410">"Utilizator curent: <xliff:g id="NAME">%1$s</xliff:g>."</string>
+ <string name="kg_emergency_call_label" msgid="684946192523830531">"Apel de urgenţă"</string>
+ <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Model uitat"</string>
+ <string name="kg_wrong_pattern" msgid="1850806070801358830">"Model greşit"</string>
+ <string name="kg_wrong_password" msgid="2333281762128113157">"Parolă greşită"</string>
+ <string name="kg_wrong_pin" msgid="1131306510833563801">"Cod PIN greşit"</string>
+ <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Încercaţi din nou peste <xliff:g id="NUMBER">%d</xliff:g> (de) secunde."</string>
+ <string name="kg_pattern_instructions" msgid="398978611683075868">"Desenaţi modelul"</string>
+ <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Introduceţi codul PIN al cardului SIM"</string>
+ <string name="kg_pin_instructions" msgid="2377242233495111557">"Introduceţi codul PIN"</string>
+ <string name="kg_password_instructions" msgid="5753646556186936819">"Introduceţi parola"</string>
+ <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"Cardul SIM este acum dezactivat. Introduceţi codul PUK pentru a continua. Contactaţi operatorul pentru mai multe detalii."</string>
+ <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Introduceţi codul PIN dorit"</string>
+ <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Confirmaţi codul PIN dorit"</string>
+ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Se deblochează cardul SIM..."</string>
+ <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Cod PIN incorect."</string>
+ <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Introduceţi un cod PIN format din 4 până la 8 cifre."</string>
+ <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"Codul PUK trebuie să aibă minimum 8 cifre."</string>
+ <string name="kg_invalid_puk" msgid="3638289409676051243">"Reintroduceţi codul PUK corect. Încercările repetate vor dezactiva definitiv cardul SIM."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"Codurile PIN nu coincid"</string>
+ <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Prea multe încercări de desenare a modelului"</string>
+ <string name="kg_login_instructions" msgid="1100551261265506448">"Pentru a debloca, conectaţi-vă cu Contul dvs. Google."</string>
+ <string name="kg_login_username_hint" msgid="5718534272070920364">"Nume de utilizator (e-mail)"</string>
+ <string name="kg_login_password_hint" msgid="9057289103827298549">"Parolă"</string>
+ <string name="kg_login_submit_button" msgid="5355904582674054702">"Conectaţi-vă"</string>
+ <string name="kg_login_invalid_input" msgid="5754664119319872197">"Nume de utilizator sau parolă nevalide."</string>
+ <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Aţi uitat numele de utilizator sau parola?"\n"Accesaţi "<b>"google.com/accounts/recovery"</b>"."</string>
+ <string name="kg_login_checking_password" msgid="1052685197710252395">"Se verifică contul…"</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Aţi introdus incorect codul PIN de <xliff:g id="NUMBER_0">%d</xliff:g> ori."\n\n"Încercaţi din nou peste <xliff:g id="NUMBER_1">%d</xliff:g> (de) secunde."</string>
+ <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Aţi introdus incorect parola de <xliff:g id="NUMBER_0">%d</xliff:g> ori. "\n\n"Încercaţi din nou peste <xliff:g id="NUMBER_1">%d</xliff:g> (de) secunde."</string>
+ <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Aţi desenat incorect modelul pentru deblocare de <xliff:g id="NUMBER_0">%d</xliff:g> ori. "\n\n"Încercaţi din nou peste <xliff:g id="NUMBER_1">%d</xliff:g> (de) secunde."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Aţi efectuat <xliff:g id="NUMBER_0">%d</xliff:g> încercări incorecte de deblocare a tabletei. După încă <xliff:g id="NUMBER_1">%d</xliff:g> încercări nereuşite, aceasta va fi resetată la setările prestabilite din fabrică, iar toate datele de utilizator se vor pierde."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Aţi efectuat <xliff:g id="NUMBER_0">%d</xliff:g> încercări incorecte de deblocare a telefonului. După încă <xliff:g id="NUMBER_1">%d</xliff:g> încercări nereuşite, acesta va fi resetat la setările prestabilite din fabrică, iar toate datele de utilizator se vor pierde."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Aţi efectuat <xliff:g id="NUMBER">%d</xliff:g> încercări incorecte de deblocare a tabletei. Tableta va fi acum resetată la setările prestabilite din fabrică."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Aţi efectuat <xliff:g id="NUMBER">%d</xliff:g> încercări incorecte de deblocare a telefonului. Telefonul va fi acum resetat la setările prestabilite din fabrică."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Aţi desenat incorect modelul pentru deblocare de <xliff:g id="NUMBER_0">%d</xliff:g> ori. După încă <xliff:g id="NUMBER_1">%d</xliff:g> încercări nereuşite, vi se va solicita să deblocaţi tableta cu ajutorul unui cont de e-mail."\n\n" Încercaţi din nou peste <xliff:g id="NUMBER_2">%d</xliff:g> (de) secunde."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Aţi desenat incorect modelul pentru deblocare de <xliff:g id="NUMBER_0">%d</xliff:g> ori. După încă <xliff:g id="NUMBER_1">%d</xliff:g> încercări nereuşite, vi se va solicita să deblocaţi telefonul cu ajutorul unui cont de e-mail."\n\n" Încercaţi din nou peste <xliff:g id="NUMBER_2">%d</xliff:g> (de) secunde."</string>
+ <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
+ <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Eliminaţi"</string>
+ <!-- no translation found for keyguard_transport_prev_description (8229108430245669854) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_next_description (4299258300283778305) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_pause_description (5093073338238310224) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_play_description (2924628863741150956) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_stop_description (3084179324810575787) -->
+ <skip />
+ <!-- no translation found for keyguard_carrier_default (8700650403054042153) -->
+ <skip />
+</resources>
diff --git a/packages/Keyguard/res/values-ru/strings.xml b/packages/Keyguard/res/values-ru/strings.xml
new file mode 100644
index 0000000..a050135
--- /dev/null
+++ b/packages/Keyguard/res/values-ru/strings.xml
@@ -0,0 +1,164 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/* //device/apps/common/assets/res/any/strings.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:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Введите PIN-код"</string>
+ <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Введите PUK-код и новый PIN-код"</string>
+ <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK-код"</string>
+ <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Новый PIN-код"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Нажмите для ввода пароля"</font></string>
+ <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Введите пароль"</string>
+ <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Введите PIN-код"</string>
+ <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Неверный PIN-код."</string>
+ <string name="keyguard_label_text" msgid="861796461028298424">"Для разблокировки нажмите \"Меню\", а затем 0."</string>
+ <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Все попытки войти с помощью Фейсконтроля использованы"</string>
+ <!-- no translation found for keyguard_charged (3272223906073492454) -->
+ <skip />
+ <!-- no translation found for keyguard_plugged_in (8117572000639998388) -->
+ <skip />
+ <!-- no translation found for keyguard_low_battery (8143808018719173859) -->
+ <skip />
+ <!-- no translation found for keyguard_instructions_when_pattern_disabled (1332288268600329841) -->
+ <skip />
+ <!-- no translation found for keyguard_network_locked_message (9169717779058037168) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message_short (494980561304211931) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (1445849005909260039) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (3481110395508637643) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions (5210891509995942250) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions_long (5968985489463870358) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_message_short (8340813989586622356) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_instructions (5892940909699723544) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_locked_message (6875773413306380902) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_puk_locked_message (3747232467471801633) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_unlock_progress_dialog_message (7975221805033614426) -->
+ <skip />
+ <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Виджет %2$d из %3$d."</string>
+ <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Добавить виджет"</string>
+ <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Пусто"</string>
+ <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Область разблокировки развернута"</string>
+ <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Область разблокировки свернута"</string>
+ <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"Виджет \"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g>\""</string>
+ <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"Выбор аккаунта"</string>
+ <string name="keyguard_accessibility_status" msgid="8008264603935930611">"Статус"</string>
+ <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"Камера"</string>
+ <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Управление блокировкой"</string>
+ <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Начато переопределение порядка виджетов"</string>
+ <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Порядок виджетов определен"</string>
+ <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Виджет <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> удален"</string>
+ <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Развернуть области разблокировки"</string>
+ <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Прокрутка"</string>
+ <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Графический ключ"</string>
+ <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Фейсконтроль"</string>
+ <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"PIN-код"</string>
+ <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Пароль"</string>
+ <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Область ввода графического ключа"</string>
+ <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Область слайдера"</string>
+ <!-- no translation found for keyguard_accessibility_transport_prev_description (1337286538318543555) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_next_description (7073928300444909320) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_pause_description (8455979545295224302) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_play_description (8146417789511154044) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_stop_description (7656358482980912216) -->
+ <skip />
+ <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+ <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"АБВ"</string>
+ <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Клавиша ALT"</string>
+ <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Отмена"</string>
+ <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Клавиша удаления"</string>
+ <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Готово"</string>
+ <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Клавиша смены режима"</string>
+ <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Клавиша смены регистра"</string>
+ <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Клавиша ввода"</string>
+ <string name="description_target_unlock" msgid="2228524900439801453">"Разблокировать"</string>
+ <string name="description_target_camera" msgid="969071997552486814">"Камера"</string>
+ <string name="description_target_silent" msgid="893551287746522182">"Без звука"</string>
+ <string name="description_target_soundon" msgid="30052466675500172">"Включить звук"</string>
+ <string name="description_target_search" msgid="3091587249776033139">"Поиск"</string>
+ <string name="description_direction_up" msgid="7169032478259485180">"Проведите вверх, чтобы <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_down" msgid="5087739728639014595">"Проведите вниз, чтобы <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_left" msgid="7207478719805562165">"Проведите влево, чтобы <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_right" msgid="8034433242579600980">"Проведите вправо, чтобы <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="user_switched" msgid="3768006783166984410">"Выбран аккаунт пользователя <xliff:g id="NAME">%1$s</xliff:g>."</string>
+ <string name="kg_emergency_call_label" msgid="684946192523830531">"Экстренный вызов"</string>
+ <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Забыли графический ключ?"</string>
+ <string name="kg_wrong_pattern" msgid="1850806070801358830">"Неправильный графический ключ"</string>
+ <string name="kg_wrong_password" msgid="2333281762128113157">"Неправильный пароль"</string>
+ <string name="kg_wrong_pin" msgid="1131306510833563801">"Неправильный PIN-код"</string>
+ <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Повторите попытку через <xliff:g id="NUMBER">%d</xliff:g> сек."</string>
+ <string name="kg_pattern_instructions" msgid="398978611683075868">"Введите графический ключ"</string>
+ <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Введите PIN-код SIM-карты"</string>
+ <string name="kg_pin_instructions" msgid="2377242233495111557">"Введите PIN"</string>
+ <string name="kg_password_instructions" msgid="5753646556186936819">"Введите пароль"</string>
+ <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"SIM-карта заблокирована. Чтобы продолжить, введите PUK-код. За подробной информацией обратитесь к своему оператору связи."</string>
+ <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Введите желаемый PIN-код"</string>
+ <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Введите PIN-код ещё раз"</string>
+ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Разблокировка SIM-карты…"</string>
+ <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Неверный PIN-код."</string>
+ <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Введите PIN-код (от 4 до 8 цифр)."</string>
+ <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK-код должен содержать не менее 8 символов."</string>
+ <string name="kg_invalid_puk" msgid="3638289409676051243">"Введите правильный PUK-код. После нескольких неудачных попыток SIM-карта будет заблокирована."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN-коды не совпадают"</string>
+ <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Слишком много попыток ввода графического ключа"</string>
+ <string name="kg_login_instructions" msgid="1100551261265506448">"Чтобы разблокировать устройство, войдите в свой аккаунт Google."</string>
+ <string name="kg_login_username_hint" msgid="5718534272070920364">"Имя пользователя (эл. почта)"</string>
+ <string name="kg_login_password_hint" msgid="9057289103827298549">"Пароль"</string>
+ <string name="kg_login_submit_button" msgid="5355904582674054702">"Войти"</string>
+ <string name="kg_login_invalid_input" msgid="5754664119319872197">"Неверное имя пользователя или пароль."</string>
+ <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Забыли имя пользователя или пароль?"\n"Перейдите на страницу "<b>"google.com/accounts/recovery"</b>"."</string>
+ <string name="kg_login_checking_password" msgid="1052685197710252395">"Проверка данных…"</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Вы <xliff:g id="NUMBER_0">%d</xliff:g> раз неверно указали PIN-код. "\n\n"Повтор через <xliff:g id="NUMBER_1">%d</xliff:g> сек."</string>
+ <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Вы <xliff:g id="NUMBER_0">%d</xliff:g> раз неверно указали пароль."\n\n"Повтор через <xliff:g id="NUMBER_1">%d</xliff:g> сек."</string>
+ <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Вы <xliff:g id="NUMBER_0">%d</xliff:g> раз неверно указали графический ключ."\n\n"Повтор через <xliff:g id="NUMBER_1">%d</xliff:g> сек."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Вы <xliff:g id="NUMBER_0">%d</xliff:g> раз не смогли разблокировать планшетный ПК. После <xliff:g id="NUMBER_1">%d</xliff:g> неверных попыток будут восстановлены заводские настройки, что приведет к удалению всех пользовательских данных."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Вы <xliff:g id="NUMBER_0">%d</xliff:g> раз не смогли разблокировать телефон. После <xliff:g id="NUMBER_1">%d</xliff:g> неверных попыток будут восстановлены заводские настройки, что приведет к удалению всех пользовательских данных."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Вы <xliff:g id="NUMBER">%d</xliff:g> раз не смогли разблокировать планшетный ПК. Будут восстановлены заводские настройки."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Вы <xliff:g id="NUMBER">%d</xliff:g> раз не смогли разблокировать телефон. Будут восстановлены заводские настройки."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Вы <xliff:g id="NUMBER_0">%d</xliff:g> раз неверно указали графический ключ. После <xliff:g id="NUMBER_1">%d</xliff:g> неверных попыток для разблокировки планшетного ПК потребуется войти в аккаунт Google."\n\n"Повтор через <xliff:g id="NUMBER_2">%d</xliff:g> сек."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Вы <xliff:g id="NUMBER_0">%d</xliff:g> раз неверно указали графический ключ. После <xliff:g id="NUMBER_1">%d</xliff:g> неверных попыток для разблокировки телефона потребуется войти в аккаунт Google."\n\n"Повтор через <xliff:g id="NUMBER_2">%d</xliff:g> сек."</string>
+ <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" – "</string>
+ <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Удалить"</string>
+ <!-- no translation found for keyguard_transport_prev_description (8229108430245669854) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_next_description (4299258300283778305) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_pause_description (5093073338238310224) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_play_description (2924628863741150956) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_stop_description (3084179324810575787) -->
+ <skip />
+ <!-- no translation found for keyguard_carrier_default (8700650403054042153) -->
+ <skip />
+</resources>
diff --git a/packages/Keyguard/res/values-sk/strings.xml b/packages/Keyguard/res/values-sk/strings.xml
new file mode 100644
index 0000000..988c3a4
--- /dev/null
+++ b/packages/Keyguard/res/values-sk/strings.xml
@@ -0,0 +1,164 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/* //device/apps/common/assets/res/any/strings.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:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Zadajte kód PIN"</string>
+ <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Zadajte kód PUK a nový kód PIN"</string>
+ <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"Kód PUK"</string>
+ <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Nový kód PIN"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Dotknutím zadajte heslo"</font></string>
+ <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Zadajte heslo na odomknutie"</string>
+ <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Zadajte kód PIN na odomknutie"</string>
+ <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Nesprávny kód PIN."</string>
+ <string name="keyguard_label_text" msgid="861796461028298424">"Ak chcete telefón odomknúť, stlačte Menu a následne 0."</string>
+ <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Prekročili ste maximálny povolený počet pokusov o odomknutie tvárou"</string>
+ <!-- no translation found for keyguard_charged (3272223906073492454) -->
+ <skip />
+ <!-- no translation found for keyguard_plugged_in (8117572000639998388) -->
+ <skip />
+ <!-- no translation found for keyguard_low_battery (8143808018719173859) -->
+ <skip />
+ <!-- no translation found for keyguard_instructions_when_pattern_disabled (1332288268600329841) -->
+ <skip />
+ <!-- no translation found for keyguard_network_locked_message (9169717779058037168) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message_short (494980561304211931) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (1445849005909260039) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (3481110395508637643) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions (5210891509995942250) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions_long (5968985489463870358) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_message_short (8340813989586622356) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_instructions (5892940909699723544) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_locked_message (6875773413306380902) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_puk_locked_message (3747232467471801633) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_unlock_progress_dialog_message (7975221805033614426) -->
+ <skip />
+ <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Miniaplikácia %2$d z %3$d."</string>
+ <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Pridať miniaplikáciu."</string>
+ <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Prázdne"</string>
+ <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Oblasť na odomknutie bola rozšírená."</string>
+ <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Oblasť na odomknutie bola zúžená."</string>
+ <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"Miniaplikácia <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>."</string>
+ <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"Výber používateľa"</string>
+ <string name="keyguard_accessibility_status" msgid="8008264603935930611">"Stav"</string>
+ <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"Fotoaparát"</string>
+ <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Ovládacie prvky médií"</string>
+ <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Zmena usporiadania miniaplikácií sa začala."</string>
+ <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Zmena usporiadania miniaplikácií sa skončila."</string>
+ <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Miniaplikácia <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> bola odstránená."</string>
+ <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Rozšíriť oblasť na odomknutie."</string>
+ <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Odomknutie prejdením prstom."</string>
+ <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Odomknutie vzorom."</string>
+ <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Odomknutie tvárou."</string>
+ <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Odomknutie kódom PIN."</string>
+ <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Odomknutie heslom."</string>
+ <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Oblasť na zadanie bezpečnostného vzoru."</string>
+ <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Oblasť na prejdenie prstom."</string>
+ <!-- no translation found for keyguard_accessibility_transport_prev_description (1337286538318543555) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_next_description (7073928300444909320) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_pause_description (8455979545295224302) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_play_description (8146417789511154044) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_stop_description (7656358482980912216) -->
+ <skip />
+ <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+ <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+ <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+ <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Zrušiť"</string>
+ <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Odstrániť"</string>
+ <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Hotovo"</string>
+ <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Zmena režimu"</string>
+ <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
+ <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
+ <string name="description_target_unlock" msgid="2228524900439801453">"Odomknúť"</string>
+ <string name="description_target_camera" msgid="969071997552486814">"Fotoaparát"</string>
+ <string name="description_target_silent" msgid="893551287746522182">"Tichý"</string>
+ <string name="description_target_soundon" msgid="30052466675500172">"Zapnúť zvuk"</string>
+ <string name="description_target_search" msgid="3091587249776033139">"Vyhľadávanie"</string>
+ <string name="description_direction_up" msgid="7169032478259485180">"Prejdite prstom nahor: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_down" msgid="5087739728639014595">"Prejdite prstom nadol: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_left" msgid="7207478719805562165">"Prejdite prstom doľava: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_right" msgid="8034433242579600980">"Prejdite prstom doprava: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="user_switched" msgid="3768006783166984410">"Aktuálny používateľ je <xliff:g id="NAME">%1$s</xliff:g>."</string>
+ <string name="kg_emergency_call_label" msgid="684946192523830531">"Tiesňové volanie"</string>
+ <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Nepamätám si vzor"</string>
+ <string name="kg_wrong_pattern" msgid="1850806070801358830">"Nesprávny vzor"</string>
+ <string name="kg_wrong_password" msgid="2333281762128113157">"Nesprávne heslo"</string>
+ <string name="kg_wrong_pin" msgid="1131306510833563801">"Nesprávny kód PIN"</string>
+ <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Skúste to znova o <xliff:g id="NUMBER">%d</xliff:g> s."</string>
+ <string name="kg_pattern_instructions" msgid="398978611683075868">"Nakreslite svoj vzor"</string>
+ <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Zadajte kód PIN karty SIM"</string>
+ <string name="kg_pin_instructions" msgid="2377242233495111557">"Zadajte kód PIN"</string>
+ <string name="kg_password_instructions" msgid="5753646556186936819">"Zadajte heslo"</string>
+ <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"Karta SIM je teraz zakázaná. Ak chcete pokračovať, zadajte kód PUK. Podrobné informácie získate od operátora."</string>
+ <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Zadajte požadovaný kód PIN"</string>
+ <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Potvrďte požadovaný kód PIN"</string>
+ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Prebieha odomykanie karty SIM..."</string>
+ <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Nesprávny kód PIN."</string>
+ <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Zadajte kód PIN s dĺžkou 4 až 8 číslic."</string>
+ <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"Kód PUK musí obsahovať 8 alebo viac číslic."</string>
+ <string name="kg_invalid_puk" msgid="3638289409676051243">"Znova zadajte správny kód PUK. Opakované pokusy zakážu kartu SIM natrvalo."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"Kódy PIN sa nezhodujú"</string>
+ <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Príliš veľa pokusov o nakreslenie vzoru"</string>
+ <string name="kg_login_instructions" msgid="1100551261265506448">"Ak chcete telefón odomknúť, prihláste sa pomocou svojho účtu Google."</string>
+ <string name="kg_login_username_hint" msgid="5718534272070920364">"Používateľské meno (e-mail)"</string>
+ <string name="kg_login_password_hint" msgid="9057289103827298549">"Heslo"</string>
+ <string name="kg_login_submit_button" msgid="5355904582674054702">"Prihlásiť sa"</string>
+ <string name="kg_login_invalid_input" msgid="5754664119319872197">"Neplatné používateľské meno alebo heslo."</string>
+ <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Zabudli ste svoje používateľské meno alebo heslo?"\n" Navštívte stránky "<b>"google.com/accounts/recovery"</b>"."</string>
+ <string name="kg_login_checking_password" msgid="1052685197710252395">"Prebieha kontrola účtu..."</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"<xliff:g id="NUMBER_0">%d</xliff:g>-krát ste zadali nesprávny kód PIN. "\n\n"Skúste to znova o <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
+ <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"<xliff:g id="NUMBER_0">%d</xliff:g>-krát ste zadali nesprávne heslo. "\n\n"Skúste to znova o <xliff:g id="NUMBER_1">%d</xliff:g>."</string>
+ <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"<xliff:g id="NUMBER_0">%d</xliff:g>-krát ste použili nesprávny bezpečnostný vzor. "\n\n"Skúste to znova o <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Tablet ste sa pokúsili odomknúť nesprávnym spôsobom <xliff:g id="NUMBER_0">%d</xliff:g>-krát. Po <xliff:g id="NUMBER_1">%d</xliff:g> ďalších neúspešných pokusoch sa v tablete obnovia predvolené továrenské nastavenia a všetky používateľské údaje budú stratené."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Telefón ste sa pokúsili odomknúť nesprávnym spôsobom <xliff:g id="NUMBER_0">%d</xliff:g>-krát. Po <xliff:g id="NUMBER_1">%d</xliff:g> ďalších neúspešných pokusoch sa v telefóne obnovia predvolené továrenské nastavenia a všetky používateľské údaje budú stratené."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Tablet ste sa pokúsili odomknúť nesprávnym spôsobom <xliff:g id="NUMBER">%d</xliff:g>-krát. V tablete sa teraz obnovia predvolené továrenské nastavenia."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Telefón ste sa pokúsili odomknúť nesprávnym spôsobom <xliff:g id="NUMBER">%d</xliff:g>-krát. V telefóne sa teraz obnovia predvolené továrenské nastavenia."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"<xliff:g id="NUMBER_0">%d</xliff:g>-krát ste nesprávne nakreslili svoj bezpečnostný vzor. Po ďalších <xliff:g id="NUMBER_1">%d</xliff:g> neúspešných pokusoch sa zobrazí výzva na odomknutie tabletu pomocou e-mailového účtu."\n\n" Skúste to znova o <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"<xliff:g id="NUMBER_0">%d</xliff:g>-krát ste nesprávne nakreslili svoj bezpečnostný vzor. Po <xliff:g id="NUMBER_1">%d</xliff:g> ďalších neúspešných pokusoch sa zobrazí výzva na odomknutie telefónu pomocou e-mailového účtu."\n\n" Skúste to znova o <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
+ <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
+ <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Odstrániť"</string>
+ <!-- no translation found for keyguard_transport_prev_description (8229108430245669854) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_next_description (4299258300283778305) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_pause_description (5093073338238310224) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_play_description (2924628863741150956) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_stop_description (3084179324810575787) -->
+ <skip />
+ <!-- no translation found for keyguard_carrier_default (8700650403054042153) -->
+ <skip />
+</resources>
diff --git a/packages/Keyguard/res/values-sl/strings.xml b/packages/Keyguard/res/values-sl/strings.xml
new file mode 100644
index 0000000..6d1cc98
--- /dev/null
+++ b/packages/Keyguard/res/values-sl/strings.xml
@@ -0,0 +1,164 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/* //device/apps/common/assets/res/any/strings.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:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Vnesite kodo PIN"</string>
+ <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Vnesite kodo PUK in novo kodo PIN"</string>
+ <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"Koda PUK"</string>
+ <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Nova koda PIN"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Dotaknite se za vnos gesla"</font></string>
+ <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Vnesite geslo za odklepanje"</string>
+ <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Vnesite PIN za odklepanje"</string>
+ <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Napačna koda PIN."</string>
+ <string name="keyguard_label_text" msgid="861796461028298424">"Če želite telefon odkleniti, pritisnite meni in nato 0."</string>
+ <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Presegli ste dovoljeno število poskusov odklepanja z obrazom"</string>
+ <!-- no translation found for keyguard_charged (3272223906073492454) -->
+ <skip />
+ <!-- no translation found for keyguard_plugged_in (8117572000639998388) -->
+ <skip />
+ <!-- no translation found for keyguard_low_battery (8143808018719173859) -->
+ <skip />
+ <!-- no translation found for keyguard_instructions_when_pattern_disabled (1332288268600329841) -->
+ <skip />
+ <!-- no translation found for keyguard_network_locked_message (9169717779058037168) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message_short (494980561304211931) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (1445849005909260039) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (3481110395508637643) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions (5210891509995942250) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions_long (5968985489463870358) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_message_short (8340813989586622356) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_instructions (5892940909699723544) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_locked_message (6875773413306380902) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_puk_locked_message (3747232467471801633) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_unlock_progress_dialog_message (7975221805033614426) -->
+ <skip />
+ <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Pripomoček %2$d za %3$d."</string>
+ <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Dodajanje pripomočka."</string>
+ <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Prazno"</string>
+ <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Območje odklepanja razširjeno."</string>
+ <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Območje odklepanja strnjeno."</string>
+ <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"Pripomoček <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>."</string>
+ <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"Izbirnik uporabnika"</string>
+ <string name="keyguard_accessibility_status" msgid="8008264603935930611">"Stanje"</string>
+ <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"Fotoaparat"</string>
+ <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Kontrolniki predstavnosti"</string>
+ <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Prerazporejanje pripomočkov začeto."</string>
+ <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Prerazporejanje pripomočkov končano."</string>
+ <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Pripomoček <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> izbrisan."</string>
+ <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Razširitev območja odklepanja."</string>
+ <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Odklepanje s podrsanjem."</string>
+ <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Odklepanje z vzorcem."</string>
+ <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Odklepanje z obrazom."</string>
+ <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Odklepanje s kodo PIN."</string>
+ <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Odklepanje z geslom."</string>
+ <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Območje vzorca."</string>
+ <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Območje podrsanja."</string>
+ <!-- no translation found for keyguard_accessibility_transport_prev_description (1337286538318543555) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_next_description (7073928300444909320) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_pause_description (8455979545295224302) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_play_description (8146417789511154044) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_stop_description (7656358482980912216) -->
+ <skip />
+ <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+ <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+ <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Tipka Alt"</string>
+ <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Prekliči"</string>
+ <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Tipka Delete"</string>
+ <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Končano"</string>
+ <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Sprememba načina"</string>
+ <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Tipka Shift"</string>
+ <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Tipka Enter"</string>
+ <string name="description_target_unlock" msgid="2228524900439801453">"Odkleni"</string>
+ <string name="description_target_camera" msgid="969071997552486814">"Fotoaparat"</string>
+ <string name="description_target_silent" msgid="893551287746522182">"Tiho"</string>
+ <string name="description_target_soundon" msgid="30052466675500172">"Vklopljen zvok"</string>
+ <string name="description_target_search" msgid="3091587249776033139">"Iskanje"</string>
+ <string name="description_direction_up" msgid="7169032478259485180">"Povlecite navzgor za <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_down" msgid="5087739728639014595">"Povlecite navzdol za <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_left" msgid="7207478719805562165">"Povlecite v levo za <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string>
+ <string name="description_direction_right" msgid="8034433242579600980">"Povlecite v desno za <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="user_switched" msgid="3768006783166984410">"Trenutni uporabnik <xliff:g id="NAME">%1$s</xliff:g>."</string>
+ <string name="kg_emergency_call_label" msgid="684946192523830531">"Klic v sili"</string>
+ <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Pozabljen vzorec"</string>
+ <string name="kg_wrong_pattern" msgid="1850806070801358830">"Napačen vzorec"</string>
+ <string name="kg_wrong_password" msgid="2333281762128113157">"Napačno geslo"</string>
+ <string name="kg_wrong_pin" msgid="1131306510833563801">"Napačen PIN"</string>
+ <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Čez <xliff:g id="NUMBER">%d</xliff:g> sekund poskusite znova."</string>
+ <string name="kg_pattern_instructions" msgid="398978611683075868">"Narišite vzorec"</string>
+ <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Vnesite PIN za kartico SIM"</string>
+ <string name="kg_pin_instructions" msgid="2377242233495111557">"Vnesite PIN"</string>
+ <string name="kg_password_instructions" msgid="5753646556186936819">"Vnesite geslo"</string>
+ <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"Kartica SIM je onemogočena. Če želite nadaljevati, vnesite kodo PUK. Za dodatne informacije se obrnite na operaterja."</string>
+ <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Vnesite želeno kodo PIN"</string>
+ <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Potrdite želeno kodo PIN"</string>
+ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Odklepanje kartice SIM ..."</string>
+ <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Napačna koda PIN."</string>
+ <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Vnesite PIN, ki vsebuje od štiri do osem številk."</string>
+ <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"Koda PUK mora vsebovati 8 ali več števk."</string>
+ <string name="kg_invalid_puk" msgid="3638289409676051243">"Vnovič vnesite pravilno kodo PUK. Večkratni poskusi bodo trajno onemogočili kartico SIM."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"Kodi PIN se ne ujemata"</string>
+ <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Preveč poskusov vzorca"</string>
+ <string name="kg_login_instructions" msgid="1100551261265506448">"Če želite odkleniti napravo, se prijavite z Google Računom."</string>
+ <string name="kg_login_username_hint" msgid="5718534272070920364">"Uporabniško ime (e-pošta)"</string>
+ <string name="kg_login_password_hint" msgid="9057289103827298549">"Geslo"</string>
+ <string name="kg_login_submit_button" msgid="5355904582674054702">"Prijava"</string>
+ <string name="kg_login_invalid_input" msgid="5754664119319872197">"Neveljavno uporabniško ime ali geslo."</string>
+ <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Ali ste pozabili uporabniško ime ali geslo?"\n"Obiščite "<b>"google.com/accounts/recovery"</b>"."</string>
+ <string name="kg_login_checking_password" msgid="1052685197710252395">"Preverjanje računa ..."</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"PIN ste <xliff:g id="NUMBER_0">%d</xliff:g>-krat vnesli napačno. "\n\n"Znova poskusite čez <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
+ <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Geslo ste <xliff:g id="NUMBER_0">%d</xliff:g>-krat vnesli napačno. "\n\n"Znova poskusite čez <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
+ <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Vzorec za odklepanje ste nepravilno narisali <xliff:g id="NUMBER_0">%d</xliff:g>-krat. "\n\n"Poskusite znova čez <xliff:g id="NUMBER_1">%d</xliff:g> s."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Tablični računalnik ste poskusili <xliff:g id="NUMBER_0">%d</xliff:g>-krat napačno odkleniti. Če poskusite še <xliff:g id="NUMBER_1">%d</xliff:g>-krat in ne uspete, bo ponastavljen na privzete tovarniške nastavitve in vsi uporabniški podatki bodo izgubljeni."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Telefon ste poskusili <xliff:g id="NUMBER_0">%d</xliff:g>-krat napačno odkleniti. Če poskusite še <xliff:g id="NUMBER_1">%d</xliff:g>-krat in ne uspete, bo ponastavljen na privzete tovarniške nastavitve in vsi uporabniški podatki bodo izgubljeni."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Tablični računalnik ste poskusili <xliff:g id="NUMBER">%d</xliff:g>-krat napačno odkleniti, zato bo ponastavljen na privzete tovarniške nastavitve."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Telefon ste poskusili <xliff:g id="NUMBER">%d</xliff:g>-krat napačno odkleniti, zato bo ponastavljen na privzete tovarniške nastavitve."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Vzorec za odklepanje ste <xliff:g id="NUMBER_0">%d</xliff:g>-krat napačno vnesli. Po nadaljnjih <xliff:g id="NUMBER_1">%d</xliff:g> neuspešnih poskusih boste pozvani, da tablični računalnik odklenete z e-poštnim računom."\n\n"Poskusite znova čez <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Vzorec za odklepanje ste <xliff:g id="NUMBER_0">%d</xliff:g>-krat napačno vnesli. Po nadaljnjih <xliff:g id="NUMBER_1">%d</xliff:g> neuspešnih poskusih boste pozvani, da odklenete telefon z Googlovimi podatki za prijavo."\n\n"Poskusite znova čez <xliff:g id="NUMBER_2">%d</xliff:g> s."</string>
+ <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" – "</string>
+ <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Odstrani"</string>
+ <!-- no translation found for keyguard_transport_prev_description (8229108430245669854) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_next_description (4299258300283778305) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_pause_description (5093073338238310224) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_play_description (2924628863741150956) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_stop_description (3084179324810575787) -->
+ <skip />
+ <!-- no translation found for keyguard_carrier_default (8700650403054042153) -->
+ <skip />
+</resources>
diff --git a/packages/Keyguard/res/values-sr/strings.xml b/packages/Keyguard/res/values-sr/strings.xml
new file mode 100644
index 0000000..12fda6d
--- /dev/null
+++ b/packages/Keyguard/res/values-sr/strings.xml
@@ -0,0 +1,164 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/* //device/apps/common/assets/res/any/strings.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:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Унесите PIN кôд"</string>
+ <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Унесите PUK и нови PIN кôд"</string>
+ <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK кôд"</string>
+ <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Нови PIN кôд"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Додирните да бисте унели лозинку"</font></string>
+ <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Откуцајте лозинку да бисте откључали"</string>
+ <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Унесите PIN за откључавање"</string>
+ <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"PIN кôд је нетачан."</string>
+ <string name="keyguard_label_text" msgid="861796461028298424">"Да бисте откључали, притисните „Мени“, а затим 0."</string>
+ <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Премашен је највећи дозвољени број покушаја Откључавања лицем"</string>
+ <!-- no translation found for keyguard_charged (3272223906073492454) -->
+ <skip />
+ <!-- no translation found for keyguard_plugged_in (8117572000639998388) -->
+ <skip />
+ <!-- no translation found for keyguard_low_battery (8143808018719173859) -->
+ <skip />
+ <!-- no translation found for keyguard_instructions_when_pattern_disabled (1332288268600329841) -->
+ <skip />
+ <!-- no translation found for keyguard_network_locked_message (9169717779058037168) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message_short (494980561304211931) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (1445849005909260039) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (3481110395508637643) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions (5210891509995942250) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions_long (5968985489463870358) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_message_short (8340813989586622356) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_instructions (5892940909699723544) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_locked_message (6875773413306380902) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_puk_locked_message (3747232467471801633) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_unlock_progress_dialog_message (7975221805033614426) -->
+ <skip />
+ <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Виџет %2$d од %3$d."</string>
+ <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Додај виџет."</string>
+ <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Празно"</string>
+ <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Област откључавања је проширена."</string>
+ <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Област откључавања је скупљена."</string>
+ <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"Виџет <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>."</string>
+ <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"Избор корисника"</string>
+ <string name="keyguard_accessibility_status" msgid="8008264603935930611">"Статус"</string>
+ <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"Камера"</string>
+ <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Контроле за медије"</string>
+ <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Започела је промена редоследа виџета."</string>
+ <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Промена редоследа виџета је завршена."</string>
+ <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Виџет <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> је избрисан."</string>
+ <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Прошири област откључавања."</string>
+ <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Откључавање превлачењем."</string>
+ <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Откључавање шаблоном."</string>
+ <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Откључавање лицем."</string>
+ <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Откључавање PIN-ом."</string>
+ <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Откључавање лозинком."</string>
+ <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Област шаблона."</string>
+ <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Област превлачења."</string>
+ <!-- no translation found for keyguard_accessibility_transport_prev_description (1337286538318543555) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_next_description (7073928300444909320) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_pause_description (8455979545295224302) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_play_description (8146417789511154044) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_stop_description (7656358482980912216) -->
+ <skip />
+ <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+ <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+ <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+ <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Откажи"</string>
+ <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Избриши"</string>
+ <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Готово"</string>
+ <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Промена режима"</string>
+ <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
+ <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
+ <string name="description_target_unlock" msgid="2228524900439801453">"Откључај"</string>
+ <string name="description_target_camera" msgid="969071997552486814">"Камера"</string>
+ <string name="description_target_silent" msgid="893551287746522182">"Нечујно"</string>
+ <string name="description_target_soundon" msgid="30052466675500172">"Укључи звук"</string>
+ <string name="description_target_search" msgid="3091587249776033139">"Претрага"</string>
+ <string name="description_direction_up" msgid="7169032478259485180">"Превуците нагоре за <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_down" msgid="5087739728639014595">"Превуците надоле за <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_left" msgid="7207478719805562165">"Превуците улево за <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_right" msgid="8034433242579600980">"Превуците удесно за <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="user_switched" msgid="3768006783166984410">"Актуелни корисник <xliff:g id="NAME">%1$s</xliff:g>."</string>
+ <string name="kg_emergency_call_label" msgid="684946192523830531">"Хитни позив"</string>
+ <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Заборављени шаблон"</string>
+ <string name="kg_wrong_pattern" msgid="1850806070801358830">"Погрешан шаблон"</string>
+ <string name="kg_wrong_password" msgid="2333281762128113157">"Погрешна лозинка"</string>
+ <string name="kg_wrong_pin" msgid="1131306510833563801">"Погрешан PIN"</string>
+ <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Покушајте поново за <xliff:g id="NUMBER">%d</xliff:g> секунде(и)."</string>
+ <string name="kg_pattern_instructions" msgid="398978611683075868">"Нацртајте шаблон"</string>
+ <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Унесите PIN SIM картице"</string>
+ <string name="kg_pin_instructions" msgid="2377242233495111557">"Унесите PIN"</string>
+ <string name="kg_password_instructions" msgid="5753646556186936819">"Унесите лозинку"</string>
+ <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"SIM картица је сада онемогућена. Унесите PUK кôд да бисте наставили. За детаље контактирајте оператера."</string>
+ <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Унесите жељени PIN кôд"</string>
+ <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Потврдите жељени PIN кôд"</string>
+ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Откључавање SIM картице…"</string>
+ <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"PIN кôд је нетачан."</string>
+ <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Унесите PIN који има од 4 до 8 бројева."</string>
+ <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK кôд треба да има 8 или више бројева."</string>
+ <string name="kg_invalid_puk" msgid="3638289409676051243">"Поново унесите исправни PUK кôд. Поновљени покушаји ће трајно онемогућити SIM."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN кодови се не подударају"</string>
+ <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Превише покушаја уноса шаблона"</string>
+ <string name="kg_login_instructions" msgid="1100551261265506448">"Да бисте откључали, пријавите се помоћу Google налога."</string>
+ <string name="kg_login_username_hint" msgid="5718534272070920364">"Корисничко име (адреса е-поште)"</string>
+ <string name="kg_login_password_hint" msgid="9057289103827298549">"Лозинка"</string>
+ <string name="kg_login_submit_button" msgid="5355904582674054702">"Пријави ме"</string>
+ <string name="kg_login_invalid_input" msgid="5754664119319872197">"Неважеће корисничко име или лозинка."</string>
+ <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Заборавили сте корисничко име или лозинку?"\n"Посетите адресу "<b>"google.com/accounts/recovery"</b>"."</string>
+ <string name="kg_login_checking_password" msgid="1052685197710252395">"Провера налога…"</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Унели сте PIN неисправно <xliff:g id="NUMBER_0">%d</xliff:g> пута. "\n\n"Покушајте поново за <xliff:g id="NUMBER_1">%d</xliff:g> секунде(и)."</string>
+ <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Унели сте лозинку неисправно <xliff:g id="NUMBER_0">%d</xliff:g> пута. "\n\n"Покушајте поново за <xliff:g id="NUMBER_1">%d</xliff:g> секунде(и)."</string>
+ <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Нацртали сте шаблон за откључавање неисправно <xliff:g id="NUMBER_0">%d</xliff:g> пута. "\n\n"Покушајте поново за <xliff:g id="NUMBER_1">%d</xliff:g> секунде(и)."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Покушали сте да откључате таблет неисправно <xliff:g id="NUMBER_0">%d</xliff:g> пута. Након још <xliff:g id="NUMBER_1">%d</xliff:g> неуспешна(их) покушаја таблет ће бити враћен на подразумевана фабричка подешавања и сви кориснички подаци ће бити изгубљени."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Покушали сте да откључате телефон неисправно <xliff:g id="NUMBER_0">%d</xliff:g> пута. После још <xliff:g id="NUMBER_1">%d</xliff:g> неуспешна(их) покушаја телефон ће бити враћен на подразумевана фабричка подешавања и сви кориснички подаци ће бити изгубљени."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Покушали сте да откључате таблет неисправно <xliff:g id="NUMBER">%d</xliff:g> пута. Таблет ће сада бити враћен на подразумевана фабричка подешавања."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Покушали сте да откључате телефон неисправно <xliff:g id="NUMBER">%d</xliff:g> пута. Телефон ће сада бити враћен на подразумевана фабричка подешавања."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Нацртали сте шаблон за откључавање неисправно <xliff:g id="NUMBER_0">%d</xliff:g> пута. После још <xliff:g id="NUMBER_1">%d</xliff:g> неуспешна(их) покушаја, од вас ће бити затражено да откључате таблет помоћу налога е-поште."\n\n"Покушајте поново за <xliff:g id="NUMBER_2">%d</xliff:g> секунде(и)."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Нацртали сте шаблон за откључавање неисправно <xliff:g id="NUMBER_0">%d</xliff:g> пута. После још <xliff:g id="NUMBER_1">%d</xliff:g> неуспешна(их) покушаја, од вас ће бити затражено да откључате телефон помоћу налога е-поште."\n\n"Покушајте поново за <xliff:g id="NUMBER_2">%d</xliff:g> секунде(и)."</string>
+ <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" – "</string>
+ <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Уклони"</string>
+ <!-- no translation found for keyguard_transport_prev_description (8229108430245669854) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_next_description (4299258300283778305) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_pause_description (5093073338238310224) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_play_description (2924628863741150956) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_stop_description (3084179324810575787) -->
+ <skip />
+ <!-- no translation found for keyguard_carrier_default (8700650403054042153) -->
+ <skip />
+</resources>
diff --git a/packages/Keyguard/res/values-sv/strings.xml b/packages/Keyguard/res/values-sv/strings.xml
new file mode 100644
index 0000000..fa1492c
--- /dev/null
+++ b/packages/Keyguard/res/values-sv/strings.xml
@@ -0,0 +1,164 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/* //device/apps/common/assets/res/any/strings.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:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Ange PIN-kod"</string>
+ <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Ange PUK-koden och en ny PIN-kod"</string>
+ <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK-kod"</string>
+ <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Ny PIN-kod"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Tryck om du vill ange lösenord"</font></string>
+ <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Ange lösenord för att låsa upp"</string>
+ <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Ange PIN-kod för att låsa upp"</string>
+ <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Fel PIN-kod."</string>
+ <string name="keyguard_label_text" msgid="861796461028298424">"Tryck på Menu och sedan på 0 om du vill låsa upp."</string>
+ <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Du har försökt låsa upp med Ansiktslås för många gånger"</string>
+ <!-- no translation found for keyguard_charged (3272223906073492454) -->
+ <skip />
+ <!-- no translation found for keyguard_plugged_in (8117572000639998388) -->
+ <skip />
+ <!-- no translation found for keyguard_low_battery (8143808018719173859) -->
+ <skip />
+ <!-- no translation found for keyguard_instructions_when_pattern_disabled (1332288268600329841) -->
+ <skip />
+ <!-- no translation found for keyguard_network_locked_message (9169717779058037168) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message_short (494980561304211931) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (1445849005909260039) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (3481110395508637643) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions (5210891509995942250) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions_long (5968985489463870358) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_message_short (8340813989586622356) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_instructions (5892940909699723544) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_locked_message (6875773413306380902) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_puk_locked_message (3747232467471801633) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_unlock_progress_dialog_message (7975221805033614426) -->
+ <skip />
+ <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d av %3$d."</string>
+ <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Lägg till en widget."</string>
+ <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Tom"</string>
+ <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Expanderad upplåsningsyta."</string>
+ <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Komprimerad upplåsningsyta."</string>
+ <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"Widget för <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>."</string>
+ <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"Användarväljare"</string>
+ <string name="keyguard_accessibility_status" msgid="8008264603935930611">"Status"</string>
+ <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"Kamera"</string>
+ <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Mediereglage"</string>
+ <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Ändring av widgetarnas ordning har påbörjats."</string>
+ <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Ändring av widgetarnas ordning har avslutats."</string>
+ <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Widgeten <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> har tagits bort."</string>
+ <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Expandera upplåsningsytan."</string>
+ <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Lås upp genom att dra."</string>
+ <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Lås upp med grafiskt lösenord."</string>
+ <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Lås upp med Ansiktslås."</string>
+ <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Lås upp med PIN-kod."</string>
+ <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Lås upp med lösenord."</string>
+ <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Fält för grafiskt lösenord."</string>
+ <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Fält med dragreglage."</string>
+ <!-- no translation found for keyguard_accessibility_transport_prev_description (1337286538318543555) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_next_description (7073928300444909320) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_pause_description (8455979545295224302) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_play_description (8146417789511154044) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_stop_description (7656358482980912216) -->
+ <skip />
+ <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+ <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+ <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+ <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Avbryt"</string>
+ <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Delete"</string>
+ <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Klar"</string>
+ <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Funktionsändring"</string>
+ <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Skift"</string>
+ <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Retur"</string>
+ <string name="description_target_unlock" msgid="2228524900439801453">"Lås upp"</string>
+ <string name="description_target_camera" msgid="969071997552486814">"Kamera"</string>
+ <string name="description_target_silent" msgid="893551287746522182">"Tyst"</string>
+ <string name="description_target_soundon" msgid="30052466675500172">"Ljud på"</string>
+ <string name="description_target_search" msgid="3091587249776033139">"Sök"</string>
+ <string name="description_direction_up" msgid="7169032478259485180">"Dra uppåt för <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string>
+ <string name="description_direction_down" msgid="5087739728639014595">"Dra nedåt för <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_left" msgid="7207478719805562165">"Dra åt vänster för <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string>
+ <string name="description_direction_right" msgid="8034433242579600980">"Dra åt höger för <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string>
+ <string name="user_switched" msgid="3768006783166984410">"Nuvarande användare: <xliff:g id="NAME">%1$s</xliff:g>."</string>
+ <string name="kg_emergency_call_label" msgid="684946192523830531">"Nödsamtal"</string>
+ <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Har du glömt ditt grafiska lösenord?"</string>
+ <string name="kg_wrong_pattern" msgid="1850806070801358830">"Fel grafiskt lösenord"</string>
+ <string name="kg_wrong_password" msgid="2333281762128113157">"Fel lösenord"</string>
+ <string name="kg_wrong_pin" msgid="1131306510833563801">"Fel PIN-kod"</string>
+ <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Försök igen om <xliff:g id="NUMBER">%d</xliff:g> sekunder."</string>
+ <string name="kg_pattern_instructions" msgid="398978611683075868">"Rita ditt grafiska lösenord"</string>
+ <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Ange PIN-kod för SIM-kortet"</string>
+ <string name="kg_pin_instructions" msgid="2377242233495111557">"Ange PIN-kod"</string>
+ <string name="kg_password_instructions" msgid="5753646556186936819">"Ange lösenord"</string>
+ <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"SIM-kortet är nu inaktiverat. Ange PUK-koden om du vill fortsätta. Kontakta operatören om du vill få mer information."</string>
+ <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Ange önskad PIN-kod"</string>
+ <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Bekräfta önskad PIN-kod"</string>
+ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Låser upp SIM-kort …"</string>
+ <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Fel PIN-kod."</string>
+ <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Ange en PIN-kod med 4 till 8 siffror."</string>
+ <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK-koden ska vara minst åtta siffror."</string>
+ <string name="kg_invalid_puk" msgid="3638289409676051243">"Ange rätt PUK-kod igen. Om försöken upprepas inaktiveras SIM-kortet permanent."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN-koderna stämmer inte överens"</string>
+ <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"För många försök med grafiskt lösenord"</string>
+ <string name="kg_login_instructions" msgid="1100551261265506448">"Logga in med ditt Google-konto om du vill låsa upp."</string>
+ <string name="kg_login_username_hint" msgid="5718534272070920364">"Användarnamn (e-post)"</string>
+ <string name="kg_login_password_hint" msgid="9057289103827298549">"Lösenord"</string>
+ <string name="kg_login_submit_button" msgid="5355904582674054702">"Logga in"</string>
+ <string name="kg_login_invalid_input" msgid="5754664119319872197">"Ogiltigt användarnamn eller lösenord."</string>
+ <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Har du glömt ditt användarnamn eller lösenord?"\n"Besök "<b>"google.com/accounts/recovery"</b>"."</string>
+ <string name="kg_login_checking_password" msgid="1052685197710252395">"Kontot kontrolleras …"</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Du har angett fel lösenord <xliff:g id="NUMBER_0">%d</xliff:g> gånger. "\n\n"Försök igen om <xliff:g id="NUMBER_1">%d</xliff:g> sekunder."</string>
+ <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Du har angett fel lösenord <xliff:g id="NUMBER_0">%d</xliff:g> gånger. "\n\n"Försök igen om <xliff:g id="NUMBER_1">%d</xliff:g> sekunder."</string>
+ <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Du har ritat ditt grafiska lösenord fel <xliff:g id="NUMBER_0">%d</xliff:g> gånger. "\n\n"Försök igen om <xliff:g id="NUMBER_1">%d</xliff:g> sekunder."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Du har försökt låsa upp mobilen på fel sätt <xliff:g id="NUMBER_0">%d</xliff:g> gånger. Efter ytterligare <xliff:g id="NUMBER_1">%d</xliff:g> misslyckade försök återställs surfplattan till fabriksinställningarna. Du förlorar då alla användardata."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Du har försökt låsa upp mobilen på fel sätt <xliff:g id="NUMBER_0">%d</xliff:g> gånger. Efter ytterligare <xliff:g id="NUMBER_1">%d</xliff:g> misslyckade försök återställs mobilen till fabriksinställningarna. Du förlorar då alla användardata."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Du har försökt låsa upp surfplattan på fel sätt <xliff:g id="NUMBER">%d</xliff:g> gånger. Surfplattan återställs nu till fabriksinställningarna."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Du har försökt låsa upp mobilen på fel sätt <xliff:g id="NUMBER">%d</xliff:g> gånger. Mobilen återställs nu till fabriksinställningarna."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Du har ritat ditt grafiska lösenord fel <xliff:g id="NUMBER_0">%d</xliff:g> gånger. Efter ytterligare <xliff:g id="NUMBER_1">%d</xliff:g> försök ombeds du låsa upp surfplattan med ett e-postkonto."\n\n" Försök igen om <xliff:g id="NUMBER_2">%d</xliff:g> sekunder."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Du har ritat ditt grafiska lösenord fel <xliff:g id="NUMBER_0">%d</xliff:g> gånger. Efter ytterligare <xliff:g id="NUMBER_1">%d</xliff:g> försök ombeds du låsa upp mobilen med hjälp av ett e-postkonto."\n\n" Försök igen om <xliff:g id="NUMBER_2">%d</xliff:g> sekunder."</string>
+ <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" – "</string>
+ <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Ta bort"</string>
+ <!-- no translation found for keyguard_transport_prev_description (8229108430245669854) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_next_description (4299258300283778305) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_pause_description (5093073338238310224) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_play_description (2924628863741150956) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_stop_description (3084179324810575787) -->
+ <skip />
+ <!-- no translation found for keyguard_carrier_default (8700650403054042153) -->
+ <skip />
+</resources>
diff --git a/packages/Keyguard/res/values-sw/strings.xml b/packages/Keyguard/res/values-sw/strings.xml
new file mode 100644
index 0000000..a8131cd
--- /dev/null
+++ b/packages/Keyguard/res/values-sw/strings.xml
@@ -0,0 +1,164 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/* //device/apps/common/assets/res/any/strings.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:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Ingiza msimbo wa PIN"</string>
+ <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Ingiza PUK na msimbo mpya wa PIN"</string>
+ <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"Msimbo wa PUK"</string>
+ <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Msimbo mpya wa PIN"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Gusa kuingiza nenosiri "</font></string>
+ <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Charaza nenosiri ili kufungua"</string>
+ <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Ingiza PIN ili kufungua"</string>
+ <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Msimbo wa PIN usio sahihi."</string>
+ <string name="keyguard_label_text" msgid="861796461028298424">"Ili kufungua, bofya Menyu kisha 0."</string>
+ <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Majaribio ya Juu ya Kufungua Uso yamezidishwa"</string>
+ <!-- no translation found for keyguard_charged (3272223906073492454) -->
+ <skip />
+ <!-- no translation found for keyguard_plugged_in (8117572000639998388) -->
+ <skip />
+ <!-- no translation found for keyguard_low_battery (8143808018719173859) -->
+ <skip />
+ <!-- no translation found for keyguard_instructions_when_pattern_disabled (1332288268600329841) -->
+ <skip />
+ <!-- no translation found for keyguard_network_locked_message (9169717779058037168) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message_short (494980561304211931) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (1445849005909260039) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (3481110395508637643) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions (5210891509995942250) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions_long (5968985489463870358) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_message_short (8340813989586622356) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_instructions (5892940909699723544) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_locked_message (6875773413306380902) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_puk_locked_message (3747232467471801633) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_unlock_progress_dialog_message (7975221805033614426) -->
+ <skip />
+ <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Wiji %2$d ya %3$d."</string>
+ <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Ongeza wiji"</string>
+ <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Tupu"</string>
+ <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Eneo la kufungua limepanuliwa."</string>
+ <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Eneo la kufungua limekunjwa."</string>
+ <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> ya wiji."</string>
+ <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"Kiteuzi cha mtumiaji"</string>
+ <string name="keyguard_accessibility_status" msgid="8008264603935930611">"Hali"</string>
+ <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"Kamera"</string>
+ <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Vidhibiti vya media"</string>
+ <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Upangaji upya wa wiji umeanza."</string>
+ <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Upangaji upya wa wiji umekamilika."</string>
+ <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Wiji <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> imefutwa."</string>
+ <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Panua eneo la kufungua."</string>
+ <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Kufungua slaidi."</string>
+ <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Kufungua kwa ruwaza."</string>
+ <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Kufungua kwa uso."</string>
+ <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Kufungua kwa PIN."</string>
+ <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Kufungua kwa nenosiri."</string>
+ <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Eneo la ruwaza."</string>
+ <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Eneo la slaidi."</string>
+ <!-- no translation found for keyguard_accessibility_transport_prev_description (1337286538318543555) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_next_description (7073928300444909320) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_pause_description (8455979545295224302) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_play_description (8146417789511154044) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_stop_description (7656358482980912216) -->
+ <skip />
+ <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+ <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+ <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+ <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Ghairi"</string>
+ <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Futa"</string>
+ <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Imefanyika"</string>
+ <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Modi ya mabadiliko"</string>
+ <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Songa"</string>
+ <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Ingiza"</string>
+ <string name="description_target_unlock" msgid="2228524900439801453">"Fungua"</string>
+ <string name="description_target_camera" msgid="969071997552486814">"Kamera"</string>
+ <string name="description_target_silent" msgid="893551287746522182">"Kimya"</string>
+ <string name="description_target_soundon" msgid="30052466675500172">"Sauti imewashwa"</string>
+ <string name="description_target_search" msgid="3091587249776033139">"Tafuta"</string>
+ <string name="description_direction_up" msgid="7169032478259485180">"Sogeza juu kwa <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string>
+ <string name="description_direction_down" msgid="5087739728639014595">"Sogeza chini kwa <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_left" msgid="7207478719805562165">"Sogeza kushoto kwa <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string>
+ <string name="description_direction_right" msgid="8034433242579600980">"Sogeza kulika kwa <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string>
+ <string name="user_switched" msgid="3768006783166984410">"Mtumiaji wa sasa <xliff:g id="NAME">%1$s</xliff:g>."</string>
+ <string name="kg_emergency_call_label" msgid="684946192523830531">"Simu ya dharura"</string>
+ <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Umesahau Ruwaza"</string>
+ <string name="kg_wrong_pattern" msgid="1850806070801358830">"Ruwaza Isiyo sahihi"</string>
+ <string name="kg_wrong_password" msgid="2333281762128113157">"Nenosiri Lisilo sahihi"</string>
+ <string name="kg_wrong_pin" msgid="1131306510833563801">"PIN isiyo sahihi"</string>
+ <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Jaribu tena baada ya sekunde <xliff:g id="NUMBER">%d</xliff:g>."</string>
+ <string name="kg_pattern_instructions" msgid="398978611683075868">"Chora ruwaza yako"</string>
+ <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Ingiza PIN ya SIM"</string>
+ <string name="kg_pin_instructions" msgid="2377242233495111557">"Ingiza PIN"</string>
+ <string name="kg_password_instructions" msgid="5753646556186936819">"Ingiza Nenosiri"</string>
+ <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"SIM sasa imelemazwa. Ingiza msimbo wa PUK ili kuendelea. Wasiliana na mtoa huduma kwa maelezo."</string>
+ <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Ingiza msimbo wa PIN unaopendelewa"</string>
+ <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Thibitisha msimbo wa PIN unaopendelewa"</string>
+ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Inafungua kadi ya SIM..."</string>
+ <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Msimbo wa PIN usio sahihi."</string>
+ <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Charaza PIN iliyo na tarakimu kati ya 4 na 8."</string>
+ <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"Msimbo wa PUK unafaa kuwa na nambari 8 au zaidi."</string>
+ <string name="kg_invalid_puk" msgid="3638289409676051243">"Ingiza upya msimbo sahihi wa PUK. Majaribio yanayorudiwa yatalemaza SIM kabisa."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"Misimbo ya PIN haifanani"</string>
+ <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Majaribio mengi mno ya mchoro"</string>
+ <string name="kg_login_instructions" msgid="1100551261265506448">"Ili kufungua, ingia kwa Akaunti yako ya Google."</string>
+ <string name="kg_login_username_hint" msgid="5718534272070920364">"Jina la mtumiaji (barua pepe)"</string>
+ <string name="kg_login_password_hint" msgid="9057289103827298549">"Nenosiri"</string>
+ <string name="kg_login_submit_button" msgid="5355904582674054702">"Ingia"</string>
+ <string name="kg_login_invalid_input" msgid="5754664119319872197">"Jina la mtumiaji au nenosiri batili."</string>
+ <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Je, umesahau jina lako la mtumiaji au nenosiri?"\n"Tembela "<b>"Bgoogle.com/accounts/recovery"</b>"."</string>
+ <string name="kg_login_checking_password" msgid="1052685197710252395">"Inakagua akaunti…"</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Umeingiza nenosiri lako kwa makosa mara <xliff:g id="NUMBER_0">%d</xliff:g>. "\n\n" Jaribu tena baada ya sekunde <xliff:g id="NUMBER_1">%d</xliff:g>."</string>
+ <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Umeingiza nenosiri lako kwa makosa mara <xliff:g id="NUMBER_0">%d</xliff:g>. "\n\n" Jaribu tena baada ya sekunde <xliff:g id="NUMBER_1">%d</xliff:g>."</string>
+ <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Umechora ruwaza yako ya kufunga kwa makosa mara <xliff:g id="NUMBER_0">%d</xliff:g>. "\n\n" Jaribu tena baada ya sekunde <xliff:g id="NUMBER_1">%d</xliff:g>."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Umejaribu kufungua kompyuta ndogo kwa njia isiyo sahihi mara <xliff:g id="NUMBER_0">%d</xliff:g>. Baada ya majaribio <xliff:g id="NUMBER_1">%d</xliff:g> zaidi yasiyofaulu, kompyuta ndogo itarejeshwa katika mfumo chaguo-msingi ilivyotoka kiwandani data yote ya mtumiaji itapotea."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Umejaribu kufungua simu kwa njia isiyo sahihi mara <xliff:g id="NUMBER_0">%d</xliff:g>. Baada ya majaribio <xliff:g id="NUMBER_1">%d</xliff:g> zaidi yasiyofaulu, simu itarejeshwa katika mfumo chaguo-msingi ilivyotoka kiwandani na data yote ya mtumiaji itapotea."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Umejaribu kufungua kompyuta ndogo kwa njia isiyo sahihi mara <xliff:g id="NUMBER">%d</xliff:g>. Sasa kompyuta ndogo itarejeshwa katika mfumo chaguo-msingi ilivyotoka kiwandani."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Umejaribu kufungua simu kwa njia isiyo sahihi mara <xliff:g id="NUMBER">%d</xliff:g>. Sasa simu itarejeshwa katika mfumo chaguo-msingi ilivyotoka kiwandani."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Umekosea katika kuweka mchoro wako wa kufungua mara <xliff:g id="NUMBER_0">%d</xliff:g>. Baada ya majaribio <xliff:g id="NUMBER_1">%d</xliff:g> bila kufaulu, utaombwa kufungua kompyuta yako ndogo kwa kutumia akaunti yako ya barua pepe."\n\n" Jaribu tena baada ya sekunde <xliff:g id="NUMBER_2">%d</xliff:g>."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Umekosea kuchora mchoro wako wa kufungua mara <xliff:g id="NUMBER_0">%d</xliff:g>. Baada ya majaribio <xliff:g id="NUMBER_1">%d</xliff:g> yasiyofaulu, utaombwa kufungua simu yako kwa kutumia akaunti ya barua pepe."\n\n" Jaribu tena baada ya sekunde <xliff:g id="NUMBER_2">%d</xliff:g>."</string>
+ <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
+ <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Ondoa"</string>
+ <!-- no translation found for keyguard_transport_prev_description (8229108430245669854) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_next_description (4299258300283778305) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_pause_description (5093073338238310224) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_play_description (2924628863741150956) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_stop_description (3084179324810575787) -->
+ <skip />
+ <!-- no translation found for keyguard_carrier_default (8700650403054042153) -->
+ <skip />
+</resources>
diff --git a/packages/Keyguard/res/values-sw380dp-land/dimens.xml b/packages/Keyguard/res/values-sw380dp-land/dimens.xml
new file mode 100644
index 0000000..20eb1be
--- /dev/null
+++ b/packages/Keyguard/res/values-sw380dp-land/dimens.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/assets/res/any/dimens.xml
+**
+** 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.
+*/
+-->
+<resources>
+ <!-- Top margin for the clock view -->
+ <dimen name="kg_clock_top_margin">48dp</dimen>
+</resources>
diff --git a/packages/Keyguard/res/values-sw380dp/dimens.xml b/packages/Keyguard/res/values-sw380dp/dimens.xml
new file mode 100644
index 0000000..fc0e85d
--- /dev/null
+++ b/packages/Keyguard/res/values-sw380dp/dimens.xml
@@ -0,0 +1,23 @@
+<?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.
+*/
+-->
+
+<resources>
+ <!-- Width of the sliding KeyguardSecurityContainer (includes 2x keyguard_security_view_margin) -->
+ <dimen name="keyguard_security_width">340dp</dimen>
+</resources> \ No newline at end of file
diff --git a/packages/Keyguard/res/values-sw600dp-land/arrays.xml b/packages/Keyguard/res/values-sw600dp-land/arrays.xml
new file mode 100644
index 0000000..5550216
--- /dev/null
+++ b/packages/Keyguard/res/values-sw600dp-land/arrays.xml
@@ -0,0 +1,72 @@
+<?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">
+
+ <!-- Resources for GlowPadView in LockScreen -->
+ <array name="lockscreen_targets_when_silent">
+ <item>@drawable/ic_lockscreen_unlock</item>
+ <item>@null</item>
+ <item>@drawable/ic_lockscreen_soundon</item>
+ <item>@null</item>
+ </array>
+
+ <array name="lockscreen_target_descriptions_when_silent">
+ <item>@string/description_target_unlock</item>
+ <item>@null</item>
+ <item>@string/description_target_soundon</item>
+ <item>@null</item>
+ </array>
+
+ <array name="lockscreen_direction_descriptions">
+ <item>@string/description_direction_right</item>
+ <item>@null</item>
+ <item>@string/description_direction_left</item>
+ <item>@null</item>
+ </array>
+
+ <array name="lockscreen_targets_when_soundon">
+ <item>@drawable/ic_lockscreen_unlock</item>
+ <item>@null</item>
+ <item>@drawable/ic_lockscreen_silent</item>
+ <item>@null</item>
+ </array>
+
+ <array name="lockscreen_target_descriptions_when_soundon">
+ <item>@string/description_target_unlock</item>
+ <item>@null</item>
+ <item>@string/description_target_silent</item>
+ <item>@null</item>
+ </array>
+
+ <array name="lockscreen_targets_with_camera">
+ <item>@drawable/ic_lockscreen_unlock</item>
+ <item>@drawable/ic_action_assist_generic</item>
+ <item>@drawable/ic_lockscreen_camera</item>
+ <item>@null</item>
+ </array>
+
+ <array name="lockscreen_target_descriptions_with_camera">
+ <item>@string/description_target_unlock</item>
+ <item>@string/description_target_search</item>
+ <item>@string/description_target_camera</item>
+ <item>@null</item>
+ </array>
+
+</resources>
diff --git a/packages/Keyguard/res/values-sw600dp-land/dimens.xml b/packages/Keyguard/res/values-sw600dp-land/dimens.xml
new file mode 100644
index 0000000..5507e5f
--- /dev/null
+++ b/packages/Keyguard/res/values-sw600dp-land/dimens.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/assets/res/any/dimens.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>
+ <!-- Top margin for the clock view -->
+ <dimen name="kg_clock_top_margin">85dp</dimen>
+
+ <!-- Size of margin on the right of keyguard's status view -->
+ <dimen name="kg_status_line_font_right_margin">16dp</dimen>
+</resources> \ No newline at end of file
diff --git a/packages/Keyguard/res/values-sw600dp-land/integers.xml b/packages/Keyguard/res/values-sw600dp-land/integers.xml
new file mode 100644
index 0000000..b724c90
--- /dev/null
+++ b/packages/Keyguard/res/values-sw600dp-land/integers.xml
@@ -0,0 +1,23 @@
+<?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.
+*/
+-->
+<resources>
+ <integer name="kg_widget_region_weight">50</integer>
+ <integer name="kg_security_flipper_weight">50</integer>
+ <integer name="kg_glowpad_rotation_offset">0</integer>
+</resources>
diff --git a/packages/Keyguard/res/values-sw600dp-port/integers.xml b/packages/Keyguard/res/values-sw600dp-port/integers.xml
new file mode 100644
index 0000000..65b854a
--- /dev/null
+++ b/packages/Keyguard/res/values-sw600dp-port/integers.xml
@@ -0,0 +1,22 @@
+<?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.
+*/
+-->
+<resources>
+ <integer name="kg_widget_region_weight">46</integer>
+ <integer name="kg_security_flipper_weight">54</integer>
+</resources> \ No newline at end of file
diff --git a/packages/Keyguard/res/values-sw600dp/alias.xml b/packages/Keyguard/res/values-sw600dp/alias.xml
new file mode 100644
index 0000000..c3ecbb9
--- /dev/null
+++ b/packages/Keyguard/res/values-sw600dp/alias.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/assets/res/any/colors.xml
+**
+** 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.
+*/
+-->
+<resources>
+ <!-- Alias used to reference one of two possible layouts in keyguard. -->
+ <item type="layout" name="keyguard_eca">@layout/keyguard_emergency_carrier_area</item>
+</resources>
diff --git a/packages/Keyguard/res/values-sw600dp/bools.xml b/packages/Keyguard/res/values-sw600dp/bools.xml
new file mode 100644
index 0000000..ddc48c5
--- /dev/null
+++ b/packages/Keyguard/res/values-sw600dp/bools.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<resources>
+ <bool name="target_honeycomb_needs_options_menu">false</bool>
+ <bool name="show_ongoing_ime_switcher">true</bool>
+ <bool name="kg_share_status_area">false</bool>
+ <bool name="kg_sim_puk_account_full_screen">false</bool>
+ <bool name="kg_show_ime_at_screen_on">false</bool>
+ <!-- No camera for you, tablet user -->
+ <bool name="kg_enable_camera_default_widget">false</bool>
+ <bool name="kg_center_small_widgets_vertically">true</bool>
+ <bool name="kg_top_align_page_shrink_on_bouncer_visible">false</bool>
+</resources>
diff --git a/packages/Keyguard/res/values-sw600dp/dimens.xml b/packages/Keyguard/res/values-sw600dp/dimens.xml
new file mode 100644
index 0000000..c0e3937
--- /dev/null
+++ b/packages/Keyguard/res/values-sw600dp/dimens.xml
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/assets/res/any/dimens.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>
+ <!-- Size of clock font in LockScreen. -->
+ <dimen name="keyguard_pattern_unlock_clock_font_size">112sp</dimen>
+
+ <!-- Size of lockscreen outerring on unsecure unlock LockScreen -->
+ <dimen name="keyguard_lockscreen_outerring_diameter">364dp</dimen>
+
+ <!-- Height of FaceUnlock view in keyguard -->
+ <dimen name="face_unlock_height">430dip</dimen>
+
+ <!-- target placement radius for GlowPadView. Should be 1/2 of outerring diameter. -->
+ <dimen name="glowpadview_target_placement_radius">182dip</dimen>
+
+ <!-- Size of status line font in LockScreen. -->
+ <dimen name="keyguard_pattern_unlock_status_line_font_size">14sp</dimen>
+
+ <!-- Keyguard dimensions -->
+ <!-- Size of the clock font in keyguard's status view -->
+ <dimen name="kg_status_clock_font_size">141dp</dimen>
+
+ <!-- Size of the date font in keyguard's status view -->
+ <dimen name="kg_status_date_font_size">25.5dp</dimen>
+
+ <!-- Size of the generic status lines keyguard's status view -->
+ <dimen name="kg_status_line_font_size">16sp</dimen>
+
+ <!-- Top margin for the clock view -->
+ <dimen name="kg_clock_top_margin">0dp</dimen>
+
+ <!-- Size of margin on the right of keyguard's status view -->
+ <dimen name="kg_status_line_font_right_margin">50dp</dimen>
+
+ <!-- Horizontal padding for the widget pager -->
+ <dimen name="kg_widget_pager_horizontal_padding">24dp</dimen>
+
+ <!-- Top padding for the widget pager -->
+ <dimen name="kg_widget_pager_top_padding">0dp</dimen>
+
+ <!-- Bottom padding for the widget pager -->
+ <dimen name="kg_widget_pager_bottom_padding">0dp</dimen>
+
+ <!-- Top margin for the runway lights. We add a negative margin in large
+ devices to account for the widget pager padding -->
+ <dimen name="kg_runway_lights_top_margin">-10dp</dimen>
+
+ <!-- Margin around the various security views -->
+ <dimen name="keyguard_security_view_margin">12dp</dimen>
+
+ <!-- Margin around the various security views -->
+ <dimen name="keyguard_muliuser_selector_margin">12dp</dimen>
+
+</resources>
diff --git a/packages/Keyguard/res/values-sw600dp/integers.xml b/packages/Keyguard/res/values-sw600dp/integers.xml
new file mode 100644
index 0000000..de9829c
--- /dev/null
+++ b/packages/Keyguard/res/values-sw600dp/integers.xml
@@ -0,0 +1,21 @@
+<?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.
+*/
+-->
+<resources>
+ <integer name="kg_carousel_angle">60</integer>
+</resources>
diff --git a/packages/Keyguard/res/values-sw720dp-land/dimens.xml b/packages/Keyguard/res/values-sw720dp-land/dimens.xml
new file mode 100644
index 0000000..14726ab
--- /dev/null
+++ b/packages/Keyguard/res/values-sw720dp-land/dimens.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/assets/res/any/dimens.xml
+**
+** 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.
+*/
+-->
+<resources>
+ <!-- Top margin for the clock view -->
+ <dimen name="kg_clock_top_margin">174dp</dimen>
+
+ <!-- Size of margin on the right of keyguard's status view -->
+ <dimen name="kg_status_line_font_right_margin">16dp</dimen>
+
+ <!-- Horizontal padding for the widget pager -->
+ <dimen name="kg_widget_pager_horizontal_padding">32dp</dimen>
+</resources>
diff --git a/packages/Keyguard/res/values-sw720dp-port/integers.xml b/packages/Keyguard/res/values-sw720dp-port/integers.xml
new file mode 100644
index 0000000..5f85f71
--- /dev/null
+++ b/packages/Keyguard/res/values-sw720dp-port/integers.xml
@@ -0,0 +1,22 @@
+<?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.
+*/
+-->
+<resources>
+ <integer name="kg_widget_region_weight">48</integer>
+ <integer name="kg_security_flipper_weight">52</integer>
+</resources> \ No newline at end of file
diff --git a/packages/Keyguard/res/values-sw720dp/dimens.xml b/packages/Keyguard/res/values-sw720dp/dimens.xml
new file mode 100644
index 0000000..b29ac22
--- /dev/null
+++ b/packages/Keyguard/res/values-sw720dp/dimens.xml
@@ -0,0 +1,66 @@
+<?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.
+*/
+-->
+<resources>
+ <!-- Keyguard dimensions -->
+ <!-- Size of the clock font in keyguard's status view -->
+ <dimen name="kg_status_clock_font_size">188dp</dimen>
+
+ <!-- Size of the date font in keyguard's status view -->
+ <dimen name="kg_status_date_font_size">34dp</dimen>
+
+ <!-- Size of the generic status lines keyguard's status view -->
+ <dimen name="kg_status_line_font_size">19sp</dimen>
+
+ <!-- Top margin for the clock view -->
+ <dimen name="kg_clock_top_margin">0dp</dimen>
+
+ <!-- Size of margin on the right of keyguard's status view -->
+ <dimen name="kg_status_line_font_right_margin">32dp</dimen>
+
+ <!-- Horizontal padding for the widget pager -->
+ <dimen name="kg_widget_pager_horizontal_padding">80dp</dimen>
+
+ <!-- Top padding for the widget pager -->
+ <dimen name="kg_widget_pager_top_padding">0dp</dimen>
+
+ <!-- Bottom padding for the widget pager -->
+ <dimen name="kg_widget_pager_bottom_padding">0dp</dimen>
+
+ <!-- Top margin for the runway lights. We add a negative margin in large
+ devices to account for the widget pager padding -->
+ <dimen name="kg_runway_lights_top_margin">-30dp</dimen>
+
+ <!-- Margin around the various security views -->
+ <dimen name="keyguard_muliuser_selector_margin">24dp</dimen>
+
+ <!-- Stroke width of the frame for the circular avatars. -->
+ <dimen name="keyguard_avatar_frame_stroke_width">3dp</dimen>
+
+ <!-- Size of the avator on the multiuser lockscreen. -->
+ <dimen name="keyguard_avatar_size">88dp</dimen>
+
+ <!-- Size of the text under the avator on the multiuser lockscreen. -->
+ <dimen name="keyguard_avatar_name_size">12sp</dimen>
+
+ <!-- Width of the sliding KeyguardSecurityContainer (includes 2x keyguard_security_view_margin) -->
+ <dimen name="keyguard_security_width">420dp</dimen>
+
+ <!-- Height of the sliding KeyguardSecurityContainer (includes 2x keyguard_security_view_margin) -->
+ <dimen name="keyguard_security_height">420dp</dimen>
+</resources>
diff --git a/packages/Keyguard/res/values-th/strings.xml b/packages/Keyguard/res/values-th/strings.xml
new file mode 100644
index 0000000..5368673
--- /dev/null
+++ b/packages/Keyguard/res/values-th/strings.xml
@@ -0,0 +1,164 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/* //device/apps/common/assets/res/any/strings.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:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"พิมพ์รหัส PIN"</string>
+ <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"พิมพ์ PUK และรหัส PIN ใหม่"</string>
+ <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"รหัส PUK"</string>
+ <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"รหัส PIN ใหม่"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"แตะเพื่อพิมพ์รหัสผ่าน"</font></string>
+ <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"พิมพ์รหัสผ่านเพื่อปลดล็อก"</string>
+ <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"พิมพ์ PIN เพื่อปลดล็อก"</string>
+ <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"รหัส PIN ไม่ถูกต้อง"</string>
+ <string name="keyguard_label_text" msgid="861796461028298424">"หากต้องการปลดล็อก กด เมนู ตามด้วย 0"</string>
+ <string name="faceunlock_multiple_failures" msgid="754137583022792429">"มีความพยายามที่จะใช้ Face Unlock เกินขีดจำกัด"</string>
+ <!-- no translation found for keyguard_charged (3272223906073492454) -->
+ <skip />
+ <!-- no translation found for keyguard_plugged_in (8117572000639998388) -->
+ <skip />
+ <!-- no translation found for keyguard_low_battery (8143808018719173859) -->
+ <skip />
+ <!-- no translation found for keyguard_instructions_when_pattern_disabled (1332288268600329841) -->
+ <skip />
+ <!-- no translation found for keyguard_network_locked_message (9169717779058037168) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message_short (494980561304211931) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (1445849005909260039) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (3481110395508637643) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions (5210891509995942250) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions_long (5968985489463870358) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_message_short (8340813989586622356) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_instructions (5892940909699723544) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_locked_message (6875773413306380902) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_puk_locked_message (3747232467471801633) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_unlock_progress_dialog_message (7975221805033614426) -->
+ <skip />
+ <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s วิดเจ็ต %2$d ของ %3$d"</string>
+ <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"เพิ่มวิดเจ็ต"</string>
+ <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"ว่าง"</string>
+ <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"ขยายพื้นที่ปลดล็อกแล้ว"</string>
+ <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"ยุบพื้นที่ปลดล็อกแล้ว"</string>
+ <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"วิดเจ็ต <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>"</string>
+ <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"ตัวเลือกผู้ใช้"</string>
+ <string name="keyguard_accessibility_status" msgid="8008264603935930611">"สถานะ"</string>
+ <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"กล้องถ่ายรูป"</string>
+ <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"การควบคุมสื่อ"</string>
+ <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"เริ่มเรียงลำดับวิดเจ็ตใหม่"</string>
+ <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"เรียงลำดับวิดเจ็ตใหม่เสร็จแล้ว"</string>
+ <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"ลบวิดเจ็ต <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> แล้ว"</string>
+ <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"ขยายพื้นที่ปลดล็อก"</string>
+ <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"การปลดล็อกด้วยการเลื่อน"</string>
+ <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"การปลดล็อกด้วยรูปแบบ"</string>
+ <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"การปลดล็อกด้วยใบหน้า"</string>
+ <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"การปลดล็อกด้วย PIN"</string>
+ <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"การปลดล็อกด้วยรหัสผ่าน"</string>
+ <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"พื้นที่สำหรับรูปแบบ"</string>
+ <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"พื้นที่สำหรับการเลื่อน"</string>
+ <!-- no translation found for keyguard_accessibility_transport_prev_description (1337286538318543555) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_next_description (7073928300444909320) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_pause_description (8455979545295224302) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_play_description (8146417789511154044) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_stop_description (7656358482980912216) -->
+ <skip />
+ <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+ <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+ <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+ <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"ยกเลิก"</string>
+ <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"ลบ"</string>
+ <string name="keyboardview_keycode_done" msgid="1992571118466679775">"เสร็จสิ้น"</string>
+ <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"เปลี่ยนโหมด"</string>
+ <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
+ <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"ป้อน"</string>
+ <string name="description_target_unlock" msgid="2228524900439801453">"ปลดล็อก"</string>
+ <string name="description_target_camera" msgid="969071997552486814">"กล้อง"</string>
+ <string name="description_target_silent" msgid="893551287746522182">"ปิดเสียง"</string>
+ <string name="description_target_soundon" msgid="30052466675500172">"เปิดเสียง"</string>
+ <string name="description_target_search" msgid="3091587249776033139">"ค้นหา"</string>
+ <string name="description_direction_up" msgid="7169032478259485180">"เลื่อนขึ้นเพื่อ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
+ <string name="description_direction_down" msgid="5087739728639014595">"เลื่อนลงเพื่อ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
+ <string name="description_direction_left" msgid="7207478719805562165">"เลื่อนไปทางซ้ายเพื่อ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
+ <string name="description_direction_right" msgid="8034433242579600980">"เลื่อนไปทางขวาเพื่อ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
+ <string name="user_switched" msgid="3768006783166984410">"ผู้ใช้ปัจจุบัน <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="kg_emergency_call_label" msgid="684946192523830531">"หมายเลขฉุกเฉิน"</string>
+ <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"ลืมรูปแบบใช่หรือไม่"</string>
+ <string name="kg_wrong_pattern" msgid="1850806070801358830">"รูปแบบไม่ถูกต้อง"</string>
+ <string name="kg_wrong_password" msgid="2333281762128113157">"รหัสผ่านไม่ถูกต้อง"</string>
+ <string name="kg_wrong_pin" msgid="1131306510833563801">"PIN ไม่ถูกต้อง"</string>
+ <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"ลองอีกครั้งในอีก <xliff:g id="NUMBER">%d</xliff:g> วินาที"</string>
+ <string name="kg_pattern_instructions" msgid="398978611683075868">"วาดรูปแบบของคุณ"</string>
+ <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"ป้อน PIN ของซิม"</string>
+ <string name="kg_pin_instructions" msgid="2377242233495111557">"ป้อน PIN"</string>
+ <string name="kg_password_instructions" msgid="5753646556186936819">"ป้อนรหัสผ่าน"</string>
+ <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"ซิมการ์ดถูกปิดใช้งานแล้วในตอนนี้ ป้อนรหัส PUK เพื่อดำเนินการต่อ โปรดติดต่อผู้ให้บริการสำหรับรายละเอียด"</string>
+ <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"ป้อนรหัส PIN ที่ต้องการ"</string>
+ <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"ยืนยันรหัส PIN ที่ต้องการ"</string>
+ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"กำลังปลดล็อกซิมการ์ด…"</string>
+ <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"รหัส PIN ไม่ถูกต้อง"</string>
+ <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"พิมพ์ PIN ซึ่งเป็นเลข 4 ถึง 8 หลัก"</string>
+ <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"รหัส PUK ต้องเป็นตัวเลขอย่างน้อย 8 หลัก"</string>
+ <string name="kg_invalid_puk" msgid="3638289409676051243">"ใส่รหัส PUK ที่ถูกต้องอีกครั้ง การพยายามซ้ำหลายครั้งจะทำให้ซิมการ์ดถูกปิดใช้งานอย่างถาวร"</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"รหัส PIN ไม่ตรง"</string>
+ <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"ลองหลายรูปแบบมากเกินไป"</string>
+ <string name="kg_login_instructions" msgid="1100551261265506448">"หากต้องการปลดล็อก ให้ลงชื่อเข้าใช้ด้วยบัญชี Google ของคุณ"</string>
+ <string name="kg_login_username_hint" msgid="5718534272070920364">"ชื่อผู้ใช้ (อีเมล)"</string>
+ <string name="kg_login_password_hint" msgid="9057289103827298549">"รหัสผ่าน"</string>
+ <string name="kg_login_submit_button" msgid="5355904582674054702">"ลงชื่อเข้าใช้"</string>
+ <string name="kg_login_invalid_input" msgid="5754664119319872197">"ชื่อผู้ใช้หรือรหัสผ่านไม่ถูกต้อง"</string>
+ <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"หากลืมชื่อผู้ใช้หรือรหัสผ่าน"\n"โปรดไปที่ "<b>"google.com/accounts/recovery"</b></string>
+ <string name="kg_login_checking_password" msgid="1052685197710252395">"กำลังตรวจสอบบัญชี…"</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"คุณพิมพ์ PIN ไม่ถูกต้องไป <xliff:g id="NUMBER_0">%d</xliff:g> ครั้งแล้ว "\n\n"โปรดลองอีกครั้งใน <xliff:g id="NUMBER_1">%d</xliff:g> วินาที"</string>
+ <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"คุณพิมพ์รหัสผ่านไม่ถูกต้องไป <xliff:g id="NUMBER_0">%d</xliff:g> ครั้งแล้ว "\n\n"โปรดลองอีกครั้งใน <xliff:g id="NUMBER_1">%d</xliff:g> วินาที"</string>
+ <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"คุณวาดรูปแบบการปลดล็อกไม่ถูกต้องไป <xliff:g id="NUMBER_0">%d</xliff:g> ครั้งแล้ว "\n\n"โปรดลองอีกครั้งใน <xliff:g id="NUMBER_1">%d</xliff:g> วินาที"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"คุณพยายามปลดล็อกแท็บเล็ตอย่างไม่ถูกต้อง <xliff:g id="NUMBER_0">%d</xliff:g> ครั้งแล้ว หากพยายามแล้วไม่สำเร็จอีก <xliff:g id="NUMBER_1">%d</xliff:g> ครั้ง แท็บเล็ตจะถูกรีเซ็ตเป็นค่าเริ่มต้นจากโรงงานและข้อมูลผู้ใช้ทั้งหมดจะหายไป"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"คุณพยายามปลดล็อกโทรศัพท์อย่างไม่ถูกต้อง <xliff:g id="NUMBER_0">%d</xliff:g> ครั้งแล้ว หากพยายามแล้วไม่สำเร็จอีก <xliff:g id="NUMBER_1">%d</xliff:g> ครั้ง โทรศัพท์จะถูกรีเซ็ตเป็นค่าเริ่มต้นจากโรงงานและข้อมูลผู้ใช้ทั้งหมดจะหายไป"</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"คุณพยายามปลดล็อกแท็บเล็ตอย่างไม่ถูกต้อง <xliff:g id="NUMBER">%d</xliff:g> ครั้งแล้ว ขณะนี้แท็บเล็ตจะถูกรีเซ็ตเป็นค่าเริ่มต้นจากโรงงาน"</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"คุณพยายามปลดล็อกโทรศัพท์อย่างไม่ถูกต้อง <xliff:g id="NUMBER">%d</xliff:g> ครั้งแล้ว ขณะนี้โทรศัพท์จะถูกรีเซ็ตเป็นค่าเริ่มต้นจากโรงงาน"</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"คุณวาดรูปแบบการปลดล็อกไม่ถูกต้อง <xliff:g id="NUMBER_0">%d</xliff:g> ครั้งแล้ว หากทำไม่สำเร็จอีก <xliff:g id="NUMBER_1">%d</xliff:g> ครั้ง ระบบจะขอให้คุณปลดล็อกแท็บเล็ตโดยใช้บัญชีอีเมล"\n\n" โปรดลองอีกครั้งใน <xliff:g id="NUMBER_2">%d</xliff:g> วินาที"</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"คุณวาดรูปแบบการปลดล็อกไม่ถูกต้อง <xliff:g id="NUMBER_0">%d</xliff:g> ครั้งแล้ว หากทำไม่สำเร็จอีก <xliff:g id="NUMBER_1">%d</xliff:g> ครั้ง ระบบจะขอให้คุณปลดล็อกโทรศัพท์โดยใช้ับัญชีอีเมล"\n\n" โปรดลองอีกครั้งในอีก <xliff:g id="NUMBER_2">%d</xliff:g> วินาที"</string>
+ <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
+ <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"นำออก"</string>
+ <!-- no translation found for keyguard_transport_prev_description (8229108430245669854) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_next_description (4299258300283778305) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_pause_description (5093073338238310224) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_play_description (2924628863741150956) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_stop_description (3084179324810575787) -->
+ <skip />
+ <!-- no translation found for keyguard_carrier_default (8700650403054042153) -->
+ <skip />
+</resources>
diff --git a/packages/Keyguard/res/values-tl/strings.xml b/packages/Keyguard/res/values-tl/strings.xml
new file mode 100644
index 0000000..02f31c9
--- /dev/null
+++ b/packages/Keyguard/res/values-tl/strings.xml
@@ -0,0 +1,164 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/* //device/apps/common/assets/res/any/strings.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:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"I-type ang PIN code"</string>
+ <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"I-type ang PUK at bagong PIN code"</string>
+ <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK code"</string>
+ <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Bagong PIN code"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Pindutin upang i-type password"</font></string>
+ <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"I-type ang password upang i-unlock"</string>
+ <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"I-type ang PIN upang i-unlock"</string>
+ <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Maling PIN code."</string>
+ <string name="keyguard_label_text" msgid="861796461028298424">"Upang i-unlock, pindutin ang Menu pagkatapos ay 0."</string>
+ <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Nalagpasan na ang maximum na mga pagtatangka sa Face Unlock"</string>
+ <!-- no translation found for keyguard_charged (3272223906073492454) -->
+ <skip />
+ <!-- no translation found for keyguard_plugged_in (8117572000639998388) -->
+ <skip />
+ <!-- no translation found for keyguard_low_battery (8143808018719173859) -->
+ <skip />
+ <!-- no translation found for keyguard_instructions_when_pattern_disabled (1332288268600329841) -->
+ <skip />
+ <!-- no translation found for keyguard_network_locked_message (9169717779058037168) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message_short (494980561304211931) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (1445849005909260039) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (3481110395508637643) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions (5210891509995942250) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions_long (5968985489463870358) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_message_short (8340813989586622356) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_instructions (5892940909699723544) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_locked_message (6875773413306380902) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_puk_locked_message (3747232467471801633) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_unlock_progress_dialog_message (7975221805033614426) -->
+ <skip />
+ <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d ng %3$d."</string>
+ <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Magdagdag ng widget."</string>
+ <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Walang laman"</string>
+ <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Pinalaki ang bahagi ng pag-unlock."</string>
+ <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Pinaliit ang bahagi ng pag-unlock."</string>
+ <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> widget."</string>
+ <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"Tagapili ng user"</string>
+ <string name="keyguard_accessibility_status" msgid="8008264603935930611">"Katayuan"</string>
+ <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"Camera"</string>
+ <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Mga kontrol ng media"</string>
+ <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Nagsimula na ang pagbabago ng ayos ng widget."</string>
+ <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Natapos na ang pagbabago ng ayos ng widget."</string>
+ <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Tinanggal ang widget na <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>."</string>
+ <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Palakihin ang bahagi ng pag-unlock."</string>
+ <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Pag-unlock ng slide."</string>
+ <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Pag-unlock ng pattern."</string>
+ <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Face unlock."</string>
+ <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Pag-unlock ng pin."</string>
+ <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Pag-unlock ng password."</string>
+ <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Bahagi ng pattern."</string>
+ <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Bahagi ng slide."</string>
+ <!-- no translation found for keyguard_accessibility_transport_prev_description (1337286538318543555) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_next_description (7073928300444909320) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_pause_description (8455979545295224302) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_play_description (8146417789511154044) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_stop_description (7656358482980912216) -->
+ <skip />
+ <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+ <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+ <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+ <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Kanselahin"</string>
+ <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Tanggalin"</string>
+ <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Tapos na"</string>
+ <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Pagbabago ng Mode"</string>
+ <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
+ <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
+ <string name="description_target_unlock" msgid="2228524900439801453">"I-unlock"</string>
+ <string name="description_target_camera" msgid="969071997552486814">"Camera"</string>
+ <string name="description_target_silent" msgid="893551287746522182">"Tahimik"</string>
+ <string name="description_target_soundon" msgid="30052466675500172">"I-on ang tunog"</string>
+ <string name="description_target_search" msgid="3091587249776033139">"Maghanap"</string>
+ <string name="description_direction_up" msgid="7169032478259485180">"Mag-slide pataas para sa <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_down" msgid="5087739728639014595">"Mag-slide pababa para sa <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_left" msgid="7207478719805562165">"Mag-slide pakaliwa para sa <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_right" msgid="8034433242579600980">"Mag-slide pakanan para sa <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="user_switched" msgid="3768006783166984410">"Kasalukuyang user <xliff:g id="NAME">%1$s</xliff:g>."</string>
+ <string name="kg_emergency_call_label" msgid="684946192523830531">"Emergency na tawag"</string>
+ <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Nakalimutan ang Pattern"</string>
+ <string name="kg_wrong_pattern" msgid="1850806070801358830">"Maling Pattern"</string>
+ <string name="kg_wrong_password" msgid="2333281762128113157">"Maling Password"</string>
+ <string name="kg_wrong_pin" msgid="1131306510833563801">"Maling PIN"</string>
+ <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Subukang muli sa loob ng <xliff:g id="NUMBER">%d</xliff:g> (na) segundo."</string>
+ <string name="kg_pattern_instructions" msgid="398978611683075868">"Iguhit ang iyong pattern"</string>
+ <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Ilagay ang SIM PIN"</string>
+ <string name="kg_pin_instructions" msgid="2377242233495111557">"Ilagay ang PIN"</string>
+ <string name="kg_password_instructions" msgid="5753646556186936819">"Ilagay ang Password"</string>
+ <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"Hindi na pinagana ang SIM ngayon. Maglagay ng PUK code upang magpatuloy. Makipag-ugnay sa carrier para sa mga detalye."</string>
+ <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Ilagay ang ninanais na PIN code"</string>
+ <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Kumpirmahin ang ninanais na PIN code"</string>
+ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Ina-unlock ang SIM card…"</string>
+ <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Hindi tamang PIN code."</string>
+ <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Mag-type ng PIN na 4 hanggang 8 numero."</string>
+ <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"Dapat ay 8 numero o higit pa ang PUK code."</string>
+ <string name="kg_invalid_puk" msgid="3638289409676051243">"Muling ilagay ang tamang PUK code. Permanenteng hindi pagaganahin ang SIM ng mga paulit-ulit na pagtatangka."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"Hindi tumutugma ang mga PIN code"</string>
+ <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Masyadong maraming pagtatangka sa pattern"</string>
+ <string name="kg_login_instructions" msgid="1100551261265506448">"Upang i-unlock, mag-sign in gamit ang iyong Google account."</string>
+ <string name="kg_login_username_hint" msgid="5718534272070920364">"Username (email)"</string>
+ <string name="kg_login_password_hint" msgid="9057289103827298549">"Password"</string>
+ <string name="kg_login_submit_button" msgid="5355904582674054702">"Mag-sign in"</string>
+ <string name="kg_login_invalid_input" msgid="5754664119319872197">"Di-wastong username o password."</string>
+ <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Nakalimutan ang iyong username o password?"\n"Bisitahin ang "<b>"google.com/accounts/recovery"</b>"."</string>
+ <string name="kg_login_checking_password" msgid="1052685197710252395">"Tinitingnan ang account…"</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Na-type mo nang hindi tama ang iyong PIN nang <xliff:g id="NUMBER_0">%d</xliff:g> (na) beses. "\n\n"Subukang muli sa loob ng <xliff:g id="NUMBER_1">%d</xliff:g> (na) segundo."</string>
+ <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Na-type mo nang hindi tama ang iyong password nang <xliff:g id="NUMBER_0">%d</xliff:g> (na) beses. "\n\n"Subukang muli sa loob ng <xliff:g id="NUMBER_1">%d</xliff:g> (na) segundo."</string>
+ <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Naguhit mo nang hindi tama ang iyong pattern sa pag-unlock nang <xliff:g id="NUMBER_0">%d</xliff:g> (na) beses. "\n\n"Subukang muli sa loob ng <xliff:g id="NUMBER_1">%d</xliff:g> (na) segundo."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Tinangka mo sa hindi tamang paraan na i-unlock ang tabelt nang <xliff:g id="NUMBER_0">%d</xliff:g> (na) beses. Pagkatapos ng <xliff:g id="NUMBER_1">%d</xliff:g> pang hindi matagumpay na pagtatangka, ire-reset ang tablet sa factory default at mawawala ang lahat ng data ng user."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Tinangka mo sa hindi tamang paraan na i-unlock ang telepono nang <xliff:g id="NUMBER_0">%d</xliff:g> (na) beses. Pagkatapos ng <xliff:g id="NUMBER_1">%d</xliff:g> pang hindi matagumpay na pagtatangka, ire-reset ang telepono sa factory default at mawawala ang lahat ng data ng user."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Tinangka mo sa hindi tamang paraan na i-unlock ang tablet nang <xliff:g id="NUMBER">%d</xliff:g> (na) beses. Ire-reset na ngayon ang tablet sa factory default."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Tinangka mo sa hindi tamang paraan na i-unlock ang telepono nang <xliff:g id="NUMBER">%d</xliff:g> (na) beses. Ire-reset na ngayon ang telepono sa factory default."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Naguhit mo nang hindi tama ang iyong pattern sa pag-unlock nang <xliff:g id="NUMBER_0">%d</xliff:g> (na) beses. Pagkatapos ng <xliff:g id="NUMBER_1">%d</xliff:g> pang hindi matagumpay na pagtatangka, hihilingin sa iyong i-unlock ang tablet mo gamit ang isang email account."\n\n" Subukang muli sa loob ng <xliff:g id="NUMBER_2">%d</xliff:g> (na) segundo."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Naguhit mo nang hindi tama ang iyong pattern sa pag-unlock nang <xliff:g id="NUMBER_0">%d</xliff:g> (na) beses. Pagkatapos ng <xliff:g id="NUMBER_1">%d</xliff:g> pang hindi matagumpay na pagtatangka, hihilingin sa iyong i-unlock ang telepono mo gamit ang isang email account."\n\n" Subukang muli sa loob ng <xliff:g id="NUMBER_2">%d</xliff:g> (na) segundo."</string>
+ <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
+ <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Alisin"</string>
+ <!-- no translation found for keyguard_transport_prev_description (8229108430245669854) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_next_description (4299258300283778305) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_pause_description (5093073338238310224) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_play_description (2924628863741150956) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_stop_description (3084179324810575787) -->
+ <skip />
+ <!-- no translation found for keyguard_carrier_default (8700650403054042153) -->
+ <skip />
+</resources>
diff --git a/packages/Keyguard/res/values-tr/strings.xml b/packages/Keyguard/res/values-tr/strings.xml
new file mode 100644
index 0000000..5ccca51
--- /dev/null
+++ b/packages/Keyguard/res/values-tr/strings.xml
@@ -0,0 +1,164 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/* //device/apps/common/assets/res/any/strings.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:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"PIN kodunu yazın"</string>
+ <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"PUK ve yeni PIN kodunu yazın"</string>
+ <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK kodu"</string>
+ <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Yeni PIN kodu"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Şifre yazmak için dokunun"</font></string>
+ <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Kilidi açmak için şifreyi yazın"</string>
+ <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Kilidi açmak için PIN kodunu yazın"</string>
+ <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Yanlış PIN kodu."</string>
+ <string name="keyguard_label_text" msgid="861796461028298424">"Kilidi açmak için önce Menü\'ye, sonra 0\'a basın."</string>
+ <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Yüz Tanıma Kilidi için maksimum deneme sayısı aşıldı"</string>
+ <!-- no translation found for keyguard_charged (3272223906073492454) -->
+ <skip />
+ <!-- no translation found for keyguard_plugged_in (8117572000639998388) -->
+ <skip />
+ <!-- no translation found for keyguard_low_battery (8143808018719173859) -->
+ <skip />
+ <!-- no translation found for keyguard_instructions_when_pattern_disabled (1332288268600329841) -->
+ <skip />
+ <!-- no translation found for keyguard_network_locked_message (9169717779058037168) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message_short (494980561304211931) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (1445849005909260039) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (3481110395508637643) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions (5210891509995942250) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions_long (5968985489463870358) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_message_short (8340813989586622356) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_instructions (5892940909699723544) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_locked_message (6875773413306380902) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_puk_locked_message (3747232467471801633) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_unlock_progress_dialog_message (7975221805033614426) -->
+ <skip />
+ <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d / %3$d."</string>
+ <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Widget ekleyin."</string>
+ <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Boş"</string>
+ <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Kilit açma alanı genişletildi."</string>
+ <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Kilit açma alanı daraltıldı."</string>
+ <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> widget\'ı."</string>
+ <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"Kullanıcı seçici"</string>
+ <string name="keyguard_accessibility_status" msgid="8008264603935930611">"Durum"</string>
+ <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"Kamera"</string>
+ <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Medya denetimleri"</string>
+ <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Widget\'ları yeniden sıralama işlemi başladı."</string>
+ <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Widget\'ları yeniden sıralama işlemi bitti."</string>
+ <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> widget\'ı silindi."</string>
+ <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Kilit açma alanını genişletin."</string>
+ <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Kaydırarak kilit açma."</string>
+ <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Desenle kilit açma."</string>
+ <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Yüzle kilit açma."</string>
+ <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Pin koduyla kilit açma."</string>
+ <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Şifreyle kilit açma."</string>
+ <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Desen alanı."</string>
+ <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Kaydırma alanı."</string>
+ <!-- no translation found for keyguard_accessibility_transport_prev_description (1337286538318543555) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_next_description (7073928300444909320) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_pause_description (8455979545295224302) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_play_description (8146417789511154044) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_stop_description (7656358482980912216) -->
+ <skip />
+ <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+ <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+ <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+ <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"İptal"</string>
+ <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Sil"</string>
+ <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Bitti"</string>
+ <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Mod değiştirme"</string>
+ <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"ÜstKrkt"</string>
+ <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Giriş"</string>
+ <string name="description_target_unlock" msgid="2228524900439801453">"Kilidi aç"</string>
+ <string name="description_target_camera" msgid="969071997552486814">"Kamera"</string>
+ <string name="description_target_silent" msgid="893551287746522182">"Sessiz"</string>
+ <string name="description_target_soundon" msgid="30052466675500172">"Ses açık"</string>
+ <string name="description_target_search" msgid="3091587249776033139">"Ara"</string>
+ <string name="description_direction_up" msgid="7169032478259485180">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> için yukarı kaydırın."</string>
+ <string name="description_direction_down" msgid="5087739728639014595">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> için aşağı kaydırın."</string>
+ <string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> için sola kaydırın."</string>
+ <string name="description_direction_right" msgid="8034433242579600980">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> için sağa kaydırın."</string>
+ <string name="user_switched" msgid="3768006783166984410">"Geçerli kullanıcı: <xliff:g id="NAME">%1$s</xliff:g>."</string>
+ <string name="kg_emergency_call_label" msgid="684946192523830531">"Acil durum çağrısı"</string>
+ <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Deseni Unuttunuz mu?"</string>
+ <string name="kg_wrong_pattern" msgid="1850806070801358830">"Yanlış Desen"</string>
+ <string name="kg_wrong_password" msgid="2333281762128113157">"Yanlış Şifre"</string>
+ <string name="kg_wrong_pin" msgid="1131306510833563801">"Yanlış PIN"</string>
+ <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"<xliff:g id="NUMBER">%d</xliff:g> saniye içinde yeniden deneyin."</string>
+ <string name="kg_pattern_instructions" msgid="398978611683075868">"Deseninizi çizin"</string>
+ <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"SIM PIN kodunu girin"</string>
+ <string name="kg_pin_instructions" msgid="2377242233495111557">"PIN\'i girin"</string>
+ <string name="kg_password_instructions" msgid="5753646556186936819">"Şifreyi Girin"</string>
+ <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"SIM kart artık devre dışı bırakıldı. Devam etmek için PUK kodunu girin. Ayrıntılı bilgi için operatörle bağlantı kurun."</string>
+ <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"İstenen PIN kodunu girin"</string>
+ <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"İstenen PIN kodunu onaylayın"</string>
+ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"SIM kart kilidi açılıyor…"</string>
+ <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Yanlış PIN kodu."</string>
+ <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"4-8 rakamdan oluşan bir PIN girin."</string>
+ <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK kodu 8 veya daha çok basamaklı bir sayı olmalıdır."</string>
+ <string name="kg_invalid_puk" msgid="3638289409676051243">"Doğru PUK kodunu tekrar girin. Çok sayıda deneme yapılırsa SIM kart kalıcı olarak devre dışı bırakılır."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN kodları eşleşmiyor"</string>
+ <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Çok fazla sayıda desen denemesi yapıldı"</string>
+ <string name="kg_login_instructions" msgid="1100551261265506448">"Kilidi açmak için Google hesabınızla oturum açın."</string>
+ <string name="kg_login_username_hint" msgid="5718534272070920364">"Kullanıcı adı (e-posta)"</string>
+ <string name="kg_login_password_hint" msgid="9057289103827298549">"Şifre"</string>
+ <string name="kg_login_submit_button" msgid="5355904582674054702">"Oturum aç"</string>
+ <string name="kg_login_invalid_input" msgid="5754664119319872197">"Geçersiz kullanıcı adı veya şifre."</string>
+ <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Kullanıcı adınızı veya şifrenizi mi unuttunuz?"\n<b>"google.com/accounts/recovery"</b>" adresini ziyaret edin."</string>
+ <string name="kg_login_checking_password" msgid="1052685197710252395">"Hesap denetleniyor…"</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"PIN kodunuzu <xliff:g id="NUMBER_0">%d</xliff:g> kez yanlış girdiniz. "\n\n"<xliff:g id="NUMBER_1">%d</xliff:g> saniye içinde tekrar deneyin."</string>
+ <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Şifrenizi <xliff:g id="NUMBER_0">%d</xliff:g> kez yanlış yazdınız. "\n\n"<xliff:g id="NUMBER_1">%d</xliff:g> saniye içinde tekrar deneyin."</string>
+ <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Kilit açma deseninizi <xliff:g id="NUMBER_0">%d</xliff:g> kez yanlış çizdiniz. "\n\n"<xliff:g id="NUMBER_1">%d</xliff:g> saniye içinde tekrar deneyin."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Tablet kilidini <xliff:g id="NUMBER_0">%d</xliff:g> defa yanlış bir şekilde açmaya çalıştınız. <xliff:g id="NUMBER_1">%d</xliff:g> defa daha başarısız deneme yapılırsa, tablet fabrika varsayılan değerine sıfırlanır ve tüm kullanıcı verileri kaybedilir."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Telefonun kilidini <xliff:g id="NUMBER_0">%d</xliff:g> defa yanlış bir şekilde açmaya çalıştınız. <xliff:g id="NUMBER_1">%d</xliff:g> defa daha başarısız deneme yapılırsa, telefon fabrika varsayılan değerine sıfırlanır ve tüm kullanıcı verileri kaybedilir."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Tablet kilidini <xliff:g id="NUMBER">%d</xliff:g> defa yanlış bir şekilde açmaya çalıştınız. Tablet şimdi fabrika varsayılanına sıfırlanacak."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Telefon kilidini <xliff:g id="NUMBER">%d</xliff:g> defa yanlış bir şekilde açmaya çalıştınız. Telefon şimdi fabrika varsayılanına sıfırlanacak."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Kilit açma deseninizi <xliff:g id="NUMBER_0">%d</xliff:g> kez yanlış çizdiniz. <xliff:g id="NUMBER_1">%d</xliff:g> başarısız denemeden sonra, tabletinizi bir e-posta hesabı kullanarak açmanız istenir."\n\n" <xliff:g id="NUMBER_2">%d</xliff:g> saniye içinde tekrar deneyin."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Kilit açma deseninizi <xliff:g id="NUMBER_0">%d</xliff:g> kez yanlış çizdiniz. <xliff:g id="NUMBER_1">%d</xliff:g> başarısız denemeden sonra telefonunuzu bir e-posta hesabı kullanarak açmanız istenir."\n\n" <xliff:g id="NUMBER_2">%d</xliff:g> saniye içinde tekrar deneyin."</string>
+ <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
+ <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Kaldır"</string>
+ <!-- no translation found for keyguard_transport_prev_description (8229108430245669854) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_next_description (4299258300283778305) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_pause_description (5093073338238310224) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_play_description (2924628863741150956) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_stop_description (3084179324810575787) -->
+ <skip />
+ <!-- no translation found for keyguard_carrier_default (8700650403054042153) -->
+ <skip />
+</resources>
diff --git a/packages/Keyguard/res/values-uk/strings.xml b/packages/Keyguard/res/values-uk/strings.xml
new file mode 100644
index 0000000..af5c14a
--- /dev/null
+++ b/packages/Keyguard/res/values-uk/strings.xml
@@ -0,0 +1,164 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/* //device/apps/common/assets/res/any/strings.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:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Введіть PIN-код"</string>
+ <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Введіть PUK-код і новий PIN-код"</string>
+ <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK-код"</string>
+ <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Новий PIN-код"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Торкніться, щоб ввести пароль"</font></string>
+ <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Введіть пароль, щоб розблокувати"</string>
+ <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Введіть PIN-код, щоб розблокувати"</string>
+ <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Неправильний PIN-код."</string>
+ <string name="keyguard_label_text" msgid="861796461028298424">"Щоб розбл., натисн. меню та 0."</string>
+ <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Перевищено максимальну кількість спроб розблокування за допомогою функції \"Фейсконтроль\""</string>
+ <!-- no translation found for keyguard_charged (3272223906073492454) -->
+ <skip />
+ <!-- no translation found for keyguard_plugged_in (8117572000639998388) -->
+ <skip />
+ <!-- no translation found for keyguard_low_battery (8143808018719173859) -->
+ <skip />
+ <!-- no translation found for keyguard_instructions_when_pattern_disabled (1332288268600329841) -->
+ <skip />
+ <!-- no translation found for keyguard_network_locked_message (9169717779058037168) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message_short (494980561304211931) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (1445849005909260039) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (3481110395508637643) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions (5210891509995942250) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions_long (5968985489463870358) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_message_short (8340813989586622356) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_instructions (5892940909699723544) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_locked_message (6875773413306380902) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_puk_locked_message (3747232467471801633) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_unlock_progress_dialog_message (7975221805033614426) -->
+ <skip />
+ <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Віджет %2$d з %3$d."</string>
+ <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Додати віджет."</string>
+ <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Порожня область"</string>
+ <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Область розблокування розгорнуто."</string>
+ <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Область розблокування згорнуто."</string>
+ <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"Віджет <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>."</string>
+ <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"Вибір користувача"</string>
+ <string name="keyguard_accessibility_status" msgid="8008264603935930611">"Статус"</string>
+ <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"Камера"</string>
+ <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Елементи керування носієм"</string>
+ <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Змінення порядку віджетів розпочато."</string>
+ <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Змінення порядку віджетів закінчено."</string>
+ <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Віджет <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> видалено."</string>
+ <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Розгорнути область розблокування."</string>
+ <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Розблокування повзунком."</string>
+ <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Розблокування ключем."</string>
+ <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Фейсконтроль"</string>
+ <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Розблокування PIN-кодом."</string>
+ <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Розблокування паролем."</string>
+ <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Область ключа."</string>
+ <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Область повзунка."</string>
+ <!-- no translation found for keyguard_accessibility_transport_prev_description (1337286538318543555) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_next_description (7073928300444909320) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_pause_description (8455979545295224302) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_play_description (8146417789511154044) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_stop_description (7656358482980912216) -->
+ <skip />
+ <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+ <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+ <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+ <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Скасувати"</string>
+ <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Delete"</string>
+ <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Готово"</string>
+ <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Зміна режиму"</string>
+ <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
+ <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
+ <string name="description_target_unlock" msgid="2228524900439801453">"Розблокувати"</string>
+ <string name="description_target_camera" msgid="969071997552486814">"Камера"</string>
+ <string name="description_target_silent" msgid="893551287746522182">"Без звуку"</string>
+ <string name="description_target_soundon" msgid="30052466675500172">"Увімкнути звук"</string>
+ <string name="description_target_search" msgid="3091587249776033139">"Пошук"</string>
+ <string name="description_direction_up" msgid="7169032478259485180">"Проведіть пальцем угору, щоб <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_down" msgid="5087739728639014595">"Проведіть пальцем униз, щоб <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_left" msgid="7207478719805562165">"Проведіть пальцем ліворуч, щоб <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_right" msgid="8034433242579600980">"Проведіть пальцем праворуч, щоб <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="user_switched" msgid="3768006783166984410">"Поточний користувач: <xliff:g id="NAME">%1$s</xliff:g>."</string>
+ <string name="kg_emergency_call_label" msgid="684946192523830531">"Екстрений виклик"</string>
+ <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Не пам’ятаю ключ"</string>
+ <string name="kg_wrong_pattern" msgid="1850806070801358830">"Неправильний ключ"</string>
+ <string name="kg_wrong_password" msgid="2333281762128113157">"Неправильний пароль"</string>
+ <string name="kg_wrong_pin" msgid="1131306510833563801">"Неправильний PIN-код"</string>
+ <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Повторіть спробу через <xliff:g id="NUMBER">%d</xliff:g> с."</string>
+ <string name="kg_pattern_instructions" msgid="398978611683075868">"Намалюйте ключ"</string>
+ <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Введіть PIN-код SIM-карти"</string>
+ <string name="kg_pin_instructions" msgid="2377242233495111557">"Введіть PIN-код"</string>
+ <string name="kg_password_instructions" msgid="5753646556186936819">"Введіть пароль"</string>
+ <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"Зараз SIM-карту вимкнено. Введіть PUK-код, щоб продовжити. Зв’яжіться з оператором, щоб дізнатися більше."</string>
+ <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Введіть потрібний PIN-код"</string>
+ <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Підтвердьте потрібний PIN-код"</string>
+ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Розблокування SIM-карти…"</string>
+ <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Неправильний PIN-код."</string>
+ <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Введіть PIN-код із 4–8 цифр."</string>
+ <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK-код має складатися зі щонайменше 8 цифр."</string>
+ <string name="kg_invalid_puk" msgid="3638289409676051243">"Повторно введіть правильний PUK-код. Численні спроби назавжди вимкнуть SIM-карту."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN-коди не збігаються"</string>
+ <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Забагато спроб намалювати ключ"</string>
+ <string name="kg_login_instructions" msgid="1100551261265506448">"Щоб розблокувати, увійдіть, використовуючи дані облікового запису Google."</string>
+ <string name="kg_login_username_hint" msgid="5718534272070920364">"Ім’я користувача (електронна адреса)"</string>
+ <string name="kg_login_password_hint" msgid="9057289103827298549">"Пароль"</string>
+ <string name="kg_login_submit_button" msgid="5355904582674054702">"Увійти"</string>
+ <string name="kg_login_invalid_input" msgid="5754664119319872197">"Недійсне ім’я користувача чи пароль."</string>
+ <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Не пам’ятаєте ім’я користувача чи пароль?"\n"Відвідайте сторінку "<b>"google.com/accounts/recovery"</b>"."</string>
+ <string name="kg_login_checking_password" msgid="1052685197710252395">"Перевірка облікового запису…"</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"PIN-код неправильно введено стільки разів: <xliff:g id="NUMBER_0">%d</xliff:g>. "\n\n"Повторіть спробу через <xliff:g id="NUMBER_1">%d</xliff:g> с."</string>
+ <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Пароль неправильно введено стільки разів: <xliff:g id="NUMBER_0">%d</xliff:g>. "\n\n"Повторіть спробу через <xliff:g id="NUMBER_1">%d</xliff:g> с."</string>
+ <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Ключ розблокування неправильно намальовано стільки разів: <xliff:g id="NUMBER_0">%d</xliff:g>. "\n\n"Повторіть спробу через <xliff:g id="NUMBER_1">%d</xliff:g> с."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Кількість невдалих спроб розблокувати планшетний ПК: <xliff:g id="NUMBER_0">%d</xliff:g>. У вас є ще стільки спроб: <xliff:g id="NUMBER_1">%d</xliff:g>. У разі невдачі налаштування планшетного ПК буде змінено на заводські за умовчанням, а всі дані користувача – втрачено."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Кількість невдалих спроб розблокувати телефон: <xliff:g id="NUMBER_0">%d</xliff:g>. У вас є ще стільки спроб: <xliff:g id="NUMBER_1">%d</xliff:g>. У разі невдачі налаштування телефону буде змінено на заводські за умовчанням, а всі дані користувача – втрачено."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Кількість невдалих спроб розблокувати планшетний ПК: <xliff:g id="NUMBER">%d</xliff:g>. Налаштування планшетного ПК буде змінено на заводські за умовчанням."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Кількість невдалих спроб розблокувати телефон: <xliff:g id="NUMBER">%d</xliff:g>. Налаштування телефону буде змінено на заводські за умовчанням."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Ключ розблокування неправильно намальовано стільки разів: <xliff:g id="NUMBER_0">%d</xliff:g>. У вас є ще стільки спроб: <xliff:g id="NUMBER_1">%d</xliff:g>. У разі невдачі з’явиться запит розблокувати планшетний ПК за допомогою облікового запису електронної пошти."\n\n" Повторіть спробу через <xliff:g id="NUMBER_2">%d</xliff:g> сек."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Ключ розблокування неправильно намальовано стільки разів: <xliff:g id="NUMBER_0">%d</xliff:g>. У вас є ще стільки спроб: <xliff:g id="NUMBER_1">%d</xliff:g>. У разі невдачі з’явиться запит розблокувати телефон за допомогою облікового запису електронної пошти."\n\n" Повторіть спробу через <xliff:g id="NUMBER_2">%d</xliff:g> сек."</string>
+ <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" – "</string>
+ <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Вилучити"</string>
+ <!-- no translation found for keyguard_transport_prev_description (8229108430245669854) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_next_description (4299258300283778305) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_pause_description (5093073338238310224) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_play_description (2924628863741150956) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_stop_description (3084179324810575787) -->
+ <skip />
+ <!-- no translation found for keyguard_carrier_default (8700650403054042153) -->
+ <skip />
+</resources>
diff --git a/packages/Keyguard/res/values-vi/strings.xml b/packages/Keyguard/res/values-vi/strings.xml
new file mode 100644
index 0000000..e512b92
--- /dev/null
+++ b/packages/Keyguard/res/values-vi/strings.xml
@@ -0,0 +1,164 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/* //device/apps/common/assets/res/any/strings.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:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Nhập mã PIN"</string>
+ <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Nhập PUK và mã PIN mới"</string>
+ <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"Mã PUK"</string>
+ <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Mã PIN mới"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Chạm để nhập mật khẩu"</font></string>
+ <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Nhập mật khẩu để mở khóa"</string>
+ <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Nhập mã PIN để mở khóa"</string>
+ <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Mã PIN không chính xác."</string>
+ <string name="keyguard_label_text" msgid="861796461028298424">"Để mở khóa, hãy nhấn vào Trình đơn sau đó nhấn 0."</string>
+ <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Đã vượt quá số lần Mở khóa bằng khuôn mặt tối đa"</string>
+ <!-- no translation found for keyguard_charged (3272223906073492454) -->
+ <skip />
+ <!-- no translation found for keyguard_plugged_in (8117572000639998388) -->
+ <skip />
+ <!-- no translation found for keyguard_low_battery (8143808018719173859) -->
+ <skip />
+ <!-- no translation found for keyguard_instructions_when_pattern_disabled (1332288268600329841) -->
+ <skip />
+ <!-- no translation found for keyguard_network_locked_message (9169717779058037168) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message_short (494980561304211931) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (1445849005909260039) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (3481110395508637643) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions (5210891509995942250) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions_long (5968985489463870358) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_message_short (8340813989586622356) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_instructions (5892940909699723544) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_locked_message (6875773413306380902) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_puk_locked_message (3747232467471801633) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_unlock_progress_dialog_message (7975221805033614426) -->
+ <skip />
+ <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Tiện ích %2$d trong số %3$d."</string>
+ <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Thêm tiện ích."</string>
+ <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Trống"</string>
+ <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Đã mở rộng vùng khóa."</string>
+ <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Đã thu gọn vùng khóa."</string>
+ <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> tiện ích."</string>
+ <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"Bộ chọn người dùng"</string>
+ <string name="keyguard_accessibility_status" msgid="8008264603935930611">"Trạng thái"</string>
+ <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"Máy ảnh"</string>
+ <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Điều khiển phương tiện"</string>
+ <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Đã bắt đầu xắp xếp lại tiện ích."</string>
+ <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Đã kết thúc sắp xếp lại tiện ích."</string>
+ <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Đã xóa tiện ích <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>."</string>
+ <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Mở rộng vùng khóa."</string>
+ <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Mở khóa bằng cách trượt."</string>
+ <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Mở khóa bằng hình."</string>
+ <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Mở khóa bằng khuôn mặt."</string>
+ <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Mở khóa bằng mã pin."</string>
+ <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Mở khóa bằng mật khẩu."</string>
+ <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Khu vực hình."</string>
+ <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Khu vực trượt."</string>
+ <!-- no translation found for keyguard_accessibility_transport_prev_description (1337286538318543555) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_next_description (7073928300444909320) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_pause_description (8455979545295224302) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_play_description (8146417789511154044) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_stop_description (7656358482980912216) -->
+ <skip />
+ <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+ <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+ <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+ <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Hủy"</string>
+ <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Xóa"</string>
+ <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Xong"</string>
+ <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Thay đổi chế độ"</string>
+ <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
+ <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
+ <string name="description_target_unlock" msgid="2228524900439801453">"Mở khóa"</string>
+ <string name="description_target_camera" msgid="969071997552486814">"Máy ảnh"</string>
+ <string name="description_target_silent" msgid="893551287746522182">"Im lặng"</string>
+ <string name="description_target_soundon" msgid="30052466675500172">"Bật âm thanh"</string>
+ <string name="description_target_search" msgid="3091587249776033139">"Tìm kiếm"</string>
+ <string name="description_direction_up" msgid="7169032478259485180">"Trượt lên để <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_down" msgid="5087739728639014595">"Trượt xuống để <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_left" msgid="7207478719805562165">"Trượt sang trái để <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_right" msgid="8034433242579600980">"Trượt sang phải để <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="user_switched" msgid="3768006783166984410">"Người dùng hiện tại <xliff:g id="NAME">%1$s</xliff:g>."</string>
+ <string name="kg_emergency_call_label" msgid="684946192523830531">"Cuộc gọi khẩn cấp"</string>
+ <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Đã quên hình"</string>
+ <string name="kg_wrong_pattern" msgid="1850806070801358830">"Hình sai"</string>
+ <string name="kg_wrong_password" msgid="2333281762128113157">"Mật khẩu sai"</string>
+ <string name="kg_wrong_pin" msgid="1131306510833563801">"PIN sai"</string>
+ <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Hãy thử lại sau <xliff:g id="NUMBER">%d</xliff:g> giây."</string>
+ <string name="kg_pattern_instructions" msgid="398978611683075868">"Vẽ hình của bạn"</string>
+ <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Nhập PIN của SIM"</string>
+ <string name="kg_pin_instructions" msgid="2377242233495111557">"Nhập PIN"</string>
+ <string name="kg_password_instructions" msgid="5753646556186936819">"Nhập mật khẩu"</string>
+ <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"SIM hiện bị vô hiệu hóa. Nhập mã PUK để tiếp tục. Liên hệ với nhà cung cấp dịch vụ để biết chi tiết."</string>
+ <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Nhập mã PIN mong muốn"</string>
+ <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Xác nhận mã PIN mong muốn"</string>
+ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Đang mở khóa thẻ SIM…"</string>
+ <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Mã PIN không chính xác."</string>
+ <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Nhập mã PIN có từ 4 đến 8 số."</string>
+ <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"Mã PUK phải có từ 8 số trở lên."</string>
+ <string name="kg_invalid_puk" msgid="3638289409676051243">"Hãy nhập lại mã PUK chính xác. Nhiều lần lặp lại sẽ vô hiệu hóa vĩnh viễn thẻ SIM."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"Mã PIN không khớp"</string>
+ <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Quá nhiều lần nhập hình"</string>
+ <string name="kg_login_instructions" msgid="1100551261265506448">"Để mở khóa, hãy đăng nhập bằng tài khoản Google của bạn."</string>
+ <string name="kg_login_username_hint" msgid="5718534272070920364">"Tên người dùng (email)"</string>
+ <string name="kg_login_password_hint" msgid="9057289103827298549">"Mật khẩu"</string>
+ <string name="kg_login_submit_button" msgid="5355904582674054702">"Đăng nhập"</string>
+ <string name="kg_login_invalid_input" msgid="5754664119319872197">"Tên người dùng hoặc mật khẩu không hợp lệ."</string>
+ <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Bạn quên tên người dùng hoặc mật khẩu?"\n"Hãy truy cập "<b>"google.com/accounts/recovery"</b>"."</string>
+ <string name="kg_login_checking_password" msgid="1052685197710252395">"Đang kiểm tra tài khoản…"</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Bạn đã <xliff:g id="NUMBER_0">%d</xliff:g> lần nhập sai mã PIN của mình. Hãy "\n\n"thử lại sau <xliff:g id="NUMBER_1">%d</xliff:g> giây."</string>
+ <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Bạn đã <xliff:g id="NUMBER_0">%d</xliff:g> lần nhập sai mật khẩu của mình. Hãy "\n\n"thử lại sau <xliff:g id="NUMBER_1">%d</xliff:g> giây."</string>
+ <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Bạn đã <xliff:g id="NUMBER_0">%d</xliff:g> lần vẽ không chính xác hình mở khóa của mình. Hãy "\n\n"thử lại sau <xliff:g id="NUMBER_1">%d</xliff:g> giây."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Bạn đã <xliff:g id="NUMBER_0">%d</xliff:g> lần mở khóa máy tính bảng không đúng cách. Sau <xliff:g id="NUMBER_1">%d</xliff:g> lần mở khóa không thành công nữa, máy tính bảng sẽ được đặt lại về mặc định ban đầu và tất cả dữ liệu người dùng sẽ bị mất."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Bạn đã <xliff:g id="NUMBER_0">%d</xliff:g> lần mở khóa điện thoại không đúng cách. Sau <xliff:g id="NUMBER_1">%d</xliff:g> lần mở khóa không thành công nữa, điện thoại sẽ được đặt lại về mặc định ban đầu và tất cả dữ liệu người dùng sẽ bị mất."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Bạn đã <xliff:g id="NUMBER">%d</xliff:g> lần mở khóa máy tính bảng không đúng cách. Bây giờ, máy tính bảng sẽ được đặt lại về mặc định ban đầu."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Bạn đã <xliff:g id="NUMBER">%d</xliff:g> lần mở khóa điện thoại không đúng cách. Bây giờ, điện thoại sẽ được đặt lại về mặc định ban đầu."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Bạn đã <xliff:g id="NUMBER_0">%d</xliff:g> lần vẽ không chính xác hình mở khóa của mình. Sau <xliff:g id="NUMBER_1">%d</xliff:g> lần thử không thành công nữa, bạn sẽ được yêu cầu mở khóa máy tính bảng bằng tài khoản email."\n\n" Vui lòng thử lại sau <xliff:g id="NUMBER_2">%d</xliff:g> giây."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Bạn đã <xliff:g id="NUMBER_0">%d</xliff:g> lần vẽ không chính xác hình mở khóa của mình. Sau <xliff:g id="NUMBER_1">%d</xliff:g> lần thử không thành công nữa, bạn sẽ được yêu cầu mở khóa điện thoại bằng tài khoản email."\n\n" Vui lòng thử lại sau <xliff:g id="NUMBER_2">%d</xliff:g> giây."</string>
+ <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
+ <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Xóa"</string>
+ <!-- no translation found for keyguard_transport_prev_description (8229108430245669854) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_next_description (4299258300283778305) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_pause_description (5093073338238310224) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_play_description (2924628863741150956) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_stop_description (3084179324810575787) -->
+ <skip />
+ <!-- no translation found for keyguard_carrier_default (8700650403054042153) -->
+ <skip />
+</resources>
diff --git a/packages/Keyguard/res/values-xlarge/dimens.xml b/packages/Keyguard/res/values-xlarge/dimens.xml
new file mode 100644
index 0000000..b8cf287
--- /dev/null
+++ b/packages/Keyguard/res/values-xlarge/dimens.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/assets/res/any/dimens.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>
+ <!-- Default height of a key in the password keyboard for alpha -->
+ <dimen name="password_keyboard_key_height_alpha">75dip</dimen>
+ <!-- Default height of a key in the password keyboard for numeric -->
+ <dimen name="password_keyboard_key_height_numeric">75dip</dimen>
+ <!-- keyboardHeight = key_height*4 + key_bottom_gap*3 -->
+ <dimen name="password_keyboard_height">48.0mm</dimen>
+</resources>
diff --git a/packages/Keyguard/res/values-zh-rCN/strings.xml b/packages/Keyguard/res/values-zh-rCN/strings.xml
new file mode 100644
index 0000000..814da04
--- /dev/null
+++ b/packages/Keyguard/res/values-zh-rCN/strings.xml
@@ -0,0 +1,164 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/* //device/apps/common/assets/res/any/strings.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:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"输入 PIN 码"</string>
+ <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"请输入 PUK 码和新的 PIN 码"</string>
+ <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK 码"</string>
+ <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"新的 PIN 码"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"触摸可输入密码"</font></string>
+ <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"输入密码以解锁"</string>
+ <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"输入 PIN 进行解锁"</string>
+ <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"PIN 码有误。"</string>
+ <string name="keyguard_label_text" msgid="861796461028298424">"要解锁,请先按 MENU 再按 0。"</string>
+ <string name="faceunlock_multiple_failures" msgid="754137583022792429">"已超过“人脸解锁”尝试次数上限"</string>
+ <!-- no translation found for keyguard_charged (3272223906073492454) -->
+ <skip />
+ <!-- no translation found for keyguard_plugged_in (8117572000639998388) -->
+ <skip />
+ <!-- no translation found for keyguard_low_battery (8143808018719173859) -->
+ <skip />
+ <!-- no translation found for keyguard_instructions_when_pattern_disabled (1332288268600329841) -->
+ <skip />
+ <!-- no translation found for keyguard_network_locked_message (9169717779058037168) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message_short (494980561304211931) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (1445849005909260039) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (3481110395508637643) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions (5210891509995942250) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions_long (5968985489463870358) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_message_short (8340813989586622356) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_instructions (5892940909699723544) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_locked_message (6875773413306380902) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_puk_locked_message (3747232467471801633) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_unlock_progress_dialog_message (7975221805033614426) -->
+ <skip />
+ <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s。%3$d的小部件%2$d。"</string>
+ <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"添加小部件。"</string>
+ <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"空白"</string>
+ <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"已展开解锁区域。"</string>
+ <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"已折叠解锁区域。"</string>
+ <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g>小部件。"</string>
+ <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"用户选择器"</string>
+ <string name="keyguard_accessibility_status" msgid="8008264603935930611">"状态"</string>
+ <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"相机"</string>
+ <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"媒体控制"</string>
+ <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"已开始将小部件重新排序。"</string>
+ <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"已完成小部件重新排序。"</string>
+ <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"已删除小部件<xliff:g id="WIDGET_INDEX">%1$s</xliff:g>。"</string>
+ <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"展开解锁区域。"</string>
+ <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"滑动解锁。"</string>
+ <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"图案解锁。"</string>
+ <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"人脸解锁。"</string>
+ <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"PIN 解锁。"</string>
+ <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"密码解锁。"</string>
+ <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"图案区域。"</string>
+ <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"滑动区域。"</string>
+ <!-- no translation found for keyguard_accessibility_transport_prev_description (1337286538318543555) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_next_description (7073928300444909320) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_pause_description (8455979545295224302) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_play_description (8146417789511154044) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_stop_description (7656358482980912216) -->
+ <skip />
+ <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+ <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+ <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+ <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"取消"</string>
+ <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Delete"</string>
+ <string name="keyboardview_keycode_done" msgid="1992571118466679775">"完成"</string>
+ <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"模式更改"</string>
+ <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
+ <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
+ <string name="description_target_unlock" msgid="2228524900439801453">"解锁"</string>
+ <string name="description_target_camera" msgid="969071997552486814">"相机"</string>
+ <string name="description_target_silent" msgid="893551287746522182">"静音"</string>
+ <string name="description_target_soundon" msgid="30052466675500172">"打开声音"</string>
+ <string name="description_target_search" msgid="3091587249776033139">"搜索"</string>
+ <string name="description_direction_up" msgid="7169032478259485180">"向上滑动以<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>。"</string>
+ <string name="description_direction_down" msgid="5087739728639014595">"向下滑动以<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>。"</string>
+ <string name="description_direction_left" msgid="7207478719805562165">"向左滑动以<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>。"</string>
+ <string name="description_direction_right" msgid="8034433242579600980">"向右滑动以<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>。"</string>
+ <string name="user_switched" msgid="3768006783166984410">"当前用户是<xliff:g id="NAME">%1$s</xliff:g>。"</string>
+ <string name="kg_emergency_call_label" msgid="684946192523830531">"紧急呼救"</string>
+ <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"忘记了图案"</string>
+ <string name="kg_wrong_pattern" msgid="1850806070801358830">"图案错误"</string>
+ <string name="kg_wrong_password" msgid="2333281762128113157">"密码错误"</string>
+ <string name="kg_wrong_pin" msgid="1131306510833563801">"PIN 有误"</string>
+ <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"请在 <xliff:g id="NUMBER">%d</xliff:g> 秒后重试。"</string>
+ <string name="kg_pattern_instructions" msgid="398978611683075868">"绘制您的图案"</string>
+ <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"输入 SIM PIN"</string>
+ <string name="kg_pin_instructions" msgid="2377242233495111557">"输入 PIN"</string>
+ <string name="kg_password_instructions" msgid="5753646556186936819">"输入密码"</string>
+ <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"SIM 卡已被停用,需要输入 PUK 码才能继续使用。有关详情,请联系您的运营商。"</string>
+ <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"请输入所需 PIN 码"</string>
+ <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"请确认所需 PIN 码"</string>
+ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"正在解锁 SIM 卡..."</string>
+ <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"PIN 码有误。"</string>
+ <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"请输入 4 至 8 位数的 PIN。"</string>
+ <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK 码应至少包含 8 位数字。"</string>
+ <string name="kg_invalid_puk" msgid="3638289409676051243">"请重新输入正确的 PUK 码。如果尝试错误次数过多,SIM 卡将永久停用。"</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN 码不匹配"</string>
+ <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"图案尝试次数过多"</string>
+ <string name="kg_login_instructions" msgid="1100551261265506448">"要解锁,请登录您的 Google 帐户。"</string>
+ <string name="kg_login_username_hint" msgid="5718534272070920364">"用户名(电子邮件地址)"</string>
+ <string name="kg_login_password_hint" msgid="9057289103827298549">"密码"</string>
+ <string name="kg_login_submit_button" msgid="5355904582674054702">"登录"</string>
+ <string name="kg_login_invalid_input" msgid="5754664119319872197">"用户名或密码无效。"</string>
+ <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"忘记了用户名或密码?"\n"请访问 "<b>"google.com/accounts/recovery"</b>"。"</string>
+ <string name="kg_login_checking_password" msgid="1052685197710252395">"正在检查帐户…"</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"您已经 <xliff:g id="NUMBER_0">%d</xliff:g> 次错误地输入了 PIN。"\n\n"请在 <xliff:g id="NUMBER_1">%d</xliff:g> 秒后重试。"</string>
+ <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"您已经 <xliff:g id="NUMBER_0">%d</xliff:g> 次错误地输入了密码。"\n\n"请在 <xliff:g id="NUMBER_1">%d</xliff:g> 秒后重试。"</string>
+ <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"您已经 <xliff:g id="NUMBER_0">%d</xliff:g> 次错误地绘制了解锁图案。"\n\n"请在 <xliff:g id="NUMBER_1">%d</xliff:g> 秒后重试。"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"您已经 <xliff:g id="NUMBER_0">%d</xliff:g> 次错误地尝试解锁平板电脑。如果再尝试 <xliff:g id="NUMBER_1">%d</xliff:g> 次后仍不成功,平板电脑就会重置为出厂默认设置,而且所有用户数据都会丢失。"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"您已经 <xliff:g id="NUMBER_0">%d</xliff:g> 次错误地尝试解锁手机。如果再尝试 <xliff:g id="NUMBER_1">%d</xliff:g> 次后仍不成功,手机就会重置为出厂默认设置,而且所有用户数据都会丢失。"</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"您已经 <xliff:g id="NUMBER">%d</xliff:g> 次错误地尝试解锁平板电脑。平板电脑现在将重置为出厂默认设置。"</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"您已经 <xliff:g id="NUMBER">%d</xliff:g> 次错误地尝试解锁手机。手机现在将重置为出厂默认设置。"</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"您已经 <xliff:g id="NUMBER_0">%d</xliff:g> 次错误地绘制了解锁图案。如果再尝试 <xliff:g id="NUMBER_1">%d</xliff:g> 次后仍不成功,系统就会要求您使用自己的电子邮件帐户解锁平板电脑。"\n\n"请在 <xliff:g id="NUMBER_2">%d</xliff:g> 秒后重试。"</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"您已经 <xliff:g id="NUMBER_0">%d</xliff:g> 次错误地绘制了解锁图案。如果再尝试 <xliff:g id="NUMBER_1">%d</xliff:g> 次后仍不成功,系统就会要求您使用自己的电子邮件帐户解锁手机。"\n\n"请在 <xliff:g id="NUMBER_2">%d</xliff:g> 秒后重试。"</string>
+ <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
+ <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"删除"</string>
+ <!-- no translation found for keyguard_transport_prev_description (8229108430245669854) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_next_description (4299258300283778305) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_pause_description (5093073338238310224) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_play_description (2924628863741150956) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_stop_description (3084179324810575787) -->
+ <skip />
+ <!-- no translation found for keyguard_carrier_default (8700650403054042153) -->
+ <skip />
+</resources>
diff --git a/packages/Keyguard/res/values-zh-rTW/strings.xml b/packages/Keyguard/res/values-zh-rTW/strings.xml
new file mode 100644
index 0000000..b17aa45
--- /dev/null
+++ b/packages/Keyguard/res/values-zh-rTW/strings.xml
@@ -0,0 +1,164 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/* //device/apps/common/assets/res/any/strings.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:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"輸入 PIN 碼"</string>
+ <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"輸入 PUK 碼和新 PIN 碼"</string>
+ <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK 碼"</string>
+ <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"新 PIN 碼"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"輕觸即可輸入密碼"</font></string>
+ <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"輸入密碼即可解鎖"</string>
+ <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"輸入 PIN 即可解鎖"</string>
+ <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"PIN 碼不正確。"</string>
+ <string name="keyguard_label_text" msgid="861796461028298424">"如要解鎖,請按 Menu 鍵,然後按 0。"</string>
+ <string name="faceunlock_multiple_failures" msgid="754137583022792429">"已超過人臉解鎖嘗試次數上限"</string>
+ <!-- no translation found for keyguard_charged (3272223906073492454) -->
+ <skip />
+ <!-- no translation found for keyguard_plugged_in (8117572000639998388) -->
+ <skip />
+ <!-- no translation found for keyguard_low_battery (8143808018719173859) -->
+ <skip />
+ <!-- no translation found for keyguard_instructions_when_pattern_disabled (1332288268600329841) -->
+ <skip />
+ <!-- no translation found for keyguard_network_locked_message (9169717779058037168) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message_short (494980561304211931) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (1445849005909260039) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (3481110395508637643) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions (5210891509995942250) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions_long (5968985489463870358) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_message_short (8340813989586622356) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_instructions (5892940909699723544) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_locked_message (6875773413306380902) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_puk_locked_message (3747232467471801633) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_unlock_progress_dialog_message (7975221805033614426) -->
+ <skip />
+ <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s。第 %2$d 個小工具,共 %3$d 個。"</string>
+ <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"新增小工具。"</string>
+ <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"空白"</string>
+ <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"解鎖區域已展開。"</string>
+ <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"解鎖區域已收合。"</string>
+ <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g>小工具。"</string>
+ <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"使用者選取工具"</string>
+ <string name="keyguard_accessibility_status" msgid="8008264603935930611">"狀態"</string>
+ <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"相機"</string>
+ <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"媒體控制項"</string>
+ <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"已開始將小工具重新排序。"</string>
+ <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"小工具重新排序已完成。"</string>
+ <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g>小工具已刪除。"</string>
+ <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"展開解鎖區域。"</string>
+ <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"滑動解鎖。"</string>
+ <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"圖形解鎖。"</string>
+ <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"人臉解鎖。"</string>
+ <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"PIN 解鎖。"</string>
+ <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"密碼解鎖。"</string>
+ <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"圖形區域。"</string>
+ <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"滑動區域。"</string>
+ <!-- no translation found for keyguard_accessibility_transport_prev_description (1337286538318543555) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_next_description (7073928300444909320) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_pause_description (8455979545295224302) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_play_description (8146417789511154044) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_stop_description (7656358482980912216) -->
+ <skip />
+ <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+ <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+ <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt 鍵"</string>
+ <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"取消"</string>
+ <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Delete 鍵"</string>
+ <string name="keyboardview_keycode_done" msgid="1992571118466679775">"完成"</string>
+ <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"模式變更"</string>
+ <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift 鍵"</string>
+ <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter 鍵"</string>
+ <string name="description_target_unlock" msgid="2228524900439801453">"解除鎖定"</string>
+ <string name="description_target_camera" msgid="969071997552486814">"相機"</string>
+ <string name="description_target_silent" msgid="893551287746522182">"靜音"</string>
+ <string name="description_target_soundon" msgid="30052466675500172">"開啟音效"</string>
+ <string name="description_target_search" msgid="3091587249776033139">"搜尋"</string>
+ <string name="description_direction_up" msgid="7169032478259485180">"向上滑動即可<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>。"</string>
+ <string name="description_direction_down" msgid="5087739728639014595">"向下滑動即可<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>。"</string>
+ <string name="description_direction_left" msgid="7207478719805562165">"向左滑動即可<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>。"</string>
+ <string name="description_direction_right" msgid="8034433242579600980">"向右滑動即可<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>。"</string>
+ <string name="user_switched" msgid="3768006783166984410">"目前的使用者是 <xliff:g id="NAME">%1$s</xliff:g>。"</string>
+ <string name="kg_emergency_call_label" msgid="684946192523830531">"緊急電話"</string>
+ <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"忘記圖形"</string>
+ <string name="kg_wrong_pattern" msgid="1850806070801358830">"圖形錯誤"</string>
+ <string name="kg_wrong_password" msgid="2333281762128113157">"密碼錯誤"</string>
+ <string name="kg_wrong_pin" msgid="1131306510833563801">"PIN 錯誤"</string>
+ <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"請在 <xliff:g id="NUMBER">%d</xliff:g> 秒後再試一次。"</string>
+ <string name="kg_pattern_instructions" msgid="398978611683075868">"畫出圖形"</string>
+ <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"輸入 SIM PIN"</string>
+ <string name="kg_pin_instructions" msgid="2377242233495111557">"輸入 PIN"</string>
+ <string name="kg_password_instructions" msgid="5753646556186936819">"輸入密碼"</string>
+ <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"SIM 卡已遭停用,必須輸入 PUK 碼才能繼續使用。詳情請洽您的行動通訊業者。"</string>
+ <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"輸入所需的 PIN 碼"</string>
+ <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"確認所需的 PIN 碼"</string>
+ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"正在解除 SIM 卡鎖定..."</string>
+ <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"PIN 碼不正確。"</string>
+ <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"請輸入 4 到 8 碼的 PIN。"</string>
+ <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK 碼至少必須為 8 碼。"</string>
+ <string name="kg_invalid_puk" msgid="3638289409676051243">"重新輸入正確的 PUK 碼。如果錯誤次數過多,SIM 卡將會永久停用。"</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN 碼不符"</string>
+ <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"圖形嘗試次數過多"</string>
+ <string name="kg_login_instructions" msgid="1100551261265506448">"如要解除鎖定,請使用 Google 帳戶登入。"</string>
+ <string name="kg_login_username_hint" msgid="5718534272070920364">"使用者名稱 (電子郵件)"</string>
+ <string name="kg_login_password_hint" msgid="9057289103827298549">"密碼"</string>
+ <string name="kg_login_submit_button" msgid="5355904582674054702">"登入"</string>
+ <string name="kg_login_invalid_input" msgid="5754664119319872197">"使用者名稱或密碼無效。"</string>
+ <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"忘了使用者名稱或密碼?"\n"請前往 "<b>"google.com/accounts/recovery"</b>"。"</string>
+ <string name="kg_login_checking_password" msgid="1052685197710252395">"正在檢查帳戶…"</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"您的 PIN 已輸錯 <xliff:g id="NUMBER_0">%d</xliff:g> 次。"\n\n"請在 <xliff:g id="NUMBER_1">%d</xliff:g> 秒後再試一次。"</string>
+ <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"您的密碼已輸錯 <xliff:g id="NUMBER_0">%d</xliff:g> 次。"\n\n"請在 <xliff:g id="NUMBER_1">%d</xliff:g> 秒後再試一次。"</string>
+ <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"您的解鎖圖形已畫錯 <xliff:g id="NUMBER_0">%d</xliff:g> 次。"\n\n"請在 <xliff:g id="NUMBER_1">%d</xliff:g> 秒後再試一次。"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"您嘗試解除這個平板電腦的鎖定已失敗 <xliff:g id="NUMBER_0">%d</xliff:g> 次,目前還剩 <xliff:g id="NUMBER_1">%d</xliff:g> 次機會。如果失敗次數超過限制,平板電腦將恢復原廠設定,所有使用者資料都會遺失。"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"您嘗試解除這支手機的鎖定已失敗 <xliff:g id="NUMBER_0">%d</xliff:g> 次,目前還剩 <xliff:g id="NUMBER_1">%d</xliff:g> 次機會。如果失敗次數超過限制,手機將恢復原廠設定,所有使用者資料都會遺失。"</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"您嘗試解除這個平板電腦的鎖定已失敗 <xliff:g id="NUMBER">%d</xliff:g> 次,平板電腦現在將恢復原廠設定。"</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"您嘗試解除這支手機的鎖定已失敗 <xliff:g id="NUMBER">%d</xliff:g> 次,手機現在將恢復原廠設定。"</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"您的解鎖圖形已畫錯 <xliff:g id="NUMBER_0">%d</xliff:g> 次,如果再嘗試 <xliff:g id="NUMBER_1">%d</xliff:g> 次仍未成功,系統就會要求您透過電子郵件帳戶解除平板電腦的鎖定狀態。"\n\n"請在 <xliff:g id="NUMBER_2">%d</xliff:g> 秒後再試一次。"</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"您的解鎖圖形已畫錯 <xliff:g id="NUMBER_0">%d</xliff:g> 次,如果再嘗試 <xliff:g id="NUMBER_1">%d</xliff:g> 次仍未成功,系統就會要求您透過電子郵件帳戶解除手機的鎖定狀態。"\n\n"請在 <xliff:g id="NUMBER_2">%d</xliff:g> 秒後再試一次。"</string>
+ <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
+ <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"移除"</string>
+ <!-- no translation found for keyguard_transport_prev_description (8229108430245669854) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_next_description (4299258300283778305) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_pause_description (5093073338238310224) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_play_description (2924628863741150956) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_stop_description (3084179324810575787) -->
+ <skip />
+ <!-- no translation found for keyguard_carrier_default (8700650403054042153) -->
+ <skip />
+</resources>
diff --git a/packages/Keyguard/res/values-zu/strings.xml b/packages/Keyguard/res/values-zu/strings.xml
new file mode 100644
index 0000000..89ce090
--- /dev/null
+++ b/packages/Keyguard/res/values-zu/strings.xml
@@ -0,0 +1,164 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/* //device/apps/common/assets/res/any/strings.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:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Faka ikhodi ye-PIN"</string>
+ <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Faka i-PUK nephinikhodi entsha"</string>
+ <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"Ikhodi le-PUK"</string>
+ <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Iphinikhodi entsha"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Thinta ukubhala iphasiwedi"</font></string>
+ <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Bhala iphasiwedi ukuze kuvuleke"</string>
+ <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Faka i-PIN ukuvula"</string>
+ <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Ikhodi ye-PIN engalungile!"</string>
+ <string name="keyguard_label_text" msgid="861796461028298424">"Ukuvula, chofoza Menyu bese 0."</string>
+ <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Ukuzama Kokuvula Ubuso Okuningi kudluliwe"</string>
+ <!-- no translation found for keyguard_charged (3272223906073492454) -->
+ <skip />
+ <!-- no translation found for keyguard_plugged_in (8117572000639998388) -->
+ <skip />
+ <!-- no translation found for keyguard_low_battery (8143808018719173859) -->
+ <skip />
+ <!-- no translation found for keyguard_instructions_when_pattern_disabled (1332288268600329841) -->
+ <skip />
+ <!-- no translation found for keyguard_network_locked_message (9169717779058037168) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message_short (494980561304211931) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (1445849005909260039) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_message (3481110395508637643) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions (5210891509995942250) -->
+ <skip />
+ <!-- no translation found for keyguard_missing_sim_instructions_long (5968985489463870358) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_message_short (8340813989586622356) -->
+ <skip />
+ <!-- no translation found for keyguard_permanent_disabled_sim_instructions (5892940909699723544) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_locked_message (6875773413306380902) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_puk_locked_message (3747232467471801633) -->
+ <skip />
+ <!-- no translation found for keyguard_sim_unlock_progress_dialog_message (7975221805033614426) -->
+ <skip />
+ <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. iwijethi %2$d ye-%3$d."</string>
+ <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Engeza iwijethi."</string>
+ <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Akunalutho"</string>
+ <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Indawo yokuvula inwetshisiwe."</string>
+ <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Indawo yokuvula inciphisiwe."</string>
+ <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> iwijethi."</string>
+ <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"Isikhethi somsebenzisi"</string>
+ <string name="keyguard_accessibility_status" msgid="8008264603935930611">"Isimo"</string>
+ <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"Ikhamera"</string>
+ <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Izilawuli zemidiya"</string>
+ <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Ukuhlelwa kabusha kwewijethi kuqalile"</string>
+ <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Ukuhlelwa kabusha kwewijethi kuphelile."</string>
+ <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Iwijethi <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> isusiwe."</string>
+ <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Nwebisa indawo yokuvula."</string>
+ <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Ukuvula ngokuslayida."</string>
+ <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Ukuvula ngephethini."</string>
+ <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Vula ngobuso"</string>
+ <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Ukuvula ngephinikhodi."</string>
+ <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Ukuvula ngephasiwedi."</string>
+ <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Indawo yephethini."</string>
+ <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Indawo yokushelelisa."</string>
+ <!-- no translation found for keyguard_accessibility_transport_prev_description (1337286538318543555) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_next_description (7073928300444909320) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_pause_description (8455979545295224302) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_play_description (8146417789511154044) -->
+ <skip />
+ <!-- no translation found for keyguard_accessibility_transport_stop_description (7656358482980912216) -->
+ <skip />
+ <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+ <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+ <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+ <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"i-ALT"</string>
+ <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Khansela"</string>
+ <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Susa"</string>
+ <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Kwenziwe"</string>
+ <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Ukushintsha kwendlela esetshenziswayo"</string>
+ <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Beka kwenye indawo"</string>
+ <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Faka"</string>
+ <string name="description_target_unlock" msgid="2228524900439801453">"Vula"</string>
+ <string name="description_target_camera" msgid="969071997552486814">"Ikhamera"</string>
+ <string name="description_target_silent" msgid="893551287746522182">"Thulile"</string>
+ <string name="description_target_soundon" msgid="30052466675500172">"Umsindo uvuliwe"</string>
+ <string name="description_target_search" msgid="3091587249776033139">"Sesha"</string>
+ <string name="description_direction_up" msgid="7169032478259485180">"Shelelisela ngenhla ku-<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_down" msgid="5087739728639014595">"Shelelisela ngezansi ku-<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_left" msgid="7207478719805562165">"Shelelisela ngakwesokunxele ku-<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="description_direction_right" msgid="8034433242579600980">"Shelelisela ngakwesokudla ku-<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+ <string name="user_switched" msgid="3768006783166984410">"Umsebenzisi wamanje <xliff:g id="NAME">%1$s</xliff:g>."</string>
+ <string name="kg_emergency_call_label" msgid="684946192523830531">"Ucingo lwezimo eziphuthumayo"</string>
+ <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Ukhohlwe iphethini?"</string>
+ <string name="kg_wrong_pattern" msgid="1850806070801358830">"Iphatheni engalungile"</string>
+ <string name="kg_wrong_password" msgid="2333281762128113157">"Iphasiwedi engalungile"</string>
+ <string name="kg_wrong_pin" msgid="1131306510833563801">"Iphinikhodi engalungile"</string>
+ <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Zama futhi emasekhondini angu-<xliff:g id="NUMBER">%d</xliff:g>."</string>
+ <string name="kg_pattern_instructions" msgid="398978611683075868">"Dweba iphethini"</string>
+ <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Faka iphinikhodi ye-SIM"</string>
+ <string name="kg_pin_instructions" msgid="2377242233495111557">"Faka iphinikhodi"</string>
+ <string name="kg_password_instructions" msgid="5753646556186936819">"Faka iphasiwedi"</string>
+ <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"I-SIM manje ikhutshaziwe. Faka ikhodi ye-PUK ukuze uqhubeke. Xhumana nenkampani yenethiwekhi ngemininingwane."</string>
+ <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Faka iphinikhodi oyithandayo"</string>
+ <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Qiniseka iphinikhodi oyithandayo"</string>
+ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Ivula ikhadi le-SIM..."</string>
+ <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Iphinikhodi engalungile."</string>
+ <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Thayipha iphinikhodi enezinombolo ezingu-4 kuya kwezingu-8."</string>
+ <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"Ikhodi ye-PUK kufanele ibe yizinombolo ezingu-8 noma eziningi."</string>
+ <string name="kg_invalid_puk" msgid="3638289409676051243">"Faka kabusha ikhodi ye-PUK elungile. Imizamo ephindiwe izokhubaza unaphakade i-SIM."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"Iphinikhodi ayifani"</string>
+ <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Kunemizamo eminingi kakhulu yephathini"</string>
+ <string name="kg_login_instructions" msgid="1100551261265506448">"Ukuvula, ngena ngemvume kwi-akhawunti ye-Google"</string>
+ <string name="kg_login_username_hint" msgid="5718534272070920364">"Igama lomsebenzisi (i-imeyli)"</string>
+ <string name="kg_login_password_hint" msgid="9057289103827298549">"Iphasiwedi"</string>
+ <string name="kg_login_submit_button" msgid="5355904582674054702">"Ngena ngemvume"</string>
+ <string name="kg_login_invalid_input" msgid="5754664119319872197">"Igama lomsebezisi elingalungile noma iphasiwedi."</string>
+ <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Ukhohlwe igama lomsebenzisi noma iphasiwedi?"\n"Vakashela"<b>"google.com/accounts/recovery"</b></string>
+ <string name="kg_login_checking_password" msgid="1052685197710252395">"Ukuhlola i-akhawunti…"</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Ubhale iphinikhodi ykho ngendlela engafanele izikhathi ezingu-<xliff:g id="NUMBER_0">%d</xliff:g>. "\n\n"Zama futhi emasekhondini angu-<xliff:g id="NUMBER_1">%d</xliff:g>."</string>
+ <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Ubhale iphasiwedi yakho ngendlela engafanele <xliff:g id="NUMBER_0">%d</xliff:g> izikhathi. "\n\n"Zama futhi emasekhondini angu-<xliff:g id="NUMBER_1">%d</xliff:g>."</string>
+ <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Udwebe iphathini yakho yokuvula ngendlela engafanele-<xliff:g id="NUMBER_0">%d</xliff:g>. "\n\n" Zama futhi emasekhondini angu-<xliff:g id="NUMBER_1">%d</xliff:g>"</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Uzame ngokusebenzisa indlela engafanele ukuvula ithebhulethi izikhathi ezingu-<xliff:g id="NUMBER_0">%d</xliff:g>. Ngemuva kokuzama ngaphandle kwempumelelo okungu-<xliff:g id="NUMBER_1">%d</xliff:g>, ithebhulethi izobuyiselwa kwizimiso zasembonini futhi yonke imininingwane yomsebenzisi izolahleka."</string>
+ <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Uzame ngokusebenzisa indlela engafanele ukuvula ifoni izikhathi ezingu-<xliff:g id="NUMBER_0">%d</xliff:g>. Ngemuva kokuzama ngaphandle kwempumelelo okungu-<xliff:g id="NUMBER_1">%d</xliff:g>, ifoni izobuyiselwa kwizimiso zasembonini futhi yonke imininingwane yomsebenzisi izolahleka."</string>
+ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Uzame ukuvula ngendlela engafanele ifoni izikhathi ezingu-<xliff:g id="NUMBER">%d</xliff:g>. Ithebhulethi manje isizosethwa kabusha ibe yizimiso ezizenzakalelayo."</string>
+ <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Uzame ukuvula ngendlela engafanele ifoni izikhathi ezingu-<xliff:g id="NUMBER">%d</xliff:g>. Ifoni manje isizosethwa kabusha ibe yizimiso ezizenzakalelayo."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Udwebe ngokungalungile iphathini yakho yokuvula izikhathi ezingu-<xliff:g id="NUMBER_0">%d</xliff:g>. Emva <xliff:g id="NUMBER_1">%d</xliff:g> kweminye imizamo engaphumelelanga, uzocelwa ukuvula ithebhulethi yakho usebenzisa ukungena ngemvume kwi-Google."\n\n" Sicela uzame futhi kwengu-<xliff:g id="NUMBER_2">%d</xliff:g> imizuzwana."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Ukulayisha ungenisa iphathini yakho yokuvula ngendlela engalungile izikhathi ezi-<xliff:g id="NUMBER_0">%d</xliff:g> Emva kweminye imizamo engu-<xliff:g id="NUMBER_1">%d</xliff:g>, uzocelwa ukuvula ifoni yakho usebenzisa ukungena ngemvume ku-Google"\n\n" Zame futhi emumva kwengu- <xliff:g id="NUMBER_2">%d</xliff:g> imizuzwana."</string>
+ <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
+ <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Susa"</string>
+ <!-- no translation found for keyguard_transport_prev_description (8229108430245669854) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_next_description (4299258300283778305) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_pause_description (5093073338238310224) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_play_description (2924628863741150956) -->
+ <skip />
+ <!-- no translation found for keyguard_transport_stop_description (3084179324810575787) -->
+ <skip />
+ <!-- no translation found for keyguard_carrier_default (8700650403054042153) -->
+ <skip />
+</resources>
diff --git a/packages/Keyguard/res/values/activitystrings.xml b/packages/Keyguard/res/values/activitystrings.xml
new file mode 100644
index 0000000..5af9dea
--- /dev/null
+++ b/packages/Keyguard/res/values/activitystrings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/assets/res/any/strings.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">
+ <string name="app_name">KeyguardTestActivity</string>
+ <string name="secure_app_name">UnifiedCamera</string>
+ <string name="none_menu_item">No security</string>
+ <string name="pin_menu_item">PIN</string>
+ <string name="password_menu_item">Password</string>
+ <string name="pattern_menu_item">Pattern</string>
+ <string name="sim_pin_menu_item">SIM PIN</string>
+ <string name="sim_puk_menu_item">SIM PUK</string>
+ <string name="add_widget_item">Choose widget...</string>
+ <string name="on_screen_turned_off">onScreenTurnedOff</string>
+ <string name="on_screen_turned_on">onScreenTurnedOn</string>
+ <string name="do_keyguard">doKeyguard</string>
+ <string name="verify_unlock">verifyUnlock</string>
+</resources>
diff --git a/packages/Keyguard/res/values/alias.xml b/packages/Keyguard/res/values/alias.xml
new file mode 100644
index 0000000..47291b2
--- /dev/null
+++ b/packages/Keyguard/res/values/alias.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/assets/res/any/colors.xml
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<resources>
+
+ <!-- Alias used to reference framework color for transparency. -->
+ <item type="color" name="transparent">@android:color/transparent</item>
+
+ <!-- Alias used to reference framework drawable in keyguard. -->
+ <item type="drawable" name="stat_sys_warning">@android:drawable/stat_sys_warning</item>
+
+ <!-- Alias used to reference framework drawable in keyguard. -->
+ <item type="drawable" name="ic_media_pause">@android:drawable/ic_media_pause</item>
+
+ <!-- Alias used to reference framework drawable in keyguard. -->
+ <item type="drawable" name="ic_media_stop">@*android:drawable/ic_media_stop</item>
+
+ <!-- Alias used to reference framework drawable in keyguard. -->
+ <item type="drawable" name="ic_contact_picture">@*android:drawable/ic_contact_picture</item>
+
+ <!-- Alias used to reference framework drawable in keyguard. -->
+ <item type="drawable" name="ic_lock_idle_alarm">@*android:drawable/ic_lock_idle_alarm</item>
+
+ <!-- Alias used to reference framework "OK" string in keyguard. -->
+ <item type="string" name="ok">@*android:string/ok</item>
+
+ <!-- Alias used to reference framework "OK" string in keyguard. -->
+ <item type="string" name="system_ui_date_pattern">@*android:string/system_ui_date_pattern</item>
+
+ <!-- Alias used to reference framework configuration for screen rotation. -->
+ <item type="bool" name="config_enableLockScreenRotation">@*android:bool/config_enableLockScreenRotation</item>
+
+ <!-- Alias used to reference framework activity duration. -->
+ <item type="integer" name="config_activityDefaultDur">@*android:integer/config_activityDefaultDur</item>
+
+</resources> \ No newline at end of file
diff --git a/packages/Keyguard/res/values/arrays.xml b/packages/Keyguard/res/values/arrays.xml
new file mode 100644
index 0000000..550f80c
--- /dev/null
+++ b/packages/Keyguard/res/values/arrays.xml
@@ -0,0 +1,93 @@
+<?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">
+
+ <!-- Resources for GlowPadView in LockScreen -->
+ <array name="lockscreen_targets_when_silent">
+ <item>@drawable/ic_lockscreen_unlock</item>
+ <item>@drawable/ic_action_assist_generic</item>
+ <item>@drawable/ic_lockscreen_soundon</item>
+ <item>@null</item>
+ </array>
+
+ <array name="lockscreen_target_descriptions_when_silent">
+ <item>@string/description_target_unlock</item>
+ <item>@string/description_target_search</item>
+ <item>@string/description_target_soundon</item>
+ <item>@null</item>
+ </array>
+
+ <array name="lockscreen_direction_descriptions">
+ <item>@string/description_direction_right</item>
+ <item>@string/description_direction_up</item>
+ <item>@string/description_direction_left</item>
+ <item>@null</item>
+ </array>
+
+ <array name="lockscreen_targets_when_soundon">
+ <item>@drawable/ic_lockscreen_unlock</item>
+ <item>@drawable/ic_action_assist_generic</item>
+ <item>@drawable/ic_lockscreen_silent</item>
+ <item>@null</item>
+ </array>
+
+ <array name="lockscreen_target_descriptions_when_soundon">
+ <item>@string/description_target_unlock</item>
+ <item>@string/description_target_search</item>
+ <item>@string/description_target_silent</item>
+ <item>@null</item>
+ </array>
+
+ <array name="lockscreen_targets_with_camera">
+ <item>@drawable/ic_lockscreen_unlock</item>
+ <item>@drawable/ic_action_assist_generic</item>
+ <item>@drawable/ic_lockscreen_camera</item>
+ <item>@null</item>
+ </array>
+
+ <array name="lockscreen_target_descriptions_with_camera">
+ <item>@string/description_target_unlock</item>
+ <item>@string/description_target_search</item>
+ <item>@string/description_target_camera</item>
+ <item>@null</item>
+ </array>
+
+ <array name="lockscreen_targets_unlock_only">
+ <item>@drawable/ic_lockscreen_unlock</item>
+ </array>
+
+ <array name="lockscreen_target_descriptions_unlock_only">
+ <item>@string/description_target_unlock</item>
+ </array>
+
+ <!-- list of 3- or 4-letter mnemonics for a 10-key numeric keypad -->
+ <string-array translatable="false" name="lockscreen_num_pad_klondike">
+ <item></item><!-- 0 -->
+ <item></item><!-- 1 -->
+ <item>ABC</item><!-- 2 -->
+ <item>DEF</item><!-- 3 -->
+ <item>GHI</item><!-- 4 -->
+ <item>JKL</item><!-- 5 -->
+ <item>MNO</item><!-- 6 -->
+ <item>PQRS</item><!-- 7 -->
+ <item>TUV</item><!-- 8 -->
+ <item>WXYZ</item><!-- 9 -->
+ </string-array>
+</resources>
diff --git a/packages/Keyguard/res/values/attrs.xml b/packages/Keyguard/res/values/attrs.xml
new file mode 100644
index 0000000..e045dd2
--- /dev/null
+++ b/packages/Keyguard/res/values/attrs.xml
@@ -0,0 +1,136 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 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.
+-->
+
+<!-- Formatting note: terminate all comments with a period, to avoid breaking
+ the documentation output. To suppress comment lines from the documentation
+ output, insert an eat-comment element after the comment lines.
+-->
+
+<resources>
+ <!-- Standard gravity constant that a child supplies to its parent.
+ Defines how the child view should be positioned, on both the X and Y axes, within its enclosing layout. -->
+ <attr name="layout_gravity">
+ <!-- Push object to the top of its container, not changing its size. -->
+ <flag name="top" value="0x30" />
+ <!-- Push object to the bottom of its container, not changing its size. -->
+ <flag name="bottom" value="0x50" />
+ <!-- Push object to the left of its container, not changing its size. -->
+ <flag name="left" value="0x03" />
+ <!-- Push object to the right of its container, not changing its size. -->
+ <flag name="right" value="0x05" />
+ <!-- Place object in the vertical center of its container, not changing its size. -->
+ <flag name="center_vertical" value="0x10" />
+ <!-- Grow the vertical size of the object if needed so it completely fills its container. -->
+ <flag name="fill_vertical" value="0x70" />
+ <!-- Place object in the horizontal center of its container, not changing its size. -->
+ <flag name="center_horizontal" value="0x01" />
+ <!-- Grow the horizontal size of the object if needed so it completely fills its container. -->
+ <flag name="fill_horizontal" value="0x07" />
+ <!-- Place the object in the center of its container in both the vertical and horizontal axis, not changing its size. -->
+ <flag name="center" value="0x11" />
+ <!-- Grow the horizontal and vertical size of the object if needed so it completely fills its container. -->
+ <flag name="fill" value="0x77" />
+ <!-- Additional option that can be set to have the top and/or bottom edges of
+ the child clipped to its container's bounds.
+ The clip will be based on the vertical gravity: a top gravity will clip the bottom
+ edge, a bottom gravity will clip the top edge, and neither will clip both edges. -->
+ <flag name="clip_vertical" value="0x80" />
+ <!-- Additional option that can be set to have the left and/or right edges of
+ the child clipped to its container's bounds.
+ The clip will be based on the horizontal gravity: a left gravity will clip the right
+ edge, a right gravity will clip the left edge, and neither will clip both edges. -->
+ <flag name="clip_horizontal" value="0x08" />
+ <!-- Push object to the beginning of its container, not changing its size. -->
+ <flag name="start" value="0x00800003" />
+ <!-- Push object to the end of its container, not changing its size. -->
+ <flag name="end" value="0x00800005" />
+ </attr>
+
+
+ <!-- PagedView specific attributes. These attributes are used to customize
+ a PagedView view in XML files. -->
+ <declare-styleable name="PagedView">
+ <!-- The space between adjacent pages of the PagedView. -->
+ <attr name="pageSpacing" format="dimension" />
+ <!-- The padding for the scroll indicator area -->
+ <attr name="scrollIndicatorPaddingLeft" format="dimension" />
+ <attr name="scrollIndicatorPaddingRight" format="dimension" />
+ </declare-styleable>
+
+ <declare-styleable name="KeyguardGlowStripView">
+ <attr name="dotSize" format="dimension" />
+ <attr name="numDots" format="integer" />
+ <attr name="glowDot" format="reference" />
+ <attr name="leftToRight" format="boolean" />
+ </declare-styleable>
+
+ <!-- Some child types have special behavior. -->
+ <attr name="layout_childType">
+ <!-- No special behavior. Layout will proceed as normal. -->
+ <enum name="none" value="0" />
+ <!-- Widget container.
+ This will be resized in response to certain events. -->
+ <enum name="widget" value="1" />
+ <!-- Security challenge container.
+ This will be dismissed/shown in response to certain events,
+ possibly obscuring widget elements. -->
+ <enum name="challenge" value="2" />
+ <!-- User switcher.
+ This will consume space from the total layout area. -->
+ <enum name="userSwitcher" value="3" />
+ <!-- Scrim. This will block access to child views that
+ come before it in the child list in bouncer mode. -->
+ <enum name="scrim" value="4" />
+ <!-- The home for widgets. All widgets will be descendents of this. -->
+ <enum name="widgets" value="5" />
+ <!-- This is a handle that is used for expanding the
+ security challenge container when it is collapsed. -->
+ <enum name="expandChallengeHandle" value="6" />
+ <!-- Delete drop target. This will be the drop target to delete pages. -->
+ <enum name="pageDeleteDropTarget" value="7" />
+ </attr>
+
+ <declare-styleable name="SlidingChallengeLayout_Layout">
+ <attr name="layout_childType" />
+ <attr name="layout_maxHeight" format="dimension" />
+ </declare-styleable>
+
+ <declare-styleable name="MultiPaneChallengeLayout">
+ <!-- Influences how layout_centerWithinArea behaves -->
+ <attr name="android:orientation" />
+ </declare-styleable>
+
+ <declare-styleable name="MultiPaneChallengeLayout_Layout">
+ <!-- Percentage of the screen this child should consume or center within.
+ If 0/default, the view will be measured by standard rules
+ as if this were a FrameLayout. -->
+ <attr name="layout_centerWithinArea" format="float" />
+ <attr name="layout_childType" />
+ <attr name="layout_gravity" />
+ <attr name="layout_maxWidth" format="dimension" />
+ <attr name="layout_maxHeight" />
+ </declare-styleable>
+
+ <declare-styleable name="KeyguardSecurityViewFlipper_Layout">
+ <attr name="layout_maxWidth" />
+ <attr name="layout_maxHeight" />
+ </declare-styleable>
+
+ <declare-styleable name="NumPadKey">
+ <attr name="digit" format="integer" />
+ <attr name="textView" format="reference" />
+ </declare-styleable>
+</resources>
diff --git a/packages/Keyguard/res/values/bools.xml b/packages/Keyguard/res/values/bools.xml
new file mode 100644
index 0000000..a9f69e5
--- /dev/null
+++ b/packages/Keyguard/res/values/bools.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<resources>
+ <bool name="kg_enable_camera_default_widget">true</bool>
+ <bool name="kg_center_small_widgets_vertically">false</bool>
+ <bool name="kg_top_align_page_shrink_on_bouncer_visible">true</bool>
+ <bool name="kg_show_ime_at_screen_on">true</bool>
+</resources>
diff --git a/packages/Keyguard/res/values/colors.xml b/packages/Keyguard/res/values/colors.xml
new file mode 100644
index 0000000..0c56a43
--- /dev/null
+++ b/packages/Keyguard/res/values/colors.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<resources>
+ <!-- Keyguard colors -->
+ <color name="keyguard_avatar_frame_color">#ffffffff</color>
+ <color name="keyguard_avatar_frame_shadow_color">#80000000</color>
+ <color name="keyguard_avatar_nick_color">#ffffffff</color>
+ <color name="keyguard_avatar_frame_pressed_color">#ff35b5e5</color>
+ <color name="kg_widget_pager_gradient">#ffffffff</color>
+
+ <!-- FaceLock -->
+ <color name="facelock_spotlight_mask">#CC000000</color>
+</resources>
diff --git a/packages/Keyguard/res/values/config.xml b/packages/Keyguard/res/values/config.xml
new file mode 100644
index 0000000..de17c4b
--- /dev/null
+++ b/packages/Keyguard/res/values/config.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2009, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+ <!-- Package name for default keyguard appwidget [DO NOT TRANSLATE] -->
+ <string name="widget_default_package_name"></string>
+
+ <!-- Class name for default keyguard appwidget [DO NOT TRANSLATE] -->
+ <string name="widget_default_class_name"></string>
+
+ <!-- Allow the menu hard key to be disabled in LockScreen on some devices [DO NOT TRANSLATE] -->
+ <bool name="config_disableMenuKeyInLockScreen">false</bool>
+
+</resources>
diff --git a/packages/Keyguard/res/values/dimens.xml b/packages/Keyguard/res/values/dimens.xml
new file mode 100644
index 0000000..fde63c4
--- /dev/null
+++ b/packages/Keyguard/res/values/dimens.xml
@@ -0,0 +1,167 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/assets/res/any/dimens.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>
+ <!-- Default height of a key in the password keyboard for alpha (used by keyguard) -->
+ <dimen name="password_keyboard_key_height_alpha">56dip</dimen>
+ <!-- Default height of a key in the password keyboard for numeric (used by keyguard) -->
+ <dimen name="password_keyboard_key_height_numeric">56dip</dimen>
+ <!-- Default correction for the space key in the password keyboard (used by keyguard) -->
+ <dimen name="password_keyboard_spacebar_vertical_correction">4dip</dimen>
+ <!-- Default horizontal gap between keys in the password keyboard (used by keyguard) -->
+ <dimen name="password_keyboard_horizontalGap">3dip</dimen>
+ <!-- Default vertical gap between keys in the password keyboard (used by keyguard) -->
+ <dimen name="password_keyboard_verticalGap">9dip</dimen>
+
+ <!-- Size of lockscreen outerring on unsecure unlock LockScreen -->
+ <dimen name="keyguard_lockscreen_outerring_diameter">270dp</dimen>
+
+ <!-- Default target placement radius for GlowPadView. Should be 1/2 of outerring diameter. -->
+ <dimen name="glowpadview_target_placement_radius">135dip</dimen>
+
+ <!-- Default glow radius for GlowPadView -->
+ <dimen name="glowpadview_glow_radius">75dip</dimen>
+
+ <!-- Default distance beyond which GlowPadView snaps to the matching target -->
+ <dimen name="glowpadview_snap_margin">40dip</dimen>
+
+ <!-- Default distance from each snap target that GlowPadView considers a "hit" -->
+ <dimen name="glowpadview_inner_radius">15dip</dimen>
+
+ <!-- Size of clock font in LockScreen on Unsecure unlock screen. -->
+ <dimen name="keyguard_lockscreen_clock_font_size">80dip</dimen>
+
+ <!-- Size of status line font on Unsecure unlock LockScreen. -->
+ <dimen name="keyguard_lockscreen_status_line_font_size">14dip</dimen>
+
+ <!-- Size of right margin on Unsecure unlock LockScreen -->
+ <dimen name="keyguard_lockscreen_status_line_font_right_margin">42dip</dimen>
+
+ <!-- Size of top margin on Clock font to edge on unlock LockScreen -->
+ <dimen name="keyguard_lockscreen_status_line_clockfont_top_margin">22dip</dimen>
+
+ <!-- Size of top margin on Clock font to edge on unlock LockScreen -->
+ <dimen name="keyguard_lockscreen_status_line_clockfont_bottom_margin">12dip</dimen>
+
+ <!-- Padding on left margin of PIN text entry field to center it when del button is showing -->
+ <dimen name="keyguard_lockscreen_pin_margin_left">40dip</dimen>
+
+ <!-- Height of FaceUnlock view in keyguard -->
+ <dimen name="face_unlock_height">330dip</dimen>
+
+ <!-- Keyguard dimensions -->
+ <!-- TEMP -->
+ <dimen name="kg_security_panel_height">600dp</dimen>
+
+ <!-- Height of security view in keyguard. -->
+ <dimen name="kg_security_view_height">480dp</dimen>
+
+ <!-- Width of widget view in keyguard. -->
+ <dimen name="kg_widget_view_width">0dp</dimen>
+
+ <!-- Height of widget view in keyguard. -->
+ <dimen name="kg_widget_view_height">0dp</dimen>
+
+ <!-- Size of the clock font in keyguard's status view -->
+ <dimen name="kg_status_clock_font_size">75dp</dimen>
+
+ <!-- Size of the date font in keyguard's status view -->
+ <dimen name="kg_status_date_font_size">15dp</dimen>
+
+ <!-- Size of the generic status lines keyguard's status view -->
+ <dimen name="kg_status_line_font_size">13dp</dimen>
+
+ <!-- Size of margin on the right of keyguard's status view -->
+ <dimen name="kg_status_line_font_right_margin">16dp</dimen>
+
+ <!-- Top margin for the clock view -->
+ <dimen name="kg_clock_top_margin">-16dp</dimen>
+
+ <!-- Horizontal gap between keys in PIN and SIM PIN numeric keyboards in keyguard -->
+ <dimen name="kg_key_horizontal_gap">0dp</dimen>
+
+ <!-- Horizontal gap between keys in PIN and SIM PIN numeric keyboards in keyguard -->
+ <dimen name="kg_key_vertical_gap">0dp</dimen>
+
+ <!-- Horizontal gap between keys in PIN and SIM PIN numeric keyboards in keyguard -->
+ <dimen name="kg_pin_key_height">60dp</dimen>
+
+ <!-- Space reserved at the bottom of secure views (pin/pattern/password/SIM pin/SIM puk) -->
+ <dimen name="kg_secure_padding_height">46dp</dimen>
+
+ <!-- The height of the runway lights strip -->
+ <dimen name="kg_runway_lights_height">7dp</dimen>
+
+ <!-- The height of the runway lights strip -->
+ <dimen name="kg_runway_lights_vertical_padding">2dp</dimen>
+
+ <!-- Horizontal padding for the widget pager -->
+ <dimen name="kg_widget_pager_horizontal_padding">16dp</dimen>
+
+ <!-- Top padding for the widget pager -->
+ <dimen name="kg_widget_pager_top_padding">0dp</dimen>
+
+ <!-- Bottom padding for the widget pager -->
+ <dimen name="kg_widget_pager_bottom_padding">64dp</dimen>
+
+ <!-- Top margin for the runway lights. We add a negative margin in large
+ devices to account for the widget pager padding -->
+ <dimen name="kg_runway_lights_top_margin">0dp</dimen>
+
+ <!-- Touch slop for the global toggle accessibility gesture -->
+ <dimen name="accessibility_touch_slop">80dip</dimen>
+
+ <!-- Width of the sliding KeyguardSecurityContainer (includes 2x keyguard_security_view_margin) -->
+ <dimen name="keyguard_security_width">320dp</dimen>
+
+ <!-- Height of the sliding KeyguardSecurityContainer (includes 2x keyguard_security_view_margin) -->
+ <dimen name="keyguard_security_height">400dp</dimen>
+
+ <!-- Margin around the various security views -->
+ <dimen name="keyguard_security_view_margin">8dp</dimen>
+
+ <!-- Margin around the various security views -->
+ <dimen name="keyguard_muliuser_selector_margin">8dp</dimen>
+
+ <!-- Stroke width of the frame for the circular avatars. -->
+ <dimen name="keyguard_avatar_frame_stroke_width">2dp</dimen>
+
+ <!-- Shadow radius under the frame for the circular avatars. -->
+ <dimen name="keyguard_avatar_frame_shadow_radius">1dp</dimen>
+
+ <!-- Size of the avator on hte multiuser lockscreen. -->
+ <dimen name="keyguard_avatar_size">66dp</dimen>
+
+ <!-- Size of the text under the avator on the multiuser lockscreen. -->
+ <dimen name="keyguard_avatar_name_size">10sp</dimen>
+
+ <!-- Size of the region along the edge of the screen that will accept
+ swipes to scroll the widget area. -->
+ <dimen name="kg_edge_swipe_region_size">24dp</dimen>
+
+ <!-- If the height if keyguard drops below this threshold (most likely
+ due to the appearance of the IME), then drop the multiuser selector. -->
+ <dimen name="kg_squashed_layout_threshold">600dp</dimen>
+
+ <!-- The height of widgets which do not support vertical resizing. This is only
+ used on tablets; on phones, this size is determined by the space left by the
+ security mode. -->
+ <dimen name="kg_small_widget_height">160dp</dimen>
+
+</resources>
diff --git a/packages/Keyguard/res/values/integers.xml b/packages/Keyguard/res/values/integers.xml
new file mode 100644
index 0000000..053fc85
--- /dev/null
+++ b/packages/Keyguard/res/values/integers.xml
@@ -0,0 +1,24 @@
+<?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.
+*/
+-->
+<resources>
+ <integer name="kg_carousel_angle">75</integer>
+ <integer name="kg_security_flip_duration">100</integer>
+ <integer name="kg_security_fade_duration">100</integer>
+ <integer name="kg_glowpad_rotation_offset">0</integer>
+</resources>
diff --git a/packages/Keyguard/res/values/strings.xml b/packages/Keyguard/res/values/strings.xml
new file mode 100644
index 0000000..5cf05f8
--- /dev/null
+++ b/packages/Keyguard/res/values/strings.xml
@@ -0,0 +1,327 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/assets/res/any/strings.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">
+ <!-- Instructions telling the user to enter their SIM PIN to unlock the keyguard.
+ Displayed in one line in a large font. -->
+ <string name="keyguard_password_enter_pin_code">Type PIN code</string>
+
+ <!-- Instructions telling the user to enter their SIM PUK to unlock the keyguard.
+ Displayed in one line in a large font. -->
+ <string name="keyguard_password_enter_puk_code">Type PUK and new PIN code</string>
+
+ <!-- Prompt to enter SIM PUK in Edit Text Box in unlock screen -->
+ <string name="keyguard_password_enter_puk_prompt">PUK code</string>
+ <!-- Prompt to enter New SIM PIN in Edit Text Box in unlock screen -->
+ <string name="keyguard_password_enter_pin_prompt">New PIN code</string>
+
+ <!-- Displayed as hint in passwordEntry EditText on PasswordUnlockScreen [CHAR LIMIT=30]-->
+ <string name="keyguard_password_entry_touch_hint"><font size="17">Touch to type password</font></string>
+
+ <!-- Instructions telling the user to enter their text password to unlock the keyguard.
+ Displayed in one line in a large font. -->
+ <string name="keyguard_password_enter_password_code">Type password to unlock</string>
+
+ <!-- Instructions telling the user to enter their PIN password to unlock the keyguard.
+ Displayed in one line in a large font. -->
+ <string name="keyguard_password_enter_pin_password_code">Type PIN to unlock</string>
+
+ <!-- Instructions telling the user that they entered the wrong pin while trying
+ to unlock the keyguard. Displayed in one line in a large font. -->
+ <string name="keyguard_password_wrong_pin_code">Incorrect PIN code.</string>
+
+ <!-- Instructions telling the user how to unlock the phone. -->
+ <string name="keyguard_label_text">To unlock, press Menu then 0.</string>
+
+ <!-- Shown when face unlock failed multiple times so we're just using the backup -->
+ <string name="faceunlock_multiple_failures">Maximum Face Unlock attempts exceeded</string>
+
+ <!-- When the lock screen is showing, the phone is plugged in and the battery is fully
+ charged, say that it is charged. -->
+ <string name="keyguard_charged">Charged</string>
+
+ <!-- When the lock screen is showing and the phone plugged in, and the battery
+ is not fully charged, show the current charge %. -->
+ <string name="keyguard_plugged_in">Charging, <xliff:g id="number">%d</xliff:g><xliff:g id="percent">%%</xliff:g></string>
+
+ <!-- When the lock screen is showing and the battery is low, warn user to plug
+ in the phone soon. -->
+ <string name="keyguard_low_battery">Connect your charger.</string>
+
+ <!-- On the keyguard screen, when pattern lock is disabled, only tell them to press menu to unlock. This is shown in small font at the bottom. -->
+ <string name="keyguard_instructions_when_pattern_disabled">Press Menu to unlock.</string>
+
+ <!-- SIM messages --><skip />
+ <!-- When the user inserts a sim card from an unsupported network, it becomes network locked -->
+ <string name="keyguard_network_locked_message">Network locked</string>
+ <!-- Shown when there is no SIM card. -->
+ <string name="keyguard_missing_sim_message_short">No SIM card</string>
+ <!-- Shown when there is no SIM card. -->
+ <string name="keyguard_missing_sim_message" product="tablet">No SIM card in tablet.</string>
+ <!-- Shown when there is no SIM card. -->
+ <string name="keyguard_missing_sim_message" product="default">No SIM card in phone.</string>
+ <!-- Shown to ask the user to insert a SIM card. -->
+ <string name="keyguard_missing_sim_instructions">Insert a SIM card.</string>
+ <!-- Shown to ask the user to insert a SIM card when sim is missing or not readable. -->
+ <string name="keyguard_missing_sim_instructions_long">The SIM card is missing or not readable. Insert a SIM card.</string>
+ <!-- Shown when SIM card is permanently disabled. -->
+ <string name="keyguard_permanent_disabled_sim_message_short">Unusable SIM card.</string>
+ <!-- Shown to inform the user to SIM card is permanently disabled. -->
+ <string name="keyguard_permanent_disabled_sim_instructions">Your SIM card has been permanently disabled.\n
+ Contact your wireless service provider for another SIM card.</string>
+ <!-- Shown to tell the user that their SIM is locked and they must unlock it. -->
+ <string name="keyguard_sim_locked_message">SIM card is locked.</string>
+ <!-- When the user enters a wrong sim pin too many times, it becomes PUK locked (Pin Unlock Kode) -->
+ <string name="keyguard_sim_puk_locked_message">SIM card is PUK-locked.</string>
+ <!-- For the unlock screen, When the user enters a sim unlock code, it takes a little while to check
+ whether it is valid, and to unlock the sim if it is valid. we display a
+ progress dialog in the meantime. this is the emssage. -->
+ <string name="keyguard_sim_unlock_progress_dialog_message">Unlocking SIM card\u2026</string>
+
+
+ <!-- Accessibility description sent when user changes the current lock screen widget. [CHAR_LIMIT=none] -->
+ <string name="keyguard_accessibility_widget_changed">%1$s. Widget %2$d of %3$d.</string>
+ <!-- Accessibility description of the add widget button. [CHAR_LIMIT=none] -->
+ <string name="keyguard_accessibility_add_widget">Add widget.</string>
+ <!-- Accessibility description of the empty sidget slot (place holder for a new widget). [CHAR_LIMIT=none] -->
+ <string name="keyguard_accessibility_widget_empty_slot">Empty</string>
+ <!-- Accessibility description of the event of expanding an unlock area. [CHAR_LIMIT=none] -->
+ <string name="keyguard_accessibility_unlock_area_expanded">Unlock area expanded.</string>
+ <!-- Accessibility description of the event of collapsing an unlock area. [CHAR_LIMIT=none] -->
+ <string name="keyguard_accessibility_unlock_area_collapsed">Unlock area collapsed.</string>
+ <!-- Accessibility description of a lock screen widget. [CHAR_LIMIT=none] -->
+ <string name="keyguard_accessibility_widget"><xliff:g id="widget_index">%1$s</xliff:g> widget.</string>
+ <!-- Accessibility description of the lock screen user selector widget. [CHAR_LIMIT=none] -->
+ <string name="keyguard_accessibility_user_selector">User selector</string>
+ <!-- Accessibility description of the lock screen status widget. [CHAR_LIMIT=none] -->
+ <string name="keyguard_accessibility_status">Status</string>
+ <!-- Accessibility description of the camera widget. [CHAR_LIMIT=none] -->
+ <string name="keyguard_accessibility_camera">Camera</string>
+ <!-- Accessibility description of the lock media control widget. [CHAR_LIMIT=none] -->
+ <string name="keygaurd_accessibility_media_controls">Media controls</string>
+ <!-- Accessibility description of widget reordering start. [CHAR_LIMIT=none] -->
+ <string name="keyguard_accessibility_widget_reorder_start">Widget reordering started.</string>
+ <!-- Accessibility description of widget reordering end. [CHAR_LIMIT=none] -->
+ <string name="keyguard_accessibility_widget_reorder_end">Widget reordering ended.</string>
+ <!-- Accessibility description of the a widget deletion event. [CHAR_LIMIT=none] -->
+ <string name="keyguard_accessibility_widget_deleted">Widget <xliff:g id="widget_index">%1$s</xliff:g> deleted.</string>
+ <!-- Accessibility description of the button to expand the lock area. [CHAR_LIMIT=none] -->
+ <string name="keyguard_accessibility_expand_lock_area">Expand unlock area.</string>
+ <!-- Accessibility description of the slide unlock. [CHAR_LIMIT=none] -->
+ <string name="keyguard_accessibility_slide_unlock">Slide unlock.</string>
+ <!-- Accessibility description of the pattern unlock. [CHAR_LIMIT=none] -->
+ <string name="keyguard_accessibility_pattern_unlock">Pattern unlock.</string>
+ <!-- Accessibility description of the face unlock. [CHAR_LIMIT=none] -->
+ <string name="keyguard_accessibility_face_unlock">Face unlock.</string>
+ <!-- Accessibility description of the pin lock. [CHAR_LIMIT=none] -->
+ <string name="keyguard_accessibility_pin_unlock">Pin unlock.</string>
+ <!-- Accessibility description of the password lock. [CHAR_LIMIT=none] -->
+ <string name="keyguard_accessibility_password_unlock">Password unlock.</string>
+ <!-- Accessibility description of the unlock pattern area. [CHAR_LIMIT=none] -->
+ <string name="keyguard_accessibility_pattern_area">Pattern area.</string>
+ <!-- Accessibility description of the unlock slide area. [CHAR_LIMIT=none] -->
+ <string name="keyguard_accessibility_slide_area">Slide area.</string>
+
+ <!-- Shown on transport control of lockscreen. Pressing button goes to previous track. -->
+ <string name="keyguard_accessibility_transport_prev_description">Previous track button</string>
+ <!-- Shown on transport control of lockscreen. Pressing button goes to next track. -->
+ <string name="keyguard_accessibility_transport_next_description">Next track button</string>
+ <!-- Shown on transport control of lockscreen. Pressing button pauses playback -->
+ <string name="keyguard_accessibility_transport_pause_description">Pause button</string>
+ <!-- Shown on transport control of lockscreen. Pressing button pauses playback -->
+ <string name="keyguard_accessibility_transport_play_description">Play button</string>
+ <!-- Shown on transport control of lockscreen. Pressing button pauses playback -->
+ <string name="keyguard_accessibility_transport_stop_description">Stop button</string>
+
+ <!-- Password keyboard strings. Used by LockScreen and Settings --><skip />
+ <!-- Label for "switch to symbols" key. Must be short to fit on key! -->
+ <string name="password_keyboard_label_symbol_key">\?123</string>
+ <!-- Label for "switch to alphabetic" key. Must be short to fit on key! -->
+ <string name="password_keyboard_label_alpha_key">ABC</string>
+ <!-- Label for ALT modifier key. Must be short to fit on key! -->
+ <string name="password_keyboard_label_alt_key">ALT</string>
+
+ <!-- KeyboardView - accessibility support --><skip />
+ <!-- Description of the Alt button in a KeyboardView. [CHAR LIMIT=NONE] -->
+ <string name="keyboardview_keycode_alt">Alt</string>
+ <!-- Description of the Cancel button in a KeyboardView. [CHAR LIMIT=NONE] -->
+ <string name="keyboardview_keycode_cancel">Cancel</string>
+ <!-- Description of the Delete button in a KeyboardView. [CHAR LIMIT=NONE] -->
+ <string name="keyboardview_keycode_delete">Delete</string>
+ <!-- Description of the Done button in a KeyboardView. [CHAR LIMIT=NONE] -->
+ <string name="keyboardview_keycode_done">Done</string>
+ <!-- Description of the Mode change button in a KeyboardView. [CHAR LIMIT=NONE] -->
+ <string name="keyboardview_keycode_mode_change">Mode change</string>
+ <!-- Description of the Shift button in a KeyboardView. [CHAR LIMIT=NONE] -->
+ <string name="keyboardview_keycode_shift">Shift</string>
+ <!-- Description of the Enter button in a KeyboardView. [CHAR LIMIT=NONE] -->
+ <string name="keyboardview_keycode_enter">Enter</string>
+
+ <!-- Description of the unlock target in the Slide unlock screen. [CHAR LIMIT=NONE] -->
+ <string name="description_target_unlock">Unlock</string>
+ <!-- Description of the camera target in the Slide unlock screen. [CHAR LIMIT=NONE] -->
+ <string name="description_target_camera">Camera</string>
+ <!-- Description of the silent target in the Slide unlock screen. [CHAR LIMIT=NONE] -->
+ <string name="description_target_silent">Silent</string>
+ <!-- Description of the sound on target in the Slide unlock screen. [CHAR LIMIT=NONE] -->
+ <string name="description_target_soundon">Sound on</string>
+ <!-- Description of the unlock target in the Slide unlock screen. [CHAR LIMIT=NONE] -->
+ <string name="description_target_search">Search</string>
+
+ <!-- Description of the up direction in which one can to slide the handle in the Slide unlock screen. [CHAR LIMIT=NONE] -->
+ <string name="description_direction_up">Slide up for <xliff:g id="target_description" example="Unlock">%s</xliff:g>.</string>
+ <!-- Description of the down direction in which one can to slide the handle in the Slide unlock screen. [CHAR LIMIT=NONE] -->
+ <string name="description_direction_down">Slide down for <xliff:g id="target_description" example="Unlock">%s</xliff:g>.</string>
+ <!-- Description of the left direction in which one can to slide the handle in the Slide unlock screen. [CHAR LIMIT=NONE] -->
+ <string name="description_direction_left">"Slide left for <xliff:g id="target_description" example="Unlock">%s</xliff:g>.</string>
+ <!-- Description of the right direction in which one can to slide the handle in the Slide unlock screen. [CHAR LIMIT=NONE] -->
+ <string name="description_direction_right">Slide right for <xliff:g id="target_description" example="Unlock">%s</xliff:g>.</string>
+
+ <!-- Text spoken when the current user is switched if accessibility is enabled. [CHAR LIMIT=none] -->
+ <string name="user_switched">Current user <xliff:g id="name" example="Bob">%1$s</xliff:g>.</string>
+
+ <!-- Label shown on emergency call button in keyguard -->
+ <string name="kg_emergency_call_label">Emergency call</string>
+ <!-- Message shown in pattern unlock after some number of unsuccessful attempts -->
+ <string name="kg_forgot_pattern_button_text">Forgot Pattern</string>
+ <!-- Message shown when user enters wrong pattern -->
+ <string name="kg_wrong_pattern">Wrong Pattern</string>
+ <!-- Message shown when user enters wrong password -->
+ <string name="kg_wrong_password">Wrong Password</string>
+ <!-- Message shown when user enters wrong PIN -->
+ <string name="kg_wrong_pin">Wrong PIN</string>
+ <!-- Countdown message shown after too many failed unlock attempts -->
+ <string name="kg_too_many_failed_attempts_countdown">Try again in <xliff:g id="number">%d</xliff:g> seconds.</string>
+ <!-- Instructions for using the pattern unlock screen -->
+ <string name="kg_pattern_instructions">Draw your pattern</string>
+ <!-- Instructions for using the SIM PIN unlock screen -->
+ <string name="kg_sim_pin_instructions">Enter SIM PIN</string>
+ <!-- Instructions for using the PIN unlock screen -->
+ <string name="kg_pin_instructions">Enter PIN</string>
+ <!-- Instructions for using the password unlock screen -->
+ <string name="kg_password_instructions">Enter Password</string>
+ <!-- Hint shown in the PUK screen that asks the user to enter the PUK code given to them by their provider -->
+ <string name="kg_puk_enter_puk_hint">SIM is now disabled. Enter PUK code to continue. Contact carrier for details.</string>
+ <!-- Hint shown in the PUK unlock screen PIN TextView -->
+ <string name="kg_puk_enter_pin_hint">Enter desired PIN code</string>
+ <!-- Message shown when the user needs to confirm the PIN they just entered in the PUK screen -->
+ <string name="kg_enter_confirm_pin_hint">Confirm desired PIN code</string>
+ <!-- Message shown in dialog while the device is unlocking the SIM card -->
+ <string name="kg_sim_unlock_progress_dialog_message">Unlocking SIM card\u2026</string>
+ <!-- Message shown when the user enters the wrong PIN code -->
+ <string name="kg_password_wrong_pin_code">Incorrect PIN code.</string>
+ <!-- Message shown when the user enters an invalid SIM pin password in PUK screen -->
+ <string name="kg_invalid_sim_pin_hint">Type a PIN that is 4 to 8 numbers.</string>
+ <!-- Message shown when the user enters an invalid PUK code in the PUK screen -->
+ <string name="kg_invalid_sim_puk_hint">PUK code should be 8 numbers or more.</string>
+ <!-- Message shown when the user enters an invalid PUK code -->
+ <string name="kg_invalid_puk">Re-enter the correct PUK code. Repeated attempts will permanently disable the SIM.</string>
+ <!-- String shown in PUK screen when PIN codes don't match -->
+ <string name="kg_invalid_confirm_pin_hint" product="default">PIN codes does not match</string>
+ <!-- Message shown when the user exceeds the maximum number of pattern attempts -->
+ <string name="kg_login_too_many_attempts">Too many pattern attempts</string>
+ <!-- Instructions show in account unlock screen allowing user to enter their email password -->
+ <string name="kg_login_instructions">To unlock, sign in with your Google account.</string>
+ <!-- Hint shown in TextView in account unlock screen of keyguard -->
+ <string name="kg_login_username_hint">Username (email)</string>
+ <!-- Hint shown in TextView in account unlock screen of keyguard -->
+ <string name="kg_login_password_hint">Password</string>
+ <!-- Label shown on sign in button on account unlock screen of keyguard -->
+ <string name="kg_login_submit_button">Sign in</string>
+ <!-- Message shown when the user enters an invalid username/password combination in account unlock screen of keyguard -->
+ <string name="kg_login_invalid_input">Invalid username or password.</string>
+ <!-- Hint text shown when user has too many failed password attempts in account unlock screen of keyguard -->
+ <string name="kg_login_account_recovery_hint">Forgot your username or password\?\nVisit <b>google.com/accounts/recovery</b>.</string>
+ <!-- Message shown while device checks username/password in account unlock screen of keyguard -->
+ <string name="kg_login_checking_password">Checking account\u2026</string>
+ <!-- Message shown in dialog when max number of attempts are reached for PIN screen of keyguard -->
+ <string name="kg_too_many_failed_pin_attempts_dialog_message">
+ You have incorrectly typed your PIN <xliff:g id="number">%d</xliff:g> times.
+ \n\nTry again in <xliff:g id="number">%d</xliff:g> seconds.
+ </string>
+ <!-- Message shown in dialog when max number of attempts are reached for password screen of keyguard -->
+ <string name="kg_too_many_failed_password_attempts_dialog_message">
+ You have incorrectly typed your password <xliff:g id="number">%d</xliff:g> times.
+ \n\nTry again in <xliff:g id="number">%d</xliff:g> seconds.
+ </string>
+ <string name="kg_too_many_failed_pattern_attempts_dialog_message">
+ You have incorrectly drawn your unlock pattern <xliff:g id="number">%d</xliff:g> times.
+ \n\nTry again in <xliff:g id="number">%d</xliff:g> seconds.
+ </string>
+ <!-- Message shown when user is almost at the limit of password attempts where the device will be wiped. -->
+ <string name="kg_failed_attempts_almost_at_wipe" product="tablet">
+ You have incorrectly attempted to unlock the tablet <xliff:g id="number">%d</xliff:g> times.
+ After <xliff:g id="number">%d</xliff:g> more unsuccessful attempts,
+ the tablet will be reset to factory default and all user data will be lost.
+ </string>
+ <!-- Message shown when user is almost at the limit of password attempts where the device will be wiped. -->
+ <string name="kg_failed_attempts_almost_at_wipe" product="default">
+ You have incorrectly attempted to unlock the phone <xliff:g id="number">%d</xliff:g> times.
+ After <xliff:g id="number">%d</xliff:g> more unsuccessful attempts,
+ the phone will be reset to factory default and all user data will be lost.
+ </string>
+ <!-- Message shown in dialog when user has exceeded the maximum attempts and the device will now be wiped -->
+ <string name="kg_failed_attempts_now_wiping" product="tablet">
+ You have incorrectly attempted to unlock the tablet <xliff:g id="number">%d</xliff:g> times.
+ The tablet will now be reset to factory default.
+ </string>
+ <!-- Message shown in dialog when user has exceeded the maximum attempts and the device will now be wiped -->
+ <string name="kg_failed_attempts_now_wiping" product="default">
+ You have incorrectly attempted to unlock the phone <xliff:g id="number">%d</xliff:g> times.
+ The phone will now be reset to factory default.
+ </string>
+ <!-- Message shown in dialog when user is almost at the limit where they will be
+ locked out and may have to enter an alternate username/password to unlock the phone -->
+ <string name="kg_failed_attempts_almost_at_login" product="tablet">
+ You have incorrectly drawn your unlock pattern <xliff:g id="number">%d</xliff:g> times.
+ After <xliff:g id="number">%d</xliff:g> more unsuccessful attempts,
+ you will be asked to unlock your tablet using an email account.\n\n
+ Try again in <xliff:g id="number">%d</xliff:g> seconds.
+ </string>
+ <!-- Message shown in dialog when user is almost at the limit where they will be
+ locked out and may have to enter an alternate username/password to unlock the phone -->
+ <string name="kg_failed_attempts_almost_at_login" product="default">
+ You have incorrectly drawn your unlock pattern <xliff:g id="number">%d</xliff:g> times.
+ After <xliff:g id="number">%d</xliff:g> more unsuccessful attempts,
+ you will be asked to unlock your phone using an email account.\n\n
+ Try again in <xliff:g id="number">%d</xliff:g> seconds.
+ </string>
+ <!-- Sequence of characters used to separate message strings in keyguard. Typically just em-dash
+ with spaces on either side. [CHAR LIMIT=3] -->
+ <string name="kg_text_message_separator" product="default">" \u2014 "</string>
+ <!-- The delete-widget drop target button text -->
+ <string name="kg_reordering_delete_drop_target_text">Remove</string>
+
+ <!-- Transport control strings -->
+ <!-- Shown on transport control of lockscreen. Pressing button goes to previous track. -->
+ <string name="keyguard_transport_prev_description">Previous track button</string>
+ <!-- Shown on transport control of lockscreen. Pressing button goes to next track. -->
+ <string name="keyguard_transport_next_description">Next track button</string>
+ <!-- Shown on transport control of lockscreen. Pressing button pauses playback -->
+ <string name="keyguard_transport_pause_description">Pause button</string>
+ <!-- Shown on transport control of lockscreen. Pressing button pauses playback -->
+ <string name="keyguard_transport_play_description">Play button</string>
+ <!-- Shown on transport control of lockscreen. Pressing button pauses playback -->
+ <string name="keyguard_transport_stop_description">Stop button</string>
+
+ <!-- On the keyguard screen, it shows the carrier the phone is connected to.
+ This is displayed if the phone is not connected to a carrier.-->
+ <string name="keyguard_carrier_default">No service.</string>
+
+</resources>
diff --git a/packages/Keyguard/res/values/styles.xml b/packages/Keyguard/res/values/styles.xml
new file mode 100644
index 0000000..16a3f3f
--- /dev/null
+++ b/packages/Keyguard/res/values/styles.xml
@@ -0,0 +1,55 @@
+<?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.
+*/
+-->
+
+<resources>
+ <!-- Keyguard PIN pad styles -->
+ <style name="Widget.Button.NumPadKey"
+ parent="@android:style/Widget.Button">
+ <item name="android:singleLine">true</item>
+ <item name="android:padding">6dip</item>
+ <item name="android:gravity">left|center_vertical</item>
+ <item name="android:background">?android:attr/selectableItemBackground</item>
+ <item name="android:textSize">34dp</item>
+ <item name="android:fontFamily">sans-serif</item>
+ <item name="android:textStyle">normal</item>
+ <item name="android:textColor">#ffffff</item>
+ <item name="android:paddingBottom">10dp</item>
+ <item name="android:paddingLeft">20dp</item>
+ </style>
+ <style name="TextAppearance.NumPadKey"
+ parent="@android:style/TextAppearance">
+ <item name="android:textSize">34dp</item>
+ <item name="android:fontFamily">sans-serif</item>
+ <item name="android:textStyle">normal</item>
+ <item name="android:textColor">#ffffff</item>
+ </style>
+ <style name="TextAppearance.NumPadKey.Klondike">
+ <item name="android:textSize">20dp</item>
+ <item name="android:fontFamily">sans-serif-condensed</item>
+ <item name="android:textStyle">normal</item>
+ <item name="android:textColor">#80ffffff</item>
+ </style>
+
+ <!-- Standard animations for a non-full-screen window or activity. -->
+ <style name="Animation.LockScreen" parent="@android:style/Animation">
+ <item name="android:windowEnterAnimation">@anim/lock_screen_enter</item>
+ <item name="android:windowExitAnimation">@anim/lock_screen_exit</item>
+ </style>
+
+</resources>
diff --git a/packages/Keyguard/scripts/copy_profile_icons.sh b/packages/Keyguard/scripts/copy_profile_icons.sh
new file mode 100755
index 0000000..5416101
--- /dev/null
+++ b/packages/Keyguard/scripts/copy_profile_icons.sh
@@ -0,0 +1,14 @@
+#!/bin/bash
+
+for user in `adb $* shell ls /data/system/users | grep -v xml`
+do
+ user=${user/$'\r'/}
+ adb shell mkdir /data/user/${user}/users
+ for photo in `adb $* shell ls /data/system/users | grep -v xml`
+ do
+ photo=${photo/$'\r'/}
+ adb shell mkdir /data/user/${user}/users/${photo}
+ adb pull /data/system/users/${photo}/photo.png
+ adb push photo.png /data/user/${user}/users/${photo}
+ done
+done
diff --git a/packages/Keyguard/scripts/new_merge.py b/packages/Keyguard/scripts/new_merge.py
new file mode 100755
index 0000000..70fafec
--- /dev/null
+++ b/packages/Keyguard/scripts/new_merge.py
@@ -0,0 +1,165 @@
+#!/usr/bin/env python
+
+import os
+import sys
+import difflib
+import filecmp
+import tempfile
+from optparse import OptionParser
+from subprocess import call
+from subprocess import Popen
+from subprocess import PIPE
+
+def which(program):
+ def executable(path):
+ return os.path.isfile(path) and os.access(path, os.X_OK)
+
+ path, file = os.path.split(program)
+ if path and executable(program):
+ return program
+ else:
+ for path in os.environ["PATH"].split(os.pathsep):
+ exe = os.path.join(path, program)
+ if executable(exe):
+ return exe
+ return ""
+
+DIFF_TOOLS=["meld", "kdiff3", "xdiff", "diffmerge.sh", "diff"]
+
+PROTO_SRC="./src/com/android/keyguard/"
+PROTO_RES="./res/"
+
+TEMP_FILE1="/tmp/tempFile1.txt"
+TEMP_FILE2="/tmp/tempFile2.txt"
+
+FW_SRC="../../../../frameworks/base/policy/src/com/android/internal/policy/impl/keyguard/"
+FW_RES="../../../../frameworks/base/core/res/res/"
+
+FW_PKG="com.android.internal.policy.impl.keyguard"
+PROTO_PKG="com.android.keyguard"
+
+FW_RES_IMPORT="import com.android.internal.R;"
+
+# Find a differ
+DIFF_TOOL=""
+if ("DIFF_TOOL" in os.environ and len(os.environ["DIFF_TOOL"]) > 0):
+ DIFF_TOOL=which(os.environ["DIFF_TOOL"])
+if len(DIFF_TOOL) == 0:
+ for differ in DIFF_TOOLS:
+ DIFF_TOOL=which(differ)
+ if len(DIFF_TOOL) > 0:
+ break
+
+print "Using differ", DIFF_TOOL
+
+#Anything file which contains any string in this list as a substring will be ommitted
+IGNORE=["LockHotnessActivity.java", "unified_lock_activity.xml", "optionmenu.xml"]
+WATCH=[]
+
+def dirCompare(sourceDir, destDir, ext, run_in_reverse):
+ sourceFiles = getFileList(sourceDir, ext)
+ destFiles = getFileList(destDir, ext)
+ for file in sourceFiles:
+ print file
+ destFile = destDir + file
+ sourceFile = sourceDir + file
+ if (file in destFiles):
+ if run_in_reverse:
+ prepareFileForCompare(sourceFile, TEMP_FILE1, FW_RES_IMPORT, FW_PKG, PROTO_PKG)
+ prepareFileForCompare(destFile, TEMP_FILE2, FW_RES_IMPORT,)
+ else:
+ prepareFileForCompare(destFile, TEMP_FILE1, FW_RES_IMPORT, FW_PKG, PROTO_PKG)
+ prepareFileForCompare(sourceFile, TEMP_FILE2, FW_RES_IMPORT,)
+ if (filecmp.cmp(TEMP_FILE1, TEMP_FILE2)):
+ print "File %s is the same in proto and framework" %(file)
+ else:
+ print "Running diff for: %s" %(file)
+ diff(sourceFile, destFile)
+ else:
+ print "File %s does not exist in framework" %(file)
+ if not run_in_reverse:
+ diff(sourceFile, destFile)
+
+def main(argv):
+ run_in_reverse = False
+ if len(argv) > 1:
+ if argv[1] == '--help' or argv[1] == '-h':
+ print ('Usage: %s [<commit>]' % argv[0])
+ print ('\tdiff to framework, ' +
+ 'optionally restricting to files in <commit>')
+ sys.exit(0)
+ elif argv[1] == '--reverse':
+ print "Running in reverse"
+ run_in_reverse = True
+ else:
+ print ("**** Pulling file list from: %s" % argv[1])
+ pipe = Popen(['git', 'diff', '--name-only', argv[1]], stdout=PIPE).stdout
+ for line in iter(pipe.readline,''):
+ path = line.rstrip()
+ file = path[path.rfind('/') + 1:]
+ print '**** watching: %s' % file
+ WATCH.append(file);
+ pipe.close()
+
+ if run_in_reverse:
+ #dirCompare(FW_RES, PROTO_RES, ".xml", run_in_reverse)
+ print ("**** Source files:")
+ dirCompare(FW_SRC, PROTO_SRC, ".java", run_in_reverse)
+ else:
+ #dirCompare(PROTO_RES, FW_RES, ".xml", run_in_reverse)
+ print ("**** Source files:")
+ dirCompare(PROTO_SRC, FW_SRC, ".java", run_in_reverse)
+
+ if (os.path.exists(TEMP_FILE1)):
+ os.remove(TEMP_FILE1)
+
+ if (os.path.exists(TEMP_FILE2)):
+ os.remove(TEMP_FILE2)
+
+def getFileList(rootdir, extension):
+ fileList = []
+
+ for root, subFolders, files in os.walk(rootdir):
+ for file in files:
+ f = os.path.join(root,file)
+ if (os.path.splitext(f)[1] == extension and (not inIgnore(f))):
+ fileList.append(f[len(rootdir):])
+ return fileList
+
+
+def prepareFileForCompare(inFile, outFile, skip="", replace="", withText=""):
+ # Delete the outfile, so we're starting with a new file
+ if (os.path.exists(outFile)):
+ os.remove(outFile)
+
+ fin = open(inFile)
+ fout = open(outFile, "w")
+ for line in fin:
+ # Ignore any lines containing the ignore string ("import com.android.internal.R;) and
+ # ignore any lines containing only whitespace.
+ if (line.find(skip) < 0 and len(line.strip(' \t\n\r')) > 0):
+ # For comparison, for framework files, we replace the fw package with the
+ # proto package, since these aren't relevant.
+ if len(replace) > 0:
+ fout.write(line.replace(replace, withText))
+ else:
+ fout.write(line)
+ fin.close()
+ fout.close()
+
+def diff(file1, file2):
+ call([DIFF_TOOL, file1, file2])
+
+def inIgnore(file):
+ for ignore in IGNORE:
+ if file.find(ignore) >= 0:
+ return True
+ if len(WATCH) > 0:
+ for watch in WATCH:
+ if file.find(watch) >= 0:
+ return False
+ return True
+ return False
+
+if __name__=="__main__":
+ main(sys.argv)
diff --git a/packages/Keyguard/src/com/android/keyguard/BiometricSensorUnlock.java b/packages/Keyguard/src/com/android/keyguard/BiometricSensorUnlock.java
new file mode 100644
index 0000000..230ef81
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/BiometricSensorUnlock.java
@@ -0,0 +1,68 @@
+/*
+ * 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.keyguard;
+
+import android.view.View;
+
+interface BiometricSensorUnlock {
+ /**
+ * Initializes the view provided for the biometric unlock UI to work within. The provided area
+ * completely covers the backup unlock mechanism.
+ * @param biometricUnlockView View provided for the biometric unlock UI.
+ */
+ public void initializeView(View biometricUnlockView);
+
+ /**
+ * Indicates whether the biometric unlock is running. Before
+ * {@link BiometricSensorUnlock#start} is called, isRunning() returns false. After a successful
+ * call to {@link BiometricSensorUnlock#start}, isRunning() returns true until the biometric
+ * unlock completes, {@link BiometricSensorUnlock#stop} has been called, or an error has
+ * forced the biometric unlock to stop.
+ * @return whether the biometric unlock is currently running.
+ */
+ public boolean isRunning();
+
+ /**
+ * Stops and removes the biometric unlock and shows the backup unlock
+ */
+ public void stopAndShowBackup();
+
+ /**
+ * Binds to the biometric unlock service and starts the unlock procedure. Called on the UI
+ * thread.
+ * @return false if it can't be started or the backup should be used.
+ */
+ public boolean start();
+
+ /**
+ * Stops the biometric unlock procedure and unbinds from the service. Called on the UI thread.
+ * @return whether the biometric unlock was running when called.
+ */
+ public boolean stop();
+
+ /**
+ * Cleans up any resources used by the biometric unlock.
+ */
+ public void cleanUp();
+
+ /**
+ * Gets the Device Policy Manager quality of the biometric unlock sensor
+ * (e.g., PASSWORD_QUALITY_BIOMETRIC_WEAK).
+ * @return biometric unlock sensor quality, as defined by Device Policy Manager.
+ */
+ public int getQuality();
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/CameraWidgetFrame.java b/packages/Keyguard/src/com/android/keyguard/CameraWidgetFrame.java
new file mode 100644
index 0000000..146c092
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/CameraWidgetFrame.java
@@ -0,0 +1,457 @@
+/*
+ * 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.keyguard;
+
+import android.content.Context;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.graphics.Color;
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.os.Handler;
+import android.os.SystemClock;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.WindowManager;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+import android.widget.ImageView.ScaleType;
+
+import com.android.keyguard.KeyguardActivityLauncher.CameraWidgetInfo;
+
+public class CameraWidgetFrame extends KeyguardWidgetFrame implements View.OnClickListener {
+ private static final String TAG = CameraWidgetFrame.class.getSimpleName();
+ private static final boolean DEBUG = KeyguardHostView.DEBUG;
+ private static final int WIDGET_ANIMATION_DURATION = 250; // ms
+ private static final int WIDGET_WAIT_DURATION = 650; // ms
+ private static final int RECOVERY_DELAY = 1000; // ms
+
+ interface Callbacks {
+ void onLaunchingCamera();
+ void onCameraLaunchedSuccessfully();
+ void onCameraLaunchedUnsuccessfully();
+ }
+
+ private final Handler mHandler = new Handler();
+ private final KeyguardActivityLauncher mActivityLauncher;
+ private final Callbacks mCallbacks;
+ private final CameraWidgetInfo mWidgetInfo;
+ private final WindowManager mWindowManager;
+ private final Point mRenderedSize = new Point();
+ private final int[] mTmpLoc = new int[2];
+ private final Rect mTmpRect = new Rect();
+
+ private long mLaunchCameraStart;
+ private boolean mActive;
+ private boolean mTransitioning;
+ private boolean mDown;
+
+ private FixedSizeFrameLayout mPreview;
+ private View mFullscreenPreview;
+
+ private final Runnable mTransitionToCameraRunnable = new Runnable() {
+ @Override
+ public void run() {
+ transitionToCamera();
+ }};
+
+ private final Runnable mTransitionToCameraEndAction = new Runnable() {
+ @Override
+ public void run() {
+ if (!mTransitioning)
+ return;
+ Handler worker = getWorkerHandler() != null ? getWorkerHandler() : mHandler;
+ mLaunchCameraStart = SystemClock.uptimeMillis();
+ if (DEBUG) Log.d(TAG, "Launching camera at " + mLaunchCameraStart);
+ mActivityLauncher.launchCamera(worker, mSecureCameraActivityStartedRunnable);
+ }};
+
+ private final Runnable mPostTransitionToCameraEndAction = new Runnable() {
+ @Override
+ public void run() {
+ mHandler.post(mTransitionToCameraEndAction);
+ }};
+
+ private final Runnable mRecoverRunnable = new Runnable() {
+ @Override
+ public void run() {
+ recover();
+ }};
+
+ private final Runnable mRenderRunnable = new Runnable() {
+ @Override
+ public void run() {
+ render();
+ }};
+
+ private final Runnable mSecureCameraActivityStartedRunnable = new Runnable() {
+ @Override
+ public void run() {
+ onSecureCameraActivityStarted();
+ }
+ };
+
+ private final KeyguardUpdateMonitorCallback mCallback = new KeyguardUpdateMonitorCallback() {
+ private boolean mShowing;
+ void onKeyguardVisibilityChanged(boolean showing) {
+ if (mShowing == showing)
+ return;
+ mShowing = showing;
+ CameraWidgetFrame.this.onKeyguardVisibilityChanged(mShowing);
+ };
+ };
+
+ private static final class FixedSizeFrameLayout extends FrameLayout {
+ int width;
+ int height;
+
+ FixedSizeFrameLayout(Context context) {
+ super(context);
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ measureChildren(
+ MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
+ MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
+ setMeasuredDimension(width, height);
+ }
+ }
+
+ private CameraWidgetFrame(Context context, Callbacks callbacks,
+ KeyguardActivityLauncher activityLauncher,
+ CameraWidgetInfo widgetInfo, View previewWidget) {
+ super(context);
+ mCallbacks = callbacks;
+ mActivityLauncher = activityLauncher;
+ mWidgetInfo = widgetInfo;
+ mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
+ KeyguardUpdateMonitor.getInstance(context).registerCallback(mCallback);
+
+ mPreview = new FixedSizeFrameLayout(context);
+ mPreview.addView(previewWidget);
+ addView(mPreview);
+
+ View clickBlocker = new View(context);
+ clickBlocker.setBackgroundColor(Color.TRANSPARENT);
+ clickBlocker.setOnClickListener(this);
+ addView(clickBlocker);
+
+ setContentDescription(context.getString(R.string.keyguard_accessibility_camera));
+ if (DEBUG) Log.d(TAG, "new CameraWidgetFrame instance " + instanceId());
+ }
+
+ public static CameraWidgetFrame create(Context context, Callbacks callbacks,
+ KeyguardActivityLauncher launcher) {
+ if (context == null || callbacks == null || launcher == null)
+ return null;
+
+ CameraWidgetInfo widgetInfo = launcher.getCameraWidgetInfo();
+ if (widgetInfo == null)
+ return null;
+ View previewWidget = getPreviewWidget(context, widgetInfo);
+ if (previewWidget == null)
+ return null;
+
+ return new CameraWidgetFrame(context, callbacks, launcher, widgetInfo, previewWidget);
+ }
+
+ private static View getPreviewWidget(Context context, CameraWidgetInfo widgetInfo) {
+ return widgetInfo.layoutId > 0 ?
+ inflateWidgetView(context, widgetInfo) :
+ inflateGenericWidgetView(context);
+ }
+
+ private static View inflateWidgetView(Context context, CameraWidgetInfo widgetInfo) {
+ if (DEBUG) Log.d(TAG, "inflateWidgetView: " + widgetInfo.contextPackage);
+ View widgetView = null;
+ Exception exception = null;
+ try {
+ Context cameraContext = context.createPackageContext(
+ widgetInfo.contextPackage, Context.CONTEXT_RESTRICTED);
+ LayoutInflater cameraInflater = (LayoutInflater)
+ cameraContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ cameraInflater = cameraInflater.cloneInContext(cameraContext);
+ widgetView = cameraInflater.inflate(widgetInfo.layoutId, null, false);
+ } catch (NameNotFoundException e) {
+ exception = e;
+ } catch (RuntimeException e) {
+ exception = e;
+ }
+ if (exception != null) {
+ Log.w(TAG, "Error creating camera widget view", exception);
+ }
+ return widgetView;
+ }
+
+ private static View inflateGenericWidgetView(Context context) {
+ if (DEBUG) Log.d(TAG, "inflateGenericWidgetView");
+ ImageView iv = new ImageView(context);
+ iv.setImageResource(R.drawable.ic_lockscreen_camera);
+ iv.setScaleType(ScaleType.CENTER);
+ iv.setBackgroundColor(Color.argb(127, 0, 0, 0));
+ return iv;
+ }
+
+ private void render() {
+ final View root = getRootView();
+ final int width = root.getWidth();
+ final int height = root.getHeight();
+ if (mRenderedSize.x == width && mRenderedSize.y == height) {
+ if (DEBUG) Log.d(TAG, String.format("Already rendered at size=%sx%s", width, height));
+ return;
+ }
+ if (width == 0 || height == 0) {
+ return;
+ }
+
+ mPreview.width = width;
+ mPreview.height = height;
+ mPreview.requestLayout();
+
+ final int thisWidth = getWidth() - getPaddingLeft() - getPaddingRight();
+ final int thisHeight = getHeight() - getPaddingTop() - getPaddingBottom();
+
+ final float pvScaleX = (float) thisWidth / width;
+ final float pvScaleY = (float) thisHeight / height;
+ final float pvScale = Math.min(pvScaleX, pvScaleY);
+
+ final int pvWidth = (int) (pvScale * width);
+ final int pvHeight = (int) (pvScale * height);
+
+ final float pvTransX = pvWidth < thisWidth ? (thisWidth - pvWidth) / 2 : 0;
+ final float pvTransY = pvHeight < thisHeight ? (thisHeight - pvHeight) / 2 : 0;
+
+ mPreview.setPivotX(0);
+ mPreview.setPivotY(0);
+ mPreview.setScaleX(pvScale);
+ mPreview.setScaleY(pvScale);
+ mPreview.setTranslationX(pvTransX);
+ mPreview.setTranslationY(pvTransY);
+
+ mRenderedSize.set(width, height);
+ if (DEBUG) Log.d(TAG, String.format("Rendered camera widget size=%sx%s instance=%s",
+ width, height, instanceId()));
+ }
+
+ private void transitionToCamera() {
+ if (mTransitioning || mDown) return;
+
+ mTransitioning = true;
+
+ enableWindowExitAnimation(false);
+
+ mPreview.getLocationInWindow(mTmpLoc);
+ final float pvHeight = mPreview.getHeight() * mPreview.getScaleY();
+ final float pvCenter = mTmpLoc[1] + pvHeight / 2f;
+
+ final ViewGroup root = (ViewGroup) getRootView();
+ if (mFullscreenPreview == null) {
+ mFullscreenPreview = getPreviewWidget(mContext, mWidgetInfo);
+ mFullscreenPreview.setClickable(false);
+ root.addView(mFullscreenPreview);
+ }
+
+ root.getWindowVisibleDisplayFrame(mTmpRect);
+ final float fsHeight = mTmpRect.height();
+ final float fsCenter = mTmpRect.top + fsHeight / 2;
+
+ final float fsScaleY = pvHeight / fsHeight;
+ final float fsTransY = pvCenter - fsCenter;
+ final float fsScaleX = mPreview.getScaleX();
+
+ mPreview.setVisibility(View.GONE);
+ mFullscreenPreview.setVisibility(View.VISIBLE);
+ mFullscreenPreview.setTranslationY(fsTransY);
+ mFullscreenPreview.setScaleX(fsScaleX);
+ mFullscreenPreview.setScaleY(fsScaleY);
+ mFullscreenPreview
+ .animate()
+ .scaleX(1)
+ .scaleY(1)
+ .translationX(0)
+ .translationY(0)
+ .setDuration(WIDGET_ANIMATION_DURATION)
+ .withEndAction(mPostTransitionToCameraEndAction)
+ .start();
+ mCallbacks.onLaunchingCamera();
+ }
+
+ private void recover() {
+ if (DEBUG) Log.d(TAG, "recovering at " + SystemClock.uptimeMillis());
+ mCallbacks.onCameraLaunchedUnsuccessfully();
+ reset();
+ }
+
+ @Override
+ public void setOnLongClickListener(OnLongClickListener l) {
+ // ignore
+ }
+
+ @Override
+ public void onClick(View v) {
+ if (DEBUG) Log.d(TAG, "clicked");
+ if (mTransitioning) return;
+ if (mActive) {
+ cancelTransitionToCamera();
+ transitionToCamera();
+ }
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ if (DEBUG) Log.d(TAG, "onDetachedFromWindow: instance " + instanceId()
+ + " at " + SystemClock.uptimeMillis());
+ super.onDetachedFromWindow();
+ KeyguardUpdateMonitor.getInstance(mContext).removeCallback(mCallback);
+ cancelTransitionToCamera();
+ mHandler.removeCallbacks(mRecoverRunnable);
+ }
+
+ @Override
+ public void onActive(boolean isActive) {
+ mActive = isActive;
+ if (mActive) {
+ rescheduleTransitionToCamera();
+ } else {
+ reset();
+ }
+ }
+
+ @Override
+ public boolean onUserInteraction(MotionEvent event) {
+ if (mTransitioning) {
+ if (DEBUG) Log.d(TAG, "onUserInteraction eaten: mTransitioning");
+ return true;
+ }
+
+ getLocationOnScreen(mTmpLoc);
+ int rawBottom = mTmpLoc[1] + getHeight();
+ if (event.getRawY() > rawBottom) {
+ if (DEBUG) Log.d(TAG, "onUserInteraction eaten: below widget");
+ return true;
+ }
+
+ int action = event.getAction();
+ mDown = action == MotionEvent.ACTION_DOWN || action == MotionEvent.ACTION_MOVE;
+ if (mActive) {
+ rescheduleTransitionToCamera();
+ }
+ if (DEBUG) Log.d(TAG, "onUserInteraction observed, not eaten");
+ return false;
+ }
+
+ @Override
+ protected void onFocusLost() {
+ if (DEBUG) Log.d(TAG, "onFocusLost at " + SystemClock.uptimeMillis());
+ cancelTransitionToCamera();
+ super.onFocusLost();
+ }
+
+ public void onScreenTurnedOff() {
+ if (DEBUG) Log.d(TAG, "onScreenTurnedOff");
+ reset();
+ }
+
+ private void rescheduleTransitionToCamera() {
+ if (DEBUG) Log.d(TAG, "rescheduleTransitionToCamera at " + SystemClock.uptimeMillis());
+ mHandler.removeCallbacks(mTransitionToCameraRunnable);
+ mHandler.postDelayed(mTransitionToCameraRunnable, WIDGET_WAIT_DURATION);
+ }
+
+ private void cancelTransitionToCamera() {
+ if (DEBUG) Log.d(TAG, "cancelTransitionToCamera at " + SystemClock.uptimeMillis());
+ mHandler.removeCallbacks(mTransitionToCameraRunnable);
+ }
+
+ private void onCameraLaunched() {
+ mCallbacks.onCameraLaunchedSuccessfully();
+ reset();
+ }
+
+ private void reset() {
+ if (DEBUG) Log.d(TAG, "reset at " + SystemClock.uptimeMillis());
+ mLaunchCameraStart = 0;
+ mTransitioning = false;
+ mDown = false;
+ cancelTransitionToCamera();
+ mHandler.removeCallbacks(mRecoverRunnable);
+ mPreview.setVisibility(View.VISIBLE);
+ if (mFullscreenPreview != null) {
+ mFullscreenPreview.animate().cancel();
+ mFullscreenPreview.setVisibility(View.GONE);
+ }
+ enableWindowExitAnimation(true);
+ }
+
+ @Override
+ protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+ if (DEBUG) Log.d(TAG, String.format("onSizeChanged new=%sx%s old=%sx%s at %s",
+ w, h, oldw, oldh, SystemClock.uptimeMillis()));
+ mHandler.post(mRenderRunnable);
+ super.onSizeChanged(w, h, oldw, oldh);
+ }
+
+ @Override
+ public void onBouncerShowing(boolean showing) {
+ if (showing) {
+ mTransitioning = false;
+ mHandler.post(mRecoverRunnable);
+ }
+ }
+
+ private void enableWindowExitAnimation(boolean isEnabled) {
+ View root = getRootView();
+ ViewGroup.LayoutParams lp = root.getLayoutParams();
+ if (!(lp instanceof WindowManager.LayoutParams))
+ return;
+ WindowManager.LayoutParams wlp = (WindowManager.LayoutParams) lp;
+ int newWindowAnimations = isEnabled ? R.style.Animation_LockScreen : 0;
+ if (newWindowAnimations != wlp.windowAnimations) {
+ if (DEBUG) Log.d(TAG, "setting windowAnimations to: " + newWindowAnimations
+ + " at " + SystemClock.uptimeMillis());
+ wlp.windowAnimations = newWindowAnimations;
+ mWindowManager.updateViewLayout(root, wlp);
+ }
+ }
+
+ private void onKeyguardVisibilityChanged(boolean showing) {
+ if (DEBUG) Log.d(TAG, "onKeyguardVisibilityChanged " + showing
+ + " at " + SystemClock.uptimeMillis());
+ if (mTransitioning && !showing) {
+ mTransitioning = false;
+ mHandler.removeCallbacks(mRecoverRunnable);
+ if (mLaunchCameraStart > 0) {
+ long launchTime = SystemClock.uptimeMillis() - mLaunchCameraStart;
+ if (DEBUG) Log.d(TAG, String.format("Camera took %sms to launch", launchTime));
+ mLaunchCameraStart = 0;
+ onCameraLaunched();
+ }
+ }
+ }
+
+ private void onSecureCameraActivityStarted() {
+ if (DEBUG) Log.d(TAG, "onSecureCameraActivityStarted at " + SystemClock.uptimeMillis());
+ mHandler.postDelayed(mRecoverRunnable, RECOVERY_DELAY);
+ }
+
+ private String instanceId() {
+ return Integer.toHexString(hashCode());
+ }
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/CarrierText.java b/packages/Keyguard/src/com/android/keyguard/CarrierText.java
new file mode 100644
index 0000000..9f0a042
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/CarrierText.java
@@ -0,0 +1,257 @@
+/*
+ * 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.keyguard;
+
+import android.content.Context;
+import android.text.TextUtils;
+import android.util.AttributeSet;
+import android.widget.TextView;
+
+import com.android.internal.telephony.IccCardConstants;
+import com.android.internal.telephony.IccCardConstants.State;
+import com.android.internal.widget.LockPatternUtils;
+
+public class CarrierText extends TextView {
+ private static CharSequence mSeparator;
+
+ private LockPatternUtils mLockPatternUtils;
+
+ private KeyguardUpdateMonitorCallback mCallback = new KeyguardUpdateMonitorCallback() {
+ private CharSequence mPlmn;
+ private CharSequence mSpn;
+ private State mSimState;
+
+ @Override
+ public void onRefreshCarrierInfo(CharSequence plmn, CharSequence spn) {
+ mPlmn = plmn;
+ mSpn = spn;
+ updateCarrierText(mSimState, mPlmn, mSpn);
+ }
+
+ @Override
+ public void onSimStateChanged(IccCardConstants.State simState) {
+ mSimState = simState;
+ updateCarrierText(mSimState, mPlmn, mSpn);
+ }
+ };
+ /**
+ * The status of this lock screen. Primarily used for widgets on LockScreen.
+ */
+ private static enum StatusMode {
+ Normal, // Normal case (sim card present, it's not locked)
+ NetworkLocked, // SIM card is 'network locked'.
+ SimMissing, // SIM card is missing.
+ SimMissingLocked, // SIM card is missing, and device isn't provisioned; don't allow access
+ SimPukLocked, // SIM card is PUK locked because SIM entered wrong too many times
+ SimLocked, // SIM card is currently locked
+ SimPermDisabled, // SIM card is permanently disabled due to PUK unlock failure
+ SimNotReady; // SIM is not ready yet. May never be on devices w/o a SIM.
+ }
+
+ public CarrierText(Context context) {
+ this(context, null);
+ }
+
+ public CarrierText(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ mLockPatternUtils = new LockPatternUtils(mContext);
+ }
+
+ protected void updateCarrierText(State simState, CharSequence plmn, CharSequence spn) {
+ CharSequence text = getCarrierTextForSimState(simState, plmn, spn);
+ if (KeyguardViewManager.USE_UPPER_CASE) {
+ setText(text != null ? text.toString().toUpperCase() : null);
+ } else {
+ setText(text);
+ }
+ }
+
+ @Override
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+ mSeparator = getResources().getString(R.string.kg_text_message_separator);
+ setSelected(true); // Allow marquee to work.
+ }
+
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mCallback);
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ KeyguardUpdateMonitor.getInstance(mContext).removeCallback(mCallback);
+ }
+
+ /**
+ * Top-level function for creating carrier text. Makes text based on simState, PLMN
+ * and SPN as well as device capabilities, such as being emergency call capable.
+ *
+ * @param simState
+ * @param plmn
+ * @param spn
+ * @return
+ */
+ private CharSequence getCarrierTextForSimState(IccCardConstants.State simState,
+ CharSequence plmn, CharSequence spn) {
+ CharSequence carrierText = null;
+ StatusMode status = getStatusForIccState(simState);
+ switch (status) {
+ case Normal:
+ carrierText = concatenate(plmn, spn);
+ break;
+
+ case SimNotReady:
+ carrierText = null; // nothing to display yet.
+ break;
+
+ case NetworkLocked:
+ carrierText = makeCarrierStringOnEmergencyCapable(
+ mContext.getText(R.string.keyguard_network_locked_message), plmn);
+ break;
+
+ case SimMissing:
+ // Shows "No SIM card | Emergency calls only" on devices that are voice-capable.
+ // This depends on mPlmn containing the text "Emergency calls only" when the radio
+ // has some connectivity. Otherwise, it should be null or empty and just show
+ // "No SIM card"
+ carrierText = makeCarrierStringOnEmergencyCapable(
+ getContext().getText(R.string.keyguard_missing_sim_message_short),
+ plmn);
+ break;
+
+ case SimPermDisabled:
+ carrierText = getContext().getText(
+ R.string.keyguard_permanent_disabled_sim_message_short);
+ break;
+
+ case SimMissingLocked:
+ carrierText = makeCarrierStringOnEmergencyCapable(
+ getContext().getText(R.string.keyguard_missing_sim_message_short),
+ plmn);
+ break;
+
+ case SimLocked:
+ carrierText = makeCarrierStringOnEmergencyCapable(
+ getContext().getText(R.string.keyguard_sim_locked_message),
+ plmn);
+ break;
+
+ case SimPukLocked:
+ carrierText = makeCarrierStringOnEmergencyCapable(
+ getContext().getText(R.string.keyguard_sim_puk_locked_message),
+ plmn);
+ break;
+ }
+
+ return carrierText;
+ }
+
+ /*
+ * Add emergencyCallMessage to carrier string only if phone supports emergency calls.
+ */
+ private CharSequence makeCarrierStringOnEmergencyCapable(
+ CharSequence simMessage, CharSequence emergencyCallMessage) {
+ if (mLockPatternUtils.isEmergencyCallCapable()) {
+ return concatenate(simMessage, emergencyCallMessage);
+ }
+ return simMessage;
+ }
+
+ /**
+ * Determine the current status of the lock screen given the SIM state and other stuff.
+ */
+ private StatusMode getStatusForIccState(IccCardConstants.State simState) {
+ // Since reading the SIM may take a while, we assume it is present until told otherwise.
+ if (simState == null) {
+ return StatusMode.Normal;
+ }
+
+ final boolean missingAndNotProvisioned =
+ !KeyguardUpdateMonitor.getInstance(mContext).isDeviceProvisioned()
+ && (simState == IccCardConstants.State.ABSENT ||
+ simState == IccCardConstants.State.PERM_DISABLED);
+
+ // Assume we're NETWORK_LOCKED if not provisioned
+ simState = missingAndNotProvisioned ? IccCardConstants.State.NETWORK_LOCKED : simState;
+ switch (simState) {
+ case ABSENT:
+ return StatusMode.SimMissing;
+ case NETWORK_LOCKED:
+ return StatusMode.SimMissingLocked;
+ case NOT_READY:
+ return StatusMode.SimNotReady;
+ case PIN_REQUIRED:
+ return StatusMode.SimLocked;
+ case PUK_REQUIRED:
+ return StatusMode.SimPukLocked;
+ case READY:
+ return StatusMode.Normal;
+ case PERM_DISABLED:
+ return StatusMode.SimPermDisabled;
+ case UNKNOWN:
+ return StatusMode.SimMissing;
+ }
+ return StatusMode.SimMissing;
+ }
+
+ private static CharSequence concatenate(CharSequence plmn, CharSequence spn) {
+ final boolean plmnValid = !TextUtils.isEmpty(plmn);
+ final boolean spnValid = !TextUtils.isEmpty(spn);
+ if (plmnValid && spnValid) {
+ return new StringBuilder().append(plmn).append(mSeparator).append(spn).toString();
+ } else if (plmnValid) {
+ return plmn;
+ } else if (spnValid) {
+ return spn;
+ } else {
+ return "";
+ }
+ }
+
+ private CharSequence getCarrierHelpTextForSimState(IccCardConstants.State simState,
+ String plmn, String spn) {
+ int carrierHelpTextId = 0;
+ StatusMode status = getStatusForIccState(simState);
+ switch (status) {
+ case NetworkLocked:
+ carrierHelpTextId = R.string.keyguard_instructions_when_pattern_disabled;
+ break;
+
+ case SimMissing:
+ carrierHelpTextId = R.string.keyguard_missing_sim_instructions_long;
+ break;
+
+ case SimPermDisabled:
+ carrierHelpTextId = R.string.keyguard_permanent_disabled_sim_instructions;
+ break;
+
+ case SimMissingLocked:
+ carrierHelpTextId = R.string.keyguard_missing_sim_instructions;
+ break;
+
+ case Normal:
+ case SimLocked:
+ case SimPukLocked:
+ break;
+ }
+
+ return mContext.getText(carrierHelpTextId);
+ }
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/ChallengeLayout.java b/packages/Keyguard/src/com/android/keyguard/ChallengeLayout.java
new file mode 100644
index 0000000..677f1f1
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/ChallengeLayout.java
@@ -0,0 +1,97 @@
+/*
+ * 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.keyguard;
+
+/**
+ * Interface implemented by ViewGroup-derived layouts that implement
+ * special logic for presenting security challenges to the user.
+ */
+public interface ChallengeLayout {
+ /**
+ * @return true if the security challenge area of this layout is currently visible
+ */
+ boolean isChallengeShowing();
+
+ /**
+ * @return true if the challenge area significantly overlaps other content
+ */
+ boolean isChallengeOverlapping();
+
+ /**
+ * Show or hide the challenge layout.
+ *
+ * If you want to show the challenge layout in bouncer mode where applicable,
+ * use {@link #showBouncer()} instead.
+ *
+ * @param b true to show, false to hide
+ */
+ void showChallenge(boolean b);
+
+ /**
+ * Show the bouncer challenge. This may block access to other child views.
+ */
+ void showBouncer();
+
+ /**
+ * Hide the bouncer challenge if it is currently showing.
+ * This may restore previously blocked access to other child views.
+ */
+ void hideBouncer();
+
+ /**
+ * Returns true if the challenge is currently in bouncer mode,
+ * potentially blocking access to other child views.
+ */
+ boolean isBouncing();
+
+ /**
+ * Returns the duration of the bounce animation.
+ */
+ int getBouncerAnimationDuration();
+
+ /**
+ * Set a listener that will respond to changes in bouncer state.
+ *
+ * @param listener listener to register
+ */
+ void setOnBouncerStateChangedListener(OnBouncerStateChangedListener listener);
+
+ /**
+ * Listener interface that reports changes in bouncer state.
+ * The bouncer is
+ */
+ public interface OnBouncerStateChangedListener {
+ /**
+ * Called when the bouncer state changes.
+ * The bouncer is activated when the user must pass a security challenge
+ * to proceed with the requested action.
+ *
+ * <p>This differs from simply showing or hiding the security challenge
+ * as the bouncer will prevent interaction with other elements of the UI.
+ * If the user attempts to escape from the bouncer, it will be dismissed,
+ * this method will be called with false as the parameter, and the action
+ * should be canceled. If the security component reports a successful
+ * authentication and the containing code calls hideBouncer() as a result,
+ * this method will also be called with a false parameter. It is up to the
+ * caller of hideBouncer to be ready for this.</p>
+ *
+ * @param bouncerActive true if the bouncer is now active,
+ * false if the bouncer was dismissed.
+ */
+ public void onBouncerStateChanged(boolean bouncerActive);
+ }
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/CheckLongPressHelper.java b/packages/Keyguard/src/com/android/keyguard/CheckLongPressHelper.java
new file mode 100644
index 0000000..52e7cd5
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/CheckLongPressHelper.java
@@ -0,0 +1,82 @@
+/*
+ * 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.keyguard;
+
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewConfiguration;
+
+public class CheckLongPressHelper {
+ private View mView;
+ private boolean mHasPerformedLongPress;
+ private CheckForLongPress mPendingCheckForLongPress;
+ private float mDownX, mDownY;
+ private int mLongPressTimeout;
+ private int mScaledTouchSlop;
+
+ class CheckForLongPress implements Runnable {
+ public void run() {
+ if ((mView.getParent() != null) && mView.hasWindowFocus()
+ && !mHasPerformedLongPress) {
+ if (mView.performLongClick()) {
+ mView.setPressed(false);
+ mHasPerformedLongPress = true;
+ }
+ }
+ }
+ }
+
+ public CheckLongPressHelper(View v) {
+ mScaledTouchSlop = ViewConfiguration.get(v.getContext()).getScaledTouchSlop();
+ mLongPressTimeout = ViewConfiguration.getLongPressTimeout();
+ mView = v;
+ }
+
+ public void postCheckForLongPress(MotionEvent ev) {
+ mDownX = ev.getX();
+ mDownY = ev.getY();
+ mHasPerformedLongPress = false;
+
+ if (mPendingCheckForLongPress == null) {
+ mPendingCheckForLongPress = new CheckForLongPress();
+ }
+ mView.postDelayed(mPendingCheckForLongPress, mLongPressTimeout);
+ }
+
+ public void onMove(MotionEvent ev) {
+ float x = ev.getX();
+ float y = ev.getY();
+ boolean xMoved = Math.abs(mDownX - x) > mScaledTouchSlop;
+ boolean yMoved = Math.abs(mDownY - y) > mScaledTouchSlop;
+
+ if (xMoved || yMoved) {
+ cancelLongPress();
+ }
+ }
+
+ public void cancelLongPress() {
+ mHasPerformedLongPress = false;
+ if (mPendingCheckForLongPress != null) {
+ mView.removeCallbacks(mPendingCheckForLongPress);
+ mPendingCheckForLongPress = null;
+ }
+ }
+
+ public boolean hasPerformedLongPress() {
+ return mHasPerformedLongPress;
+ }
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/ClockView.java b/packages/Keyguard/src/com/android/keyguard/ClockView.java
new file mode 100644
index 0000000..c2930cb
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/ClockView.java
@@ -0,0 +1,223 @@
+/*
+ * 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.keyguard;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.database.ContentObserver;
+import android.graphics.Typeface;
+import android.os.Handler;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.text.format.DateFormat;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.RelativeLayout;
+import android.widget.TextView;
+
+import java.lang.ref.WeakReference;
+import java.text.DateFormatSymbols;
+import java.util.Calendar;
+
+/**
+ * Displays the time
+ */
+public class ClockView extends RelativeLayout {
+ private static final String ANDROID_CLOCK_FONT_FILE = "/system/fonts/AndroidClock.ttf";
+ private final static String M12 = "h:mm";
+ private final static String M24 = "kk:mm";
+
+ private Calendar mCalendar;
+ private String mFormat;
+ private TextView mTimeView;
+ private AmPm mAmPm;
+ private ContentObserver mFormatChangeObserver;
+ private int mAttached = 0; // for debugging - tells us whether attach/detach is unbalanced
+
+ /* called by system on minute ticks */
+ private final Handler mHandler = new Handler();
+ private BroadcastReceiver mIntentReceiver;
+
+ private static class TimeChangedReceiver extends BroadcastReceiver {
+ private WeakReference<ClockView> mClock;
+ private Context mContext;
+
+ public TimeChangedReceiver(ClockView clock) {
+ mClock = new WeakReference<ClockView>(clock);
+ mContext = clock.getContext();
+ }
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ // Post a runnable to avoid blocking the broadcast.
+ final boolean timezoneChanged =
+ intent.getAction().equals(Intent.ACTION_TIMEZONE_CHANGED);
+ final ClockView clock = mClock.get();
+ if (clock != null) {
+ clock.mHandler.post(new Runnable() {
+ public void run() {
+ if (timezoneChanged) {
+ clock.mCalendar = Calendar.getInstance();
+ }
+ clock.updateTime();
+ }
+ });
+ } else {
+ try {
+ mContext.unregisterReceiver(this);
+ } catch (RuntimeException e) {
+ // Shouldn't happen
+ }
+ }
+ }
+ };
+
+ static class AmPm {
+ private TextView mAmPmTextView;
+ private String mAmString, mPmString;
+
+ AmPm(View parent, Typeface tf) {
+ // No longer used, uncomment if we decide to use AM/PM indicator again
+ // mAmPmTextView = (TextView) parent.findViewById(R.id.am_pm);
+ if (mAmPmTextView != null && tf != null) {
+ mAmPmTextView.setTypeface(tf);
+ }
+
+ String[] ampm = new DateFormatSymbols().getAmPmStrings();
+ mAmString = ampm[0];
+ mPmString = ampm[1];
+ }
+
+ void setShowAmPm(boolean show) {
+ if (mAmPmTextView != null) {
+ mAmPmTextView.setVisibility(show ? View.VISIBLE : View.GONE);
+ }
+ }
+
+ void setIsMorning(boolean isMorning) {
+ if (mAmPmTextView != null) {
+ mAmPmTextView.setText(isMorning ? mAmString : mPmString);
+ }
+ }
+ }
+
+ private static class FormatChangeObserver extends ContentObserver {
+ private WeakReference<ClockView> mClock;
+ private Context mContext;
+ public FormatChangeObserver(ClockView clock) {
+ super(new Handler());
+ mClock = new WeakReference<ClockView>(clock);
+ mContext = clock.getContext();
+ }
+ @Override
+ public void onChange(boolean selfChange) {
+ ClockView digitalClock = mClock.get();
+ if (digitalClock != null) {
+ digitalClock.setDateFormat();
+ digitalClock.updateTime();
+ } else {
+ try {
+ mContext.getContentResolver().unregisterContentObserver(this);
+ } catch (RuntimeException e) {
+ // Shouldn't happen
+ }
+ }
+ }
+ }
+
+ public ClockView(Context context) {
+ this(context, null);
+ }
+
+ public ClockView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ @Override
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+ mTimeView = (TextView) findViewById(R.id.clock_text);
+ mTimeView.setTypeface(Typeface.createFromFile(ANDROID_CLOCK_FONT_FILE));
+ mAmPm = new AmPm(this, null);
+ mCalendar = Calendar.getInstance();
+ setDateFormat();
+ }
+
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+
+ mAttached++;
+
+ /* monitor time ticks, time changed, timezone */
+ if (mIntentReceiver == null) {
+ mIntentReceiver = new TimeChangedReceiver(this);
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(Intent.ACTION_TIME_TICK);
+ filter.addAction(Intent.ACTION_TIME_CHANGED);
+ filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
+ mContext.registerReceiverAsUser(mIntentReceiver, UserHandle.OWNER, filter, null, null );
+ }
+
+ /* monitor 12/24-hour display preference */
+ if (mFormatChangeObserver == null) {
+ mFormatChangeObserver = new FormatChangeObserver(this);
+ mContext.getContentResolver().registerContentObserver(
+ Settings.System.CONTENT_URI, true, mFormatChangeObserver);
+ }
+
+ updateTime();
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+
+ mAttached--;
+
+ if (mIntentReceiver != null) {
+ mContext.unregisterReceiver(mIntentReceiver);
+ }
+ if (mFormatChangeObserver != null) {
+ mContext.getContentResolver().unregisterContentObserver(
+ mFormatChangeObserver);
+ }
+
+ mFormatChangeObserver = null;
+ mIntentReceiver = null;
+ }
+
+ void updateTime(Calendar c) {
+ mCalendar = c;
+ updateTime();
+ }
+
+ public void updateTime() {
+ mCalendar.setTimeInMillis(System.currentTimeMillis());
+
+ CharSequence newTime = DateFormat.format(mFormat, mCalendar);
+ mTimeView.setText(newTime);
+ mAmPm.setIsMorning(mCalendar.get(Calendar.AM_PM) == 0);
+ }
+
+ private void setDateFormat() {
+ mFormat = android.text.format.DateFormat.is24HourFormat(getContext()) ? M24 : M12;
+ mAmPm.setShowAmPm(mFormat.equals(M12));
+ }
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/EmergencyButton.java b/packages/Keyguard/src/com/android/keyguard/EmergencyButton.java
new file mode 100644
index 0000000..3871cea
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/EmergencyButton.java
@@ -0,0 +1,130 @@
+/*
+ * 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 com.android.keyguard;
+
+import android.content.Context;
+import android.content.Intent;
+import android.os.PowerManager;
+import android.os.SystemClock;
+import android.telephony.TelephonyManager;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.Button;
+
+import com.android.internal.telephony.IccCardConstants.State;
+import com.android.internal.widget.LockPatternUtils;
+
+/**
+ * This class implements a smart emergency button that updates itself based
+ * on telephony state. When the phone is idle, it is an emergency call button.
+ * When there's a call in progress, it presents an appropriate message and
+ * allows the user to return to the call.
+ */
+public class EmergencyButton extends Button {
+
+ private static final int EMERGENCY_CALL_TIMEOUT = 10000; // screen timeout after starting e.d.
+ private static final String ACTION_EMERGENCY_DIAL = "com.android.phone.EmergencyDialer.DIAL";
+
+ KeyguardUpdateMonitorCallback mInfoCallback = new KeyguardUpdateMonitorCallback() {
+
+ @Override
+ public void onSimStateChanged(State simState) {
+ int phoneState = KeyguardUpdateMonitor.getInstance(mContext).getPhoneState();
+ updateEmergencyCallButton(simState, phoneState);
+ }
+
+ void onPhoneStateChanged(int phoneState) {
+ State simState = KeyguardUpdateMonitor.getInstance(mContext).getSimState();
+ updateEmergencyCallButton(simState, phoneState);
+ };
+ };
+ private LockPatternUtils mLockPatternUtils;
+ private PowerManager mPowerManager;
+
+ public EmergencyButton(Context context) {
+ this(context, null);
+ }
+
+ public EmergencyButton(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mInfoCallback);
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ KeyguardUpdateMonitor.getInstance(mContext).removeCallback(mInfoCallback);
+ }
+
+ @Override
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+ mLockPatternUtils = new LockPatternUtils(mContext);
+ mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
+ setOnClickListener(new OnClickListener() {
+ public void onClick(View v) {
+ takeEmergencyCallAction();
+ }
+ });
+ int phoneState = KeyguardUpdateMonitor.getInstance(mContext).getPhoneState();
+ State simState = KeyguardUpdateMonitor.getInstance(mContext).getSimState();
+ updateEmergencyCallButton(simState, phoneState);
+ }
+
+ /**
+ * Shows the emergency dialer or returns the user to the existing call.
+ */
+ public void takeEmergencyCallAction() {
+ // TODO: implement a shorter timeout once new PowerManager API is ready.
+ // should be the equivalent to the old userActivity(EMERGENCY_CALL_TIMEOUT)
+ mPowerManager.userActivity(SystemClock.uptimeMillis(), true);
+ 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);
+ }
+ }
+
+ private void updateEmergencyCallButton(State simState, int phoneState) {
+ boolean enabled = false;
+ if (phoneState == TelephonyManager.CALL_STATE_OFFHOOK) {
+ enabled = true; // always show "return to call" if phone is off-hook
+ } else if (mLockPatternUtils.isEmergencyCallCapable()) {
+ boolean simLocked = KeyguardUpdateMonitor.getInstance(mContext).isSimLocked();
+ if (simLocked) {
+ // Some countries can't handle emergency calls while SIM is locked.
+ enabled = mLockPatternUtils.isEmergencyCallEnabledWhileSimLocked();
+ } else {
+ // True if we need to show a secure screen (pin/pattern/SIM pin/SIM puk);
+ // hides emergency button on "Slide" screen if device is not secure.
+ enabled = mLockPatternUtils.isSecure();
+ }
+ }
+ mLockPatternUtils.updateEmergencyCallButtonState(this, phoneState, enabled,
+ KeyguardViewManager.USE_UPPER_CASE, false);
+ }
+
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/FaceUnlock.java b/packages/Keyguard/src/com/android/keyguard/FaceUnlock.java
new file mode 100644
index 0000000..689366b
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/FaceUnlock.java
@@ -0,0 +1,462 @@
+/*
+ * 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.keyguard;
+
+import com.android.internal.policy.IFaceLockCallback;
+import com.android.internal.policy.IFaceLockInterface;
+import com.android.internal.widget.LockPatternUtils;
+
+import android.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.os.PowerManager;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.util.Log;
+import android.view.View;
+
+public class FaceUnlock implements BiometricSensorUnlock, Handler.Callback {
+
+ private static final boolean DEBUG = false;
+ private static final String TAG = "FULLockscreen";
+
+ private final Context mContext;
+ private final LockPatternUtils mLockPatternUtils;
+
+ // TODO: is mServiceRunning needed or can we just use mIsRunning or check if mService is null?
+ private boolean mServiceRunning = false;
+ // TODO: now that the code has been restructure to do almost all operations from a handler, this
+ // lock may no longer be necessary.
+ private final Object mServiceRunningLock = new Object();
+ private IFaceLockInterface mService;
+ private boolean mBoundToService = false;
+ private View mFaceUnlockView;
+
+ private Handler mHandler;
+ private final int MSG_SERVICE_CONNECTED = 0;
+ private final int MSG_SERVICE_DISCONNECTED = 1;
+ private final int MSG_UNLOCK = 2;
+ private final int MSG_CANCEL = 3;
+ private final int MSG_REPORT_FAILED_ATTEMPT = 4;
+ private final int MSG_POKE_WAKELOCK = 5;
+
+ // TODO: This was added for the purpose of adhering to what the biometric interface expects
+ // the isRunning() function to return. However, it is probably not necessary to have both
+ // mRunning and mServiceRunning. I'd just rather wait to change that logic.
+ private volatile boolean mIsRunning = false;
+
+ // So the user has a consistent amount of time when brought to the backup method from Face
+ // Unlock
+ private final int BACKUP_LOCK_TIMEOUT = 5000;
+
+ KeyguardSecurityCallback mKeyguardScreenCallback;
+
+ /**
+ * Stores some of the structures that Face Unlock will need to access and creates the handler
+ * will be used to execute messages on the UI thread.
+ */
+ public FaceUnlock(Context context) {
+ mContext = context;
+ mLockPatternUtils = new LockPatternUtils(context);
+ mHandler = new Handler(this);
+ }
+
+ public void setKeyguardCallback(KeyguardSecurityCallback keyguardScreenCallback) {
+ mKeyguardScreenCallback = keyguardScreenCallback;
+ }
+
+ /**
+ * Stores and displays the view that Face Unlock is allowed to draw within.
+ * TODO: since the layout object will eventually be shared by multiple biometric unlock
+ * methods, we will have to add our other views (background, cancel button) here.
+ */
+ public void initializeView(View biometricUnlockView) {
+ Log.d(TAG, "initializeView()");
+ mFaceUnlockView = biometricUnlockView;
+ }
+
+ /**
+ * Indicates whether Face Unlock is currently running.
+ */
+ public boolean isRunning() {
+ return mIsRunning;
+ }
+
+ /**
+ * Dismisses face unlock and goes to the backup lock
+ */
+ public void stopAndShowBackup() {
+ if (DEBUG) Log.d(TAG, "stopAndShowBackup()");
+ mHandler.sendEmptyMessage(MSG_CANCEL);
+ }
+
+ /**
+ * Binds to the Face Unlock service. Face Unlock will be started when the bind completes. The
+ * Face Unlock view is displayed to hide the backup lock while the service is starting up.
+ * Called on the UI thread.
+ */
+ public boolean start() {
+ if (DEBUG) Log.d(TAG, "start()");
+ if (mHandler.getLooper() != Looper.myLooper()) {
+ Log.e(TAG, "start() called off of the UI thread");
+ }
+
+ if (mIsRunning) {
+ Log.w(TAG, "start() called when already running");
+ }
+
+ if (!mBoundToService) {
+ Log.d(TAG, "Binding to Face Unlock service for user="
+ + mLockPatternUtils.getCurrentUser());
+ mContext.bindServiceAsUser(new Intent(IFaceLockInterface.class.getName()),
+ mConnection,
+ Context.BIND_AUTO_CREATE,
+ new UserHandle(mLockPatternUtils.getCurrentUser()));
+ mBoundToService = true;
+ } else {
+ Log.w(TAG, "Attempt to bind to Face Unlock when already bound");
+ }
+
+ mIsRunning = true;
+ return true;
+ }
+
+ /**
+ * Stops Face Unlock and unbinds from the service. Called on the UI thread.
+ */
+ public boolean stop() {
+ if (DEBUG) Log.d(TAG, "stop()");
+ if (mHandler.getLooper() != Looper.myLooper()) {
+ Log.e(TAG, "stop() called from non-UI thread");
+ }
+
+ // Clearing any old service connected messages.
+ mHandler.removeMessages(MSG_SERVICE_CONNECTED);
+
+ boolean mWasRunning = mIsRunning;
+
+ stopUi();
+
+ if (mBoundToService) {
+ if (mService != null) {
+ try {
+ mService.unregisterCallback(mFaceUnlockCallback);
+ } catch (RemoteException e) {
+ // Not much we can do
+ }
+ }
+ Log.d(TAG, "Unbinding from Face Unlock service");
+ mContext.unbindService(mConnection);
+ mBoundToService = false;
+ } else {
+ // This is usually not an error when this happens. Sometimes we will tell it to
+ // unbind multiple times because it's called from both onWindowFocusChanged and
+ // onDetachedFromWindow.
+ if (DEBUG) Log.d(TAG, "Attempt to unbind from Face Unlock when not bound");
+ }
+ mIsRunning = false;
+ return mWasRunning;
+ }
+
+ /**
+ * Frees up resources used by Face Unlock and stops it if it is still running.
+ */
+ public void cleanUp() {
+ if (DEBUG) Log.d(TAG, "cleanUp()");
+ if (mService != null) {
+ try {
+ mService.unregisterCallback(mFaceUnlockCallback);
+ } catch (RemoteException e) {
+ // Not much we can do
+ }
+ stopUi();
+ mService = null;
+ }
+ }
+
+ /**
+ * Returns the Device Policy Manager quality for Face Unlock, which is BIOMETRIC_WEAK.
+ */
+ public int getQuality() {
+ return DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK;
+ }
+
+ /**
+ * Handles messages such that everything happens on the UI thread in a deterministic order.
+ * Calls from the Face Unlock service come from binder threads. Calls from lockscreen typically
+ * come from the UI thread. This makes sure there are no race conditions between those calls.
+ */
+ public boolean handleMessage(Message msg) {
+ switch (msg.what) {
+ case MSG_SERVICE_CONNECTED:
+ handleServiceConnected();
+ break;
+ case MSG_SERVICE_DISCONNECTED:
+ handleServiceDisconnected();
+ break;
+ case MSG_UNLOCK:
+ handleUnlock(msg.arg1);
+ break;
+ case MSG_CANCEL:
+ handleCancel();
+ break;
+ case MSG_REPORT_FAILED_ATTEMPT:
+ handleReportFailedAttempt();
+ break;
+ case MSG_POKE_WAKELOCK:
+ handlePokeWakelock(msg.arg1);
+ break;
+ default:
+ Log.e(TAG, "Unhandled message");
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Tells the service to start its UI via an AIDL interface. Called when the
+ * onServiceConnected() callback is received.
+ */
+ void handleServiceConnected() {
+ Log.d(TAG, "handleServiceConnected()");
+
+ // It is possible that an unbind has occurred in the time between the bind and when this
+ // function is reached. If an unbind has already occurred, proceeding on to call startUi()
+ // can result in a fatal error. Note that the onServiceConnected() callback is
+ // asynchronous, so this possibility would still exist if we executed this directly in
+ // onServiceConnected() rather than using a handler.
+ if (!mBoundToService) {
+ Log.d(TAG, "Dropping startUi() in handleServiceConnected() because no longer bound");
+ return;
+ }
+
+ try {
+ mService.registerCallback(mFaceUnlockCallback);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Caught exception connecting to Face Unlock: " + e.toString());
+ mService = null;
+ mBoundToService = false;
+ mIsRunning = false;
+ return;
+ }
+
+ if (mFaceUnlockView != null) {
+ IBinder windowToken = mFaceUnlockView.getWindowToken();
+ if (windowToken != null) {
+ // When switching between portrait and landscape view while Face Unlock is running,
+ // the screen will eventually go dark unless we poke the wakelock when Face Unlock
+ // is restarted.
+ mKeyguardScreenCallback.userActivity(0);
+
+ int[] position;
+ position = new int[2];
+ mFaceUnlockView.getLocationInWindow(position);
+ startUi(windowToken, position[0], position[1], mFaceUnlockView.getWidth(),
+ mFaceUnlockView.getHeight());
+ } else {
+ Log.e(TAG, "windowToken is null in handleServiceConnected()");
+ }
+ }
+ }
+
+ /**
+ * Called when the onServiceDisconnected() callback is received. This should not happen during
+ * normal operation. It indicates an error has occurred.
+ */
+ void handleServiceDisconnected() {
+ Log.e(TAG, "handleServiceDisconnected()");
+ // TODO: this lock may no longer be needed now that everything is being called from a
+ // handler
+ synchronized (mServiceRunningLock) {
+ mService = null;
+ mServiceRunning = false;
+ }
+ mBoundToService = false;
+ mIsRunning = false;
+ }
+
+ /**
+ * Stops the Face Unlock service and tells the device to grant access to the user.
+ */
+ void handleUnlock(int authenticatedUserId) {
+ if (DEBUG) Log.d(TAG, "handleUnlock()");
+ stop();
+ int currentUserId = mLockPatternUtils.getCurrentUser();
+ if (authenticatedUserId == currentUserId) {
+ if (DEBUG) Log.d(TAG, "Unlocking for user " + authenticatedUserId);
+ mKeyguardScreenCallback.reportSuccessfulUnlockAttempt();
+ mKeyguardScreenCallback.dismiss(true);
+ } else {
+ Log.d(TAG, "Ignoring unlock for authenticated user (" + authenticatedUserId +
+ ") because the current user is " + currentUserId);
+ }
+ }
+
+ /**
+ * Stops the Face Unlock service and goes to the backup lock.
+ */
+ void handleCancel() {
+ if (DEBUG) Log.d(TAG, "handleCancel()");
+ // We are going to the backup method, so we don't want to see Face Unlock again until the
+ // next time the user visits keyguard.
+ KeyguardUpdateMonitor.getInstance(mContext).setAlternateUnlockEnabled(false);
+
+ mKeyguardScreenCallback.showBackupSecurity();
+ stop();
+ mKeyguardScreenCallback.userActivity(BACKUP_LOCK_TIMEOUT);
+ }
+
+ /**
+ * Increments the number of failed Face Unlock attempts.
+ */
+ void handleReportFailedAttempt() {
+ if (DEBUG) Log.d(TAG, "handleReportFailedAttempt()");
+ // We are going to the backup method, so we don't want to see Face Unlock again until the
+ // next time the user visits keyguard.
+ KeyguardUpdateMonitor.getInstance(mContext).setAlternateUnlockEnabled(false);
+
+ mKeyguardScreenCallback.reportFailedUnlockAttempt();
+ }
+
+ /**
+ * If the screen is on, pokes the wakelock to keep the screen alive and active for a specific
+ * amount of time.
+ */
+ void handlePokeWakelock(int millis) {
+ PowerManager powerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
+ if (powerManager.isScreenOn()) {
+ mKeyguardScreenCallback.userActivity(millis);
+ }
+ }
+
+ /**
+ * Implements service connection methods.
+ */
+ private ServiceConnection mConnection = new ServiceConnection() {
+ /**
+ * Called when the Face Unlock service connects after calling bind().
+ */
+ public void onServiceConnected(ComponentName className, IBinder iservice) {
+ Log.d(TAG, "Connected to Face Unlock service");
+ mService = IFaceLockInterface.Stub.asInterface(iservice);
+ mHandler.sendEmptyMessage(MSG_SERVICE_CONNECTED);
+ }
+
+ /**
+ * Called if the Face Unlock service unexpectedly disconnects. This indicates an error.
+ */
+ public void onServiceDisconnected(ComponentName className) {
+ Log.e(TAG, "Unexpected disconnect from Face Unlock service");
+ mHandler.sendEmptyMessage(MSG_SERVICE_DISCONNECTED);
+ }
+ };
+
+ /**
+ * Tells the Face Unlock service to start displaying its UI and start processing.
+ */
+ private void startUi(IBinder windowToken, int x, int y, int w, int h) {
+ if (DEBUG) Log.d(TAG, "startUi()");
+ synchronized (mServiceRunningLock) {
+ if (!mServiceRunning) {
+ Log.d(TAG, "Starting Face Unlock");
+ try {
+ mService.startUi(windowToken, x, y, w, h,
+ mLockPatternUtils.isBiometricWeakLivelinessEnabled());
+ } catch (RemoteException e) {
+ Log.e(TAG, "Caught exception starting Face Unlock: " + e.toString());
+ return;
+ }
+ mServiceRunning = true;
+ } else {
+ Log.w(TAG, "startUi() attempted while running");
+ }
+ }
+ }
+
+ /**
+ * Tells the Face Unlock service to stop displaying its UI and stop processing.
+ */
+ private void stopUi() {
+ if (DEBUG) Log.d(TAG, "stopUi()");
+ // Note that attempting to stop Face Unlock when it's not running is not an issue.
+ // Face Unlock can return, which stops it and then we try to stop it when the
+ // screen is turned off. That's why we check.
+ synchronized (mServiceRunningLock) {
+ if (mServiceRunning) {
+ Log.d(TAG, "Stopping Face Unlock");
+ try {
+ mService.stopUi();
+ } catch (RemoteException e) {
+ Log.e(TAG, "Caught exception stopping Face Unlock: " + e.toString());
+ }
+ mServiceRunning = false;
+ } else {
+ // This is usually not an error when this happens. Sometimes we will tell it to
+ // stop multiple times because it's called from both onWindowFocusChanged and
+ // onDetachedFromWindow.
+ if (DEBUG) Log.d(TAG, "stopUi() attempted while not running");
+ }
+ }
+ }
+
+ /**
+ * Implements the AIDL biometric unlock service callback interface.
+ */
+ private final IFaceLockCallback mFaceUnlockCallback = new IFaceLockCallback.Stub() {
+ /**
+ * Called when Face Unlock wants to grant access to the user.
+ */
+ public void unlock() {
+ if (DEBUG) Log.d(TAG, "unlock()");
+ Message message = mHandler.obtainMessage(MSG_UNLOCK, UserHandle.getCallingUserId(), -1);
+ mHandler.sendMessage(message);
+ }
+
+ /**
+ * Called when Face Unlock wants to go to the backup.
+ */
+ public void cancel() {
+ if (DEBUG) Log.d(TAG, "cancel()");
+ mHandler.sendEmptyMessage(MSG_CANCEL);
+ }
+
+ /**
+ * Called when Face Unlock wants to increment the number of failed attempts.
+ */
+ public void reportFailedAttempt() {
+ if (DEBUG) Log.d(TAG, "reportFailedAttempt()");
+ mHandler.sendEmptyMessage(MSG_REPORT_FAILED_ATTEMPT);
+ }
+
+ /**
+ * Called when Face Unlock wants to keep the screen alive and active for a specific amount
+ * of time.
+ */
+ public void pokeWakelock(int millis) {
+ if (DEBUG) Log.d(TAG, "pokeWakelock() for " + millis + "ms");
+ Message message = mHandler.obtainMessage(MSG_POKE_WAKELOCK, millis, -1);
+ mHandler.sendMessage(message);
+ }
+
+ };
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardAbsKeyInputView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardAbsKeyInputView.java
new file mode 100644
index 0000000..fb2eeda
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardAbsKeyInputView.java
@@ -0,0 +1,262 @@
+/*
+ * 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.keyguard;
+
+import android.content.Context;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.os.CountDownTimer;
+import android.os.SystemClock;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.util.AttributeSet;
+import android.view.HapticFeedbackConstants;
+import android.view.KeyEvent;
+import android.view.View;
+import android.view.inputmethod.EditorInfo;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+import android.widget.TextView.OnEditorActionListener;
+
+import com.android.internal.widget.LockPatternUtils;
+
+/**
+ * Base class for PIN and password unlock screens.
+ */
+public abstract class KeyguardAbsKeyInputView extends LinearLayout
+ implements KeyguardSecurityView, OnEditorActionListener, TextWatcher {
+ protected KeyguardSecurityCallback mCallback;
+ protected TextView mPasswordEntry;
+ protected LockPatternUtils mLockPatternUtils;
+ protected SecurityMessageDisplay mSecurityMessageDisplay;
+ protected View mEcaView;
+ private Drawable mBouncerFrame;
+ protected boolean mEnableHaptics;
+
+ // To avoid accidental lockout due to events while the device in in the pocket, ignore
+ // any passwords with length less than or equal to this length.
+ protected static final int MINIMUM_PASSWORD_LENGTH_BEFORE_REPORT = 3;
+
+ public KeyguardAbsKeyInputView(Context context) {
+ this(context, null);
+ }
+
+ public KeyguardAbsKeyInputView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public void setKeyguardCallback(KeyguardSecurityCallback callback) {
+ mCallback = callback;
+ }
+
+ public void setLockPatternUtils(LockPatternUtils utils) {
+ mLockPatternUtils = utils;
+ mEnableHaptics = mLockPatternUtils.isTactileFeedbackEnabled();
+ }
+
+ @Override
+ public void onWindowFocusChanged(boolean hasWindowFocus) {
+ if (hasWindowFocus) {
+ reset();
+ }
+ }
+
+ public void reset() {
+ // start fresh
+ mPasswordEntry.setText("");
+ mPasswordEntry.requestFocus();
+
+ // if the user is currently locked out, enforce it.
+ long deadline = mLockPatternUtils.getLockoutAttemptDeadline();
+ if (deadline != 0) {
+ handleAttemptLockout(deadline);
+ } else {
+ resetState();
+ }
+ }
+
+ protected abstract int getPasswordTextViewId();
+ protected abstract void resetState();
+
+ @Override
+ protected void onFinishInflate() {
+ mLockPatternUtils = new LockPatternUtils(mContext);
+
+ mPasswordEntry = (TextView) findViewById(getPasswordTextViewId());
+ mPasswordEntry.setOnEditorActionListener(this);
+ mPasswordEntry.addTextChangedListener(this);
+
+ // Set selected property on so the view can send accessibility events.
+ mPasswordEntry.setSelected(true);
+
+ // Poke the wakelock any time the text is selected or modified
+ mPasswordEntry.setOnClickListener(new OnClickListener() {
+ public void onClick(View v) {
+ mCallback.userActivity(0); // TODO: customize timeout for text?
+ }
+ });
+
+ mPasswordEntry.addTextChangedListener(new TextWatcher() {
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
+ }
+
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+ }
+
+ public void afterTextChanged(Editable s) {
+ if (mCallback != null) {
+ mCallback.userActivity(0);
+ }
+ }
+ });
+ mSecurityMessageDisplay = new KeyguardMessageArea.Helper(this);
+ mEcaView = findViewById(R.id.keyguard_selector_fade_container);
+ View bouncerFrameView = findViewById(R.id.keyguard_bouncer_frame);
+ if (bouncerFrameView != null) {
+ mBouncerFrame = bouncerFrameView.getBackground();
+ }
+ }
+
+ @Override
+ protected boolean onRequestFocusInDescendants(int direction, Rect previouslyFocusedRect) {
+ // send focus to the password field
+ return mPasswordEntry.requestFocus(direction, previouslyFocusedRect);
+ }
+
+ /*
+ * Override this if you have a different string for "wrong password"
+ *
+ * Note that PIN/PUK have their own implementation of verifyPasswordAndUnlock and so don't need this
+ */
+ protected int getWrongPasswordStringId() {
+ return R.string.kg_wrong_password;
+ }
+
+ protected void verifyPasswordAndUnlock() {
+ String entry = mPasswordEntry.getText().toString();
+ if (mLockPatternUtils.checkPassword(entry)) {
+ mCallback.reportSuccessfulUnlockAttempt();
+ mCallback.dismiss(true);
+ } else if (entry.length() > MINIMUM_PASSWORD_LENGTH_BEFORE_REPORT ) {
+ // to avoid accidental lockout, only count attempts that are long enough to be a
+ // real password. This may require some tweaking.
+ mCallback.reportFailedUnlockAttempt();
+ if (0 == (mCallback.getFailedAttempts()
+ % LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT)) {
+ long deadline = mLockPatternUtils.setLockoutAttemptDeadline();
+ handleAttemptLockout(deadline);
+ }
+ mSecurityMessageDisplay.setMessage(getWrongPasswordStringId(), true);
+ }
+ mPasswordEntry.setText("");
+ }
+
+ // Prevent user from using the PIN/Password entry until scheduled deadline.
+ protected void handleAttemptLockout(long elapsedRealtimeDeadline) {
+ mPasswordEntry.setEnabled(false);
+ long elapsedRealtime = SystemClock.elapsedRealtime();
+ new CountDownTimer(elapsedRealtimeDeadline - elapsedRealtime, 1000) {
+
+ @Override
+ public void onTick(long millisUntilFinished) {
+ int secondsRemaining = (int) (millisUntilFinished / 1000);
+ mSecurityMessageDisplay.setMessage(
+ R.string.kg_too_many_failed_attempts_countdown, true, secondsRemaining);
+ }
+
+ @Override
+ public void onFinish() {
+ mSecurityMessageDisplay.setMessage("", false);
+ resetState();
+ }
+ }.start();
+ }
+
+ @Override
+ public boolean onKeyDown(int keyCode, KeyEvent event) {
+ mCallback.userActivity(0);
+ return false;
+ }
+
+ @Override
+ public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
+ // Check if this was the result of hitting the enter key
+ if (actionId == EditorInfo.IME_NULL || actionId == EditorInfo.IME_ACTION_DONE
+ || actionId == EditorInfo.IME_ACTION_NEXT) {
+ verifyPasswordAndUnlock();
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public boolean needsInput() {
+ return false;
+ }
+
+ @Override
+ public void onPause() {
+
+ }
+
+ @Override
+ public void onResume(int reason) {
+ reset();
+ }
+
+ @Override
+ public KeyguardSecurityCallback getCallback() {
+ return mCallback;
+ }
+
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+ if (mCallback != null) {
+ mCallback.userActivity(KeyguardViewManager.DIGIT_PRESS_WAKE_MILLIS);
+ }
+ }
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
+ }
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ }
+
+ // Cause a VIRTUAL_KEY vibration
+ public void doHapticKeyClick() {
+ if (mEnableHaptics) {
+ performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY,
+ HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING
+ | HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING);
+ }
+ }
+
+ @Override
+ public void showBouncer(int duration) {
+ KeyguardSecurityViewHelper.
+ showBouncer(mSecurityMessageDisplay, mEcaView, mBouncerFrame, duration);
+ }
+
+ @Override
+ public void hideBouncer(int duration) {
+ KeyguardSecurityViewHelper.
+ hideBouncer(mSecurityMessageDisplay, mEcaView, mBouncerFrame, duration);
+ }
+}
+
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardAccountView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardAccountView.java
new file mode 100644
index 0000000..6b8be69
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardAccountView.java
@@ -0,0 +1,332 @@
+/*
+ * 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.keyguard;
+
+import android.accounts.Account;
+import android.accounts.AccountManager;
+import android.accounts.AccountManagerCallback;
+import android.accounts.AccountManagerFuture;
+import android.accounts.AuthenticatorException;
+import android.accounts.OperationCanceledException;
+import android.app.Dialog;
+import android.app.ProgressDialog;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Rect;
+import android.os.Bundle;
+import android.os.UserHandle;
+import android.text.Editable;
+import android.text.InputFilter;
+import android.text.LoginFilter;
+import android.text.TextWatcher;
+import android.util.AttributeSet;
+import android.view.KeyEvent;
+import android.view.View;
+import android.view.WindowManager;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.LinearLayout;
+
+import com.android.internal.widget.LockPatternUtils;
+
+import java.io.IOException;
+
+/**
+ * When the user forgets their password a bunch of times, we fall back on their
+ * account's login/password to unlock the phone (and reset their lock pattern).
+ */
+public class KeyguardAccountView extends LinearLayout implements KeyguardSecurityView,
+ View.OnClickListener, TextWatcher {
+ private static final int AWAKE_POKE_MILLIS = 30000;
+ private static final String LOCK_PATTERN_PACKAGE = "com.android.settings";
+ private static final String LOCK_PATTERN_CLASS = LOCK_PATTERN_PACKAGE + ".ChooseLockGeneric";
+
+ private KeyguardSecurityCallback mCallback;
+ private LockPatternUtils mLockPatternUtils;
+ private EditText mLogin;
+ private EditText mPassword;
+ private Button mOk;
+ public boolean mEnableFallback;
+ private SecurityMessageDisplay mSecurityMessageDisplay;
+
+ /**
+ * Shown while making asynchronous check of password.
+ */
+ private ProgressDialog mCheckingDialog;
+
+ public KeyguardAccountView(Context context) {
+ this(context, null, 0);
+ }
+
+ public KeyguardAccountView(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public KeyguardAccountView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ mLockPatternUtils = new LockPatternUtils(getContext());
+ }
+
+ @Override
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+
+ mLogin = (EditText) findViewById(R.id.login);
+ mLogin.setFilters(new InputFilter[] { new LoginFilter.UsernameFilterGeneric() } );
+ mLogin.addTextChangedListener(this);
+
+ mPassword = (EditText) findViewById(R.id.password);
+ mPassword.addTextChangedListener(this);
+
+ mOk = (Button) findViewById(R.id.ok);
+ mOk.setOnClickListener(this);
+
+ mSecurityMessageDisplay = new KeyguardMessageArea.Helper(this);
+ reset();
+ }
+
+ public void setKeyguardCallback(KeyguardSecurityCallback callback) {
+ mCallback = callback;
+ }
+
+ public void setLockPatternUtils(LockPatternUtils utils) {
+ mLockPatternUtils = utils;
+ }
+
+ public KeyguardSecurityCallback getCallback() {
+ return mCallback;
+ }
+
+
+ public void afterTextChanged(Editable s) {
+ }
+
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+ }
+
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
+ if (mCallback != null) {
+ mCallback.userActivity(AWAKE_POKE_MILLIS);
+ }
+ }
+
+ @Override
+ protected boolean onRequestFocusInDescendants(int direction,
+ Rect previouslyFocusedRect) {
+ // send focus to the login field
+ return mLogin.requestFocus(direction, previouslyFocusedRect);
+ }
+
+ public boolean needsInput() {
+ return true;
+ }
+
+ public void reset() {
+ // start fresh
+ mLogin.setText("");
+ mPassword.setText("");
+ mLogin.requestFocus();
+ boolean permLocked = mLockPatternUtils.isPermanentlyLocked();
+ mSecurityMessageDisplay.setMessage(permLocked ? R.string.kg_login_too_many_attempts :
+ R.string.kg_login_instructions, permLocked ? true : false);
+ }
+
+ /** {@inheritDoc} */
+ public void cleanUp() {
+ if (mCheckingDialog != null) {
+ mCheckingDialog.hide();
+ }
+ mCallback = null;
+ mLockPatternUtils = null;
+ }
+
+ public void onClick(View v) {
+ mCallback.userActivity(0);
+ if (v == mOk) {
+ asyncCheckPassword();
+ }
+ }
+
+ private void postOnCheckPasswordResult(final boolean success) {
+ // ensure this runs on UI thread
+ mLogin.post(new Runnable() {
+ public void run() {
+ if (success) {
+ // clear out forgotten password
+ mLockPatternUtils.setPermanentlyLocked(false);
+ mLockPatternUtils.setLockPatternEnabled(false);
+ mLockPatternUtils.saveLockPattern(null);
+
+ // launch the 'choose lock pattern' activity so
+ // the user can pick a new one if they want to
+ Intent intent = new Intent();
+ intent.setClassName(LOCK_PATTERN_PACKAGE, LOCK_PATTERN_CLASS);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ mContext.startActivityAsUser(intent,
+ new UserHandle(mLockPatternUtils.getCurrentUser()));
+ mCallback.reportSuccessfulUnlockAttempt();
+
+ // dismiss keyguard
+ mCallback.dismiss(true);
+ } else {
+ mSecurityMessageDisplay.setMessage(R.string.kg_login_invalid_input, true);
+ mPassword.setText("");
+ mCallback.reportFailedUnlockAttempt();
+ }
+ }
+ });
+ }
+
+ @Override
+ public boolean dispatchKeyEvent(KeyEvent event) {
+ if (event.getAction() == KeyEvent.ACTION_DOWN
+ && event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
+ if (mLockPatternUtils.isPermanentlyLocked()) {
+ mCallback.dismiss(false);
+ } else {
+ // TODO: mCallback.forgotPattern(false);
+ }
+ return true;
+ }
+ return super.dispatchKeyEvent(event);
+ }
+
+ /**
+ * Given the string the user entered in the 'username' field, find
+ * the stored account that they probably intended. Prefer, in order:
+ *
+ * - an exact match for what was typed, or
+ * - a case-insensitive match for what was typed, or
+ * - if they didn't include a domain, an exact match of the username, or
+ * - if they didn't include a domain, a case-insensitive
+ * match of the username.
+ *
+ * If there is a tie for the best match, choose neither --
+ * the user needs to be more specific.
+ *
+ * @return an account name from the database, or null if we can't
+ * find a single best match.
+ */
+ private Account findIntendedAccount(String username) {
+ Account[] accounts = AccountManager.get(mContext).getAccountsByTypeAsUser("com.google",
+ new UserHandle(mLockPatternUtils.getCurrentUser()));
+
+ // Try to figure out which account they meant if they
+ // typed only the username (and not the domain), or got
+ // the case wrong.
+
+ Account bestAccount = null;
+ int bestScore = 0;
+ for (Account a: accounts) {
+ int score = 0;
+ if (username.equals(a.name)) {
+ score = 4;
+ } else if (username.equalsIgnoreCase(a.name)) {
+ score = 3;
+ } else if (username.indexOf('@') < 0) {
+ int i = a.name.indexOf('@');
+ if (i >= 0) {
+ String aUsername = a.name.substring(0, i);
+ if (username.equals(aUsername)) {
+ score = 2;
+ } else if (username.equalsIgnoreCase(aUsername)) {
+ score = 1;
+ }
+ }
+ }
+ if (score > bestScore) {
+ bestAccount = a;
+ bestScore = score;
+ } else if (score == bestScore) {
+ bestAccount = null;
+ }
+ }
+ return bestAccount;
+ }
+
+ private void asyncCheckPassword() {
+ mCallback.userActivity(AWAKE_POKE_MILLIS);
+ final String login = mLogin.getText().toString();
+ final String password = mPassword.getText().toString();
+ Account account = findIntendedAccount(login);
+ if (account == null) {
+ postOnCheckPasswordResult(false);
+ return;
+ }
+ getProgressDialog().show();
+ Bundle options = new Bundle();
+ options.putString(AccountManager.KEY_PASSWORD, password);
+ AccountManager.get(mContext).confirmCredentialsAsUser(account, options, null /* activity */,
+ new AccountManagerCallback<Bundle>() {
+ public void run(AccountManagerFuture<Bundle> future) {
+ try {
+ mCallback.userActivity(AWAKE_POKE_MILLIS);
+ final Bundle result = future.getResult();
+ final boolean verified = result.getBoolean(AccountManager.KEY_BOOLEAN_RESULT);
+ postOnCheckPasswordResult(verified);
+ } catch (OperationCanceledException e) {
+ postOnCheckPasswordResult(false);
+ } catch (IOException e) {
+ postOnCheckPasswordResult(false);
+ } catch (AuthenticatorException e) {
+ postOnCheckPasswordResult(false);
+ } finally {
+ mLogin.post(new Runnable() {
+ public void run() {
+ getProgressDialog().hide();
+ }
+ });
+ }
+ }
+ }, null /* handler */, new UserHandle(mLockPatternUtils.getCurrentUser()));
+ }
+
+ private Dialog getProgressDialog() {
+ if (mCheckingDialog == null) {
+ mCheckingDialog = new ProgressDialog(mContext);
+ mCheckingDialog.setMessage(
+ mContext.getString(R.string.kg_login_checking_password));
+ mCheckingDialog.setIndeterminate(true);
+ mCheckingDialog.setCancelable(false);
+ mCheckingDialog.getWindow().setType(
+ WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
+ }
+ return mCheckingDialog;
+ }
+
+ @Override
+ public void onPause() {
+
+ }
+
+ @Override
+ public void onResume(int reason) {
+ reset();
+ }
+
+ @Override
+ public void showUsabilityHint() {
+ }
+
+ @Override
+ public void showBouncer(int duration) {
+ }
+
+ @Override
+ public void hideBouncer(int duration) {
+ }
+}
+
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardActivityLauncher.java b/packages/Keyguard/src/com/android/keyguard/KeyguardActivityLauncher.java
new file mode 100644
index 0000000..9a1aa5b
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardActivityLauncher.java
@@ -0,0 +1,274 @@
+/*
+ * 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.keyguard;
+
+import com.android.internal.widget.LockPatternUtils;
+
+import android.app.ActivityManagerNative;
+import android.app.ActivityOptions;
+import android.app.IActivityManager.WaitResult;
+import android.appwidget.AppWidgetManager;
+import android.appwidget.AppWidgetProviderInfo;
+import android.content.ActivityNotFoundException;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.RemoteException;
+import android.os.SystemClock;
+import android.os.UserHandle;
+import android.provider.MediaStore;
+import android.util.Log;
+import android.view.WindowManager;
+
+import com.android.keyguard.KeyguardHostView.OnDismissAction;
+
+import java.util.List;
+
+public abstract class KeyguardActivityLauncher {
+ private static final String TAG = KeyguardActivityLauncher.class.getSimpleName();
+ private static final boolean DEBUG = KeyguardHostView.DEBUG;
+ private static final String META_DATA_KEYGUARD_LAYOUT = "com.android.keyguard.layout";
+ private static final Intent SECURE_CAMERA_INTENT =
+ new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE)
+ .addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
+ private static final Intent INSECURE_CAMERA_INTENT =
+ new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA);
+
+ abstract Context getContext();
+
+ abstract KeyguardSecurityCallback getCallback();
+
+ abstract LockPatternUtils getLockPatternUtils();
+
+ public static class CameraWidgetInfo {
+ public String contextPackage;
+ public int layoutId;
+ }
+
+ public CameraWidgetInfo getCameraWidgetInfo() {
+ CameraWidgetInfo info = new CameraWidgetInfo();
+ Intent intent = getCameraIntent();
+ PackageManager packageManager = getContext().getPackageManager();
+ final List<ResolveInfo> appList = packageManager.queryIntentActivitiesAsUser(
+ intent, PackageManager.MATCH_DEFAULT_ONLY, getLockPatternUtils().getCurrentUser());
+ if (appList.size() == 0) {
+ if (DEBUG) Log.d(TAG, "getCameraWidgetInfo(): Nothing found");
+ return null;
+ }
+ ResolveInfo resolved = packageManager.resolveActivityAsUser(intent,
+ PackageManager.MATCH_DEFAULT_ONLY | PackageManager.GET_META_DATA,
+ getLockPatternUtils().getCurrentUser());
+ if (DEBUG) Log.d(TAG, "getCameraWidgetInfo(): resolved: " + resolved);
+ if (wouldLaunchResolverActivity(resolved, appList)) {
+ if (DEBUG) Log.d(TAG, "getCameraWidgetInfo(): Would launch resolver");
+ return info;
+ }
+ if (resolved == null || resolved.activityInfo == null) {
+ return null;
+ }
+ if (resolved.activityInfo.metaData == null || resolved.activityInfo.metaData.isEmpty()) {
+ if (DEBUG) Log.d(TAG, "getCameraWidgetInfo(): no metadata found");
+ return info;
+ }
+ int layoutId = resolved.activityInfo.metaData.getInt(META_DATA_KEYGUARD_LAYOUT);
+ if (layoutId == 0) {
+ if (DEBUG) Log.d(TAG, "getCameraWidgetInfo(): no layout specified");
+ return info;
+ }
+ info.contextPackage = resolved.activityInfo.packageName;
+ info.layoutId = layoutId;
+ return info;
+ }
+
+ public void launchCamera(Handler worker, Runnable onSecureCameraStarted) {
+ LockPatternUtils lockPatternUtils = getLockPatternUtils();
+ if (lockPatternUtils.isSecure()) {
+ // Launch the secure version of the camera
+ if (wouldLaunchResolverActivity(SECURE_CAMERA_INTENT)) {
+ // TODO: Show disambiguation dialog instead.
+ // For now, we'll treat this like launching any other app from secure keyguard.
+ // When they do, user sees the system's ResolverActivity which lets them choose
+ // which secure camera to use.
+ launchActivity(SECURE_CAMERA_INTENT, false, false, null, null);
+ } else {
+ launchActivity(SECURE_CAMERA_INTENT, true, false, worker, onSecureCameraStarted);
+ }
+ } else {
+ // Launch the normal camera
+ launchActivity(INSECURE_CAMERA_INTENT, false, false, null, null);
+ }
+ }
+
+ public void launchWidgetPicker(int appWidgetId) {
+ Intent pickIntent = new Intent(AppWidgetManager.ACTION_KEYGUARD_APPWIDGET_PICK);
+
+ pickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
+ pickIntent.putExtra(AppWidgetManager.EXTRA_CUSTOM_SORT, false);
+ pickIntent.putExtra(AppWidgetManager.EXTRA_CATEGORY_FILTER,
+ AppWidgetProviderInfo.WIDGET_CATEGORY_KEYGUARD);
+
+ Bundle options = new Bundle();
+ options.putInt(AppWidgetManager.OPTION_APPWIDGET_HOST_CATEGORY,
+ AppWidgetProviderInfo.WIDGET_CATEGORY_KEYGUARD);
+ pickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS, options);
+ pickIntent.addFlags(
+ Intent.FLAG_ACTIVITY_NEW_TASK
+ | Intent.FLAG_ACTIVITY_SINGLE_TOP
+ | Intent.FLAG_ACTIVITY_CLEAR_TOP
+ | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
+
+ launchActivity(pickIntent, false, false, null, null);
+ }
+
+ /**
+ * Launches the said intent for the current foreground user.
+ *
+ * @param intent
+ * @param showsWhileLocked true if the activity can be run on top of keyguard.
+ * See {@link WindowManager#FLAG_SHOW_WHEN_LOCKED}
+ * @param useDefaultAnimations true if default transitions should be used, else suppressed.
+ * @param worker if supplied along with onStarted, used to launch the blocking activity call.
+ * @param onStarted if supplied along with worker, called after activity is started.
+ */
+ public void launchActivity(final Intent intent,
+ boolean showsWhileLocked,
+ boolean useDefaultAnimations,
+ final Handler worker,
+ final Runnable onStarted) {
+
+ final Context context = getContext();
+ final Bundle animation = useDefaultAnimations ? null
+ : ActivityOptions.makeCustomAnimation(context, 0, 0).toBundle();
+ launchActivityWithAnimation(intent, showsWhileLocked, animation, worker, onStarted);
+ }
+
+ public void launchActivityWithAnimation(final Intent intent,
+ boolean showsWhileLocked,
+ final Bundle animation,
+ final Handler worker,
+ final Runnable onStarted) {
+
+ LockPatternUtils lockPatternUtils = getLockPatternUtils();
+ intent.addFlags(
+ Intent.FLAG_ACTIVITY_NEW_TASK
+ | Intent.FLAG_ACTIVITY_SINGLE_TOP
+ | Intent.FLAG_ACTIVITY_CLEAR_TOP);
+ boolean isSecure = lockPatternUtils.isSecure();
+ if (!isSecure || showsWhileLocked) {
+ if (!isSecure) {
+ dismissKeyguardOnNextActivity();
+ }
+ try {
+ if (DEBUG) Log.d(TAG, String.format("Starting activity for intent %s at %s",
+ intent, SystemClock.uptimeMillis()));
+ startActivityForCurrentUser(intent, animation, worker, onStarted);
+ } catch (ActivityNotFoundException e) {
+ Log.w(TAG, "Activity not found for intent + " + intent.getAction());
+ }
+ } else {
+ // Create a runnable to start the activity and ask the user to enter their
+ // credentials.
+ KeyguardSecurityCallback callback = getCallback();
+ callback.setOnDismissAction(new OnDismissAction() {
+ @Override
+ public boolean onDismiss() {
+ dismissKeyguardOnNextActivity();
+ startActivityForCurrentUser(intent, animation, worker, onStarted);
+ return true;
+ }
+ });
+ callback.dismiss(false);
+ }
+ }
+
+ private void dismissKeyguardOnNextActivity() {
+ try {
+ ActivityManagerNative.getDefault().dismissKeyguardOnNextActivity();
+ } catch (RemoteException e) {
+ Log.w(TAG, "can't dismiss keyguard on launch");
+ }
+ }
+
+ private void startActivityForCurrentUser(final Intent intent, final Bundle options,
+ Handler worker, final Runnable onStarted) {
+ final UserHandle user = new UserHandle(UserHandle.USER_CURRENT);
+ if (worker == null || onStarted == null) {
+ getContext().startActivityAsUser(intent, options, user);
+ return;
+ }
+ // if worker + onStarted are supplied, run blocking activity launch call in the background
+ worker.post(new Runnable(){
+ @Override
+ public void run() {
+ try {
+ WaitResult result = ActivityManagerNative.getDefault().startActivityAndWait(
+ null /*caller*/,
+ null /*caller pkg*/,
+ intent,
+ intent.resolveTypeIfNeeded(getContext().getContentResolver()),
+ null /*resultTo*/,
+ null /*resultWho*/,
+ 0 /*requestCode*/,
+ Intent.FLAG_ACTIVITY_NEW_TASK,
+ null /*profileFile*/,
+ null /*profileFd*/,
+ options,
+ user.getIdentifier());
+ if (DEBUG) Log.d(TAG, String.format("waitResult[%s,%s,%s,%s] at %s",
+ result.result, result.thisTime, result.totalTime, result.who,
+ SystemClock.uptimeMillis()));
+ } catch (RemoteException e) {
+ Log.w(TAG, "Error starting activity", e);
+ return;
+ }
+ try {
+ onStarted.run();
+ } catch (Throwable t) {
+ Log.w(TAG, "Error running onStarted callback", t);
+ }
+ }});
+ }
+
+ private Intent getCameraIntent() {
+ return getLockPatternUtils().isSecure() ? SECURE_CAMERA_INTENT : INSECURE_CAMERA_INTENT;
+ }
+
+ private boolean wouldLaunchResolverActivity(Intent intent) {
+ PackageManager packageManager = getContext().getPackageManager();
+ ResolveInfo resolved = packageManager.resolveActivityAsUser(intent,
+ PackageManager.MATCH_DEFAULT_ONLY, getLockPatternUtils().getCurrentUser());
+ List<ResolveInfo> appList = packageManager.queryIntentActivitiesAsUser(
+ intent, PackageManager.MATCH_DEFAULT_ONLY, getLockPatternUtils().getCurrentUser());
+ return wouldLaunchResolverActivity(resolved, appList);
+ }
+
+ private boolean wouldLaunchResolverActivity(ResolveInfo resolved, List<ResolveInfo> appList) {
+ // If the list contains the above resolved activity, then it can't be
+ // ResolverActivity itself.
+ for (int i = 0; i < appList.size(); i++) {
+ ResolveInfo tmp = appList.get(i);
+ if (tmp.activityInfo.name.equals(resolved.activityInfo.name)
+ && tmp.activityInfo.packageName.equals(resolved.activityInfo.packageName)) {
+ return false;
+ }
+ }
+ return true;
+ }
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardCircleFramedDrawable.java b/packages/Keyguard/src/com/android/keyguard/KeyguardCircleFramedDrawable.java
new file mode 100644
index 0000000..ed3faea
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardCircleFramedDrawable.java
@@ -0,0 +1,160 @@
+/*
+ * 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.keyguard;
+
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.ColorFilter;
+import android.graphics.Paint;
+import android.graphics.Path;
+import android.graphics.PixelFormat;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffXfermode;
+import android.graphics.Rect;
+import android.graphics.RectF;
+import android.graphics.drawable.Drawable;
+
+import android.util.Log;
+
+class KeyguardCircleFramedDrawable extends Drawable {
+
+ private final Bitmap mBitmap;
+ private final int mSize;
+ private final Paint mPaint;
+ private final float mShadowRadius;
+ private final float mStrokeWidth;
+ private final int mFrameColor;
+ private final int mHighlightColor;
+ private final int mFrameShadowColor;
+
+ private float mScale;
+ private Path mFramePath;
+ private Rect mSrcRect;
+ private RectF mDstRect;
+ private RectF mFrameRect;
+ private boolean mPressed;
+
+ public KeyguardCircleFramedDrawable(Bitmap bitmap, int size,
+ int frameColor, float strokeWidth,
+ int frameShadowColor, float shadowRadius,
+ int highlightColor) {
+ super();
+ mSize = size;
+ mShadowRadius = shadowRadius;
+ mFrameColor = frameColor;
+ mFrameShadowColor = frameShadowColor;
+ mStrokeWidth = strokeWidth;
+ mHighlightColor = highlightColor;
+
+ mBitmap = Bitmap.createBitmap(mSize, mSize, Bitmap.Config.ARGB_8888);
+ final Canvas canvas = new Canvas(mBitmap);
+
+ final int width = bitmap.getWidth();
+ final int height = bitmap.getHeight();
+ final int square = Math.min(width, height);
+
+ final Rect cropRect = new Rect((width - square) / 2, (height - square) / 2, square, square);
+ final RectF circleRect = new RectF(0f, 0f, mSize, mSize);
+ circleRect.inset(mStrokeWidth / 2f, mStrokeWidth / 2f);
+ circleRect.inset(mShadowRadius, mShadowRadius);
+
+ final Path fillPath = new Path();
+ fillPath.addArc(circleRect, 0f, 360f);
+
+ canvas.drawColor(0, PorterDuff.Mode.CLEAR);
+
+ // opaque circle matte
+ mPaint = new Paint();
+ mPaint.setAntiAlias(true);
+ mPaint.setColor(Color.BLACK);
+ mPaint.setStyle(Paint.Style.FILL);
+ canvas.drawPath(fillPath, mPaint);
+
+ // mask in the icon where the bitmap is opaque
+ mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP));
+ canvas.drawBitmap(bitmap, cropRect, circleRect, mPaint);
+
+ // prepare paint for frame drawing
+ mPaint.setXfermode(null);
+
+ mScale = 1f;
+
+ mSrcRect = new Rect(0, 0, mSize, mSize);
+ mDstRect = new RectF(0, 0, mSize, mSize);
+ mFrameRect = new RectF(mDstRect);
+ mFramePath = new Path();
+ }
+
+ @Override
+ public void draw(Canvas canvas) {
+ // clear background
+ final float outside = Math.min(canvas.getWidth(), canvas.getHeight());
+ final float inside = mScale * outside;
+ final float pad = (outside - inside) / 2f;
+
+ mDstRect.set(pad, pad, outside - pad, outside - pad);
+ canvas.drawBitmap(mBitmap, mSrcRect, mDstRect, null);
+
+ mFrameRect.set(mDstRect);
+ mFrameRect.inset(mStrokeWidth / 2f, mStrokeWidth / 2f);
+ mFrameRect.inset(mShadowRadius, mShadowRadius);
+
+ mFramePath.reset();
+ mFramePath.addArc(mFrameRect, 0f, 360f);
+
+ // white frame
+ if (mPressed) {
+ mPaint.setStyle(Paint.Style.FILL);
+ mPaint.setColor(Color.argb((int) (0.33f * 255),
+ Color.red(mHighlightColor),
+ Color.green(mHighlightColor),
+ Color.blue(mHighlightColor)));
+ canvas.drawPath(mFramePath, mPaint);
+ }
+ mPaint.setStrokeWidth(mStrokeWidth);
+ mPaint.setStyle(Paint.Style.STROKE);
+ mPaint.setColor(mPressed ? mHighlightColor : mFrameColor);
+ mPaint.setShadowLayer(mShadowRadius, 0f, 0f, mFrameShadowColor);
+ canvas.drawPath(mFramePath, mPaint);
+ }
+
+ public void setScale(float scale) {
+ mScale = scale;
+ }
+
+ public float getScale() {
+ return mScale;
+ }
+
+ public void setPressed(boolean pressed) {
+ mPressed = pressed;
+ }
+
+ @Override
+ public int getOpacity() {
+ return PixelFormat.TRANSLUCENT;
+ }
+
+ @Override
+ public void setAlpha(int alpha) {
+ }
+
+ @Override
+ public void setColorFilter(ColorFilter cf) {
+ }
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardFaceUnlockView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardFaceUnlockView.java
new file mode 100644
index 0000000..041f7f2
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardFaceUnlockView.java
@@ -0,0 +1,243 @@
+/*
+ * 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.keyguard;
+
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.os.PowerManager;
+import android.telephony.TelephonyManager;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.View;
+import android.widget.ImageButton;
+import android.widget.LinearLayout;
+
+import com.android.internal.widget.LockPatternUtils;
+
+public class KeyguardFaceUnlockView extends LinearLayout implements KeyguardSecurityView {
+
+ private static final String TAG = "FULKeyguardFaceUnlockView";
+ private static final boolean DEBUG = false;
+ private KeyguardSecurityCallback mKeyguardSecurityCallback;
+ private LockPatternUtils mLockPatternUtils;
+ private BiometricSensorUnlock mBiometricUnlock;
+ private View mFaceUnlockAreaView;
+ private ImageButton mCancelButton;
+ private SecurityMessageDisplay mSecurityMessageDisplay;
+ private View mEcaView;
+ private Drawable mBouncerFrame;
+
+ private boolean mIsShowing = false;
+ private final Object mIsShowingLock = new Object();
+
+ public KeyguardFaceUnlockView(Context context) {
+ this(context, null);
+ }
+
+ public KeyguardFaceUnlockView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ @Override
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+
+ initializeBiometricUnlockView();
+
+ mSecurityMessageDisplay = new KeyguardMessageArea.Helper(this);
+ mEcaView = findViewById(R.id.keyguard_selector_fade_container);
+ View bouncerFrameView = findViewById(R.id.keyguard_bouncer_frame);
+ if (bouncerFrameView != null) {
+ mBouncerFrame = bouncerFrameView.getBackground();
+ }
+ }
+
+ @Override
+ public void setKeyguardCallback(KeyguardSecurityCallback callback) {
+ mKeyguardSecurityCallback = callback;
+ // TODO: formalize this in the interface or factor it out
+ ((FaceUnlock)mBiometricUnlock).setKeyguardCallback(callback);
+ }
+
+ @Override
+ public void setLockPatternUtils(LockPatternUtils utils) {
+ mLockPatternUtils = utils;
+ }
+
+ @Override
+ public void reset() {
+
+ }
+
+ @Override
+ public void onDetachedFromWindow() {
+ if (DEBUG) Log.d(TAG, "onDetachedFromWindow()");
+ if (mBiometricUnlock != null) {
+ mBiometricUnlock.stop();
+ }
+ KeyguardUpdateMonitor.getInstance(mContext).removeCallback(mUpdateCallback);
+ }
+
+ @Override
+ public void onPause() {
+ if (DEBUG) Log.d(TAG, "onPause()");
+ if (mBiometricUnlock != null) {
+ mBiometricUnlock.stop();
+ }
+ KeyguardUpdateMonitor.getInstance(mContext).removeCallback(mUpdateCallback);
+ }
+
+ @Override
+ public void onResume(int reason) {
+ if (DEBUG) Log.d(TAG, "onResume()");
+ mIsShowing = KeyguardUpdateMonitor.getInstance(mContext).isKeyguardVisible();
+ maybeStartBiometricUnlock();
+ KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mUpdateCallback);
+ }
+
+ @Override
+ public boolean needsInput() {
+ return false;
+ }
+
+ @Override
+ public KeyguardSecurityCallback getCallback() {
+ return mKeyguardSecurityCallback;
+ }
+
+ @Override
+ protected void onLayout(boolean changed, int l, int t, int r, int b) {
+ super.onLayout(changed, l, t, r, b);
+ mBiometricUnlock.initializeView(mFaceUnlockAreaView);
+ }
+
+ private void initializeBiometricUnlockView() {
+ if (DEBUG) Log.d(TAG, "initializeBiometricUnlockView()");
+ mFaceUnlockAreaView = findViewById(R.id.face_unlock_area_view);
+ if (mFaceUnlockAreaView != null) {
+ mBiometricUnlock = new FaceUnlock(mContext);
+
+ mCancelButton = (ImageButton) findViewById(R.id.face_unlock_cancel_button);
+ mCancelButton.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ mBiometricUnlock.stopAndShowBackup();
+ }
+ });
+ } else {
+ Log.w(TAG, "Couldn't find biometric unlock view");
+ }
+ }
+
+ /**
+ * Starts the biometric unlock if it should be started based on a number of factors. If it
+ * should not be started, it either goes to the back up, or remains showing to prepare for
+ * it being started later.
+ */
+ private void maybeStartBiometricUnlock() {
+ if (DEBUG) Log.d(TAG, "maybeStartBiometricUnlock()");
+ if (mBiometricUnlock != null) {
+ KeyguardUpdateMonitor monitor = KeyguardUpdateMonitor.getInstance(mContext);
+ final boolean backupIsTimedOut = (
+ monitor.getFailedUnlockAttempts() >=
+ LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT);
+ PowerManager powerManager = (PowerManager) mContext.getSystemService(
+ Context.POWER_SERVICE);
+
+ boolean isShowing;
+ synchronized(mIsShowingLock) {
+ isShowing = mIsShowing;
+ }
+
+ // Don't start it if the screen is off or if it's not showing, but keep this view up
+ // because we want it here and ready for when the screen turns on or when it does start
+ // showing.
+ if (!powerManager.isScreenOn() || !isShowing) {
+ mBiometricUnlock.stop(); // It shouldn't be running but calling this can't hurt.
+ return;
+ }
+
+ // TODO: Some of these conditions are handled in KeyguardSecurityModel and may not be
+ // necessary here.
+ if (monitor.getPhoneState() == TelephonyManager.CALL_STATE_IDLE
+ && !monitor.getMaxBiometricUnlockAttemptsReached()
+ && !backupIsTimedOut) {
+ mBiometricUnlock.start();
+ } else {
+ mBiometricUnlock.stopAndShowBackup();
+ }
+ }
+ }
+
+ KeyguardUpdateMonitorCallback mUpdateCallback = new KeyguardUpdateMonitorCallback() {
+ // We need to stop the biometric unlock when a phone call comes in
+ @Override
+ public void onPhoneStateChanged(int phoneState) {
+ if (DEBUG) Log.d(TAG, "onPhoneStateChanged(" + phoneState + ")");
+ if (phoneState == TelephonyManager.CALL_STATE_RINGING) {
+ if (mBiometricUnlock != null) {
+ mBiometricUnlock.stopAndShowBackup();
+ }
+ }
+ }
+
+ @Override
+ public void onUserSwitching(int userId) {
+ if (DEBUG) Log.d(TAG, "onUserSwitched(" + userId + ")");
+ if (mBiometricUnlock != null) {
+ mBiometricUnlock.stop();
+ }
+ // No longer required; static value set by KeyguardViewMediator
+ // mLockPatternUtils.setCurrentUser(userId);
+ }
+
+ @Override
+ public void onKeyguardVisibilityChanged(boolean showing) {
+ if (DEBUG) Log.d(TAG, "onKeyguardVisibilityChanged(" + showing + ")");
+ boolean wasShowing = false;
+ synchronized(mIsShowingLock) {
+ wasShowing = mIsShowing;
+ mIsShowing = showing;
+ }
+ PowerManager powerManager = (PowerManager) mContext.getSystemService(
+ Context.POWER_SERVICE);
+ if (mBiometricUnlock != null) {
+ if (!showing && wasShowing) {
+ mBiometricUnlock.stop();
+ } else if (showing && powerManager.isScreenOn() && !wasShowing) {
+ maybeStartBiometricUnlock();
+ }
+ }
+ }
+ };
+
+ @Override
+ public void showUsabilityHint() {
+ }
+
+ @Override
+ public void showBouncer(int duration) {
+ KeyguardSecurityViewHelper.
+ showBouncer(mSecurityMessageDisplay, mEcaView, mBouncerFrame, duration);
+ }
+
+ @Override
+ public void hideBouncer(int duration) {
+ KeyguardSecurityViewHelper.
+ hideBouncer(mSecurityMessageDisplay, mEcaView, mBouncerFrame, duration);
+ }
+
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardGlowStripView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardGlowStripView.java
new file mode 100644
index 0000000..98a44a6
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardGlowStripView.java
@@ -0,0 +1,137 @@
+/*
+ * 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.keyguard;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ValueAnimator;
+import android.animation.ValueAnimator.AnimatorUpdateListener;
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.Canvas;
+import android.graphics.drawable.Drawable;
+import android.util.AttributeSet;
+import android.view.animation.DecelerateInterpolator;
+import android.view.animation.Interpolator;
+import android.view.animation.LinearInterpolator;
+import android.widget.LinearLayout;
+
+/**
+ * A layout which animates a strip of horizontal, pulsing dots on request. This is used
+ * to indicate the presence of pages to the left / right.
+ */
+public class KeyguardGlowStripView extends LinearLayout {
+ private static final int DURATION = 500;
+
+ private static final float SLIDING_WINDOW_SIZE = 0.4f;
+ private int mDotStripTop;
+ private int mHorizontalDotGap;
+
+ private int mDotSize;
+ private int mNumDots;
+ private Drawable mDotDrawable;
+ private boolean mLeftToRight = true;
+
+ private float mAnimationProgress = 0f;
+ private boolean mDrawDots = false;
+ private ValueAnimator mAnimator;
+ private Interpolator mDotAlphaInterpolator = new DecelerateInterpolator(0.5f);
+
+ public KeyguardGlowStripView(Context context) {
+ this(context, null, 0);
+ }
+
+ public KeyguardGlowStripView(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public KeyguardGlowStripView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+
+ TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.KeyguardGlowStripView);
+ mDotSize = a.getDimensionPixelSize(R.styleable.KeyguardGlowStripView_dotSize, mDotSize);
+ mNumDots = a.getInt(R.styleable.KeyguardGlowStripView_numDots, mNumDots);
+ mDotDrawable = a.getDrawable(R.styleable.KeyguardGlowStripView_glowDot);
+ mLeftToRight = a.getBoolean(R.styleable.KeyguardGlowStripView_leftToRight, mLeftToRight);
+ }
+
+ protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+ int availableWidth = w - getPaddingLeft() - getPaddingRight();
+ mHorizontalDotGap = (availableWidth - mDotSize * mNumDots) / (mNumDots - 1);
+ mDotStripTop = getPaddingTop();
+ invalidate();
+ }
+
+ @Override
+ protected void dispatchDraw(Canvas canvas) {
+ super.dispatchDraw(canvas);
+
+ if (!mDrawDots) return;
+
+ int xOffset = getPaddingLeft();
+ mDotDrawable.setBounds(0, 0, mDotSize, mDotSize);
+
+ for (int i = 0; i < mNumDots; i++) {
+ // We fudge the relative position to provide a fade in of the first dot and a fade
+ // out of the final dot.
+ float relativeDotPosition = SLIDING_WINDOW_SIZE / 2 + ((1.0f * i) / (mNumDots - 1)) *
+ (1 - SLIDING_WINDOW_SIZE);
+ float distance = Math.abs(relativeDotPosition - mAnimationProgress);
+ float alpha = Math.max(0, 1 - distance / (SLIDING_WINDOW_SIZE / 2));
+
+ alpha = mDotAlphaInterpolator.getInterpolation(alpha);
+
+ canvas.save();
+ canvas.translate(xOffset, mDotStripTop);
+ mDotDrawable.setAlpha((int) (alpha * 255));
+ mDotDrawable.draw(canvas);
+ canvas.restore();
+ xOffset += mDotSize + mHorizontalDotGap;
+ }
+ }
+
+ public void makeEmGo() {
+ if (mAnimator != null) {
+ mAnimator.cancel();
+ }
+ float from = mLeftToRight ? 0f : 1f;
+ float to = mLeftToRight ? 1f : 0f;
+ mAnimator = ValueAnimator.ofFloat(from, to);
+ mAnimator.setDuration(DURATION);
+ mAnimator.setInterpolator(new LinearInterpolator());
+ mAnimator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mDrawDots = false;
+ // make sure we draw one frame at the end with everything gone.
+ invalidate();
+ }
+
+ @Override
+ public void onAnimationStart(Animator animation) {
+ mDrawDots = true;
+ }
+ });
+ mAnimator.addUpdateListener(new AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ mAnimationProgress = (Float) animation.getAnimatedValue();
+ invalidate();
+ }
+ });
+ mAnimator.start();
+ }
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java
new file mode 100644
index 0000000..e2bc54b
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java
@@ -0,0 +1,1596 @@
+/*
+ * 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.keyguard;
+
+import com.android.internal.widget.LockPatternUtils;
+import com.android.keyguard.KeyguardSecurityModel.SecurityMode;
+
+import android.app.Activity;
+import android.app.ActivityManager;
+import android.app.ActivityOptions;
+import android.app.AlertDialog;
+import android.app.SearchManager;
+import android.app.admin.DevicePolicyManager;
+import android.appwidget.AppWidgetHost;
+import android.appwidget.AppWidgetHostView;
+import android.appwidget.AppWidgetManager;
+import android.appwidget.AppWidgetProviderInfo;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentSender;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.UserInfo;
+import android.content.res.Resources;
+import android.graphics.Canvas;
+import android.graphics.Rect;
+import android.os.Looper;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.SystemClock;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.provider.Settings;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.util.Slog;
+import android.view.KeyEvent;
+import android.view.LayoutInflater;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.WindowManager;
+import android.view.animation.AnimationUtils;
+import android.widget.RemoteViews.OnClickHandler;
+
+import java.io.File;
+import java.util.List;
+
+public class KeyguardHostView extends KeyguardViewBase {
+ private static final String TAG = "KeyguardHostView";
+
+ // Use this to debug all of keyguard
+ public static boolean DEBUG = KeyguardViewMediator.DEBUG;
+
+ // Found in KeyguardAppWidgetPickActivity.java
+ static final int APPWIDGET_HOST_ID = 0x4B455947;
+
+ private final int MAX_WIDGETS = 5;
+
+ private AppWidgetHost mAppWidgetHost;
+ private AppWidgetManager mAppWidgetManager;
+ private KeyguardWidgetPager mAppWidgetContainer;
+ private KeyguardSecurityViewFlipper mSecurityViewContainer;
+ private KeyguardSelectorView mKeyguardSelectorView;
+ private KeyguardTransportControlView mTransportControl;
+ private boolean mIsVerifyUnlockOnly;
+ private boolean mEnableFallback; // TODO: This should get the value from KeyguardPatternView
+ private SecurityMode mCurrentSecuritySelection = SecurityMode.Invalid;
+ private int mAppWidgetToShow;
+
+ private boolean mCheckAppWidgetConsistencyOnBootCompleted = false;
+ private boolean mCleanupAppWidgetsOnBootCompleted = false;
+
+ protected OnDismissAction mDismissAction;
+
+ protected int mFailedAttempts;
+ private LockPatternUtils mLockPatternUtils;
+
+ private KeyguardSecurityModel mSecurityModel;
+ private KeyguardViewStateManager mViewStateManager;
+
+ private Rect mTempRect = new Rect();
+
+ private int mDisabledFeatures;
+
+ private boolean mCameraDisabled;
+
+ private boolean mSafeModeEnabled;
+
+ private boolean mUserSetupCompleted;
+
+ // User for whom this host view was created. Final because we should never change the
+ // id without reconstructing an instance of KeyguardHostView. See note below...
+ private final int mUserId;
+
+ private KeyguardMultiUserSelectorView mKeyguardMultiUserSelectorView;
+
+ /*package*/ interface TransportCallback {
+ void onListenerDetached();
+ void onListenerAttached();
+ void onPlayStateChanged();
+ }
+
+ /*package*/ interface UserSwitcherCallback {
+ void hideSecurityView(int duration);
+ void showSecurityView();
+ void showUnlockHint();
+ void userActivity();
+ }
+
+ /*package*/ interface OnDismissAction {
+ /* returns true if the dismiss should be deferred */
+ boolean onDismiss();
+ }
+
+ public KeyguardHostView(Context context) {
+ this(context, null);
+ }
+
+ public KeyguardHostView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ mLockPatternUtils = new LockPatternUtils(context);
+
+ // Note: This depends on KeyguardHostView getting reconstructed every time the
+ // user switches, since mUserId will be used for the entire session.
+ // Once created, keyguard should *never* re-use this instance with another user.
+ // In other words, mUserId should never change - hence it's marked final.
+ mUserId = mLockPatternUtils.getCurrentUser();
+
+ DevicePolicyManager dpm =
+ (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
+ if (dpm != null) {
+ mDisabledFeatures = getDisabledFeatures(dpm);
+ mCameraDisabled = dpm.getCameraDisabled(null);
+ }
+
+ mSafeModeEnabled = LockPatternUtils.isSafeModeEnabled();
+
+ // These need to be created with the user context...
+ Context userContext = null;
+ try {
+ final String packageName = "system";
+ userContext = mContext.createPackageContextAsUser(packageName, 0,
+ new UserHandle(mUserId));
+
+ } catch (NameNotFoundException e) {
+ e.printStackTrace();
+ // This should never happen, but it's better to have no widgets than to crash.
+ userContext = context;
+ }
+
+ mAppWidgetHost = new AppWidgetHost(userContext, APPWIDGET_HOST_ID, mOnClickHandler,
+ Looper.myLooper());
+
+ cleanupAppWidgetIds();
+
+ mAppWidgetManager = AppWidgetManager.getInstance(userContext);
+
+ mSecurityModel = new KeyguardSecurityModel(context);
+
+ mViewStateManager = new KeyguardViewStateManager(this);
+
+ mUserSetupCompleted = Settings.Secure.getIntForUser(mContext.getContentResolver(),
+ Settings.Secure.USER_SETUP_COMPLETE, 0, UserHandle.USER_CURRENT) != 0;
+
+ if (mSafeModeEnabled) {
+ Log.v(TAG, "Keyguard widgets disabled by safe mode");
+ }
+ if ((mDisabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_WIDGETS_ALL) != 0) {
+ Log.v(TAG, "Keyguard widgets disabled by DPM");
+ }
+ if ((mDisabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA) != 0) {
+ Log.v(TAG, "Keyguard secure camera disabled by DPM");
+ }
+ }
+
+ private void cleanupAppWidgetIds() {
+ // Since this method may delete a widget (which we can't do until boot completed) we
+ // may have to defer it until after boot complete.
+ if (!KeyguardUpdateMonitor.getInstance(mContext).hasBootCompleted()) {
+ mCleanupAppWidgetsOnBootCompleted = true;
+ return;
+ }
+ if (!mSafeModeEnabled && !widgetsDisabledByDpm()) {
+ // Clean up appWidgetIds that are bound to lockscreen, but not actually used
+ // This is only to clean up after another bug: we used to not call
+ // deleteAppWidgetId when a user manually deleted a widget in keyguard. This code
+ // shouldn't have to run more than once per user. AppWidgetProviders rely on callbacks
+ // that are triggered by deleteAppWidgetId, which is why we're doing this
+ int[] appWidgetIdsInKeyguardSettings = mLockPatternUtils.getAppWidgets();
+ int[] appWidgetIdsBoundToHost = mAppWidgetHost.getAppWidgetIds();
+ for (int i = 0; i < appWidgetIdsBoundToHost.length; i++) {
+ int appWidgetId = appWidgetIdsBoundToHost[i];
+ if (!contains(appWidgetIdsInKeyguardSettings, appWidgetId)) {
+ Log.d(TAG, "Found a appWidgetId that's not being used by keyguard, deleting id "
+ + appWidgetId);
+ mAppWidgetHost.deleteAppWidgetId(appWidgetId);
+ }
+ }
+ }
+ }
+
+ private static boolean contains(int[] array, int target) {
+ for (int value : array) {
+ if (value == target) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private KeyguardUpdateMonitorCallback mUpdateMonitorCallbacks =
+ new KeyguardUpdateMonitorCallback() {
+ @Override
+ public void onBootCompleted() {
+ if (mCheckAppWidgetConsistencyOnBootCompleted) {
+ checkAppWidgetConsistency();
+ mSwitchPageRunnable.run();
+ mCheckAppWidgetConsistencyOnBootCompleted = false;
+ }
+ if (mCleanupAppWidgetsOnBootCompleted) {
+ cleanupAppWidgetIds();
+ mCleanupAppWidgetsOnBootCompleted = false;
+ }
+ }
+ @Override
+ public void onUserSwitchComplete(int userId) {
+ if (mKeyguardMultiUserSelectorView != null) {
+ mKeyguardMultiUserSelectorView.finalizeActiveUserView(true);
+ }
+ }
+ };
+
+ private SlidingChallengeLayout mSlidingChallengeLayout;
+
+ @Override
+ public boolean onTouchEvent(MotionEvent ev) {
+ boolean result = super.onTouchEvent(ev);
+ mTempRect.set(0, 0, 0, 0);
+ offsetRectIntoDescendantCoords(mSecurityViewContainer, mTempRect);
+ ev.offsetLocation(mTempRect.left, mTempRect.top);
+ result = mSecurityViewContainer.dispatchTouchEvent(ev) || result;
+ ev.offsetLocation(-mTempRect.left, -mTempRect.top);
+ return result;
+ }
+
+ @Override
+ protected void dispatchDraw(Canvas canvas) {
+ super.dispatchDraw(canvas);
+ if (mViewMediatorCallback != null) {
+ mViewMediatorCallback.keyguardDoneDrawing();
+ }
+ }
+
+ private int getWidgetPosition(int id) {
+ final int children = mAppWidgetContainer.getChildCount();
+ for (int i = 0; i < children; i++) {
+ if (mAppWidgetContainer.getWidgetPageAt(i).getContent().getId() == id) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ @Override
+ protected void onFinishInflate() {
+ // Grab instances of and make any necessary changes to the main layouts. Create
+ // view state manager and wire up necessary listeners / callbacks.
+ View deleteDropTarget = findViewById(R.id.keyguard_widget_pager_delete_target);
+ mAppWidgetContainer = (KeyguardWidgetPager) findViewById(R.id.app_widget_container);
+ mAppWidgetContainer.setVisibility(VISIBLE);
+ mAppWidgetContainer.setCallbacks(mWidgetCallbacks);
+ mAppWidgetContainer.setDeleteDropTarget(deleteDropTarget);
+ mAppWidgetContainer.setMinScale(0.5f);
+
+ mSlidingChallengeLayout = (SlidingChallengeLayout) findViewById(R.id.sliding_layout);
+ if (mSlidingChallengeLayout != null) {
+ mSlidingChallengeLayout.setOnChallengeScrolledListener(mViewStateManager);
+ }
+ mAppWidgetContainer.setViewStateManager(mViewStateManager);
+ mAppWidgetContainer.setLockPatternUtils(mLockPatternUtils);
+
+ ChallengeLayout challenge = mSlidingChallengeLayout != null ? mSlidingChallengeLayout :
+ (ChallengeLayout) findViewById(R.id.multi_pane_challenge);
+ challenge.setOnBouncerStateChangedListener(mViewStateManager);
+ mAppWidgetContainer.setBouncerAnimationDuration(challenge.getBouncerAnimationDuration());
+ mViewStateManager.setPagedView(mAppWidgetContainer);
+ mViewStateManager.setChallengeLayout(challenge);
+ mSecurityViewContainer = (KeyguardSecurityViewFlipper) findViewById(R.id.view_flipper);
+ mKeyguardSelectorView = (KeyguardSelectorView) findViewById(R.id.keyguard_selector_view);
+ mViewStateManager.setSecurityViewContainer(mSecurityViewContainer);
+
+ if (!(mContext instanceof Activity)) {
+ setSystemUiVisibility(getSystemUiVisibility() | View.STATUS_BAR_DISABLE_BACK);
+ }
+
+ addDefaultWidgets();
+
+ addWidgetsFromSettings();
+ if (!shouldEnableAddWidget()) {
+ mAppWidgetContainer.setAddWidgetEnabled(false);
+ }
+ checkAppWidgetConsistency();
+ mSwitchPageRunnable.run();
+ // This needs to be called after the pages are all added.
+ mViewStateManager.showUsabilityHints();
+
+ showPrimarySecurityScreen(false);
+ updateSecurityViews();
+ }
+
+ private boolean shouldEnableAddWidget() {
+ return numWidgets() < MAX_WIDGETS && mUserSetupCompleted;
+ }
+
+ private int getDisabledFeatures(DevicePolicyManager dpm) {
+ int disabledFeatures = DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_NONE;
+ if (dpm != null) {
+ final int currentUser = mLockPatternUtils.getCurrentUser();
+ disabledFeatures = dpm.getKeyguardDisabledFeatures(null, currentUser);
+ }
+ return disabledFeatures;
+ }
+
+ private boolean widgetsDisabledByDpm() {
+ return (mDisabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_WIDGETS_ALL) != 0;
+ }
+
+ private boolean cameraDisabledByDpm() {
+ return mCameraDisabled
+ || (mDisabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA) != 0;
+ }
+
+ private void updateSecurityViews() {
+ int children = mSecurityViewContainer.getChildCount();
+ for (int i = 0; i < children; i++) {
+ updateSecurityView(mSecurityViewContainer.getChildAt(i));
+ }
+ }
+
+ private void updateSecurityView(View view) {
+ if (view instanceof KeyguardSecurityView) {
+ KeyguardSecurityView ksv = (KeyguardSecurityView) view;
+ ksv.setKeyguardCallback(mCallback);
+ ksv.setLockPatternUtils(mLockPatternUtils);
+ if (mViewStateManager.isBouncing()) {
+ ksv.showBouncer(0);
+ } else {
+ ksv.hideBouncer(0);
+ }
+ } else {
+ Log.w(TAG, "View " + view + " is not a KeyguardSecurityView");
+ }
+ }
+
+ void setLockPatternUtils(LockPatternUtils utils) {
+ mSecurityModel.setLockPatternUtils(utils);
+ mLockPatternUtils = utils;
+ updateSecurityViews();
+ }
+
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ mAppWidgetHost.startListening();
+ KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mUpdateMonitorCallbacks);
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ mAppWidgetHost.stopListening();
+ KeyguardUpdateMonitor.getInstance(mContext).removeCallback(mUpdateMonitorCallbacks);
+ }
+
+ void addWidget(AppWidgetHostView view, int pageIndex) {
+ mAppWidgetContainer.addWidget(view, pageIndex);
+ }
+
+ private KeyguardWidgetPager.Callbacks mWidgetCallbacks
+ = new KeyguardWidgetPager.Callbacks() {
+ @Override
+ public void userActivity() {
+ KeyguardHostView.this.userActivity();
+ }
+
+ @Override
+ public void onUserActivityTimeoutChanged() {
+ KeyguardHostView.this.onUserActivityTimeoutChanged();
+ }
+
+ @Override
+ public void onAddView(View v) {
+ if (!shouldEnableAddWidget()) {
+ mAppWidgetContainer.setAddWidgetEnabled(false);
+ }
+ }
+
+ @Override
+ public void onRemoveView(View v, boolean deletePermanently) {
+ if (deletePermanently) {
+ final int appWidgetId = ((KeyguardWidgetFrame) v).getContentAppWidgetId();
+ if (appWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID &&
+ appWidgetId != LockPatternUtils.ID_DEFAULT_STATUS_WIDGET) {
+ mAppWidgetHost.deleteAppWidgetId(appWidgetId);
+ }
+ }
+ }
+
+ @Override
+ public void onRemoveViewAnimationCompleted() {
+ if (shouldEnableAddWidget()) {
+ mAppWidgetContainer.setAddWidgetEnabled(true);
+ }
+ }
+ };
+
+ public void initializeSwitchingUserState(boolean switching) {
+ if (!switching && mKeyguardMultiUserSelectorView != null) {
+ mKeyguardMultiUserSelectorView.finalizeActiveUserView(false);
+ }
+ }
+
+ public void userActivity() {
+ if (mViewMediatorCallback != null) {
+ mViewMediatorCallback.userActivity();
+ }
+ }
+
+ public void onUserActivityTimeoutChanged() {
+ if (mViewMediatorCallback != null) {
+ mViewMediatorCallback.onUserActivityTimeoutChanged();
+ }
+ }
+
+ @Override
+ public long getUserActivityTimeout() {
+ // Currently only considering user activity timeouts needed by widgets.
+ // Could also take into account longer timeouts for certain security views.
+ if (mAppWidgetContainer != null) {
+ return mAppWidgetContainer.getUserActivityTimeout();
+ }
+ return -1;
+ }
+
+ private KeyguardSecurityCallback mCallback = new KeyguardSecurityCallback() {
+
+ public void userActivity(long timeout) {
+ if (mViewMediatorCallback != null) {
+ mViewMediatorCallback.userActivity(timeout);
+ }
+ }
+
+ public void dismiss(boolean authenticated) {
+ showNextSecurityScreenOrFinish(authenticated);
+ }
+
+ public boolean isVerifyUnlockOnly() {
+ return mIsVerifyUnlockOnly;
+ }
+
+ public void reportSuccessfulUnlockAttempt() {
+ KeyguardUpdateMonitor.getInstance(mContext).clearFailedUnlockAttempts();
+ mLockPatternUtils.reportSuccessfulPasswordAttempt();
+ }
+
+ public void reportFailedUnlockAttempt() {
+ if (mCurrentSecuritySelection == SecurityMode.Biometric) {
+ KeyguardUpdateMonitor.getInstance(mContext).reportFailedBiometricUnlockAttempt();
+ } else {
+ KeyguardHostView.this.reportFailedUnlockAttempt();
+ }
+ }
+
+ public int getFailedAttempts() {
+ return KeyguardUpdateMonitor.getInstance(mContext).getFailedUnlockAttempts();
+ }
+
+ @Override
+ public void showBackupSecurity() {
+ KeyguardHostView.this.showBackupSecurityScreen();
+ }
+
+ @Override
+ public void setOnDismissAction(OnDismissAction action) {
+ KeyguardHostView.this.setOnDismissAction(action);
+ }
+
+ };
+
+ private void showDialog(String title, String message) {
+ final AlertDialog dialog = new AlertDialog.Builder(mContext)
+ .setTitle(title)
+ .setMessage(message)
+ .setNeutralButton(R.string.ok, null)
+ .create();
+ if (!(mContext instanceof Activity)) {
+ dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
+ }
+ dialog.show();
+ }
+
+ private void showTimeoutDialog() {
+ int timeoutInSeconds = (int) LockPatternUtils.FAILED_ATTEMPT_TIMEOUT_MS / 1000;
+ int messageId = 0;
+
+ switch (mSecurityModel.getSecurityMode()) {
+ case Pattern:
+ messageId = R.string.kg_too_many_failed_pattern_attempts_dialog_message;
+ break;
+ case PIN:
+ messageId = R.string.kg_too_many_failed_pin_attempts_dialog_message;
+ break;
+ case Password:
+ messageId = R.string.kg_too_many_failed_password_attempts_dialog_message;
+ break;
+ }
+
+ if (messageId != 0) {
+ final String message = mContext.getString(messageId,
+ KeyguardUpdateMonitor.getInstance(mContext).getFailedUnlockAttempts(),
+ timeoutInSeconds);
+ showDialog(null, message);
+ }
+ }
+
+ private void showAlmostAtWipeDialog(int attempts, int remaining) {
+ int timeoutInSeconds = (int) LockPatternUtils.FAILED_ATTEMPT_TIMEOUT_MS / 1000;
+ String message = mContext.getString(R.string.kg_failed_attempts_almost_at_wipe,
+ attempts, remaining);
+ showDialog(null, message);
+ }
+
+ private void showWipeDialog(int attempts) {
+ String message = mContext.getString(R.string.kg_failed_attempts_now_wiping, attempts);
+ showDialog(null, message);
+ }
+
+ private void showAlmostAtAccountLoginDialog() {
+ final int timeoutInSeconds = (int) LockPatternUtils.FAILED_ATTEMPT_TIMEOUT_MS / 1000;
+ final int count = LockPatternUtils.FAILED_ATTEMPTS_BEFORE_RESET
+ - LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT;
+ String message = mContext.getString(R.string.kg_failed_attempts_almost_at_login,
+ count, LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT, timeoutInSeconds);
+ showDialog(null, message);
+ }
+
+ private void reportFailedUnlockAttempt() {
+ final KeyguardUpdateMonitor monitor = KeyguardUpdateMonitor.getInstance(mContext);
+ final int failedAttempts = monitor.getFailedUnlockAttempts() + 1; // +1 for this time
+
+ if (DEBUG) Log.d(TAG, "reportFailedPatternAttempt: #" + failedAttempts);
+
+ SecurityMode mode = mSecurityModel.getSecurityMode();
+ final boolean usingPattern = mode == KeyguardSecurityModel.SecurityMode.Pattern;
+
+ final int failedAttemptsBeforeWipe = mLockPatternUtils.getDevicePolicyManager()
+ .getMaximumFailedPasswordsForWipe(null, mLockPatternUtils.getCurrentUser());
+
+ 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
+
+ boolean showTimeout = false;
+ 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);
+ }
+ } else {
+ 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);
+ showSecurityScreen(SecurityMode.Account);
+ // don't show timeout dialog because we show account unlock screen next
+ showTimeout = false;
+ }
+ }
+ }
+ monitor.reportFailedUnlockAttempt();
+ mLockPatternUtils.reportFailedPasswordAttempt();
+ if (showTimeout) {
+ showTimeoutDialog();
+ }
+ }
+
+ /**
+ * Shows the primary security screen for the user. This will be either the multi-selector
+ * or the user's security method.
+ * @param turningOff true if the device is being turned off
+ */
+ void showPrimarySecurityScreen(boolean turningOff) {
+ SecurityMode securityMode = mSecurityModel.getSecurityMode();
+ if (DEBUG) Log.v(TAG, "showPrimarySecurityScreen(turningOff=" + turningOff + ")");
+ if (!turningOff &&
+ KeyguardUpdateMonitor.getInstance(mContext).isAlternateUnlockEnabled()) {
+ // If we're not turning off, then allow biometric alternate.
+ // We'll reload it when the device comes back on.
+ securityMode = mSecurityModel.getAlternateFor(securityMode);
+ }
+ showSecurityScreen(securityMode);
+ }
+
+ /**
+ * Shows the backup security screen for the current security mode. This could be used for
+ * password recovery screens but is currently only used for pattern unlock to show the
+ * account unlock screen and biometric unlock to show the user's normal unlock.
+ */
+ private void showBackupSecurityScreen() {
+ if (DEBUG) Log.d(TAG, "showBackupSecurity()");
+ SecurityMode backup = mSecurityModel.getBackupSecurityMode(mCurrentSecuritySelection);
+ showSecurityScreen(backup);
+ }
+
+ public boolean showNextSecurityScreenIfPresent() {
+ SecurityMode securityMode = mSecurityModel.getSecurityMode();
+ // Allow an alternate, such as biometric unlock
+ securityMode = mSecurityModel.getAlternateFor(securityMode);
+ if (SecurityMode.None == securityMode) {
+ return false;
+ } else {
+ showSecurityScreen(securityMode); // switch to the alternate security view
+ return true;
+ }
+ }
+
+ private void showNextSecurityScreenOrFinish(boolean authenticated) {
+ if (DEBUG) Log.d(TAG, "showNextSecurityScreenOrFinish(" + authenticated + ")");
+ boolean finish = false;
+ if (SecurityMode.None == mCurrentSecuritySelection) {
+ SecurityMode securityMode = mSecurityModel.getSecurityMode();
+ // Allow an alternate, such as biometric unlock
+ securityMode = mSecurityModel.getAlternateFor(securityMode);
+ if (SecurityMode.None == securityMode) {
+ finish = true; // no security required
+ } else {
+ showSecurityScreen(securityMode); // switch to the alternate security view
+ }
+ } else if (authenticated) {
+ switch (mCurrentSecuritySelection) {
+ case Pattern:
+ case Password:
+ case PIN:
+ case Account:
+ case Biometric:
+ finish = true;
+ break;
+
+ case SimPin:
+ case SimPuk:
+ // Shortcut for SIM PIN/PUK to go to directly to user's security screen or home
+ SecurityMode securityMode = mSecurityModel.getSecurityMode();
+ if (securityMode != SecurityMode.None) {
+ showSecurityScreen(securityMode);
+ } else {
+ finish = true;
+ }
+ break;
+
+ default:
+ Log.v(TAG, "Bad security screen " + mCurrentSecuritySelection + ", fail safe");
+ showPrimarySecurityScreen(false);
+ break;
+ }
+ } else {
+ showPrimarySecurityScreen(false);
+ }
+ if (finish) {
+ // If the alternate unlock was suppressed, it can now be safely
+ // enabled because the user has left keyguard.
+ KeyguardUpdateMonitor.getInstance(mContext).setAlternateUnlockEnabled(true);
+
+ // If there's a pending runnable because the user interacted with a widget
+ // and we're leaving keyguard, then run it.
+ boolean deferKeyguardDone = false;
+ if (mDismissAction != null) {
+ deferKeyguardDone = mDismissAction.onDismiss();
+ mDismissAction = null;
+ }
+ if (mViewMediatorCallback != null) {
+ if (deferKeyguardDone) {
+ mViewMediatorCallback.keyguardDonePending();
+ } else {
+ mViewMediatorCallback.keyguardDone(true);
+ }
+ }
+ } else {
+ mViewStateManager.showBouncer(true);
+ }
+ }
+
+ private OnClickHandler mOnClickHandler = new OnClickHandler() {
+ @Override
+ public boolean onClickHandler(final View view,
+ final android.app.PendingIntent pendingIntent,
+ final Intent fillInIntent) {
+ if (pendingIntent.isActivity()) {
+ setOnDismissAction(new OnDismissAction() {
+ public boolean onDismiss() {
+ try {
+ // TODO: Unregister this handler if PendingIntent.FLAG_ONE_SHOT?
+ Context context = view.getContext();
+ ActivityOptions opts = ActivityOptions.makeScaleUpAnimation(view,
+ 0, 0,
+ view.getMeasuredWidth(), view.getMeasuredHeight());
+ context.startIntentSender(
+ pendingIntent.getIntentSender(), fillInIntent,
+ Intent.FLAG_ACTIVITY_NEW_TASK,
+ Intent.FLAG_ACTIVITY_NEW_TASK, 0, opts.toBundle());
+ } catch (IntentSender.SendIntentException e) {
+ android.util.Log.e(TAG, "Cannot send pending intent: ", e);
+ } catch (Exception e) {
+ android.util.Log.e(TAG, "Cannot send pending intent due to " +
+ "unknown exception: ", e);
+ }
+ return false;
+ }
+ });
+
+ if (mViewStateManager.isChallengeShowing()) {
+ mViewStateManager.showBouncer(true);
+ } else {
+ mCallback.dismiss(false);
+ }
+ return true;
+ } else {
+ return super.onClickHandler(view, pendingIntent, fillInIntent);
+ }
+ };
+ };
+
+ // Used to ignore callbacks from methods that are no longer current (e.g. face unlock).
+ // This avoids unwanted asynchronous events from messing with the state.
+ private KeyguardSecurityCallback mNullCallback = new KeyguardSecurityCallback() {
+
+ @Override
+ public void userActivity(long timeout) {
+ }
+
+ @Override
+ public void showBackupSecurity() {
+ }
+
+ @Override
+ public void setOnDismissAction(OnDismissAction action) {
+ }
+
+ @Override
+ public void reportSuccessfulUnlockAttempt() {
+ }
+
+ @Override
+ public void reportFailedUnlockAttempt() {
+ }
+
+ @Override
+ public boolean isVerifyUnlockOnly() {
+ return false;
+ }
+
+ @Override
+ public int getFailedAttempts() {
+ return 0;
+ }
+
+ @Override
+ public void dismiss(boolean securityVerified) {
+ }
+ };
+
+ protected boolean mShowSecurityWhenReturn;
+
+ @Override
+ public void reset() {
+ mIsVerifyUnlockOnly = false;
+ mAppWidgetContainer.setCurrentPage(getWidgetPosition(R.id.keyguard_status_view));
+ }
+
+ /**
+ * Sets an action to perform when keyguard is dismissed.
+ * @param action
+ */
+ protected void setOnDismissAction(OnDismissAction action) {
+ mDismissAction = action;
+ }
+
+ private KeyguardSecurityView getSecurityView(SecurityMode securityMode) {
+ final int securityViewIdForMode = getSecurityViewIdForMode(securityMode);
+ KeyguardSecurityView view = null;
+ final int children = mSecurityViewContainer.getChildCount();
+ for (int child = 0; child < children; child++) {
+ if (mSecurityViewContainer.getChildAt(child).getId() == securityViewIdForMode) {
+ view = ((KeyguardSecurityView)mSecurityViewContainer.getChildAt(child));
+ break;
+ }
+ }
+ int layoutId = getLayoutIdFor(securityMode);
+ if (view == null && layoutId != 0) {
+ final LayoutInflater inflater = LayoutInflater.from(mContext);
+ if (DEBUG) Log.v(TAG, "inflating id = " + layoutId);
+ View v = inflater.inflate(layoutId, mSecurityViewContainer, false);
+ mSecurityViewContainer.addView(v);
+ updateSecurityView(v);
+ view = (KeyguardSecurityView)v;
+ }
+
+ if (view instanceof KeyguardSelectorView) {
+ KeyguardSelectorView selectorView = (KeyguardSelectorView) view;
+ View carrierText = selectorView.findViewById(R.id.keyguard_selector_fade_container);
+ selectorView.setCarrierArea(carrierText);
+ }
+
+ return view;
+ }
+
+ /**
+ * Switches to the given security view unless it's already being shown, in which case
+ * this is a no-op.
+ *
+ * @param securityMode
+ */
+ private void showSecurityScreen(SecurityMode securityMode) {
+ if (DEBUG) Log.d(TAG, "showSecurityScreen(" + securityMode + ")");
+
+ if (securityMode == mCurrentSecuritySelection) return;
+
+ KeyguardSecurityView oldView = getSecurityView(mCurrentSecuritySelection);
+ KeyguardSecurityView newView = getSecurityView(securityMode);
+
+ // Enter full screen mode if we're in SIM or Account screen
+ boolean fullScreenEnabled = getResources().getBoolean(R.bool.kg_sim_puk_account_full_screen);
+ boolean isSimOrAccount = securityMode == SecurityMode.SimPin
+ || securityMode == SecurityMode.SimPuk
+ || securityMode == SecurityMode.Account;
+ mAppWidgetContainer.setVisibility(
+ isSimOrAccount && fullScreenEnabled ? View.GONE : View.VISIBLE);
+
+ if (mSlidingChallengeLayout != null) {
+ mSlidingChallengeLayout.setChallengeInteractive(!fullScreenEnabled);
+ }
+
+ // Emulate Activity life cycle
+ if (oldView != null) {
+ oldView.onPause();
+ oldView.setKeyguardCallback(mNullCallback); // ignore requests from old view
+ }
+ newView.onResume(KeyguardSecurityView.VIEW_REVEALED);
+ newView.setKeyguardCallback(mCallback);
+
+ final boolean needsInput = newView.needsInput();
+ if (mViewMediatorCallback != null) {
+ mViewMediatorCallback.setNeedsInput(needsInput);
+ }
+
+ // Find and show this child.
+ final int childCount = mSecurityViewContainer.getChildCount();
+
+ mSecurityViewContainer.setInAnimation(
+ AnimationUtils.loadAnimation(mContext, R.anim.keyguard_security_fade_in));
+ mSecurityViewContainer.setOutAnimation(
+ AnimationUtils.loadAnimation(mContext, R.anim.keyguard_security_fade_out));
+ final int securityViewIdForMode = getSecurityViewIdForMode(securityMode);
+ for (int i = 0; i < childCount; i++) {
+ if (mSecurityViewContainer.getChildAt(i).getId() == securityViewIdForMode) {
+ mSecurityViewContainer.setDisplayedChild(i);
+ break;
+ }
+ }
+
+ if (securityMode == SecurityMode.None) {
+ // Discard current runnable if we're switching back to the selector view
+ setOnDismissAction(null);
+ }
+ mCurrentSecuritySelection = securityMode;
+ }
+
+ @Override
+ public void onScreenTurnedOn() {
+ if (DEBUG) Log.d(TAG, "screen on, instance " + Integer.toHexString(hashCode()));
+ showPrimarySecurityScreen(false);
+ getSecurityView(mCurrentSecuritySelection).onResume(KeyguardSecurityView.SCREEN_ON);
+
+ // This is a an attempt to fix bug 7137389 where the device comes back on but the entire
+ // layout is blank but forcing a layout causes it to reappear (e.g. with with
+ // hierarchyviewer).
+ requestLayout();
+
+ if (mViewStateManager != null) {
+ mViewStateManager.showUsabilityHints();
+ }
+ requestFocus();
+ }
+
+ @Override
+ public void onScreenTurnedOff() {
+ if (DEBUG) Log.d(TAG, String.format("screen off, instance %s at %s",
+ Integer.toHexString(hashCode()), SystemClock.uptimeMillis()));
+ // Once the screen turns off, we no longer consider this to be first boot and we want the
+ // biometric unlock to start next time keyguard is shown.
+ KeyguardUpdateMonitor.getInstance(mContext).setAlternateUnlockEnabled(true);
+ // We use mAppWidgetToShow to show a particular widget after you add it-- once the screen
+ // turns off we reset that behavior
+ clearAppWidgetToShow();
+ checkAppWidgetConsistency();
+ showPrimarySecurityScreen(true);
+ getSecurityView(mCurrentSecuritySelection).onPause();
+ CameraWidgetFrame cameraPage = findCameraPage();
+ if (cameraPage != null) {
+ cameraPage.onScreenTurnedOff();
+ }
+ clearFocus();
+ }
+
+ public void clearAppWidgetToShow() {
+ mAppWidgetToShow = AppWidgetManager.INVALID_APPWIDGET_ID;
+ }
+
+ @Override
+ public void show() {
+ if (DEBUG) Log.d(TAG, "show()");
+ showPrimarySecurityScreen(false);
+ }
+
+ private boolean isSecure() {
+ SecurityMode mode = mSecurityModel.getSecurityMode();
+ switch (mode) {
+ case Pattern:
+ return mLockPatternUtils.isLockPatternEnabled();
+ case Password:
+ case PIN:
+ return mLockPatternUtils.isLockPasswordEnabled();
+ case SimPin:
+ case SimPuk:
+ case Account:
+ return true;
+ case None:
+ return false;
+ default:
+ throw new IllegalStateException("Unknown security mode " + mode);
+ }
+ }
+
+ @Override
+ public void wakeWhenReadyTq(int keyCode) {
+ if (DEBUG) Log.d(TAG, "onWakeKey");
+ if (keyCode == KeyEvent.KEYCODE_MENU && isSecure()) {
+ if (DEBUG) Log.d(TAG, "switching screens to unlock screen because wake key was MENU");
+ showSecurityScreen(SecurityMode.None);
+ } else {
+ if (DEBUG) Log.d(TAG, "poking wake lock immediately");
+ }
+ if (mViewMediatorCallback != null) {
+ mViewMediatorCallback.wakeUp();
+ }
+ }
+
+ @Override
+ public void verifyUnlock() {
+ SecurityMode securityMode = mSecurityModel.getSecurityMode();
+ if (securityMode == KeyguardSecurityModel.SecurityMode.None) {
+ if (mViewMediatorCallback != null) {
+ mViewMediatorCallback.keyguardDone(true);
+ }
+ } else if (securityMode != KeyguardSecurityModel.SecurityMode.Pattern
+ && securityMode != KeyguardSecurityModel.SecurityMode.PIN
+ && securityMode != KeyguardSecurityModel.SecurityMode.Password) {
+ // can only verify unlock when in pattern/password mode
+ if (mViewMediatorCallback != null) {
+ mViewMediatorCallback.keyguardDone(false);
+ }
+ } else {
+ // otherwise, go to the unlock screen, see if they can verify it
+ mIsVerifyUnlockOnly = true;
+ showSecurityScreen(securityMode);
+ }
+ }
+
+ private int getSecurityViewIdForMode(SecurityMode securityMode) {
+ switch (securityMode) {
+ case None: return R.id.keyguard_selector_view;
+ case Pattern: return R.id.keyguard_pattern_view;
+ case PIN: return R.id.keyguard_pin_view;
+ case Password: return R.id.keyguard_password_view;
+ case Biometric: return R.id.keyguard_face_unlock_view;
+ case Account: return R.id.keyguard_account_view;
+ case SimPin: return R.id.keyguard_sim_pin_view;
+ case SimPuk: return R.id.keyguard_sim_puk_view;
+ }
+ return 0;
+ }
+
+ private int getLayoutIdFor(SecurityMode securityMode) {
+ switch (securityMode) {
+ case None: return R.layout.keyguard_selector_view;
+ case Pattern: return R.layout.keyguard_pattern_view;
+ case PIN: return R.layout.keyguard_pin_view;
+ case Password: return R.layout.keyguard_password_view;
+ case Biometric: return R.layout.keyguard_face_unlock_view;
+ case Account: return R.layout.keyguard_account_view;
+ case SimPin: return R.layout.keyguard_sim_pin_view;
+ case SimPuk: return R.layout.keyguard_sim_puk_view;
+ default:
+ return 0;
+ }
+ }
+
+ private boolean addWidget(int appId, int pageIndex, boolean updateDbIfFailed) {
+ AppWidgetProviderInfo appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(appId);
+ if (appWidgetInfo != null) {
+ AppWidgetHostView view = mAppWidgetHost.createView(mContext, appId, appWidgetInfo);
+ addWidget(view, pageIndex);
+ return true;
+ } else {
+ if (updateDbIfFailed) {
+ Log.w(TAG, "*** AppWidgetInfo for app widget id " + appId + " was null for user"
+ + mUserId + ", deleting");
+ mAppWidgetHost.deleteAppWidgetId(appId);
+ mLockPatternUtils.removeAppWidget(appId);
+ }
+ return false;
+ }
+ }
+
+ private final CameraWidgetFrame.Callbacks mCameraWidgetCallbacks =
+ new CameraWidgetFrame.Callbacks() {
+ @Override
+ public void onLaunchingCamera() {
+ setSliderHandleAlpha(0);
+ }
+
+ @Override
+ public void onCameraLaunchedSuccessfully() {
+ if (mAppWidgetContainer.isCameraPage(mAppWidgetContainer.getCurrentPage())) {
+ mAppWidgetContainer.scrollLeft();
+ }
+ setSliderHandleAlpha(1);
+ mShowSecurityWhenReturn = true;
+ }
+
+ @Override
+ public void onCameraLaunchedUnsuccessfully() {
+ setSliderHandleAlpha(1);
+ }
+
+ private void setSliderHandleAlpha(float alpha) {
+ SlidingChallengeLayout slider =
+ (SlidingChallengeLayout) findViewById(R.id.sliding_layout);
+ if (slider != null) {
+ slider.setHandleAlpha(alpha);
+ }
+ }
+ };
+
+ private final KeyguardActivityLauncher mActivityLauncher = new KeyguardActivityLauncher() {
+ @Override
+ Context getContext() {
+ return mContext;
+ }
+
+ @Override
+ KeyguardSecurityCallback getCallback() {
+ return mCallback;
+ }
+
+ @Override
+ LockPatternUtils getLockPatternUtils() {
+ return mLockPatternUtils;
+ }
+ };
+
+ private int numWidgets() {
+ final int childCount = mAppWidgetContainer.getChildCount();
+ int widgetCount = 0;
+ for (int i = 0; i < childCount; i++) {
+ if (mAppWidgetContainer.isWidgetPage(i)) {
+ widgetCount++;
+ }
+ }
+ return widgetCount;
+ }
+
+ private void addDefaultWidgets() {
+ LayoutInflater inflater = LayoutInflater.from(mContext);
+ inflater.inflate(R.layout.keyguard_transport_control_view, this, true);
+
+ if (!mSafeModeEnabled && !widgetsDisabledByDpm()) {
+ View addWidget = inflater.inflate(R.layout.keyguard_add_widget, this, false);
+ mAppWidgetContainer.addWidget(addWidget, 0);
+ View addWidgetButton = addWidget.findViewById(R.id.keyguard_add_widget_view);
+ addWidgetButton.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ // Pass in an invalid widget id... the picker will allocate an ID for us
+ mActivityLauncher.launchWidgetPicker(AppWidgetManager.INVALID_APPWIDGET_ID);
+ }
+ });
+ }
+
+ // We currently disable cameras in safe mode because we support loading 3rd party
+ // cameras we can't trust. TODO: plumb safe mode into camera creation code and only
+ // inflate system-provided camera?
+ if (!mSafeModeEnabled && !cameraDisabledByDpm() && mUserSetupCompleted
+ && mContext.getResources().getBoolean(R.bool.kg_enable_camera_default_widget)) {
+ View cameraWidget =
+ CameraWidgetFrame.create(mContext, mCameraWidgetCallbacks, mActivityLauncher);
+ if (cameraWidget != null) {
+ mAppWidgetContainer.addWidget(cameraWidget);
+ }
+ }
+
+ enableUserSelectorIfNecessary();
+ initializeTransportControl();
+ }
+
+ private boolean removeTransportFromWidgetPager() {
+ int page = getWidgetPosition(R.id.keyguard_transport_control);
+ if (page != -1) {
+ mAppWidgetContainer.removeWidget(mTransportControl);
+
+ // XXX keep view attached so we still get show/hide events from AudioManager
+ KeyguardHostView.this.addView(mTransportControl);
+ mTransportControl.setVisibility(View.GONE);
+ mViewStateManager.setTransportState(KeyguardViewStateManager.TRANSPORT_GONE);
+ return true;
+ }
+ return false;
+ }
+
+ private void addTransportToWidgetPager() {
+ if (getWidgetPosition(R.id.keyguard_transport_control) == -1) {
+ KeyguardHostView.this.removeView(mTransportControl);
+ // insert to left of camera if it exists, otherwise after right-most widget
+ int lastWidget = mAppWidgetContainer.getChildCount() - 1;
+ int position = 0; // handle no widget case
+ if (lastWidget >= 0) {
+ position = mAppWidgetContainer.isCameraPage(lastWidget) ?
+ lastWidget : lastWidget + 1;
+ }
+ mAppWidgetContainer.addWidget(mTransportControl, position);
+ mTransportControl.setVisibility(View.VISIBLE);
+ }
+ }
+
+ private void initializeTransportControl() {
+ mTransportControl =
+ (KeyguardTransportControlView) findViewById(R.id.keyguard_transport_control);
+ mTransportControl.setVisibility(View.GONE);
+
+ // This code manages showing/hiding the transport control. We keep it around and only
+ // add it to the hierarchy if it needs to be present.
+ if (mTransportControl != null) {
+ mTransportControl.setKeyguardCallback(new TransportCallback() {
+ @Override
+ public void onListenerDetached() {
+ if (removeTransportFromWidgetPager()) {
+ mTransportControl.post(mSwitchPageRunnable);
+ }
+ }
+
+ @Override
+ public void onListenerAttached() {
+ // Transport will be added when playstate changes...
+ mTransportControl.post(mSwitchPageRunnable);
+ }
+
+ @Override
+ public void onPlayStateChanged() {
+ mTransportControl.post(mSwitchPageRunnable);
+ }
+ });
+ }
+ }
+
+ private int getInsertPageIndex() {
+ View addWidget = mAppWidgetContainer.findViewById(R.id.keyguard_add_widget);
+ int insertionIndex = mAppWidgetContainer.indexOfChild(addWidget);
+ if (insertionIndex < 0) {
+ insertionIndex = 0; // no add widget page found
+ } else {
+ insertionIndex++; // place after add widget
+ }
+ return insertionIndex;
+ }
+
+ private void addDefaultStatusWidget(int index) {
+ LayoutInflater inflater = LayoutInflater.from(mContext);
+ View statusWidget = inflater.inflate(R.layout.keyguard_status_view, null, true);
+ mAppWidgetContainer.addWidget(statusWidget, index);
+ }
+
+ private void addWidgetsFromSettings() {
+ if (mSafeModeEnabled || widgetsDisabledByDpm()) {
+ return;
+ }
+
+ int insertionIndex = getInsertPageIndex();
+
+ // Add user-selected widget
+ final int[] widgets = mLockPatternUtils.getAppWidgets();
+
+ if (widgets == null) {
+ Log.d(TAG, "Problem reading widgets");
+ } else {
+ for (int i = widgets.length -1; i >= 0; i--) {
+ if (widgets[i] == LockPatternUtils.ID_DEFAULT_STATUS_WIDGET) {
+ addDefaultStatusWidget(insertionIndex);
+ } else {
+ // We add the widgets from left to right, starting after the first page after
+ // the add page. We count down, since the order will be persisted from right
+ // to left, starting after camera.
+ addWidget(widgets[i], insertionIndex, true);
+ }
+ }
+ }
+ }
+
+ private int allocateIdForDefaultAppWidget() {
+ int appWidgetId;
+ Resources res = getContext().getResources();
+ ComponentName defaultAppWidget = new ComponentName(
+ res.getString(R.string.widget_default_package_name),
+ res.getString(R.string.widget_default_class_name));
+
+ // Note: we don't support configuring the widget
+ appWidgetId = mAppWidgetHost.allocateAppWidgetId();
+
+ try {
+ mAppWidgetManager.bindAppWidgetId(appWidgetId, defaultAppWidget);
+
+ } catch (IllegalArgumentException e) {
+ Log.e(TAG, "Error when trying to bind default AppWidget: " + e);
+ mAppWidgetHost.deleteAppWidgetId(appWidgetId);
+ appWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;
+ }
+ return appWidgetId;
+ }
+ public void checkAppWidgetConsistency() {
+ // Since this method may bind a widget (which we can't do until boot completed) we
+ // may have to defer it until after boot complete.
+ if (!KeyguardUpdateMonitor.getInstance(mContext).hasBootCompleted()) {
+ mCheckAppWidgetConsistencyOnBootCompleted = true;
+ return;
+ }
+ final int childCount = mAppWidgetContainer.getChildCount();
+ boolean widgetPageExists = false;
+ for (int i = 0; i < childCount; i++) {
+ if (mAppWidgetContainer.isWidgetPage(i)) {
+ widgetPageExists = true;
+ break;
+ }
+ }
+ if (!widgetPageExists) {
+ final int insertPageIndex = getInsertPageIndex();
+
+ final boolean userAddedWidgetsEnabled = !widgetsDisabledByDpm();
+ boolean addedDefaultAppWidget = false;
+
+ if (!mSafeModeEnabled) {
+ if (userAddedWidgetsEnabled) {
+ int appWidgetId = allocateIdForDefaultAppWidget();
+ if (appWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID) {
+ addedDefaultAppWidget = addWidget(appWidgetId, insertPageIndex, true);
+ }
+ } else {
+ // note: even if widgetsDisabledByDpm() returns true, we still bind/create
+ // the default appwidget if possible
+ int appWidgetId = mLockPatternUtils.getFallbackAppWidgetId();
+ if (appWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) {
+ appWidgetId = allocateIdForDefaultAppWidget();
+ if (appWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID) {
+ mLockPatternUtils.writeFallbackAppWidgetId(appWidgetId);
+ }
+ }
+ if (appWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID) {
+ addedDefaultAppWidget = addWidget(appWidgetId, insertPageIndex, false);
+ if (!addedDefaultAppWidget) {
+ mAppWidgetHost.deleteAppWidgetId(appWidgetId);
+ mLockPatternUtils.writeFallbackAppWidgetId(
+ AppWidgetManager.INVALID_APPWIDGET_ID);
+ }
+ }
+ }
+ }
+
+ // Use the built-in status/clock view if we can't inflate the default widget
+ if (!addedDefaultAppWidget) {
+ addDefaultStatusWidget(insertPageIndex);
+ }
+
+ // trigger DB updates only if user-added widgets are enabled
+ if (!mSafeModeEnabled && userAddedWidgetsEnabled) {
+ mAppWidgetContainer.onAddView(
+ mAppWidgetContainer.getChildAt(insertPageIndex), insertPageIndex);
+ }
+ }
+ }
+
+ Runnable mSwitchPageRunnable = new Runnable() {
+ @Override
+ public void run() {
+ showAppropriateWidgetPage();
+ }
+ };
+
+ static class SavedState extends BaseSavedState {
+ int transportState;
+ int appWidgetToShow = AppWidgetManager.INVALID_APPWIDGET_ID;
+
+ SavedState(Parcelable superState) {
+ super(superState);
+ }
+
+ private SavedState(Parcel in) {
+ super(in);
+ this.transportState = in.readInt();
+ this.appWidgetToShow = in.readInt();
+ }
+
+ @Override
+ public void writeToParcel(Parcel out, int flags) {
+ super.writeToParcel(out, flags);
+ out.writeInt(this.transportState);
+ out.writeInt(this.appWidgetToShow);
+ }
+
+ public static final Parcelable.Creator<SavedState> CREATOR
+ = new Parcelable.Creator<SavedState>() {
+ public SavedState createFromParcel(Parcel in) {
+ return new SavedState(in);
+ }
+
+ public SavedState[] newArray(int size) {
+ return new SavedState[size];
+ }
+ };
+ }
+
+ @Override
+ public Parcelable onSaveInstanceState() {
+ if (DEBUG) Log.d(TAG, "onSaveInstanceState");
+ Parcelable superState = super.onSaveInstanceState();
+ SavedState ss = new SavedState(superState);
+ ss.transportState = mViewStateManager.getTransportState();
+ ss.appWidgetToShow = mAppWidgetToShow;
+ return ss;
+ }
+
+ @Override
+ public void onRestoreInstanceState(Parcelable state) {
+ if (DEBUG) Log.d(TAG, "onRestoreInstanceState");
+ if (!(state instanceof SavedState)) {
+ super.onRestoreInstanceState(state);
+ return;
+ }
+ SavedState ss = (SavedState) state;
+ super.onRestoreInstanceState(ss.getSuperState());
+ mViewStateManager.setTransportState(ss.transportState);
+ mAppWidgetToShow = ss.appWidgetToShow;
+ post(mSwitchPageRunnable);
+ }
+
+ @Override
+ public void onWindowFocusChanged(boolean hasWindowFocus) {
+ super.onWindowFocusChanged(hasWindowFocus);
+ if (DEBUG) Log.d(TAG, "Window is " + (hasWindowFocus ? "focused" : "unfocused"));
+ if (hasWindowFocus && mShowSecurityWhenReturn) {
+ SlidingChallengeLayout slider =
+ (SlidingChallengeLayout) findViewById(R.id.sliding_layout);
+ if (slider != null) {
+ slider.setHandleAlpha(1);
+ slider.showChallenge(true);
+ }
+ mShowSecurityWhenReturn = false;
+ }
+ }
+
+ private void showAppropriateWidgetPage() {
+ int state = mViewStateManager.getTransportState();
+ boolean isMusicPlaying = mTransportControl.isMusicPlaying()
+ || state == KeyguardViewStateManager.TRANSPORT_VISIBLE;
+ if (isMusicPlaying) {
+ mViewStateManager.setTransportState(KeyguardViewStateManager.TRANSPORT_VISIBLE);
+ addTransportToWidgetPager();
+ } else if (state == KeyguardViewStateManager.TRANSPORT_VISIBLE) {
+ mViewStateManager.setTransportState(KeyguardViewStateManager.TRANSPORT_INVISIBLE);
+ }
+ int pageToShow = getAppropriateWidgetPage(isMusicPlaying);
+ mAppWidgetContainer.setCurrentPage(pageToShow);
+ }
+
+ private CameraWidgetFrame findCameraPage() {
+ for (int i = mAppWidgetContainer.getChildCount() - 1; i >= 0; i--) {
+ if (mAppWidgetContainer.isCameraPage(i)) {
+ return (CameraWidgetFrame) mAppWidgetContainer.getChildAt(i);
+ }
+ }
+ return null;
+ }
+
+ boolean isMusicPage(int pageIndex) {
+ return pageIndex >= 0 && pageIndex == getWidgetPosition(R.id.keyguard_transport_control);
+ }
+
+ private int getAppropriateWidgetPage(boolean isMusicPlaying) {
+ // assumes at least one widget (besides camera + add)
+ if (mAppWidgetToShow != AppWidgetManager.INVALID_APPWIDGET_ID) {
+ final int childCount = mAppWidgetContainer.getChildCount();
+ for (int i = 0; i < childCount; i++) {
+ if (mAppWidgetContainer.getWidgetPageAt(i).getContentAppWidgetId()
+ == mAppWidgetToShow) {
+ return i;
+ }
+ }
+ mAppWidgetToShow = AppWidgetManager.INVALID_APPWIDGET_ID;
+ }
+ // if music playing, show transport
+ if (isMusicPlaying) {
+ if (DEBUG) Log.d(TAG, "Music playing, show transport");
+ return mAppWidgetContainer.getWidgetPageIndex(mTransportControl);
+ }
+
+ // else show the right-most widget (except for camera)
+ int rightMost = mAppWidgetContainer.getChildCount() - 1;
+ if (mAppWidgetContainer.isCameraPage(rightMost)) {
+ rightMost--;
+ }
+ if (DEBUG) Log.d(TAG, "Show right-most page " + rightMost);
+ return rightMost;
+ }
+
+ private void enableUserSelectorIfNecessary() {
+ if (!UserManager.supportsMultipleUsers()) {
+ return; // device doesn't support multi-user mode
+ }
+ final UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
+ if (um == null) {
+ Throwable t = new Throwable();
+ t.fillInStackTrace();
+ Log.e(TAG, "user service is null.", t);
+ return;
+ }
+
+ // if there are multiple users, we need to enable to multi-user switcher
+ final List<UserInfo> users = um.getUsers(true);
+ if (users == null) {
+ Throwable t = new Throwable();
+ t.fillInStackTrace();
+ Log.e(TAG, "list of users is null.", t);
+ return;
+ }
+
+ final View multiUserView = findViewById(R.id.keyguard_user_selector);
+ if (multiUserView == null) {
+ Throwable t = new Throwable();
+ t.fillInStackTrace();
+ Log.e(TAG, "can't find user_selector in layout.", t);
+ return;
+ }
+
+ if (users.size() > 1) {
+ if (multiUserView instanceof KeyguardMultiUserSelectorView) {
+ mKeyguardMultiUserSelectorView = (KeyguardMultiUserSelectorView) multiUserView;
+ mKeyguardMultiUserSelectorView.setVisibility(View.VISIBLE);
+ mKeyguardMultiUserSelectorView.addUsers(users);
+ UserSwitcherCallback callback = new UserSwitcherCallback() {
+ @Override
+ public void hideSecurityView(int duration) {
+ mSecurityViewContainer.animate().alpha(0).setDuration(duration);
+ }
+
+ @Override
+ public void showSecurityView() {
+ mSecurityViewContainer.setAlpha(1.0f);
+ }
+
+ @Override
+ public void showUnlockHint() {
+ if (mKeyguardSelectorView != null) {
+ mKeyguardSelectorView.showUsabilityHint();
+ }
+ }
+
+ @Override
+ public void userActivity() {
+ if (mViewMediatorCallback != null) {
+ mViewMediatorCallback.userActivity();
+ }
+ }
+ };
+ mKeyguardMultiUserSelectorView.setCallback(callback);
+ } else {
+ Throwable t = new Throwable();
+ t.fillInStackTrace();
+ if (multiUserView == null) {
+ Log.e(TAG, "could not find the user_selector.", t);
+ } else {
+ Log.e(TAG, "user_selector is the wrong type.", t);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void cleanUp() {
+
+ }
+
+ /**
+ * In general, we enable unlocking the insecure keyguard with the menu key. However, there are
+ * some cases where we wish to disable it, notably when the menu button placement or technology
+ * is prone to false positives.
+ *
+ * @return true if the menu key should be enabled
+ */
+ private static final String ENABLE_MENU_KEY_FILE = "/data/local/enable_menu_key";
+ private boolean shouldEnableMenuKey() {
+ final Resources res = getResources();
+ final boolean configDisabled = res.getBoolean(R.bool.config_disableMenuKeyInLockScreen);
+ final boolean isTestHarness = ActivityManager.isRunningInTestHarness();
+ final boolean fileOverride = (new File(ENABLE_MENU_KEY_FILE)).exists();
+ return !configDisabled || isTestHarness || fileOverride;
+ }
+
+ public void goToWidget(int appWidgetId) {
+ mAppWidgetToShow = appWidgetId;
+ mSwitchPageRunnable.run();
+ }
+
+ public boolean handleMenuKey() {
+ // The following enables the MENU key to work for testing automation
+ if (shouldEnableMenuKey()) {
+ showNextSecurityScreenOrFinish(false);
+ return true;
+ }
+ return false;
+ }
+
+ public boolean handleBackKey() {
+ if (mCurrentSecuritySelection != SecurityMode.None) {
+ mCallback.dismiss(false);
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Dismisses the keyguard by going to the next screen or making it gone.
+ */
+ public void dismiss() {
+ showNextSecurityScreenOrFinish(false);
+ }
+
+ public void showAssistant() {
+ final Intent intent = ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE))
+ .getAssistIntent(mContext, true, UserHandle.USER_CURRENT);
+
+ if (intent == null) return;
+
+ final ActivityOptions opts = ActivityOptions.makeCustomAnimation(mContext,
+ R.anim.keyguard_action_assist_enter, R.anim.keyguard_action_assist_exit,
+ getHandler(), null);
+
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+
+ mActivityLauncher.launchActivityWithAnimation(
+ intent, false, opts.toBundle(), null, null);
+ }
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardLinearLayout.java b/packages/Keyguard/src/com/android/keyguard/KeyguardLinearLayout.java
new file mode 100644
index 0000000..343fdcb
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardLinearLayout.java
@@ -0,0 +1,46 @@
+/*
+ * 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.keyguard;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.LinearLayout;
+
+/**
+ * A layout that arranges its children into a special type of grid.
+ */
+public class KeyguardLinearLayout extends LinearLayout {
+ int mTopChild = 0;
+
+ public KeyguardLinearLayout(Context context) {
+ this(context, null, 0);
+ }
+
+ public KeyguardLinearLayout(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public KeyguardLinearLayout(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ public void setTopChild(View child) {
+ int top = indexOfChild(child);
+ mTopChild = top;
+ invalidate();
+ }
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardMessageArea.java b/packages/Keyguard/src/com/android/keyguard/KeyguardMessageArea.java
new file mode 100644
index 0000000..194162a
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardMessageArea.java
@@ -0,0 +1,305 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.keyguard;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ObjectAnimator;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.os.BatteryManager;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.SystemClock;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.text.TextUtils;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.TextView;
+
+import libcore.util.MutableInt;
+
+import java.lang.ref.WeakReference;
+/***
+ * Manages a number of views inside of the given layout. See below for a list of widgets.
+ */
+class KeyguardMessageArea extends TextView {
+ /** Handler token posted with accessibility announcement runnables. */
+ private static final Object ANNOUNCE_TOKEN = new Object();
+
+ /**
+ * Delay before speaking an accessibility announcement. Used to prevent
+ * lift-to-type from interrupting itself.
+ */
+ private static final long ANNOUNCEMENT_DELAY = 250;
+
+ static final int CHARGING_ICON = 0; //R.drawable.ic_lock_idle_charging;
+ static final int BATTERY_LOW_ICON = 0; //R.drawable.ic_lock_idle_low_battery;
+
+ static final int SECURITY_MESSAGE_DURATION = 5000;
+ protected static final int FADE_DURATION = 750;
+
+ // are we showing battery information?
+ boolean mShowingBatteryInfo = false;
+
+ // is the bouncer up?
+ boolean mShowingBouncer = false;
+
+ // last known plugged in state
+ boolean mCharging = false;
+
+ // last known battery level
+ int mBatteryLevel = 100;
+
+ KeyguardUpdateMonitor mUpdateMonitor;
+
+ // Timeout before we reset the message to show charging/owner info
+ long mTimeout = SECURITY_MESSAGE_DURATION;
+
+ // Shadowed text values
+ protected boolean mBatteryCharged;
+ protected boolean mBatteryIsLow;
+
+ private Handler mHandler;
+
+ CharSequence mMessage;
+ boolean mShowingMessage;
+ Runnable mClearMessageRunnable = new Runnable() {
+ @Override
+ public void run() {
+ mMessage = null;
+ mShowingMessage = false;
+ if (mShowingBouncer) {
+ hideMessage(FADE_DURATION, true);
+ } else {
+ update();
+ }
+ }
+ };
+
+ public static class Helper implements SecurityMessageDisplay {
+ KeyguardMessageArea mMessageArea;
+ Helper(View v) {
+ mMessageArea = (KeyguardMessageArea) v.findViewById(R.id.keyguard_message_area);
+ if (mMessageArea == null) {
+ throw new RuntimeException("Can't find keyguard_message_area in " + v.getClass());
+ }
+ }
+
+ public void setMessage(CharSequence msg, boolean important) {
+ if (!TextUtils.isEmpty(msg) && important) {
+ mMessageArea.mMessage = msg;
+ mMessageArea.securityMessageChanged();
+ }
+ }
+
+ public void setMessage(int resId, boolean important) {
+ if (resId != 0 && important) {
+ mMessageArea.mMessage = mMessageArea.getContext().getResources().getText(resId);
+ mMessageArea.securityMessageChanged();
+ }
+ }
+
+ public void setMessage(int resId, boolean important, Object... formatArgs) {
+ if (resId != 0 && important) {
+ mMessageArea.mMessage = mMessageArea.getContext().getString(resId, formatArgs);
+ mMessageArea.securityMessageChanged();
+ }
+ }
+
+ @Override
+ public void showBouncer(int duration) {
+ mMessageArea.hideMessage(duration, false);
+ mMessageArea.mShowingBouncer = true;
+ }
+
+ @Override
+ public void hideBouncer(int duration) {
+ mMessageArea.showMessage(duration);
+ mMessageArea.mShowingBouncer = false;
+ }
+
+ @Override
+ public void setTimeout(int timeoutMs) {
+ mMessageArea.mTimeout = timeoutMs;
+ }
+ }
+
+ private KeyguardUpdateMonitorCallback mInfoCallback = new KeyguardUpdateMonitorCallback() {
+ @Override
+ public void onRefreshBatteryInfo(KeyguardUpdateMonitor.BatteryStatus status) {
+ mShowingBatteryInfo = status.isPluggedIn() || status.isBatteryLow();
+ mCharging = status.status == BatteryManager.BATTERY_STATUS_CHARGING
+ || status.status == BatteryManager.BATTERY_STATUS_FULL;
+ mBatteryLevel = status.level;
+ mBatteryCharged = status.isCharged();
+ mBatteryIsLow = status.isBatteryLow();
+ update();
+ }
+ };
+
+ private CharSequence mSeparator;
+
+ public KeyguardMessageArea(Context context) {
+ this(context, null);
+ }
+
+ public KeyguardMessageArea(Context context, AttributeSet attrs) {
+ super(context, attrs);
+
+ // This is required to ensure marquee works
+ setSelected(true);
+
+ // Registering this callback immediately updates the battery state, among other things.
+ mUpdateMonitor = KeyguardUpdateMonitor.getInstance(getContext());
+ mUpdateMonitor.registerCallback(mInfoCallback);
+ mHandler = new Handler(Looper.myLooper());
+
+ mSeparator = getResources().getString(R.string.kg_text_message_separator);
+
+ update();
+ }
+
+ public void securityMessageChanged() {
+ setAlpha(1f);
+ mShowingMessage = true;
+ update();
+ mHandler.removeCallbacks(mClearMessageRunnable);
+ if (mTimeout > 0) {
+ mHandler.postDelayed(mClearMessageRunnable, mTimeout);
+ }
+ mHandler.removeCallbacksAndMessages(ANNOUNCE_TOKEN);
+ mHandler.postAtTime(new AnnounceRunnable(this, getText()), ANNOUNCE_TOKEN,
+ (SystemClock.uptimeMillis() + ANNOUNCEMENT_DELAY));
+ }
+
+ /**
+ * Update the status lines based on these rules:
+ * AlarmStatus: Alarm state always gets it's own line.
+ * Status1 is shared between help, battery status and generic unlock instructions,
+ * prioritized in that order.
+ * @param showStatusLines status lines are shown if true
+ */
+ void update() {
+ MutableInt icon = new MutableInt(0);
+ CharSequence status = concat(getChargeInfo(icon), getOwnerInfo(), getCurrentMessage());
+ setCompoundDrawablesWithIntrinsicBounds(icon.value, 0, 0, 0);
+ setText(status);
+ }
+
+ private CharSequence concat(CharSequence... args) {
+ StringBuilder b = new StringBuilder();
+ if (!TextUtils.isEmpty(args[0])) {
+ b.append(args[0]);
+ }
+ for (int i = 1; i < args.length; i++) {
+ CharSequence text = args[i];
+ if (!TextUtils.isEmpty(text)) {
+ if (b.length() > 0) {
+ b.append(mSeparator);
+ }
+ b.append(text);
+ }
+ }
+ return b.toString();
+ }
+
+ CharSequence getCurrentMessage() {
+ return mShowingMessage ? mMessage : null;
+ }
+
+ String getOwnerInfo() {
+ ContentResolver res = getContext().getContentResolver();
+ final boolean ownerInfoEnabled = Settings.Secure.getIntForUser(res,
+ Settings.Secure.LOCK_SCREEN_OWNER_INFO_ENABLED, 1, UserHandle.USER_CURRENT) != 0;
+ return ownerInfoEnabled && !mShowingMessage ?
+ Settings.Secure.getStringForUser(res, Settings.Secure.LOCK_SCREEN_OWNER_INFO,
+ UserHandle.USER_CURRENT) : null;
+ }
+
+ private CharSequence getChargeInfo(MutableInt icon) {
+ CharSequence string = null;
+ if (mShowingBatteryInfo && !mShowingMessage) {
+ // Battery status
+ if (mCharging) {
+ // Charging, charged or waiting to charge.
+ string = getContext().getString(mBatteryCharged
+ ? R.string.keyguard_charged
+ : R.string.keyguard_plugged_in, mBatteryLevel);
+ icon.value = CHARGING_ICON;
+ } else if (mBatteryIsLow) {
+ // Battery is low
+ string = getContext().getString(R.string.keyguard_low_battery);
+ icon.value = BATTERY_LOW_ICON;
+ }
+ }
+ return string;
+ }
+
+ private void hideMessage(int duration, boolean thenUpdate) {
+ if (duration > 0) {
+ Animator anim = ObjectAnimator.ofFloat(this, "alpha", 0f);
+ anim.setDuration(duration);
+ if (thenUpdate) {
+ anim.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ update();
+ }
+ });
+ }
+ anim.start();
+ } else {
+ setAlpha(0f);
+ if (thenUpdate) {
+ update();
+ }
+ }
+ }
+
+ private void showMessage(int duration) {
+ if (duration > 0) {
+ Animator anim = ObjectAnimator.ofFloat(this, "alpha", 1f);
+ anim.setDuration(duration);
+ anim.start();
+ } else {
+ setAlpha(1f);
+ }
+ }
+
+ /**
+ * Runnable used to delay accessibility announcements.
+ */
+ private static class AnnounceRunnable implements Runnable {
+ private final WeakReference<View> mHost;
+ private final CharSequence mTextToAnnounce;
+
+ public AnnounceRunnable(View host, CharSequence textToAnnounce) {
+ mHost = new WeakReference<View>(host);
+ mTextToAnnounce = textToAnnounce;
+ }
+
+ @Override
+ public void run() {
+ final View host = mHost.get();
+ if (host != null) {
+ host.announceForAccessibility(mTextToAnnounce);
+ }
+ }
+ }
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardMultiUserAvatar.java b/packages/Keyguard/src/com/android/keyguard/KeyguardMultiUserAvatar.java
new file mode 100644
index 0000000..7ef5b26
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardMultiUserAvatar.java
@@ -0,0 +1,229 @@
+/*
+ * 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.keyguard;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ValueAnimator.AnimatorUpdateListener;
+import android.animation.ValueAnimator;
+import android.content.Context;
+import android.content.pm.UserInfo;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Color;
+import android.os.UserManager;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+class KeyguardMultiUserAvatar extends FrameLayout {
+ private static final String TAG = KeyguardMultiUserAvatar.class.getSimpleName();
+ private static final boolean DEBUG = KeyguardHostView.DEBUG;
+
+ private ImageView mUserImage;
+ private TextView mUserName;
+ private UserInfo mUserInfo;
+ private static final float ACTIVE_ALPHA = 1.0f;
+ private static final float INACTIVE_ALPHA = 1.0f;
+ private static final float ACTIVE_SCALE = 1.5f;
+ private static final float ACTIVE_TEXT_ALPHA = 0f;
+ private static final float INACTIVE_TEXT_ALPHA = 0.5f;
+ private static final int SWITCH_ANIMATION_DURATION = 150;
+
+ private final float mActiveAlpha;
+ private final float mActiveScale;
+ private final float mActiveTextAlpha;
+ private final float mInactiveAlpha;
+ private final float mInactiveTextAlpha;
+ private final float mShadowRadius;
+ private final float mStroke;
+ private final float mIconSize;
+ private final int mFrameColor;
+ private final int mFrameShadowColor;
+ private final int mTextColor;
+ private final int mHighlightColor;
+
+ private boolean mTouched;
+
+ private boolean mActive;
+ private boolean mInit = true;
+ private KeyguardMultiUserSelectorView mUserSelector;
+ private KeyguardCircleFramedDrawable mFramed;
+ private boolean mPressLock;
+ private UserManager mUserManager;
+
+ public static KeyguardMultiUserAvatar fromXml(int resId, Context context,
+ KeyguardMultiUserSelectorView userSelector, UserInfo info) {
+ KeyguardMultiUserAvatar icon = (KeyguardMultiUserAvatar)
+ LayoutInflater.from(context).inflate(resId, userSelector, false);
+
+ icon.init(info, userSelector);
+ return icon;
+ }
+
+ public KeyguardMultiUserAvatar(Context context) {
+ this(context, null, 0);
+ }
+
+ public KeyguardMultiUserAvatar(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public KeyguardMultiUserAvatar(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+
+ Resources res = mContext.getResources();
+ mTextColor = res.getColor(R.color.keyguard_avatar_nick_color);
+ mIconSize = res.getDimension(R.dimen.keyguard_avatar_size);
+ mStroke = res.getDimension(R.dimen.keyguard_avatar_frame_stroke_width);
+ mShadowRadius = res.getDimension(R.dimen.keyguard_avatar_frame_shadow_radius);
+ mFrameColor = res.getColor(R.color.keyguard_avatar_frame_color);
+ mFrameShadowColor = res.getColor(R.color.keyguard_avatar_frame_shadow_color);
+ mHighlightColor = res.getColor(R.color.keyguard_avatar_frame_pressed_color);
+ mActiveTextAlpha = ACTIVE_TEXT_ALPHA;
+ mInactiveTextAlpha = INACTIVE_TEXT_ALPHA;
+ mActiveScale = ACTIVE_SCALE;
+ mActiveAlpha = ACTIVE_ALPHA;
+ mInactiveAlpha = INACTIVE_ALPHA;
+ mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
+
+ mTouched = false;
+
+ setLayerType(View.LAYER_TYPE_SOFTWARE, null);
+ }
+
+ protected String rewriteIconPath(String path) {
+ return path;
+ }
+
+ public void init(UserInfo user, KeyguardMultiUserSelectorView userSelector) {
+ mUserInfo = user;
+ mUserSelector = userSelector;
+
+ mUserImage = (ImageView) findViewById(R.id.keyguard_user_avatar);
+ mUserName = (TextView) findViewById(R.id.keyguard_user_name);
+
+ Bitmap icon = mUserManager.getUserIcon(user.id);
+
+ if (icon == null) {
+ if (DEBUG) Log.w(TAG, "Couldn't get user icon for user id " + user.id);
+ icon = BitmapFactory.decodeResource(mContext.getResources(),
+ R.drawable.ic_contact_picture);
+ }
+
+ mFramed = new KeyguardCircleFramedDrawable(icon, (int) mIconSize, mFrameColor, mStroke,
+ mFrameShadowColor, mShadowRadius, mHighlightColor);
+ mUserImage.setImageDrawable(mFramed);
+ mUserName.setText(mUserInfo.name);
+ setOnClickListener(mUserSelector);
+ mInit = false;
+ }
+
+ public void setActive(boolean active, boolean animate, final Runnable onComplete) {
+ if (mActive != active || mInit) {
+ mActive = active;
+
+ if (active) {
+ KeyguardLinearLayout parent = (KeyguardLinearLayout) getParent();
+ parent.setTopChild(this);
+ // TODO: Create an appropriate asset when string changes are possible.
+ setContentDescription(mUserName.getText()
+ + ". " + mContext.getString(R.string.user_switched, ""));
+ } else {
+ setContentDescription(mUserName.getText());
+ }
+ }
+ updateVisualsForActive(mActive, animate, SWITCH_ANIMATION_DURATION, onComplete);
+ }
+
+ void updateVisualsForActive(boolean active, boolean animate, int duration,
+ final Runnable onComplete) {
+ final float finalAlpha = active ? mActiveAlpha : mInactiveAlpha;
+ final float initAlpha = active ? mInactiveAlpha : mActiveAlpha;
+ final float finalScale = active ? 1f : 1f / mActiveScale;
+ final float initScale = mFramed.getScale();
+ final int finalTextAlpha = active ? (int) (mActiveTextAlpha * 255) :
+ (int) (mInactiveTextAlpha * 255);
+ final int initTextAlpha = active ? (int) (mInactiveTextAlpha * 255) :
+ (int) (mActiveTextAlpha * 255);
+ int textColor = mTextColor;
+ mUserName.setTextColor(textColor);
+
+ if (animate && mTouched) {
+ ValueAnimator va = ValueAnimator.ofFloat(0f, 1f);
+ va.addUpdateListener(new AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ float r = animation.getAnimatedFraction();
+ float scale = (1 - r) * initScale + r * finalScale;
+ float alpha = (1 - r) * initAlpha + r * finalAlpha;
+ int textAlpha = (int) ((1 - r) * initTextAlpha + r * finalTextAlpha);
+ mFramed.setScale(scale);
+ mUserImage.setAlpha(alpha);
+ mUserName.setTextColor(Color.argb(textAlpha, 255, 255, 255));
+ mUserImage.invalidate();
+ }
+ });
+ va.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ if (onComplete != null) {
+ onComplete.run();
+ }
+ }
+ });
+ va.setDuration(duration);
+ va.start();
+ } else {
+ mFramed.setScale(finalScale);
+ mUserImage.setAlpha(finalAlpha);
+ mUserName.setTextColor(Color.argb(finalTextAlpha, 255, 255, 255));
+ if (onComplete != null) {
+ post(onComplete);
+ }
+ }
+
+ mTouched = true;
+ }
+
+ @Override
+ public void setPressed(boolean pressed) {
+ if (mPressLock && !pressed) {
+ return;
+ }
+
+ if (mPressLock || !pressed || isClickable()) {
+ super.setPressed(pressed);
+ mFramed.setPressed(pressed);
+ mUserImage.invalidate();
+ }
+ }
+
+ public void lockPressed(boolean pressed) {
+ mPressLock = pressed;
+ setPressed(pressed);
+ }
+
+ public UserInfo getUserInfo() {
+ return mUserInfo;
+ }
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardMultiUserSelectorView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardMultiUserSelectorView.java
new file mode 100644
index 0000000..7975d8e
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardMultiUserSelectorView.java
@@ -0,0 +1,166 @@
+/*
+ * 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.keyguard;
+
+import android.app.ActivityManagerNative;
+import android.content.Context;
+import android.content.pm.UserInfo;
+import android.os.RemoteException;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.FrameLayout;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+
+public class KeyguardMultiUserSelectorView extends FrameLayout implements View.OnClickListener {
+ private static final String TAG = "KeyguardMultiUserSelectorView";
+
+ private ViewGroup mUsersGrid;
+ private KeyguardMultiUserAvatar mActiveUserAvatar;
+ private KeyguardHostView.UserSwitcherCallback mCallback;
+ private static final int FADE_OUT_ANIMATION_DURATION = 100;
+
+ public KeyguardMultiUserSelectorView(Context context) {
+ this(context, null, 0);
+ }
+
+ public KeyguardMultiUserSelectorView(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public KeyguardMultiUserSelectorView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ protected void onFinishInflate () {
+ mUsersGrid = (ViewGroup) findViewById(R.id.keyguard_users_grid);
+ mUsersGrid.removeAllViews();
+ setClipChildren(false);
+ setClipToPadding(false);
+
+ }
+
+ public void setCallback(KeyguardHostView.UserSwitcherCallback callback) {
+ mCallback = callback;
+ }
+
+ public void addUsers(Collection<UserInfo> userList) {
+ UserInfo activeUser;
+ try {
+ activeUser = ActivityManagerNative.getDefault().getCurrentUser();
+ } catch (RemoteException re) {
+ activeUser = null;
+ }
+
+ ArrayList<UserInfo> users = new ArrayList<UserInfo>(userList);
+ Collections.sort(users, mOrderAddedComparator);
+
+ for (UserInfo user: users) {
+ KeyguardMultiUserAvatar uv = createAndAddUser(user);
+ if (user.id == activeUser.id) {
+ mActiveUserAvatar = uv;
+ }
+ uv.setActive(false, false, null);
+ }
+ mActiveUserAvatar.lockPressed(true);
+ }
+
+ public void finalizeActiveUserView(boolean animate) {
+ if (animate) {
+ getHandler().postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ finalizeActiveUserNow(true);
+ }
+ }, 500);
+ } else {
+ finalizeActiveUserNow(animate);
+ }
+ }
+
+ void finalizeActiveUserNow(boolean animate) {
+ mActiveUserAvatar.lockPressed(false);
+ mActiveUserAvatar.setActive(true, animate, null);
+ }
+
+ Comparator<UserInfo> mOrderAddedComparator = new Comparator<UserInfo>() {
+ @Override
+ public int compare(UserInfo lhs, UserInfo rhs) {
+ return (lhs.serialNumber - rhs.serialNumber);
+ }
+ };
+
+ private KeyguardMultiUserAvatar createAndAddUser(UserInfo user) {
+ KeyguardMultiUserAvatar uv = KeyguardMultiUserAvatar.fromXml(
+ R.layout.keyguard_multi_user_avatar, mContext, this, user);
+ mUsersGrid.addView(uv);
+ return uv;
+ }
+
+ @Override
+ public boolean onInterceptTouchEvent(MotionEvent event) {
+ if(event.getActionMasked() != MotionEvent.ACTION_CANCEL && mCallback != null) {
+ mCallback.userActivity();
+ }
+ return false;
+ }
+
+ private void setAllClickable(boolean clickable)
+ {
+ for(int i = 0; i < mUsersGrid.getChildCount(); i++) {
+ View v = mUsersGrid.getChildAt(i);
+ v.setClickable(clickable);
+ v.setPressed(false);
+ }
+ }
+
+ @Override
+ public void onClick(View v) {
+ if (!(v instanceof KeyguardMultiUserAvatar)) return;
+ final KeyguardMultiUserAvatar avatar = (KeyguardMultiUserAvatar) v;
+ if (avatar.isClickable()) { // catch race conditions
+ if (mActiveUserAvatar == avatar) {
+ // If they click the currently active user, show the unlock hint
+ mCallback.showUnlockHint();
+ return;
+ } else {
+ // Reset the previously active user to appear inactive
+ mCallback.hideSecurityView(FADE_OUT_ANIMATION_DURATION);
+ setAllClickable(false);
+ avatar.lockPressed(true);
+ mActiveUserAvatar.setActive(false, true, new Runnable() {
+ @Override
+ public void run() {
+ mActiveUserAvatar = avatar;
+ try {
+ ActivityManagerNative.getDefault()
+ .switchUser(avatar.getUserInfo().id);
+ } catch (RemoteException re) {
+ Log.e(TAG, "Couldn't switch user " + re);
+ }
+ }
+ });
+ }
+ }
+ }
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardPINView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardPINView.java
new file mode 100644
index 0000000..3d1c3f3
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardPINView.java
@@ -0,0 +1,118 @@
+/*
+ * 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.keyguard;
+
+import android.content.Context;
+import android.text.Editable;
+import android.text.InputType;
+import android.text.TextWatcher;
+import android.text.method.DigitsKeyListener;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.TextView.OnEditorActionListener;
+
+/**
+ * Displays a PIN pad for unlocking.
+ */
+public class KeyguardPINView extends KeyguardAbsKeyInputView
+ implements KeyguardSecurityView, OnEditorActionListener, TextWatcher {
+
+ public KeyguardPINView(Context context) {
+ this(context, null);
+ }
+
+ public KeyguardPINView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ protected void resetState() {
+ if (KeyguardUpdateMonitor.getInstance(mContext).getMaxBiometricUnlockAttemptsReached()) {
+ mSecurityMessageDisplay.setMessage(R.string.faceunlock_multiple_failures, true);
+ } else {
+ mSecurityMessageDisplay.setMessage(R.string.kg_pin_instructions, false);
+ }
+ mPasswordEntry.setEnabled(true);
+ }
+
+ @Override
+ protected int getPasswordTextViewId() {
+ return R.id.pinEntry;
+ }
+
+ @Override
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+
+ final View ok = findViewById(R.id.key_enter);
+ if (ok != null) {
+ ok.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ doHapticKeyClick();
+ if (mPasswordEntry.isEnabled()) {
+ verifyPasswordAndUnlock();
+ }
+ }
+ });
+ ok.setOnHoverListener(new LiftToActivateListener(getContext()));
+ }
+
+ // The delete button is of the PIN keyboard itself in some (e.g. tablet) layouts,
+ // not a separate view
+ View pinDelete = findViewById(R.id.delete_button);
+ if (pinDelete != null) {
+ pinDelete.setVisibility(View.VISIBLE);
+ pinDelete.setOnClickListener(new OnClickListener() {
+ public void onClick(View v) {
+ // check for time-based lockouts
+ if (mPasswordEntry.isEnabled()) {
+ CharSequence str = mPasswordEntry.getText();
+ if (str.length() > 0) {
+ mPasswordEntry.setText(str.subSequence(0, str.length()-1));
+ }
+ }
+ doHapticKeyClick();
+ }
+ });
+ pinDelete.setOnLongClickListener(new View.OnLongClickListener() {
+ public boolean onLongClick(View v) {
+ // check for time-based lockouts
+ if (mPasswordEntry.isEnabled()) {
+ mPasswordEntry.setText("");
+ }
+ doHapticKeyClick();
+ return true;
+ }
+ });
+ }
+
+ mPasswordEntry.setKeyListener(DigitsKeyListener.getInstance());
+ mPasswordEntry.setInputType(InputType.TYPE_CLASS_NUMBER
+ | InputType.TYPE_NUMBER_VARIATION_PASSWORD);
+
+ mPasswordEntry.requestFocus();
+ }
+
+ @Override
+ public void showUsabilityHint() {
+ }
+
+ @Override
+ public int getWrongPasswordStringId() {
+ return R.string.kg_wrong_pin;
+ }
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardPasswordView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardPasswordView.java
new file mode 100644
index 0000000..4e3568b
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardPasswordView.java
@@ -0,0 +1,207 @@
+/*
+ * 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.keyguard;
+
+import android.app.admin.DevicePolicyManager;
+import android.content.Context;
+import android.content.res.Configuration;
+import android.text.Editable;
+import android.text.InputType;
+import android.text.TextWatcher;
+import android.text.method.DigitsKeyListener;
+import android.text.method.TextKeyListener;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.inputmethod.InputMethodInfo;
+import android.view.inputmethod.InputMethodManager;
+import android.view.inputmethod.InputMethodSubtype;
+import android.widget.TextView.OnEditorActionListener;
+
+import com.android.internal.widget.PasswordEntryKeyboardHelper;
+import com.android.internal.widget.PasswordEntryKeyboardView;
+
+import java.util.List;
+/**
+ * Displays an alphanumeric (latin-1) key entry for the user to enter
+ * an unlock password
+ */
+
+public class KeyguardPasswordView extends KeyguardAbsKeyInputView
+ implements KeyguardSecurityView, OnEditorActionListener, TextWatcher {
+
+ private final boolean mShowImeAtScreenOn;
+
+ InputMethodManager mImm;
+
+ public KeyguardPasswordView(Context context) {
+ this(context, null);
+ }
+
+ public KeyguardPasswordView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ mShowImeAtScreenOn = context.getResources().
+ getBoolean(R.bool.kg_show_ime_at_screen_on);
+ }
+
+ protected void resetState() {
+ mSecurityMessageDisplay.setMessage(R.string.kg_password_instructions, false);
+ mPasswordEntry.setEnabled(true);
+ }
+
+ @Override
+ protected int getPasswordTextViewId() {
+ return R.id.passwordEntry;
+ }
+
+ @Override
+ public boolean needsInput() {
+ return true;
+ }
+
+ @Override
+ public void onResume(int reason) {
+ super.onResume(reason);
+ mPasswordEntry.requestFocus();
+ if (reason != KeyguardSecurityView.SCREEN_ON || mShowImeAtScreenOn) {
+ mImm.showSoftInput(mPasswordEntry, InputMethodManager.SHOW_IMPLICIT);
+ }
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ mImm.hideSoftInputFromWindow(getWindowToken(), 0);
+ }
+
+ @Override
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+
+ boolean imeOrDeleteButtonVisible = false;
+
+ mImm = (InputMethodManager) getContext().getSystemService(
+ Context.INPUT_METHOD_SERVICE);
+
+ mPasswordEntry.setKeyListener(TextKeyListener.getInstance());
+ mPasswordEntry.setInputType(InputType.TYPE_CLASS_TEXT
+ | InputType.TYPE_TEXT_VARIATION_PASSWORD);
+
+ // Poke the wakelock any time the text is selected or modified
+ mPasswordEntry.setOnClickListener(new OnClickListener() {
+ public void onClick(View v) {
+ mCallback.userActivity(0); // TODO: customize timeout for text?
+ }
+ });
+
+ mPasswordEntry.addTextChangedListener(new TextWatcher() {
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
+ }
+
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+ }
+
+ public void afterTextChanged(Editable s) {
+ if (mCallback != null) {
+ mCallback.userActivity(0);
+ }
+ }
+ });
+
+ mPasswordEntry.requestFocus();
+
+ // If there's more than one IME, enable the IME switcher button
+ View switchImeButton = findViewById(R.id.switch_ime_button);
+ if (switchImeButton != null && hasMultipleEnabledIMEsOrSubtypes(mImm, false)) {
+ switchImeButton.setVisibility(View.VISIBLE);
+ imeOrDeleteButtonVisible = true;
+ switchImeButton.setOnClickListener(new OnClickListener() {
+ public void onClick(View v) {
+ mCallback.userActivity(0); // Leave the screen on a bit longer
+ mImm.showInputMethodPicker();
+ }
+ });
+ }
+
+ // If no icon is visible, reset the start margin on the password field so the text is
+ // still centered.
+ if (!imeOrDeleteButtonVisible) {
+ android.view.ViewGroup.LayoutParams params = mPasswordEntry.getLayoutParams();
+ if (params instanceof MarginLayoutParams) {
+ final MarginLayoutParams mlp = (MarginLayoutParams) params;
+ mlp.setMarginStart(0);
+ mPasswordEntry.setLayoutParams(params);
+ }
+ }
+ }
+
+ /**
+ * Method adapted from com.android.inputmethod.latin.Utils
+ *
+ * @param imm The input method manager
+ * @param shouldIncludeAuxiliarySubtypes
+ * @return true if we have multiple IMEs to choose from
+ */
+ private boolean hasMultipleEnabledIMEsOrSubtypes(InputMethodManager imm,
+ final boolean shouldIncludeAuxiliarySubtypes) {
+ final List<InputMethodInfo> enabledImis = imm.getEnabledInputMethodList();
+
+ // Number of the filtered IMEs
+ int filteredImisCount = 0;
+
+ for (InputMethodInfo imi : enabledImis) {
+ // We can return true immediately after we find two or more filtered IMEs.
+ if (filteredImisCount > 1) return true;
+ final List<InputMethodSubtype> subtypes =
+ imm.getEnabledInputMethodSubtypeList(imi, true);
+ // IMEs that have no subtypes should be counted.
+ if (subtypes.isEmpty()) {
+ ++filteredImisCount;
+ continue;
+ }
+
+ int auxCount = 0;
+ for (InputMethodSubtype subtype : subtypes) {
+ if (subtype.isAuxiliary()) {
+ ++auxCount;
+ }
+ }
+ final int nonAuxCount = subtypes.size() - auxCount;
+
+ // IMEs that have one or more non-auxiliary subtypes should be counted.
+ // If shouldIncludeAuxiliarySubtypes is true, IMEs that have two or more auxiliary
+ // subtypes should be counted as well.
+ if (nonAuxCount > 0 || (shouldIncludeAuxiliarySubtypes && auxCount > 1)) {
+ ++filteredImisCount;
+ continue;
+ }
+ }
+
+ return filteredImisCount > 1
+ // imm.getEnabledInputMethodSubtypeList(null, false) will return the current IME's enabled
+ // input method subtype (The current IME should be LatinIME.)
+ || imm.getEnabledInputMethodSubtypeList(null, false).size() > 1;
+ }
+
+ @Override
+ public void showUsabilityHint() {
+ }
+
+ @Override
+ public int getWrongPasswordStringId() {
+ return R.string.kg_wrong_password;
+ }
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java
new file mode 100644
index 0000000..e7f1259
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java
@@ -0,0 +1,411 @@
+/*
+ * 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.keyguard;
+
+import android.accounts.Account;
+import android.accounts.AccountManager;
+import android.accounts.AccountManagerCallback;
+import android.accounts.AccountManagerFuture;
+import android.accounts.AuthenticatorException;
+import android.accounts.OperationCanceledException;
+import android.content.Context;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+import android.os.CountDownTimer;
+import android.os.SystemClock;
+import android.os.UserHandle;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.MotionEvent;
+import android.view.View;
+import android.widget.Button;
+import android.widget.LinearLayout;
+
+import com.android.internal.widget.LockPatternUtils;
+import com.android.internal.widget.LockPatternView;
+
+import java.io.IOException;
+import java.util.List;
+
+public class KeyguardPatternView extends LinearLayout implements KeyguardSecurityView {
+
+ private static final String TAG = "SecurityPatternView";
+ private static final boolean DEBUG = false;
+
+ // how long before we clear the wrong pattern
+ private static final int PATTERN_CLEAR_TIMEOUT_MS = 2000;
+
+ // how long we stay awake after each key beyond MIN_PATTERN_BEFORE_POKE_WAKELOCK
+ private static final int UNLOCK_PATTERN_WAKE_INTERVAL_MS = 7000;
+
+ // how long we stay awake after the user hits the first dot.
+ private static final int UNLOCK_PATTERN_WAKE_INTERVAL_FIRST_DOTS_MS = 2000;
+
+ // how many cells the user has to cross before we poke the wakelock
+ private static final int MIN_PATTERN_BEFORE_POKE_WAKELOCK = 2;
+
+ private int mFailedPatternAttemptsSinceLastTimeout = 0;
+ private int mTotalFailedPatternAttempts = 0;
+ private CountDownTimer mCountdownTimer = null;
+ private LockPatternUtils mLockPatternUtils;
+ private LockPatternView mLockPatternView;
+ private Button mForgotPatternButton;
+ private KeyguardSecurityCallback mCallback;
+ private boolean mEnableFallback;
+
+ /**
+ * Keeps track of the last time we poked the wake lock during dispatching of the touch event.
+ * Initialized to something guaranteed to make us poke the wakelock when the user starts
+ * drawing the pattern.
+ * @see #dispatchTouchEvent(android.view.MotionEvent)
+ */
+ private long mLastPokeTime = -UNLOCK_PATTERN_WAKE_INTERVAL_MS;
+
+ /**
+ * Useful for clearing out the wrong pattern after a delay
+ */
+ private Runnable mCancelPatternRunnable = new Runnable() {
+ public void run() {
+ mLockPatternView.clearPattern();
+ }
+ };
+ private Rect mTempRect = new Rect();
+ private SecurityMessageDisplay mSecurityMessageDisplay;
+ private View mEcaView;
+ private Drawable mBouncerFrame;
+
+ enum FooterMode {
+ Normal,
+ ForgotLockPattern,
+ VerifyUnlocked
+ }
+
+ public KeyguardPatternView(Context context) {
+ this(context, null);
+ }
+
+ public KeyguardPatternView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public void setKeyguardCallback(KeyguardSecurityCallback callback) {
+ mCallback = callback;
+ }
+
+ public void setLockPatternUtils(LockPatternUtils utils) {
+ mLockPatternUtils = utils;
+ }
+
+ @Override
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+ mLockPatternUtils = mLockPatternUtils == null
+ ? new LockPatternUtils(mContext) : mLockPatternUtils;
+
+ mLockPatternView = (LockPatternView) findViewById(R.id.lockPatternView);
+ mLockPatternView.setSaveEnabled(false);
+ mLockPatternView.setFocusable(false);
+ mLockPatternView.setOnPatternListener(new UnlockPatternListener());
+
+ // stealth mode will be the same for the life of this screen
+ mLockPatternView.setInStealthMode(!mLockPatternUtils.isVisiblePatternEnabled());
+
+ // vibrate mode will be the same for the life of this screen
+ mLockPatternView.setTactileFeedbackEnabled(mLockPatternUtils.isTactileFeedbackEnabled());
+
+ mForgotPatternButton = (Button) findViewById(R.id.forgot_password_button);
+ // note: some configurations don't have an emergency call area
+ if (mForgotPatternButton != null) {
+ mForgotPatternButton.setText(R.string.kg_forgot_pattern_button_text);
+ mForgotPatternButton.setOnClickListener(new OnClickListener() {
+ public void onClick(View v) {
+ mCallback.showBackupSecurity();
+ }
+ });
+ }
+
+ setFocusableInTouchMode(true);
+
+ maybeEnableFallback(mContext);
+ mSecurityMessageDisplay = new KeyguardMessageArea.Helper(this);
+ mEcaView = findViewById(R.id.keyguard_selector_fade_container);
+ View bouncerFrameView = findViewById(R.id.keyguard_bouncer_frame);
+ if (bouncerFrameView != null) {
+ mBouncerFrame = bouncerFrameView.getBackground();
+ }
+ }
+
+ private void updateFooter(FooterMode mode) {
+ if (mForgotPatternButton == null) return; // no ECA? no footer
+
+ switch (mode) {
+ case Normal:
+ if (DEBUG) Log.d(TAG, "mode normal");
+ mForgotPatternButton.setVisibility(View.GONE);
+ break;
+ case ForgotLockPattern:
+ if (DEBUG) Log.d(TAG, "mode ForgotLockPattern");
+ mForgotPatternButton.setVisibility(View.VISIBLE);
+ break;
+ case VerifyUnlocked:
+ if (DEBUG) Log.d(TAG, "mode VerifyUnlocked");
+ mForgotPatternButton.setVisibility(View.GONE);
+ }
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent ev) {
+ boolean result = super.onTouchEvent(ev);
+ // as long as the user is entering a pattern (i.e sending a touch event that was handled
+ // by this screen), keep poking the wake lock so that the screen will stay on.
+ final long elapsed = SystemClock.elapsedRealtime() - mLastPokeTime;
+ if (result && (elapsed > (UNLOCK_PATTERN_WAKE_INTERVAL_MS - 100))) {
+ mLastPokeTime = SystemClock.elapsedRealtime();
+ }
+ mTempRect.set(0, 0, 0, 0);
+ offsetRectIntoDescendantCoords(mLockPatternView, mTempRect);
+ ev.offsetLocation(mTempRect.left, mTempRect.top);
+ result = mLockPatternView.dispatchTouchEvent(ev) || result;
+ ev.offsetLocation(-mTempRect.left, -mTempRect.top);
+ return result;
+ }
+
+ public void reset() {
+ // reset lock pattern
+ mLockPatternView.enableInput();
+ mLockPatternView.setEnabled(true);
+ mLockPatternView.clearPattern();
+
+ // if the user is currently locked out, enforce it.
+ long deadline = mLockPatternUtils.getLockoutAttemptDeadline();
+ if (deadline != 0) {
+ handleAttemptLockout(deadline);
+ } else {
+ displayDefaultSecurityMessage();
+ }
+
+ // the footer depends on how many total attempts the user has failed
+ if (mCallback.isVerifyUnlockOnly()) {
+ updateFooter(FooterMode.VerifyUnlocked);
+ } else if (mEnableFallback &&
+ (mTotalFailedPatternAttempts >= LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT)) {
+ updateFooter(FooterMode.ForgotLockPattern);
+ } else {
+ updateFooter(FooterMode.Normal);
+ }
+
+ }
+
+ private void displayDefaultSecurityMessage() {
+ if (KeyguardUpdateMonitor.getInstance(mContext).getMaxBiometricUnlockAttemptsReached()) {
+ mSecurityMessageDisplay.setMessage(R.string.faceunlock_multiple_failures, true);
+ } else {
+ mSecurityMessageDisplay.setMessage(R.string.kg_pattern_instructions, false);
+ }
+ }
+
+ @Override
+ public void showUsabilityHint() {
+ }
+
+ /** TODO: hook this up */
+ public void cleanUp() {
+ if (DEBUG) Log.v(TAG, "Cleanup() called on " + this);
+ mLockPatternUtils = null;
+ mLockPatternView.setOnPatternListener(null);
+ }
+
+ @Override
+ public void onWindowFocusChanged(boolean hasWindowFocus) {
+ super.onWindowFocusChanged(hasWindowFocus);
+ if (hasWindowFocus) {
+ // when timeout dialog closes we want to update our state
+ reset();
+ }
+ }
+
+ private class UnlockPatternListener implements LockPatternView.OnPatternListener {
+
+ public void onPatternStart() {
+ mLockPatternView.removeCallbacks(mCancelPatternRunnable);
+ }
+
+ public void onPatternCleared() {
+ }
+
+ public void onPatternCellAdded(List<LockPatternView.Cell> pattern) {
+ // To guard against accidental poking of the wakelock, look for
+ // the user actually trying to draw a pattern of some minimal length.
+ if (pattern.size() > MIN_PATTERN_BEFORE_POKE_WAKELOCK) {
+ mCallback.userActivity(UNLOCK_PATTERN_WAKE_INTERVAL_MS);
+ } else {
+ // Give just a little extra time if they hit one of the first few dots
+ mCallback.userActivity(UNLOCK_PATTERN_WAKE_INTERVAL_FIRST_DOTS_MS);
+ }
+ }
+
+ public void onPatternDetected(List<LockPatternView.Cell> pattern) {
+ if (mLockPatternUtils.checkPattern(pattern)) {
+ mCallback.reportSuccessfulUnlockAttempt();
+ mLockPatternView.setDisplayMode(LockPatternView.DisplayMode.Correct);
+ mTotalFailedPatternAttempts = 0;
+ mCallback.dismiss(true);
+ } else {
+ if (pattern.size() > MIN_PATTERN_BEFORE_POKE_WAKELOCK) {
+ mCallback.userActivity(UNLOCK_PATTERN_WAKE_INTERVAL_MS);
+ }
+ mLockPatternView.setDisplayMode(LockPatternView.DisplayMode.Wrong);
+ if (pattern.size() >= LockPatternUtils.MIN_PATTERN_REGISTER_FAIL) {
+ mTotalFailedPatternAttempts++;
+ mFailedPatternAttemptsSinceLastTimeout++;
+ mCallback.reportFailedUnlockAttempt();
+ }
+ if (mFailedPatternAttemptsSinceLastTimeout
+ >= LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT) {
+ long deadline = mLockPatternUtils.setLockoutAttemptDeadline();
+ handleAttemptLockout(deadline);
+ } else {
+ mSecurityMessageDisplay.setMessage(R.string.kg_wrong_pattern, true);
+ mLockPatternView.postDelayed(mCancelPatternRunnable, PATTERN_CLEAR_TIMEOUT_MS);
+ }
+ }
+ }
+ }
+
+ private void maybeEnableFallback(Context context) {
+ // Ask the account manager if we have an account that can be used as a
+ // fallback in case the user forgets his pattern.
+ AccountAnalyzer accountAnalyzer = new AccountAnalyzer(AccountManager.get(context));
+ accountAnalyzer.start();
+ }
+
+ private class AccountAnalyzer implements AccountManagerCallback<Bundle> {
+ private final AccountManager mAccountManager;
+ private final Account[] mAccounts;
+ private int mAccountIndex;
+
+ private AccountAnalyzer(AccountManager accountManager) {
+ mAccountManager = accountManager;
+ mAccounts = accountManager.getAccountsByTypeAsUser("com.google",
+ new UserHandle(mLockPatternUtils.getCurrentUser()));
+ }
+
+ private void next() {
+ // if we are ready to enable the fallback or if we depleted the list of accounts
+ // then finish and get out
+ if (mEnableFallback || mAccountIndex >= mAccounts.length) {
+ return;
+ }
+
+ // lookup the confirmCredentials intent for the current account
+ mAccountManager.confirmCredentialsAsUser(mAccounts[mAccountIndex], null, null, this,
+ null, new UserHandle(mLockPatternUtils.getCurrentUser()));
+ }
+
+ public void start() {
+ mEnableFallback = false;
+ mAccountIndex = 0;
+ next();
+ }
+
+ public void run(AccountManagerFuture<Bundle> future) {
+ try {
+ Bundle result = future.getResult();
+ if (result.getParcelable(AccountManager.KEY_INTENT) != null) {
+ mEnableFallback = true;
+ }
+ } catch (OperationCanceledException e) {
+ // just skip the account if we are unable to query it
+ } catch (IOException e) {
+ // just skip the account if we are unable to query it
+ } catch (AuthenticatorException e) {
+ // just skip the account if we are unable to query it
+ } finally {
+ mAccountIndex++;
+ next();
+ }
+ }
+ }
+
+ private void handleAttemptLockout(long elapsedRealtimeDeadline) {
+ mLockPatternView.clearPattern();
+ mLockPatternView.setEnabled(false);
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ if (mEnableFallback) {
+ updateFooter(FooterMode.ForgotLockPattern);
+ }
+
+ mCountdownTimer = new CountDownTimer(elapsedRealtimeDeadline - elapsedRealtime, 1000) {
+
+ @Override
+ public void onTick(long millisUntilFinished) {
+ final int secondsRemaining = (int) (millisUntilFinished / 1000);
+ mSecurityMessageDisplay.setMessage(
+ R.string.kg_too_many_failed_attempts_countdown, true, secondsRemaining);
+ }
+
+ @Override
+ public void onFinish() {
+ mLockPatternView.setEnabled(true);
+ displayDefaultSecurityMessage();
+ // TODO mUnlockIcon.setVisibility(View.VISIBLE);
+ mFailedPatternAttemptsSinceLastTimeout = 0;
+ if (mEnableFallback) {
+ updateFooter(FooterMode.ForgotLockPattern);
+ } else {
+ updateFooter(FooterMode.Normal);
+ }
+ }
+
+ }.start();
+ }
+
+ @Override
+ public boolean needsInput() {
+ return false;
+ }
+
+ @Override
+ public void onPause() {
+ if (mCountdownTimer != null) {
+ mCountdownTimer.cancel();
+ mCountdownTimer = null;
+ }
+ }
+
+ @Override
+ public void onResume(int reason) {
+ reset();
+ }
+
+ @Override
+ public KeyguardSecurityCallback getCallback() {
+ return mCallback;
+ }
+
+ @Override
+ public void showBouncer(int duration) {
+ KeyguardSecurityViewHelper.
+ showBouncer(mSecurityMessageDisplay, mEcaView, mBouncerFrame, duration);
+ }
+
+ @Override
+ public void hideBouncer(int duration) {
+ KeyguardSecurityViewHelper.
+ hideBouncer(mSecurityMessageDisplay, mEcaView, mBouncerFrame, duration);
+ }
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityCallback.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityCallback.java
new file mode 100644
index 0000000..4f139ad
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityCallback.java
@@ -0,0 +1,68 @@
+/*
+ * 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.keyguard;
+
+import com.android.keyguard.KeyguardHostView.OnDismissAction;
+
+public interface KeyguardSecurityCallback {
+
+ /**
+ * Dismiss the given security screen.
+ * @param securityVerified true if the user correctly entered credentials for the given screen.
+ */
+ void dismiss(boolean securityVerified);
+
+ /**
+ * Manually report user activity to keep the device awake. If timeout is 0,
+ * uses user-defined timeout.
+ * @param timeout
+ */
+ void userActivity(long timeout);
+
+ /**
+ * Checks if keyguard is in "verify credentials" mode.
+ * @return true if user has been asked to verify security.
+ */
+ boolean isVerifyUnlockOnly();
+
+ /**
+ * Call when user correctly enters their credentials
+ */
+ void reportSuccessfulUnlockAttempt();
+
+ /**
+ * Call when the user incorrectly enters their credentials
+ */
+ void reportFailedUnlockAttempt();
+
+ /**
+ * Gets the number of attempts thus far as reported by {@link #reportFailedUnlockAttempt()}
+ * @return number of failed attempts
+ */
+ int getFailedAttempts();
+
+ /**
+ * Shows the backup security for the current method. If none available, this call is a no-op.
+ */
+ void showBackupSecurity();
+
+ /**
+ * Sets an action to perform after the user successfully enters their credentials.
+ * @param action
+ */
+ void setOnDismissAction(OnDismissAction action);
+
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java
new file mode 100644
index 0000000..9d03c6a
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java
@@ -0,0 +1,45 @@
+package com.android.keyguard;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.FrameLayout;
+
+public class KeyguardSecurityContainer extends FrameLayout {
+ public KeyguardSecurityContainer(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public KeyguardSecurityContainer(Context context) {
+ this(null, null, 0);
+ }
+
+ public KeyguardSecurityContainer(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ KeyguardSecurityViewFlipper getFlipper() {
+ for (int i = 0; i < getChildCount(); i++) {
+ View child = getChildAt(i);
+ if (child instanceof KeyguardSecurityViewFlipper) {
+ return (KeyguardSecurityViewFlipper) child;
+ }
+ }
+ return null;
+ }
+
+ public void showBouncer(int duration) {
+ KeyguardSecurityViewFlipper flipper = getFlipper();
+ if (flipper != null) {
+ flipper.showBouncer(duration);
+ }
+ }
+
+ public void hideBouncer(int duration) {
+ KeyguardSecurityViewFlipper flipper = getFlipper();
+ if (flipper != null) {
+ flipper.hideBouncer(duration);
+ }
+ }
+}
+
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityModel.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityModel.java
new file mode 100644
index 0000000..4129e33
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityModel.java
@@ -0,0 +1,147 @@
+/*
+ * 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.keyguard;
+
+import android.app.admin.DevicePolicyManager;
+import android.content.Context;
+import android.telephony.TelephonyManager;
+
+import com.android.internal.telephony.IccCardConstants;
+import com.android.internal.widget.LockPatternUtils;
+
+public class KeyguardSecurityModel {
+ /**
+ * The different types of security available for {@link Mode#UnlockScreen}.
+ * @see com.android.internal.policy.impl.LockPatternKeyguardView#getUnlockMode()
+ */
+ enum SecurityMode {
+ Invalid, // NULL state
+ None, // No security enabled
+ Pattern, // Unlock by drawing a pattern.
+ Password, // Unlock by entering an alphanumeric password
+ PIN, // Strictly numeric password
+ Biometric, // Unlock with a biometric key (e.g. finger print or face unlock)
+ Account, // Unlock by entering an account's login and password.
+ SimPin, // Unlock by entering a sim pin.
+ SimPuk // Unlock by entering a sim puk
+ }
+
+ private Context mContext;
+ private LockPatternUtils mLockPatternUtils;
+
+ KeyguardSecurityModel(Context context) {
+ mContext = context;
+ mLockPatternUtils = new LockPatternUtils(context);
+ }
+
+ void setLockPatternUtils(LockPatternUtils utils) {
+ mLockPatternUtils = utils;
+ }
+
+ /**
+ * Returns true if biometric unlock is installed and selected. If this returns false there is
+ * no need to even construct the biometric unlock.
+ */
+ boolean isBiometricUnlockEnabled() {
+ return mLockPatternUtils.usingBiometricWeak()
+ && mLockPatternUtils.isBiometricWeakInstalled();
+ }
+
+ /**
+ * Returns true if a condition is currently suppressing the biometric unlock. If this returns
+ * true there is no need to even construct the biometric unlock.
+ */
+ private boolean isBiometricUnlockSuppressed() {
+ KeyguardUpdateMonitor monitor = KeyguardUpdateMonitor.getInstance(mContext);
+ final boolean backupIsTimedOut = monitor.getFailedUnlockAttempts() >=
+ LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT;
+ return monitor.getMaxBiometricUnlockAttemptsReached() || backupIsTimedOut
+ || !monitor.isAlternateUnlockEnabled()
+ || monitor.getPhoneState() != TelephonyManager.CALL_STATE_IDLE;
+ }
+
+ SecurityMode getSecurityMode() {
+ KeyguardUpdateMonitor updateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
+ final IccCardConstants.State simState = updateMonitor.getSimState();
+ SecurityMode mode = SecurityMode.None;
+ if (simState == IccCardConstants.State.PIN_REQUIRED) {
+ mode = SecurityMode.SimPin;
+ } else if (simState == IccCardConstants.State.PUK_REQUIRED
+ && mLockPatternUtils.isPukUnlockScreenEnable()) {
+ mode = SecurityMode.SimPuk;
+ } else {
+ final int security = mLockPatternUtils.getKeyguardStoredPasswordQuality();
+ switch (security) {
+ case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
+ mode = mLockPatternUtils.isLockPasswordEnabled() ?
+ SecurityMode.PIN : SecurityMode.None;
+ break;
+ case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC:
+ case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC:
+ case DevicePolicyManager.PASSWORD_QUALITY_COMPLEX:
+ mode = mLockPatternUtils.isLockPasswordEnabled() ?
+ SecurityMode.Password : SecurityMode.None;
+ break;
+
+ case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
+ case DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED:
+ if (mLockPatternUtils.isLockPatternEnabled()) {
+ mode = mLockPatternUtils.isPermanentlyLocked() ?
+ SecurityMode.Account : SecurityMode.Pattern;
+ }
+ break;
+
+ default:
+ throw new IllegalStateException("Unknown unlock mode:" + mode);
+ }
+ }
+ return mode;
+ }
+
+ /**
+ * Some unlock methods can have an alternate, such as biometric unlocks (e.g. face unlock).
+ * This function decides if an alternate unlock is available and returns it. Otherwise,
+ * returns @param mode.
+ *
+ * @param mode the mode we want the alternate for
+ * @return alternate or the given mode
+ */
+ SecurityMode getAlternateFor(SecurityMode mode) {
+ if (isBiometricUnlockEnabled() && !isBiometricUnlockSuppressed()
+ && (mode == SecurityMode.Password
+ || mode == SecurityMode.PIN
+ || mode == SecurityMode.Pattern)) {
+ return SecurityMode.Biometric;
+ }
+ return mode; // no alternate, return what was given
+ }
+
+ /**
+ * Some unlock methods can have a backup which gives the user another way to get into
+ * the device. This is currently only supported for Biometric and Pattern unlock.
+ *
+ * @return backup method or current security mode
+ */
+ SecurityMode getBackupSecurityMode(SecurityMode mode) {
+ switch(mode) {
+ case Biometric:
+ return getSecurityMode();
+ case Pattern:
+ return SecurityMode.Account;
+ }
+ return mode; // no backup, return current security mode
+ }
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityView.java
new file mode 100644
index 0000000..dfeacf3
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityView.java
@@ -0,0 +1,87 @@
+/*
+ * 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.keyguard;
+
+import com.android.internal.widget.LockPatternUtils;
+
+public interface KeyguardSecurityView {
+ static public final int SCREEN_ON = 1;
+ static public final int VIEW_REVEALED = 2;
+
+ /**
+ * Interface back to keyguard to tell it when security
+ * @param callback
+ */
+ void setKeyguardCallback(KeyguardSecurityCallback callback);
+
+ /**
+ * Set {@link LockPatternUtils} object. Useful for providing a mock interface.
+ * @param utils
+ */
+ void setLockPatternUtils(LockPatternUtils utils);
+
+ /**
+ * Reset the view and prepare to take input. This should do things like clearing the
+ * password or pattern and clear error messages.
+ */
+ void reset();
+
+ /**
+ * Emulate activity life cycle within the view. When called, the view should clean up
+ * and prepare to be removed.
+ */
+ void onPause();
+
+ /**
+ * Emulate activity life cycle within this view. When called, the view should prepare itself
+ * to be shown.
+ * @param reason the root cause of the event.
+ */
+ void onResume(int reason);
+
+ /**
+ * Inquire whether this view requires IME (keyboard) interaction.
+ *
+ * @return true if IME interaction is required.
+ */
+ boolean needsInput();
+
+ /**
+ * Get {@link KeyguardSecurityCallback} for the given object
+ * @return KeyguardSecurityCallback
+ */
+ KeyguardSecurityCallback getCallback();
+
+ /**
+ * Instruct the view to show usability hints, if any.
+ *
+ */
+ void showUsabilityHint();
+
+ /**
+ * Place the security view into bouncer mode.
+ * Animate transisiton if duration is non-zero.
+ * @param duration millisends for the transisiton animation.
+ */
+ void showBouncer(int duration);
+
+ /**
+ * Place the security view into non-bouncer mode.
+ * Animate transisiton if duration is non-zero.
+ * @param duration millisends for the transisiton animation.
+ */
+ void hideBouncer(int duration);
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityViewFlipper.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityViewFlipper.java
new file mode 100644
index 0000000..70a0e44
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityViewFlipper.java
@@ -0,0 +1,278 @@
+/*
+ * 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.keyguard;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.Rect;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewDebug;
+import android.view.ViewGroup;
+import android.view.WindowManager;
+import android.widget.FrameLayout;
+import android.widget.ViewFlipper;
+
+import com.android.internal.widget.LockPatternUtils;
+
+/**
+ * Subclass of the current view flipper that allows us to overload dispatchTouchEvent() so
+ * we can emulate {@link WindowManager.LayoutParams#FLAG_SLIPPERY} within a view hierarchy.
+ *
+ */
+public class KeyguardSecurityViewFlipper extends ViewFlipper implements KeyguardSecurityView {
+ private static final String TAG = "KeyguardSecurityViewFlipper";
+ private static final boolean DEBUG = false;
+
+ private Rect mTempRect = new Rect();
+
+ public KeyguardSecurityViewFlipper(Context context) {
+ this(context, null);
+ }
+
+ public KeyguardSecurityViewFlipper(Context context, AttributeSet attr) {
+ super(context, attr);
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent ev) {
+ boolean result = super.onTouchEvent(ev);
+ mTempRect.set(0, 0, 0, 0);
+ for (int i = 0; i < getChildCount(); i++) {
+ View child = getChildAt(i);
+ if (child.getVisibility() == View.VISIBLE) {
+ offsetRectIntoDescendantCoords(child, mTempRect);
+ ev.offsetLocation(mTempRect.left, mTempRect.top);
+ result = child.dispatchTouchEvent(ev) || result;
+ ev.offsetLocation(-mTempRect.left, -mTempRect.top);
+ }
+ }
+ return result;
+ }
+
+ KeyguardSecurityView getSecurityView() {
+ View child = getChildAt(getDisplayedChild());
+ if (child instanceof KeyguardSecurityView) {
+ return (KeyguardSecurityView) child;
+ }
+ return null;
+ }
+
+ @Override
+ public void setKeyguardCallback(KeyguardSecurityCallback callback) {
+ KeyguardSecurityView ksv = getSecurityView();
+ if (ksv != null) {
+ ksv.setKeyguardCallback(callback);
+ }
+ }
+
+ @Override
+ public void setLockPatternUtils(LockPatternUtils utils) {
+ KeyguardSecurityView ksv = getSecurityView();
+ if (ksv != null) {
+ ksv.setLockPatternUtils(utils);
+ }
+ }
+
+ @Override
+ public void reset() {
+ KeyguardSecurityView ksv = getSecurityView();
+ if (ksv != null) {
+ ksv.reset();
+ }
+ }
+
+ @Override
+ public void onPause() {
+ KeyguardSecurityView ksv = getSecurityView();
+ if (ksv != null) {
+ ksv.onPause();
+ }
+ }
+
+ @Override
+ public void onResume(int reason) {
+ KeyguardSecurityView ksv = getSecurityView();
+ if (ksv != null) {
+ ksv.onResume(reason);
+ }
+ }
+
+ @Override
+ public boolean needsInput() {
+ KeyguardSecurityView ksv = getSecurityView();
+ return (ksv != null) ? ksv.needsInput() : false;
+ }
+
+ @Override
+ public KeyguardSecurityCallback getCallback() {
+ KeyguardSecurityView ksv = getSecurityView();
+ return (ksv != null) ? ksv.getCallback() : null;
+ }
+
+ @Override
+ public void showUsabilityHint() {
+ KeyguardSecurityView ksv = getSecurityView();
+ if (ksv != null) {
+ ksv.showUsabilityHint();
+ }
+ }
+
+ @Override
+ public void showBouncer(int duration) {
+ KeyguardSecurityView active = getSecurityView();
+ for (int i = 0; i < getChildCount(); i++) {
+ View child = getChildAt(i);
+ if (child instanceof KeyguardSecurityView) {
+ KeyguardSecurityView ksv = (KeyguardSecurityView) child;
+ ksv.showBouncer(ksv == active ? duration : 0);
+ }
+ }
+ }
+
+ @Override
+ public void hideBouncer(int duration) {
+ KeyguardSecurityView active = getSecurityView();
+ for (int i = 0; i < getChildCount(); i++) {
+ View child = getChildAt(i);
+ if (child instanceof KeyguardSecurityView) {
+ KeyguardSecurityView ksv = (KeyguardSecurityView) child;
+ ksv.hideBouncer(ksv == active ? duration : 0);
+ }
+ }
+ }
+
+ @Override
+ protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
+ return p instanceof LayoutParams;
+ }
+
+ @Override
+ protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
+ return p instanceof LayoutParams ? new LayoutParams((LayoutParams) p) : new LayoutParams(p);
+ }
+
+ @Override
+ public LayoutParams generateLayoutParams(AttributeSet attrs) {
+ return new LayoutParams(getContext(), attrs);
+ }
+
+ @Override
+ protected void onMeasure(int widthSpec, int heightSpec) {
+ final int widthMode = MeasureSpec.getMode(widthSpec);
+ final int heightMode = MeasureSpec.getMode(heightSpec);
+ if (DEBUG && widthMode != MeasureSpec.AT_MOST) {
+ Log.w(TAG, "onMeasure: widthSpec " + MeasureSpec.toString(widthSpec) +
+ " should be AT_MOST");
+ }
+ if (DEBUG && heightMode != MeasureSpec.AT_MOST) {
+ Log.w(TAG, "onMeasure: heightSpec " + MeasureSpec.toString(heightSpec) +
+ " should be AT_MOST");
+ }
+
+ final int widthSize = MeasureSpec.getSize(widthSpec);
+ final int heightSize = MeasureSpec.getSize(heightSpec);
+ int maxWidth = widthSize;
+ int maxHeight = heightSize;
+ final int count = getChildCount();
+ for (int i = 0; i < count; i++) {
+ final View child = getChildAt(i);
+ final LayoutParams lp = (LayoutParams) child.getLayoutParams();
+
+ if (lp.maxWidth > 0 && lp.maxWidth < maxWidth) {
+ maxWidth = lp.maxWidth;
+ }
+ if (lp.maxHeight > 0 && lp.maxHeight < maxHeight) {
+ maxHeight = lp.maxHeight;
+ }
+ }
+
+ final int wPadding = getPaddingLeft() + getPaddingRight();
+ final int hPadding = getPaddingTop() + getPaddingBottom();
+ maxWidth -= wPadding;
+ maxHeight -= hPadding;
+
+ int width = widthMode == MeasureSpec.EXACTLY ? widthSize : 0;
+ int height = heightMode == MeasureSpec.EXACTLY ? heightSize : 0;
+ for (int i = 0; i < count; i++) {
+ final View child = getChildAt(i);
+ final LayoutParams lp = (LayoutParams) child.getLayoutParams();
+
+ final int childWidthSpec = makeChildMeasureSpec(maxWidth, lp.width);
+ final int childHeightSpec = makeChildMeasureSpec(maxHeight, lp.height);
+
+ child.measure(childWidthSpec, childHeightSpec);
+
+ width = Math.max(width, Math.min(child.getMeasuredWidth(), widthSize - wPadding));
+ height = Math.max(height, Math.min(child.getMeasuredHeight(), heightSize - hPadding));
+ }
+ setMeasuredDimension(width + wPadding, height + hPadding);
+ }
+
+ private int makeChildMeasureSpec(int maxSize, int childDimen) {
+ final int mode;
+ final int size;
+ switch (childDimen) {
+ case LayoutParams.WRAP_CONTENT:
+ mode = MeasureSpec.AT_MOST;
+ size = maxSize;
+ break;
+ case LayoutParams.MATCH_PARENT:
+ mode = MeasureSpec.EXACTLY;
+ size = maxSize;
+ break;
+ default:
+ mode = MeasureSpec.EXACTLY;
+ size = Math.min(maxSize, childDimen);
+ break;
+ }
+ return MeasureSpec.makeMeasureSpec(size, mode);
+ }
+
+ public static class LayoutParams extends FrameLayout.LayoutParams {
+ @ViewDebug.ExportedProperty(category = "layout")
+ public int maxWidth;
+
+ @ViewDebug.ExportedProperty(category = "layout")
+ public int maxHeight;
+
+ public LayoutParams(ViewGroup.LayoutParams other) {
+ super(other);
+ }
+
+ public LayoutParams(LayoutParams other) {
+ super(other);
+
+ maxWidth = other.maxWidth;
+ maxHeight = other.maxHeight;
+ }
+
+ public LayoutParams(Context c, AttributeSet attrs) {
+ super(c, attrs);
+
+ final TypedArray a = c.obtainStyledAttributes(attrs,
+ R.styleable.KeyguardSecurityViewFlipper_Layout, 0, 0);
+ maxWidth = a.getDimensionPixelSize(
+ R.styleable.KeyguardSecurityViewFlipper_Layout_layout_maxWidth, 0);
+ maxHeight = a.getDimensionPixelSize(
+ R.styleable.KeyguardSecurityViewFlipper_Layout_layout_maxHeight, 0);
+ a.recycle();
+ }
+ }
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityViewHelper.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityViewHelper.java
new file mode 100644
index 0000000..67a6f52
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityViewHelper.java
@@ -0,0 +1,94 @@
+/*
+ * 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.keyguard;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ObjectAnimator;
+import android.graphics.drawable.Drawable;
+import android.view.View;
+
+/**
+ * Some common functions that are useful for KeyguardSecurityViews.
+ */
+public class KeyguardSecurityViewHelper {
+
+ public static void showBouncer(SecurityMessageDisplay securityMessageDisplay,
+ final View ecaView, Drawable bouncerFrame, int duration) {
+ if (securityMessageDisplay != null) {
+ securityMessageDisplay.showBouncer(duration);
+ }
+ if (ecaView != null) {
+ if (duration > 0) {
+ Animator anim = ObjectAnimator.ofFloat(ecaView, "alpha", 0f);
+ anim.setDuration(duration);
+ anim.addListener(new AnimatorListenerAdapter() {
+ private boolean mCanceled;
+ @Override
+ public void onAnimationCancel(Animator animation) {
+ // Fail safe and show the emergency button in onAnimationEnd()
+ mCanceled = true;
+ ecaView.setAlpha(1f);
+ }
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ ecaView.setVisibility(mCanceled ? View.VISIBLE : View.INVISIBLE);
+ }
+ });
+ anim.start();
+ } else {
+ ecaView.setAlpha(0f);
+ ecaView.setVisibility(View.INVISIBLE);
+ }
+ }
+ if (bouncerFrame != null) {
+ if (duration > 0) {
+ Animator anim = ObjectAnimator.ofInt(bouncerFrame, "alpha", 0, 255);
+ anim.setDuration(duration);
+ anim.start();
+ } else {
+ bouncerFrame.setAlpha(255);
+ }
+ }
+ }
+
+ public static void hideBouncer(SecurityMessageDisplay securityMessageDisplay,
+ View ecaView, Drawable bouncerFrame, int duration) {
+ if (securityMessageDisplay != null) {
+ securityMessageDisplay.hideBouncer(duration);
+ }
+ if (ecaView != null) {
+ ecaView.setVisibility(View.VISIBLE);
+ if (duration > 0) {
+ Animator anim = ObjectAnimator.ofFloat(ecaView, "alpha", 1f);
+ anim.setDuration(duration);
+ anim.start();
+ } else {
+ ecaView.setAlpha(1f);
+ }
+ }
+ if (bouncerFrame != null) {
+ if (duration > 0) {
+ Animator anim = ObjectAnimator.ofInt(bouncerFrame, "alpha", 255, 0);
+ anim.setDuration(duration);
+ anim.start();
+ } else {
+ bouncerFrame.setAlpha(0);
+ }
+ }
+ }
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSelectorView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSelectorView.java
new file mode 100644
index 0000000..4d891be
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSelectorView.java
@@ -0,0 +1,283 @@
+/*
+ * 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.keyguard;
+
+import android.animation.ObjectAnimator;
+import android.app.SearchManager;
+import android.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.drawable.Drawable;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.util.Slog;
+import android.view.View;
+import android.widget.LinearLayout;
+
+import com.android.internal.telephony.IccCardConstants.State;
+import com.android.internal.widget.LockPatternUtils;
+import com.android.internal.widget.multiwaveview.GlowPadView;
+import com.android.internal.widget.multiwaveview.GlowPadView.OnTriggerListener;
+
+public class KeyguardSelectorView extends LinearLayout implements KeyguardSecurityView {
+ private static final boolean DEBUG = KeyguardHostView.DEBUG;
+ private static final String TAG = "SecuritySelectorView";
+ private static final String ASSIST_ICON_METADATA_NAME =
+ "com.android.systemui.action_assist_icon";
+
+ private KeyguardSecurityCallback mCallback;
+ private GlowPadView mGlowPadView;
+ private ObjectAnimator mAnim;
+ private View mFadeView;
+ private boolean mIsBouncing;
+ private boolean mCameraDisabled;
+ private boolean mSearchDisabled;
+ private LockPatternUtils mLockPatternUtils;
+ private SecurityMessageDisplay mSecurityMessageDisplay;
+ private Drawable mBouncerFrame;
+
+ OnTriggerListener mOnTriggerListener = new OnTriggerListener() {
+
+ public void onTrigger(View v, int target) {
+ final int resId = mGlowPadView.getResourceIdForTarget(target);
+ switch (resId) {
+ case R.drawable.ic_action_assist_generic:
+ Intent assistIntent =
+ ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE))
+ .getAssistIntent(mContext, true, UserHandle.USER_CURRENT);
+ if (assistIntent != null) {
+ mActivityLauncher.launchActivity(assistIntent, false, true, null, null);
+ } else {
+ Log.w(TAG, "Failed to get intent for assist activity");
+ }
+ mCallback.userActivity(0);
+ break;
+
+ case R.drawable.ic_lockscreen_camera:
+ mActivityLauncher.launchCamera(null, null);
+ mCallback.userActivity(0);
+ break;
+
+ case R.drawable.ic_lockscreen_unlock_phantom:
+ case R.drawable.ic_lockscreen_unlock:
+ mCallback.userActivity(0);
+ mCallback.dismiss(false);
+ break;
+ }
+ }
+
+ public void onReleased(View v, int handle) {
+ if (!mIsBouncing) {
+ doTransition(mFadeView, 1.0f);
+ }
+ }
+
+ public void onGrabbed(View v, int handle) {
+ mCallback.userActivity(0);
+ doTransition(mFadeView, 0.0f);
+ }
+
+ public void onGrabbedStateChange(View v, int handle) {
+
+ }
+
+ public void onFinishFinalAnimation() {
+
+ }
+
+ };
+
+ KeyguardUpdateMonitorCallback mInfoCallback = new KeyguardUpdateMonitorCallback() {
+
+ @Override
+ public void onDevicePolicyManagerStateChanged() {
+ updateTargets();
+ }
+
+ @Override
+ public void onSimStateChanged(State simState) {
+ updateTargets();
+ }
+ };
+
+ private final KeyguardActivityLauncher mActivityLauncher = new KeyguardActivityLauncher() {
+
+ @Override
+ KeyguardSecurityCallback getCallback() {
+ return mCallback;
+ }
+
+ @Override
+ LockPatternUtils getLockPatternUtils() {
+ return mLockPatternUtils;
+ }
+
+ @Override
+ Context getContext() {
+ return mContext;
+ }};
+
+ public KeyguardSelectorView(Context context) {
+ this(context, null);
+ }
+
+ public KeyguardSelectorView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ mLockPatternUtils = new LockPatternUtils(getContext());
+ }
+
+ @Override
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+ mGlowPadView = (GlowPadView) findViewById(R.id.glow_pad_view);
+ mGlowPadView.setOnTriggerListener(mOnTriggerListener);
+ updateTargets();
+
+ mSecurityMessageDisplay = new KeyguardMessageArea.Helper(this);
+ View bouncerFrameView = findViewById(R.id.keyguard_selector_view_frame);
+ mBouncerFrame = bouncerFrameView.getBackground();
+ }
+
+ public void setCarrierArea(View carrierArea) {
+ mFadeView = carrierArea;
+ }
+
+ public boolean isTargetPresent(int resId) {
+ return mGlowPadView.getTargetPosition(resId) != -1;
+ }
+
+ @Override
+ public void showUsabilityHint() {
+ mGlowPadView.ping();
+ }
+
+ private void updateTargets() {
+ int currentUserHandle = mLockPatternUtils.getCurrentUser();
+ DevicePolicyManager dpm = mLockPatternUtils.getDevicePolicyManager();
+ int disabledFeatures = dpm.getKeyguardDisabledFeatures(null, currentUserHandle);
+ boolean secureCameraDisabled = mLockPatternUtils.isSecure()
+ && (disabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA) != 0;
+ boolean cameraDisabledByAdmin = dpm.getCameraDisabled(null, currentUserHandle)
+ || secureCameraDisabled;
+ final KeyguardUpdateMonitor monitor = KeyguardUpdateMonitor.getInstance(getContext());
+ boolean disabledBySimState = monitor.isSimLocked();
+ boolean cameraTargetPresent =
+ isTargetPresent(R.drawable.ic_lockscreen_camera);
+ boolean searchTargetPresent =
+ isTargetPresent(R.drawable.ic_action_assist_generic);
+
+ if (cameraDisabledByAdmin) {
+ Log.v(TAG, "Camera disabled by Device Policy");
+ } else if (disabledBySimState) {
+ Log.v(TAG, "Camera disabled by Sim State");
+ }
+ boolean currentUserSetup = 0 != Settings.Secure.getIntForUser(
+ mContext.getContentResolver(),
+ Settings.Secure.USER_SETUP_COMPLETE,
+ 0 /*default */,
+ currentUserHandle);
+ boolean searchActionAvailable =
+ ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE))
+ .getAssistIntent(mContext, false, UserHandle.USER_CURRENT) != null;
+ mCameraDisabled = cameraDisabledByAdmin || disabledBySimState || !cameraTargetPresent
+ || !currentUserSetup;
+ mSearchDisabled = disabledBySimState || !searchActionAvailable || !searchTargetPresent
+ || !currentUserSetup;
+ updateResources();
+ }
+
+ public void updateResources() {
+ // Update the search icon with drawable from the search .apk
+ if (!mSearchDisabled) {
+ Intent intent = ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE))
+ .getAssistIntent(mContext, false, UserHandle.USER_CURRENT);
+ if (intent != null) {
+ // XXX Hack. We need to substitute the icon here but haven't formalized
+ // the public API. The "_google" metadata will be going away, so
+ // DON'T USE IT!
+ ComponentName component = intent.getComponent();
+ boolean replaced = mGlowPadView.replaceTargetDrawablesIfPresent(component,
+ ASSIST_ICON_METADATA_NAME + "_google", R.drawable.ic_action_assist_generic);
+
+ if (!replaced && !mGlowPadView.replaceTargetDrawablesIfPresent(component,
+ ASSIST_ICON_METADATA_NAME, R.drawable.ic_action_assist_generic)) {
+ Slog.w(TAG, "Couldn't grab icon from package " + component);
+ }
+ }
+ }
+
+ mGlowPadView.setEnableTarget(R.drawable.ic_lockscreen_camera, !mCameraDisabled);
+ mGlowPadView.setEnableTarget(R.drawable.ic_action_assist_generic, !mSearchDisabled);
+ }
+
+ void doTransition(View view, float to) {
+ if (mAnim != null) {
+ mAnim.cancel();
+ }
+ mAnim = ObjectAnimator.ofFloat(view, "alpha", to);
+ mAnim.start();
+ }
+
+ public void setKeyguardCallback(KeyguardSecurityCallback callback) {
+ mCallback = callback;
+ }
+
+ public void setLockPatternUtils(LockPatternUtils utils) {
+ mLockPatternUtils = utils;
+ }
+
+ @Override
+ public void reset() {
+ mGlowPadView.reset(false);
+ }
+
+ @Override
+ public boolean needsInput() {
+ return false;
+ }
+
+ @Override
+ public void onPause() {
+ KeyguardUpdateMonitor.getInstance(getContext()).removeCallback(mInfoCallback);
+ }
+
+ @Override
+ public void onResume(int reason) {
+ KeyguardUpdateMonitor.getInstance(getContext()).registerCallback(mInfoCallback);
+ }
+
+ @Override
+ public KeyguardSecurityCallback getCallback() {
+ return mCallback;
+ }
+
+ @Override
+ public void showBouncer(int duration) {
+ mIsBouncing = true;
+ KeyguardSecurityViewHelper.
+ showBouncer(mSecurityMessageDisplay, mFadeView, mBouncerFrame, duration);
+ }
+
+ @Override
+ public void hideBouncer(int duration) {
+ mIsBouncing = false;
+ KeyguardSecurityViewHelper.
+ hideBouncer(mSecurityMessageDisplay, mFadeView, mBouncerFrame, duration);
+ }
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardService.java b/packages/Keyguard/src/com/android/keyguard/KeyguardService.java
new file mode 100644
index 0000000..9fa4790
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardService.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.keyguard;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+
+import android.app.Service;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.util.Log;
+
+import com.android.internal.policy.IKeyguardService;
+import com.android.internal.policy.IKeyguardExitCallback;
+import com.android.internal.policy.IKeyguardShowCallback;
+import com.android.internal.widget.LockPatternUtils;
+
+public class KeyguardService extends Service {
+ static final String TAG = "KeyguardService";
+ private KeyguardViewMediator mKeyguardViewMediator;
+
+ @Override
+ public void onCreate() {
+ if (mKeyguardViewMediator == null) {
+ mKeyguardViewMediator = new KeyguardViewMediator(
+ KeyguardService.this, new LockPatternUtils(KeyguardService.this));
+ }
+ Log.v(TAG, "onCreate()");
+ }
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return mBinder;
+ }
+
+ @Override
+ protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ // TODO
+ }
+
+ private final IKeyguardService.Stub mBinder = new IKeyguardService.Stub() {
+ public boolean isShowing() {
+ return mKeyguardViewMediator.isShowing();
+ }
+ public boolean isSecure() {
+ return mKeyguardViewMediator.isSecure();
+ }
+ public boolean isShowingAndNotHidden() {
+ return mKeyguardViewMediator.isShowingAndNotHidden();
+ }
+ public boolean isInputRestricted() {
+ return mKeyguardViewMediator.isInputRestricted();
+ }
+ public void verifyUnlock(IKeyguardExitCallback callback) {
+ mKeyguardViewMediator.verifyUnlock(callback);
+ }
+ public void keyguardDone(boolean authenticated, boolean wakeup) {
+ mKeyguardViewMediator.keyguardDone(authenticated, wakeup);
+ }
+ public void setHidden(boolean isHidden) {
+ mKeyguardViewMediator.setHidden(isHidden);
+ }
+ public void dismiss() {
+ mKeyguardViewMediator.dismiss();
+ }
+ public void onWakeKeyWhenKeyguardShowing(int keyCode) {
+ mKeyguardViewMediator.onWakeKeyWhenKeyguardShowing(keyCode);
+ }
+ public void onWakeMotionWhenKeyguardShowing() {
+ mKeyguardViewMediator.onWakeMotionWhenKeyguardShowing();
+ }
+ public void onDreamingStarted() {
+ mKeyguardViewMediator.onDreamingStarted();
+ }
+ public void onDreamingStopped() {
+ mKeyguardViewMediator.onDreamingStopped();
+ }
+ public void onScreenTurnedOff(int reason) {
+ mKeyguardViewMediator.onScreenTurnedOff(reason);
+ }
+ public void onScreenTurnedOn(IKeyguardShowCallback callback) {
+ mKeyguardViewMediator.onScreenTurnedOn(callback);
+ }
+ public void setKeyguardEnabled(boolean enabled) {
+ mKeyguardViewMediator.setKeyguardEnabled(enabled);
+ }
+ public boolean isDismissable() {
+ return mKeyguardViewMediator.isDismissable();
+ }
+ public void onSystemReady() {
+ mKeyguardViewMediator.onSystemReady();
+ }
+ public void doKeyguardTimeout(Bundle options) {
+ mKeyguardViewMediator.doKeyguardTimeout(options);
+ }
+ public void setCurrentUser(int userId) {
+ mKeyguardViewMediator.setCurrentUser(userId);
+ }
+ public void showAssistant() {
+ mKeyguardViewMediator.showAssistant();
+ }
+ };
+
+}
+
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSimPinView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSimPinView.java
new file mode 100644
index 0000000..865a7c4
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSimPinView.java
@@ -0,0 +1,211 @@
+/*
+ * 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.keyguard;
+
+import com.android.internal.telephony.ITelephony;
+
+import android.content.Context;
+import android.app.Activity;
+import android.app.Dialog;
+import android.app.ProgressDialog;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.text.Editable;
+import android.text.InputType;
+import android.text.TextWatcher;
+import android.text.method.DigitsKeyListener;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.WindowManager;
+import android.widget.TextView.OnEditorActionListener;
+
+/**
+ * Displays a PIN pad for unlocking.
+ */
+public class KeyguardSimPinView extends KeyguardAbsKeyInputView
+ implements KeyguardSecurityView, OnEditorActionListener, TextWatcher {
+
+ private ProgressDialog mSimUnlockProgressDialog = null;
+ private volatile boolean mSimCheckInProgress;
+
+ public KeyguardSimPinView(Context context) {
+ this(context, null);
+ }
+
+ public KeyguardSimPinView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public void resetState() {
+ mSecurityMessageDisplay.setMessage(R.string.kg_sim_pin_instructions, true);
+ mPasswordEntry.setEnabled(true);
+ }
+
+ @Override
+ protected int getPasswordTextViewId() {
+ return R.id.pinEntry;
+ }
+
+ @Override
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+
+ final View ok = findViewById(R.id.key_enter);
+ if (ok != null) {
+ ok.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ doHapticKeyClick();
+ verifyPasswordAndUnlock();
+ }
+ });
+ }
+
+ // The delete button is of the PIN keyboard itself in some (e.g. tablet) layouts,
+ // not a separate view
+ View pinDelete = findViewById(R.id.delete_button);
+ if (pinDelete != null) {
+ pinDelete.setVisibility(View.VISIBLE);
+ pinDelete.setOnClickListener(new OnClickListener() {
+ public void onClick(View v) {
+ CharSequence str = mPasswordEntry.getText();
+ if (str.length() > 0) {
+ mPasswordEntry.setText(str.subSequence(0, str.length()-1));
+ }
+ doHapticKeyClick();
+ }
+ });
+ pinDelete.setOnLongClickListener(new View.OnLongClickListener() {
+ public boolean onLongClick(View v) {
+ mPasswordEntry.setText("");
+ doHapticKeyClick();
+ return true;
+ }
+ });
+ }
+
+ mPasswordEntry.setKeyListener(DigitsKeyListener.getInstance());
+ mPasswordEntry.setInputType(InputType.TYPE_CLASS_NUMBER
+ | InputType.TYPE_NUMBER_VARIATION_PASSWORD);
+
+ mPasswordEntry.requestFocus();
+ }
+
+ @Override
+ public void showUsabilityHint() {
+ }
+
+ @Override
+ public void onPause() {
+ // dismiss the dialog.
+ if (mSimUnlockProgressDialog != null) {
+ mSimUnlockProgressDialog.dismiss();
+ mSimUnlockProgressDialog = null;
+ }
+ }
+
+ /**
+ * Since the IPC can block, we want to run the request in a separate thread
+ * with a callback.
+ */
+ private abstract class CheckSimPin extends Thread {
+ private final String mPin;
+
+ protected CheckSimPin(String pin) {
+ mPin = pin;
+ }
+
+ abstract void onSimCheckResponse(boolean success);
+
+ @Override
+ public void run() {
+ try {
+ final boolean result = ITelephony.Stub.asInterface(ServiceManager
+ .checkService("phone")).supplyPin(mPin);
+ post(new Runnable() {
+ public void run() {
+ onSimCheckResponse(result);
+ }
+ });
+ } catch (RemoteException e) {
+ post(new Runnable() {
+ public void run() {
+ onSimCheckResponse(false);
+ }
+ });
+ }
+ }
+ }
+
+ private Dialog getSimUnlockProgressDialog() {
+ if (mSimUnlockProgressDialog == null) {
+ mSimUnlockProgressDialog = new ProgressDialog(mContext);
+ mSimUnlockProgressDialog.setMessage(
+ mContext.getString(R.string.kg_sim_unlock_progress_dialog_message));
+ mSimUnlockProgressDialog.setIndeterminate(true);
+ mSimUnlockProgressDialog.setCancelable(false);
+ if (!(mContext instanceof Activity)) {
+ mSimUnlockProgressDialog.getWindow().setType(
+ WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
+ }
+ }
+ return mSimUnlockProgressDialog;
+ }
+
+ @Override
+ protected void verifyPasswordAndUnlock() {
+ String entry = mPasswordEntry.getText().toString();
+
+ if (entry.length() < 4) {
+ // otherwise, display a message to the user, and don't submit.
+ mSecurityMessageDisplay.setMessage(R.string.kg_invalid_sim_pin_hint, true);
+ mPasswordEntry.setText("");
+ mCallback.userActivity(0);
+ return;
+ }
+
+ getSimUnlockProgressDialog().show();
+
+ if (!mSimCheckInProgress) {
+ mSimCheckInProgress = true; // there should be only one
+ new CheckSimPin(mPasswordEntry.getText().toString()) {
+ void onSimCheckResponse(final boolean success) {
+ post(new Runnable() {
+ public void run() {
+ if (mSimUnlockProgressDialog != null) {
+ mSimUnlockProgressDialog.hide();
+ }
+ if (success) {
+ // before closing the keyguard, report back that the sim is unlocked
+ // so it knows right away.
+ KeyguardUpdateMonitor.getInstance(getContext()).reportSimUnlocked();
+ mCallback.dismiss(true);
+ } else {
+ mSecurityMessageDisplay.setMessage
+ (R.string.kg_password_wrong_pin_code, true);
+ mPasswordEntry.setText("");
+ }
+ mCallback.userActivity(0);
+ mSimCheckInProgress = false;
+ }
+ });
+ }
+ }.start();
+ }
+ }
+}
+
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSimPukView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSimPukView.java
new file mode 100644
index 0000000..7424fab
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSimPukView.java
@@ -0,0 +1,280 @@
+/*
+ * 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.keyguard;
+
+import com.android.internal.telephony.ITelephony;
+
+import android.content.Context;
+import android.app.Activity;
+import android.app.Dialog;
+import android.app.ProgressDialog;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.text.Editable;
+import android.text.InputType;
+import android.text.TextWatcher;
+import android.text.method.DigitsKeyListener;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.WindowManager;
+import android.widget.TextView.OnEditorActionListener;
+
+/**
+ * Displays a PIN pad for entering a PUK (Pin Unlock Kode) provided by a carrier.
+ */
+public class KeyguardSimPukView extends KeyguardAbsKeyInputView
+ implements KeyguardSecurityView, OnEditorActionListener, TextWatcher {
+
+ private ProgressDialog mSimUnlockProgressDialog = null;
+ private volatile boolean mCheckInProgress;
+ private String mPukText;
+ private String mPinText;
+ private StateMachine mStateMachine = new StateMachine();
+
+ private class StateMachine {
+ final int ENTER_PUK = 0;
+ final int ENTER_PIN = 1;
+ final int CONFIRM_PIN = 2;
+ final int DONE = 3;
+ private int state = ENTER_PUK;
+
+ public void next() {
+ int msg = 0;
+ if (state == ENTER_PUK) {
+ if (checkPuk()) {
+ state = ENTER_PIN;
+ msg = R.string.kg_puk_enter_pin_hint;
+ } else {
+ msg = R.string.kg_invalid_sim_puk_hint;
+ }
+ } else if (state == ENTER_PIN) {
+ if (checkPin()) {
+ state = CONFIRM_PIN;
+ msg = R.string.kg_enter_confirm_pin_hint;
+ } else {
+ msg = R.string.kg_invalid_sim_pin_hint;
+ }
+ } else if (state == CONFIRM_PIN) {
+ if (confirmPin()) {
+ state = DONE;
+ msg = R.string.keyguard_sim_unlock_progress_dialog_message;
+ updateSim();
+ } else {
+ state = ENTER_PIN; // try again?
+ msg = R.string.kg_invalid_confirm_pin_hint;
+ }
+ }
+ mPasswordEntry.setText(null);
+ if (msg != 0) {
+ mSecurityMessageDisplay.setMessage(msg, true);
+ }
+ }
+
+ void reset() {
+ mPinText="";
+ mPukText="";
+ state = ENTER_PUK;
+ mSecurityMessageDisplay.setMessage(R.string.kg_puk_enter_puk_hint, true);
+ mPasswordEntry.requestFocus();
+ }
+ }
+
+ public KeyguardSimPukView(Context context) {
+ this(context, null);
+ }
+
+ public KeyguardSimPukView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public void resetState() {
+ mStateMachine.reset();
+ mPasswordEntry.setEnabled(true);
+ }
+
+ @Override
+ protected int getPasswordTextViewId() {
+ return R.id.pinEntry;
+ }
+
+ @Override
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+
+ final View ok = findViewById(R.id.key_enter);
+ if (ok != null) {
+ ok.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ doHapticKeyClick();
+ verifyPasswordAndUnlock();
+ }
+ });
+ }
+
+ // The delete button is of the PIN keyboard itself in some (e.g. tablet) layouts,
+ // not a separate view
+ View pinDelete = findViewById(R.id.delete_button);
+ if (pinDelete != null) {
+ pinDelete.setVisibility(View.VISIBLE);
+ pinDelete.setOnClickListener(new OnClickListener() {
+ public void onClick(View v) {
+ CharSequence str = mPasswordEntry.getText();
+ if (str.length() > 0) {
+ mPasswordEntry.setText(str.subSequence(0, str.length()-1));
+ }
+ doHapticKeyClick();
+ }
+ });
+ pinDelete.setOnLongClickListener(new View.OnLongClickListener() {
+ public boolean onLongClick(View v) {
+ mPasswordEntry.setText("");
+ doHapticKeyClick();
+ return true;
+ }
+ });
+ }
+
+ mPasswordEntry.setKeyListener(DigitsKeyListener.getInstance());
+ mPasswordEntry.setInputType(InputType.TYPE_CLASS_NUMBER
+ | InputType.TYPE_NUMBER_VARIATION_PASSWORD);
+
+ mPasswordEntry.requestFocus();
+
+ mSecurityMessageDisplay.setTimeout(0); // don't show ownerinfo/charging status by default
+ }
+
+ @Override
+ public void showUsabilityHint() {
+ }
+
+ @Override
+ public void onPause() {
+ // dismiss the dialog.
+ if (mSimUnlockProgressDialog != null) {
+ mSimUnlockProgressDialog.dismiss();
+ mSimUnlockProgressDialog = null;
+ }
+ }
+
+ /**
+ * Since the IPC can block, we want to run the request in a separate thread
+ * with a callback.
+ */
+ private abstract class CheckSimPuk extends Thread {
+
+ private final String mPin, mPuk;
+
+ protected CheckSimPuk(String puk, String pin) {
+ mPuk = puk;
+ mPin = pin;
+ }
+
+ abstract void onSimLockChangedResponse(boolean success);
+
+ @Override
+ public void run() {
+ try {
+ final boolean result = ITelephony.Stub.asInterface(ServiceManager
+ .checkService("phone")).supplyPuk(mPuk, mPin);
+
+ post(new Runnable() {
+ public void run() {
+ onSimLockChangedResponse(result);
+ }
+ });
+ } catch (RemoteException e) {
+ post(new Runnable() {
+ public void run() {
+ onSimLockChangedResponse(false);
+ }
+ });
+ }
+ }
+ }
+
+ private Dialog getSimUnlockProgressDialog() {
+ if (mSimUnlockProgressDialog == null) {
+ mSimUnlockProgressDialog = new ProgressDialog(mContext);
+ mSimUnlockProgressDialog.setMessage(
+ mContext.getString(R.string.kg_sim_unlock_progress_dialog_message));
+ mSimUnlockProgressDialog.setIndeterminate(true);
+ mSimUnlockProgressDialog.setCancelable(false);
+ if (!(mContext instanceof Activity)) {
+ mSimUnlockProgressDialog.getWindow().setType(
+ WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
+ }
+ }
+ return mSimUnlockProgressDialog;
+ }
+
+ private boolean checkPuk() {
+ // make sure the puk is at least 8 digits long.
+ if (mPasswordEntry.getText().length() >= 8) {
+ mPukText = mPasswordEntry.getText().toString();
+ return true;
+ }
+ return false;
+ }
+
+ private boolean checkPin() {
+ // make sure the PIN is between 4 and 8 digits
+ int length = mPasswordEntry.getText().length();
+ if (length >= 4 && length <= 8) {
+ mPinText = mPasswordEntry.getText().toString();
+ return true;
+ }
+ return false;
+ }
+
+ public boolean confirmPin() {
+ return mPinText.equals(mPasswordEntry.getText().toString());
+ }
+
+ private void updateSim() {
+ getSimUnlockProgressDialog().show();
+
+ if (!mCheckInProgress) {
+ mCheckInProgress = true;
+ new CheckSimPuk(mPukText, mPinText) {
+ void onSimLockChangedResponse(final boolean success) {
+ post(new Runnable() {
+ public void run() {
+ if (mSimUnlockProgressDialog != null) {
+ mSimUnlockProgressDialog.hide();
+ }
+ if (success) {
+ mCallback.dismiss(true);
+ } else {
+ mStateMachine.reset();
+ mSecurityMessageDisplay.setMessage(R.string.kg_invalid_puk, true);
+ }
+ mCheckInProgress = false;
+ }
+ });
+ }
+ }.start();
+ }
+ }
+
+ @Override
+ protected void verifyPasswordAndUnlock() {
+ mStateMachine.next();
+ }
+}
+
+
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java
new file mode 100644
index 0000000..29f76f3
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java
@@ -0,0 +1,154 @@
+/*
+ * 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.keyguard;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Typeface;
+import android.text.TextUtils;
+import android.util.AttributeSet;
+import android.util.Slog;
+import android.view.View;
+import android.widget.GridLayout;
+import android.widget.TextView;
+
+import com.android.internal.widget.LockPatternUtils;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+
+import libcore.icu.ICU;
+
+public class KeyguardStatusView extends GridLayout {
+ private static final boolean DEBUG = KeyguardViewMediator.DEBUG;
+ private static final String TAG = "KeyguardStatusView";
+
+ public static final int LOCK_ICON = 0; // R.drawable.ic_lock_idle_lock;
+ public static final int ALARM_ICON = R.drawable.ic_lock_idle_alarm;
+ public static final int CHARGING_ICON = 0; //R.drawable.ic_lock_idle_charging;
+ public static final int BATTERY_LOW_ICON = 0; //R.drawable.ic_lock_idle_low_battery;
+
+ private SimpleDateFormat mDateFormat;
+ private LockPatternUtils mLockPatternUtils;
+
+ private TextView mDateView;
+ private TextView mAlarmStatusView;
+ private ClockView mClockView;
+
+ private KeyguardUpdateMonitorCallback mInfoCallback = new KeyguardUpdateMonitorCallback() {
+
+ @Override
+ public void onTimeChanged() {
+ refresh();
+ }
+
+ @Override
+ void onKeyguardVisibilityChanged(boolean showing) {
+ if (showing) {
+ if (DEBUG) Slog.v(TAG, "refresh statusview showing:" + showing);
+ refresh();
+ }
+ };
+ };
+
+ public KeyguardStatusView(Context context) {
+ this(context, null, 0);
+ }
+
+ public KeyguardStatusView(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public KeyguardStatusView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ @Override
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+ Resources res = getContext().getResources();
+ final Locale locale = Locale.getDefault();
+ final String datePattern = res.getString(R.string.system_ui_date_pattern);
+ final String bestFormat = ICU.getBestDateTimePattern(datePattern, locale.toString());
+ mDateFormat = new SimpleDateFormat(bestFormat, locale);
+ mDateView = (TextView) findViewById(R.id.date);
+ mAlarmStatusView = (TextView) findViewById(R.id.alarm_status);
+ mClockView = (ClockView) findViewById(R.id.clock_view);
+ mLockPatternUtils = new LockPatternUtils(getContext());
+
+ // Use custom font in mDateView
+ mDateView.setTypeface(Typeface.SANS_SERIF, Typeface.BOLD);
+
+ // Required to get Marquee to work.
+ final View marqueeViews[] = { mDateView, mAlarmStatusView };
+ for (int i = 0; i < marqueeViews.length; i++) {
+ View v = marqueeViews[i];
+ if (v == null) {
+ throw new RuntimeException("Can't find widget at index " + i);
+ }
+ v.setSelected(true);
+ }
+ refresh();
+ }
+
+ protected void refresh() {
+ mClockView.updateTime();
+ refreshDate();
+ refreshAlarmStatus(); // might as well
+ }
+
+ void refreshAlarmStatus() {
+ // Update Alarm status
+ String nextAlarm = mLockPatternUtils.getNextAlarm();
+ if (!TextUtils.isEmpty(nextAlarm)) {
+ maybeSetUpperCaseText(mAlarmStatusView, nextAlarm);
+ mAlarmStatusView.setCompoundDrawablesWithIntrinsicBounds(ALARM_ICON, 0, 0, 0);
+ mAlarmStatusView.setVisibility(View.VISIBLE);
+ } else {
+ mAlarmStatusView.setVisibility(View.GONE);
+ }
+ }
+
+ void refreshDate() {
+ maybeSetUpperCaseText(mDateView, mDateFormat.format(new Date()));
+ }
+
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mInfoCallback);
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ KeyguardUpdateMonitor.getInstance(mContext).removeCallback(mInfoCallback);
+ }
+
+ public int getAppWidgetId() {
+ return LockPatternUtils.ID_DEFAULT_STATUS_WIDGET;
+ }
+
+ private void maybeSetUpperCaseText(TextView textView, CharSequence text) {
+ if (KeyguardViewManager.USE_UPPER_CASE) {
+ textView.setText(text != null ? text.toString().toUpperCase() : null);
+ } else {
+ textView.setText(text);
+ }
+ }
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardStatusViewManager.java b/packages/Keyguard/src/com/android/keyguard/KeyguardStatusViewManager.java
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardStatusViewManager.java
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardTestActivity.java b/packages/Keyguard/src/com/android/keyguard/KeyguardTestActivity.java
new file mode 100644
index 0000000..0ff00e3
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardTestActivity.java
@@ -0,0 +1,356 @@
+/*
+ * 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.keyguard;
+
+import com.android.internal.policy.IKeyguardShowCallback;
+import com.android.internal.policy.IKeyguardExitCallback;
+import com.android.internal.policy.IKeyguardService;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.SystemClock;
+import android.provider.Settings;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.WindowManagerPolicy;
+
+import com.android.internal.widget.LockPatternUtils;
+import com.android.internal.widget.LockPatternView.Cell;
+
+import java.util.List;
+
+public class KeyguardTestActivity extends Activity implements OnClickListener {
+ private static final String KEYGUARD_PACKAGE = "com.android.keyguard";
+ private static final String KEYGUARD_CLASS = "com.android.keyguard.KeyguardService";
+ private static final String TAG = "LockScreenTestActivity";
+ private static final int MODE_NONE = 0;
+ private static final int MODE_PIN = 1;
+ private static final int MODE_PASSWORD = 2;
+ private static final int MODE_PATTERN = 3;
+ private static final int MODE_SIM_PIN = 4;
+ private static final int MODE_SIM_PUK = 5;
+ private static final String SECURITY_MODE = "security_mode";
+
+ IKeyguardService mService = null;
+
+ KeyguardShowCallback mKeyguardShowCallback = new KeyguardShowCallback();
+ KeyguardExitCallback mKeyguardExitCallback = new KeyguardExitCallback();
+
+ RemoteServiceConnection mConnection;
+ private boolean mSentSystemReady;
+
+ class KeyguardShowCallback extends IKeyguardShowCallback.Stub {
+
+ @Override
+ public void onShown(IBinder windowToken) throws RemoteException {
+ Log.v(TAG, "Keyguard is shown, windowToken = " + windowToken);
+ }
+ }
+
+ class KeyguardExitCallback extends IKeyguardExitCallback.Stub {
+
+ @Override
+ public void onKeyguardExitResult(boolean success) throws RemoteException {
+ new AlertDialog.Builder(KeyguardTestActivity.this)
+ .setMessage("Result: " + success)
+ .setPositiveButton("OK", null)
+ .show();
+ }
+
+ };
+
+ private class RemoteServiceConnection implements ServiceConnection {
+ public void onServiceConnected(ComponentName className, IBinder service) {
+ Log.v(TAG, "onServiceConnected()");
+ mService = IKeyguardService.Stub.asInterface(service);
+ try {
+ mService.asBinder().linkToDeath(new IBinder.DeathRecipient() {
+ @Override
+ public void binderDied() {
+ new AlertDialog.Builder(KeyguardTestActivity.this)
+ .setMessage("Oops! Keygued died")
+ .setPositiveButton("OK", null)
+ .show();
+ }
+ }, 0);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Couldn't linkToDeath");
+ e.printStackTrace();
+ }
+// try {
+// mService.onSystemReady();
+// } catch (RemoteException e) {
+// Log.v(TAG, "Remote service died trying to call onSystemReady");
+// e.printStackTrace();
+// }
+ }
+
+ public void onServiceDisconnected(ComponentName className) {
+ Log.v(TAG, "onServiceDisconnected()");
+ mService = null;
+ }
+ };
+
+ private void bindService() {
+ if (mConnection == null) {
+ mConnection = new RemoteServiceConnection();
+ Intent intent = new Intent();
+ intent.setClassName(KEYGUARD_PACKAGE, KEYGUARD_CLASS);
+ Log.v(TAG, "BINDING SERVICE: " + KEYGUARD_CLASS);
+ if (!bindService(intent, mConnection, Context.BIND_AUTO_CREATE)) {
+ Log.v(TAG, "FAILED TO BIND TO KEYGUARD!");
+ }
+ } else {
+ Log.v(TAG, "Service already bound");
+ }
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.keyguard_test_activity);
+ final int[] buttons = {
+ R.id.on_screen_turned_off, R.id.on_screen_turned_on,
+ R.id.do_keyguard, R.id.verify_unlock
+ };
+ for (int i = 0; i < buttons.length; i++) {
+ findViewById(buttons[i]).setOnClickListener(this);
+ }
+ Log.v(TAG, "Binding service...");
+ bindService();
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ outState.putInt(SECURITY_MODE, mSecurityMode);
+ }
+
+ @Override
+ protected void onRestoreInstanceState(Bundle savedInstanceState) {
+ super.onRestoreInstanceState(savedInstanceState);
+ setMode(savedInstanceState.getInt(SECURITY_MODE));
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ MenuInflater inflater = getMenuInflater();
+ inflater.inflate(R.menu.optionmenu, menu);
+ return true;
+ }
+
+ private void setMode(int mode) {
+ mTestSimPin = false;
+ mTestSimPuk = false;
+ mLockPasswordEnabled = false;
+ mLockPatternEnabled = false;
+ switch(mode) {
+ case MODE_NONE:
+ mSecurityModeMock = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
+ break;
+ case MODE_PIN:
+ mSecurityModeMock = DevicePolicyManager.PASSWORD_QUALITY_NUMERIC;
+ mLockPasswordEnabled = true;
+ break;
+ case MODE_PASSWORD:
+ mSecurityModeMock = DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC;
+ mLockPasswordEnabled = true;
+ break;
+ case MODE_PATTERN:
+ mSecurityModeMock = DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;
+ mLockPatternEnabled = true;
+ break;
+ case MODE_SIM_PIN:
+ mTestSimPin = true;
+ break;
+ case MODE_SIM_PUK:
+ mTestSimPuk = true;
+ break;
+ }
+ mSecurityMode = mode;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ // Handle item selection
+ switch (item.getItemId()) {
+ case R.id.none_menu_item:
+ setMode(MODE_NONE);
+ break;
+ case R.id.pin_menu_item:
+ setMode(MODE_PIN);
+ break;
+ case R.id.password_menu_item:
+ setMode(MODE_PASSWORD);
+ break;
+ case R.id.pattern_menu_item:
+ setMode(MODE_PATTERN);
+ break;
+ case R.id.sim_pin_menu_item:
+ setMode(MODE_SIM_PIN);
+ break;
+ case R.id.sim_puk_menu_item:
+ setMode(MODE_SIM_PUK);
+ break;
+ case R.id.add_widget_item:
+ startWidgetPicker();
+ break;
+ default:
+ return super.onOptionsItemSelected(item);
+ }
+ try {
+ mService.doKeyguardTimeout(null);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Remote service died");
+ e.printStackTrace();
+ }
+ return true;
+ }
+
+ private void startWidgetPicker() {
+ startActivity(new Intent(Settings.ACTION_SECURITY_SETTINGS));
+ }
+
+ @Override
+ public void onClick(View v) {
+ try {
+ switch (v.getId()) {
+ case R.id.on_screen_turned_on:
+ mService.onScreenTurnedOn(mKeyguardShowCallback);
+ break;
+ case R.id.on_screen_turned_off:
+ mService.onScreenTurnedOff(WindowManagerPolicy.OFF_BECAUSE_OF_USER);
+ break;
+ case R.id.do_keyguard:
+ if (!mSentSystemReady) {
+ mSentSystemReady = true;
+ mService.onSystemReady();
+ }
+ mService.doKeyguardTimeout(null);
+ break;
+ case R.id.verify_unlock:
+ mService.verifyUnlock(mKeyguardExitCallback);
+ break;
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "Remote service died");
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ try {
+ if (mService != null) {
+ mService.setHidden(true);
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "Remote service died");
+ e.printStackTrace();
+ }
+ }
+
+ protected void onResume() {
+ super.onResume();
+ try {
+ if (mService != null) {
+ mService.setHidden(false);
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "Remote service died");
+ e.printStackTrace();
+ }
+ }
+
+ public int mSecurityModeMock;
+ private boolean mTestSimPin;
+ private boolean mTestSimPuk;
+ private boolean mLockPasswordEnabled;
+ public boolean mLockPatternEnabled;
+ private int mSecurityMode;
+
+ class LockPatternUtilsMock extends LockPatternUtils {
+ private long mDeadline;
+ public LockPatternUtilsMock(Context context) {
+ super(context);
+ }
+
+ @Override
+ public boolean checkPattern(List<Cell> pattern) {
+ return pattern.size() > 4;
+ }
+
+ @Override
+ public boolean checkPassword(String password) {
+ return password.length() > 4;
+ }
+ @Override
+ public long setLockoutAttemptDeadline() {
+ final long deadline = SystemClock.elapsedRealtime() + FAILED_ATTEMPT_TIMEOUT_MS;
+ mDeadline = deadline;
+ return deadline;
+ }
+ @Override
+ public boolean isLockScreenDisabled() {
+ return false;
+ }
+ @Override
+ public long getLockoutAttemptDeadline() {
+ return mDeadline;
+ }
+ @Override
+ public void reportFailedPasswordAttempt() {
+ // Ignored
+ }
+ @Override
+ public void reportSuccessfulPasswordAttempt() {
+ // Ignored
+ }
+ @Override
+ public boolean isLockPatternEnabled() {
+ return mLockPatternEnabled;
+ }
+
+ @Override
+ public boolean isLockPasswordEnabled() {
+ return mLockPasswordEnabled;
+ }
+
+ @Override
+ public int getKeyguardStoredPasswordQuality() {
+ return mSecurityModeMock;
+ }
+
+ public boolean isSecure() {
+ return mLockPatternEnabled || mLockPasswordEnabled || mTestSimPin || mTestSimPuk;
+ }
+
+ }
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardTransportControlView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardTransportControlView.java
new file mode 100644
index 0000000..315dca6
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardTransportControlView.java
@@ -0,0 +1,527 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.keyguard;
+
+import android.app.PendingIntent;
+import android.app.PendingIntent.CanceledException;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.media.AudioManager;
+import android.media.IRemoteControlDisplay;
+import android.media.MediaMetadataRetriever;
+import android.media.RemoteControlClient;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.RemoteException;
+import android.os.SystemClock;
+import android.text.Spannable;
+import android.text.TextUtils;
+import android.text.style.ForegroundColorSpan;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import java.lang.ref.WeakReference;
+/**
+ * This is the widget responsible for showing music controls in keyguard.
+ */
+public class KeyguardTransportControlView extends FrameLayout implements OnClickListener {
+
+ private static final int MSG_UPDATE_STATE = 100;
+ private static final int MSG_SET_METADATA = 101;
+ private static final int MSG_SET_TRANSPORT_CONTROLS = 102;
+ private static final int MSG_SET_ARTWORK = 103;
+ private static final int MSG_SET_GENERATION_ID = 104;
+ private static final int DISPLAY_TIMEOUT_MS = 5000; // 5s
+ protected static final boolean DEBUG = false;
+ protected static final String TAG = "TransportControlView";
+
+ private ImageView mAlbumArt;
+ private TextView mTrackTitle;
+ private ImageView mBtnPrev;
+ private ImageView mBtnPlay;
+ private ImageView mBtnNext;
+ private int mClientGeneration;
+ private Metadata mMetadata = new Metadata();
+ private boolean mAttached;
+ private PendingIntent mClientIntent;
+ private int mTransportControlFlags;
+ private int mCurrentPlayState;
+ private AudioManager mAudioManager;
+ private IRemoteControlDisplayWeak mIRCD;
+ private boolean mMusicClientPresent = true;
+
+ /**
+ * The metadata which should be populated into the view once we've been attached
+ */
+ private Bundle mPopulateMetadataWhenAttached = null;
+
+ // This handler is required to ensure messages from IRCD are handled in sequence and on
+ // the UI thread.
+ private Handler mHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case MSG_UPDATE_STATE:
+ if (mClientGeneration == msg.arg1) updatePlayPauseState(msg.arg2);
+ break;
+
+ case MSG_SET_METADATA:
+ if (mClientGeneration == msg.arg1) updateMetadata((Bundle) msg.obj);
+ break;
+
+ case MSG_SET_TRANSPORT_CONTROLS:
+ if (mClientGeneration == msg.arg1) updateTransportControls(msg.arg2);
+ break;
+
+ case MSG_SET_ARTWORK:
+ if (mClientGeneration == msg.arg1) {
+ if (mMetadata.bitmap != null) {
+ mMetadata.bitmap.recycle();
+ }
+ mMetadata.bitmap = (Bitmap) msg.obj;
+ mAlbumArt.setImageBitmap(mMetadata.bitmap);
+ }
+ break;
+
+ case MSG_SET_GENERATION_ID:
+ if (msg.arg2 != 0) {
+ // This means nobody is currently registered. Hide the view.
+ onListenerDetached();
+ } else {
+ onListenerAttached();
+ }
+ if (DEBUG) Log.v(TAG, "New genId = " + msg.arg1 + ", clearing = " + msg.arg2);
+ mClientGeneration = msg.arg1;
+ mClientIntent = (PendingIntent) msg.obj;
+ break;
+
+ }
+ }
+ };
+ private KeyguardHostView.TransportCallback mTransportCallback;
+
+ /**
+ * This class is required to have weak linkage to the current TransportControlView
+ * because the remote process can hold a strong reference to this binder object and
+ * we can't predict when it will be GC'd in the remote process. Without this code, it
+ * would allow a heavyweight object to be held on this side of the binder when there's
+ * no requirement to run a GC on the other side.
+ */
+ private static class IRemoteControlDisplayWeak extends IRemoteControlDisplay.Stub {
+ private WeakReference<Handler> mLocalHandler;
+
+ IRemoteControlDisplayWeak(Handler handler) {
+ mLocalHandler = new WeakReference<Handler>(handler);
+ }
+
+ public void setPlaybackState(int generationId, int state, long stateChangeTimeMs) {
+ Handler handler = mLocalHandler.get();
+ if (handler != null) {
+ handler.obtainMessage(MSG_UPDATE_STATE, generationId, state).sendToTarget();
+ }
+ }
+
+ public void setMetadata(int generationId, Bundle metadata) {
+ Handler handler = mLocalHandler.get();
+ if (handler != null) {
+ handler.obtainMessage(MSG_SET_METADATA, generationId, 0, metadata).sendToTarget();
+ }
+ }
+
+ public void setTransportControlFlags(int generationId, int flags) {
+ Handler handler = mLocalHandler.get();
+ if (handler != null) {
+ handler.obtainMessage(MSG_SET_TRANSPORT_CONTROLS, generationId, flags)
+ .sendToTarget();
+ }
+ }
+
+ public void setArtwork(int generationId, Bitmap bitmap) {
+ Handler handler = mLocalHandler.get();
+ if (handler != null) {
+ handler.obtainMessage(MSG_SET_ARTWORK, generationId, 0, bitmap).sendToTarget();
+ }
+ }
+
+ public void setAllMetadata(int generationId, Bundle metadata, Bitmap bitmap) {
+ Handler handler = mLocalHandler.get();
+ if (handler != null) {
+ handler.obtainMessage(MSG_SET_METADATA, generationId, 0, metadata).sendToTarget();
+ handler.obtainMessage(MSG_SET_ARTWORK, generationId, 0, bitmap).sendToTarget();
+ }
+ }
+
+ public void setCurrentClientId(int clientGeneration, PendingIntent mediaIntent,
+ boolean clearing) throws RemoteException {
+ Handler handler = mLocalHandler.get();
+ if (handler != null) {
+ handler.obtainMessage(MSG_SET_GENERATION_ID,
+ clientGeneration, (clearing ? 1 : 0), mediaIntent).sendToTarget();
+ }
+ }
+ };
+
+ public KeyguardTransportControlView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ if (DEBUG) Log.v(TAG, "Create TCV " + this);
+ mAudioManager = new AudioManager(mContext);
+ mCurrentPlayState = RemoteControlClient.PLAYSTATE_NONE; // until we get a callback
+ mIRCD = new IRemoteControlDisplayWeak(mHandler);
+ }
+
+ protected void onListenerDetached() {
+ mMusicClientPresent = false;
+ if (DEBUG) Log.v(TAG, "onListenerDetached()");
+ if (mTransportCallback != null) {
+ mTransportCallback.onListenerDetached();
+ } else {
+ Log.w(TAG, "onListenerDetached: no callback");
+ }
+ }
+
+ private void onListenerAttached() {
+ mMusicClientPresent = true;
+ if (DEBUG) Log.v(TAG, "onListenerAttached()");
+ if (mTransportCallback != null) {
+ mTransportCallback.onListenerAttached();
+ } else {
+ Log.w(TAG, "onListenerAttached(): no callback");
+ }
+ }
+
+ private void updateTransportControls(int transportControlFlags) {
+ mTransportControlFlags = transportControlFlags;
+ }
+
+ @Override
+ public void onFinishInflate() {
+ super.onFinishInflate();
+ mTrackTitle = (TextView) findViewById(R.id.title);
+ mTrackTitle.setSelected(true); // enable marquee
+ mAlbumArt = (ImageView) findViewById(R.id.albumart);
+ mBtnPrev = (ImageView) findViewById(R.id.btn_prev);
+ mBtnPlay = (ImageView) findViewById(R.id.btn_play);
+ mBtnNext = (ImageView) findViewById(R.id.btn_next);
+ final View buttons[] = { mBtnPrev, mBtnPlay, mBtnNext };
+ for (View view : buttons) {
+ view.setOnClickListener(this);
+ }
+ }
+
+ @Override
+ public void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ if (DEBUG) Log.v(TAG, "onAttachToWindow()");
+ if (mPopulateMetadataWhenAttached != null) {
+ updateMetadata(mPopulateMetadataWhenAttached);
+ mPopulateMetadataWhenAttached = null;
+ }
+ if (!mAttached) {
+ if (DEBUG) Log.v(TAG, "Registering TCV " + this);
+ mAudioManager.registerRemoteControlDisplay(mIRCD);
+ }
+ mAttached = true;
+ }
+
+ @Override
+ protected void onSizeChanged (int w, int h, int oldw, int oldh) {
+ if (mAttached) {
+ int dim = Math.min(512, Math.max(w, h));
+ if (DEBUG) Log.v(TAG, "TCV uses bitmap size=" + dim);
+ mAudioManager.remoteControlDisplayUsesBitmapSize(mIRCD, dim, dim);
+ }
+ }
+
+ @Override
+ public void onDetachedFromWindow() {
+ if (DEBUG) Log.v(TAG, "onDetachFromWindow()");
+ super.onDetachedFromWindow();
+ if (mAttached) {
+ if (DEBUG) Log.v(TAG, "Unregistering TCV " + this);
+ mAudioManager.unregisterRemoteControlDisplay(mIRCD);
+ }
+ mAttached = false;
+ }
+
+ class Metadata {
+ private String artist;
+ private String trackTitle;
+ private String albumTitle;
+ private Bitmap bitmap;
+
+ public String toString() {
+ return "Metadata[artist=" + artist + " trackTitle=" + trackTitle + " albumTitle=" + albumTitle + "]";
+ }
+ }
+
+ private String getMdString(Bundle data, int id) {
+ return data.getString(Integer.toString(id));
+ }
+
+ private void updateMetadata(Bundle data) {
+ if (mAttached) {
+ mMetadata.artist = getMdString(data, MediaMetadataRetriever.METADATA_KEY_ALBUMARTIST);
+ mMetadata.trackTitle = getMdString(data, MediaMetadataRetriever.METADATA_KEY_TITLE);
+ mMetadata.albumTitle = getMdString(data, MediaMetadataRetriever.METADATA_KEY_ALBUM);
+ populateMetadata();
+ } else {
+ mPopulateMetadataWhenAttached = data;
+ }
+ }
+
+ /**
+ * Populates the given metadata into the view
+ */
+ private void populateMetadata() {
+ StringBuilder sb = new StringBuilder();
+ int trackTitleLength = 0;
+ if (!TextUtils.isEmpty(mMetadata.trackTitle)) {
+ sb.append(mMetadata.trackTitle);
+ trackTitleLength = mMetadata.trackTitle.length();
+ }
+ if (!TextUtils.isEmpty(mMetadata.artist)) {
+ if (sb.length() != 0) {
+ sb.append(" - ");
+ }
+ sb.append(mMetadata.artist);
+ }
+ if (!TextUtils.isEmpty(mMetadata.albumTitle)) {
+ if (sb.length() != 0) {
+ sb.append(" - ");
+ }
+ sb.append(mMetadata.albumTitle);
+ }
+ mTrackTitle.setText(sb.toString(), TextView.BufferType.SPANNABLE);
+ Spannable str = (Spannable) mTrackTitle.getText();
+ if (trackTitleLength != 0) {
+ str.setSpan(new ForegroundColorSpan(0xffffffff), 0, trackTitleLength,
+ Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+ trackTitleLength++;
+ }
+ if (sb.length() > trackTitleLength) {
+ str.setSpan(new ForegroundColorSpan(0x7fffffff), trackTitleLength, sb.length(),
+ Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+ }
+
+ mAlbumArt.setImageBitmap(mMetadata.bitmap);
+ final int flags = mTransportControlFlags;
+ setVisibilityBasedOnFlag(mBtnPrev, flags, RemoteControlClient.FLAG_KEY_MEDIA_PREVIOUS);
+ setVisibilityBasedOnFlag(mBtnNext, flags, RemoteControlClient.FLAG_KEY_MEDIA_NEXT);
+ setVisibilityBasedOnFlag(mBtnPlay, flags,
+ RemoteControlClient.FLAG_KEY_MEDIA_PLAY
+ | RemoteControlClient.FLAG_KEY_MEDIA_PAUSE
+ | RemoteControlClient.FLAG_KEY_MEDIA_PLAY_PAUSE
+ | RemoteControlClient.FLAG_KEY_MEDIA_STOP);
+
+ updatePlayPauseState(mCurrentPlayState);
+ }
+
+ public boolean isMusicPlaying() {
+ return mCurrentPlayState == RemoteControlClient.PLAYSTATE_PLAYING
+ || mCurrentPlayState == RemoteControlClient.PLAYSTATE_BUFFERING;
+ }
+
+ private static void setVisibilityBasedOnFlag(View view, int flags, int flag) {
+ if ((flags & flag) != 0) {
+ view.setVisibility(View.VISIBLE);
+ } else {
+ view.setVisibility(View.GONE);
+ }
+ }
+
+ private void updatePlayPauseState(int state) {
+ if (DEBUG) Log.v(TAG,
+ "updatePlayPauseState(), old=" + mCurrentPlayState + ", state=" + state);
+ if (state == mCurrentPlayState) {
+ return;
+ }
+ final int imageResId;
+ final int imageDescId;
+ switch (state) {
+ case RemoteControlClient.PLAYSTATE_ERROR:
+ imageResId = R.drawable.stat_sys_warning;
+ // TODO use more specific image description string for warning, but here the "play"
+ // message is still valid because this button triggers a play command.
+ imageDescId = R.string.keyguard_transport_play_description;
+ break;
+
+ case RemoteControlClient.PLAYSTATE_PLAYING:
+ imageResId = R.drawable.ic_media_pause;
+ imageDescId = R.string.keyguard_transport_pause_description;
+ break;
+
+ case RemoteControlClient.PLAYSTATE_BUFFERING:
+ imageResId = R.drawable.ic_media_stop;
+ imageDescId = R.string.keyguard_transport_stop_description;
+ break;
+
+ case RemoteControlClient.PLAYSTATE_PAUSED:
+ default:
+ imageResId = R.drawable.ic_media_play;
+ imageDescId = R.string.keyguard_transport_play_description;
+ break;
+ }
+ mBtnPlay.setImageResource(imageResId);
+ mBtnPlay.setContentDescription(getResources().getString(imageDescId));
+ mCurrentPlayState = state;
+ mTransportCallback.onPlayStateChanged();
+ }
+
+ static class SavedState extends BaseSavedState {
+ boolean clientPresent;
+
+ SavedState(Parcelable superState) {
+ super(superState);
+ }
+
+ private SavedState(Parcel in) {
+ super(in);
+ this.clientPresent = in.readInt() != 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel out, int flags) {
+ super.writeToParcel(out, flags);
+ out.writeInt(this.clientPresent ? 1 : 0);
+ }
+
+ public static final Parcelable.Creator<SavedState> CREATOR
+ = new Parcelable.Creator<SavedState>() {
+ public SavedState createFromParcel(Parcel in) {
+ return new SavedState(in);
+ }
+
+ public SavedState[] newArray(int size) {
+ return new SavedState[size];
+ }
+ };
+ }
+
+ @Override
+ public Parcelable onSaveInstanceState() {
+ Parcelable superState = super.onSaveInstanceState();
+ SavedState ss = new SavedState(superState);
+ ss.clientPresent = mMusicClientPresent;
+ return ss;
+ }
+
+ @Override
+ public void onRestoreInstanceState(Parcelable state) {
+ if (!(state instanceof SavedState)) {
+ super.onRestoreInstanceState(state);
+ return;
+ }
+ SavedState ss = (SavedState) state;
+ super.onRestoreInstanceState(ss.getSuperState());
+ if (ss.clientPresent) {
+ if (DEBUG) Log.v(TAG, "Reattaching client because it was attached");
+ onListenerAttached();
+ }
+ }
+
+ public void onClick(View v) {
+ int keyCode = -1;
+ if (v == mBtnPrev) {
+ keyCode = KeyEvent.KEYCODE_MEDIA_PREVIOUS;
+ } else if (v == mBtnNext) {
+ keyCode = KeyEvent.KEYCODE_MEDIA_NEXT;
+ } else if (v == mBtnPlay) {
+ keyCode = KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE;
+
+ }
+ if (keyCode != -1) {
+ sendMediaButtonClick(keyCode);
+ }
+ }
+
+ private void sendMediaButtonClick(int keyCode) {
+ if (mClientIntent == null) {
+ // Shouldn't be possible because this view should be hidden in this case.
+ Log.e(TAG, "sendMediaButtonClick(): No client is currently registered");
+ return;
+ }
+ // use the registered PendingIntent that will be processed by the registered
+ // media button event receiver, which is the component of mClientIntent
+ KeyEvent keyEvent = new KeyEvent(KeyEvent.ACTION_DOWN, keyCode);
+ Intent intent = new Intent(Intent.ACTION_MEDIA_BUTTON);
+ intent.putExtra(Intent.EXTRA_KEY_EVENT, keyEvent);
+ try {
+ mClientIntent.send(getContext(), 0, intent);
+ } catch (CanceledException e) {
+ Log.e(TAG, "Error sending intent for media button down: "+e);
+ e.printStackTrace();
+ }
+
+ keyEvent = new KeyEvent(KeyEvent.ACTION_UP, keyCode);
+ intent = new Intent(Intent.ACTION_MEDIA_BUTTON);
+ intent.putExtra(Intent.EXTRA_KEY_EVENT, keyEvent);
+ try {
+ mClientIntent.send(getContext(), 0, intent);
+ } catch (CanceledException e) {
+ Log.e(TAG, "Error sending intent for media button up: "+e);
+ e.printStackTrace();
+ }
+ }
+
+ public boolean providesClock() {
+ return false;
+ }
+
+ private boolean wasPlayingRecently(int state, long stateChangeTimeMs) {
+ switch (state) {
+ case RemoteControlClient.PLAYSTATE_PLAYING:
+ case RemoteControlClient.PLAYSTATE_FAST_FORWARDING:
+ case RemoteControlClient.PLAYSTATE_REWINDING:
+ case RemoteControlClient.PLAYSTATE_SKIPPING_FORWARDS:
+ case RemoteControlClient.PLAYSTATE_SKIPPING_BACKWARDS:
+ case RemoteControlClient.PLAYSTATE_BUFFERING:
+ // actively playing or about to play
+ return true;
+ case RemoteControlClient.PLAYSTATE_NONE:
+ return false;
+ case RemoteControlClient.PLAYSTATE_STOPPED:
+ case RemoteControlClient.PLAYSTATE_PAUSED:
+ case RemoteControlClient.PLAYSTATE_ERROR:
+ // we have stopped playing, check how long ago
+ if (DEBUG) {
+ if ((SystemClock.elapsedRealtime() - stateChangeTimeMs) < DISPLAY_TIMEOUT_MS) {
+ Log.v(TAG, "wasPlayingRecently: time < TIMEOUT was playing recently");
+ } else {
+ Log.v(TAG, "wasPlayingRecently: time > TIMEOUT");
+ }
+ }
+ return ((SystemClock.elapsedRealtime() - stateChangeTimeMs) < DISPLAY_TIMEOUT_MS);
+ default:
+ Log.e(TAG, "Unknown playback state " + state + " in wasPlayingRecently()");
+ return false;
+ }
+ }
+
+ public void setKeyguardCallback(KeyguardHostView.TransportCallback transportCallback) {
+ mTransportCallback = transportCallback;
+ }
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
new file mode 100644
index 0000000..ff0dee7
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -0,0 +1,839 @@
+/*
+ * 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 com.android.keyguard;
+
+import android.app.ActivityManagerNative;
+import android.app.IUserSwitchObserver;
+import android.app.admin.DevicePolicyManager;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.database.ContentObserver;
+import static android.os.BatteryManager.BATTERY_STATUS_FULL;
+import static android.os.BatteryManager.BATTERY_STATUS_UNKNOWN;
+import static android.os.BatteryManager.BATTERY_HEALTH_UNKNOWN;
+import static android.os.BatteryManager.EXTRA_STATUS;
+import static android.os.BatteryManager.EXTRA_PLUGGED;
+import static android.os.BatteryManager.EXTRA_LEVEL;
+import static android.os.BatteryManager.EXTRA_HEALTH;
+import android.media.AudioManager;
+import android.os.BatteryManager;
+import android.os.Handler;
+import android.os.IRemoteCallback;
+import android.os.Message;
+import android.os.RemoteException;
+import android.provider.Settings;
+
+import com.android.internal.telephony.IccCardConstants;
+import com.android.internal.telephony.TelephonyIntents;
+
+import android.telephony.TelephonyManager;
+import android.util.Log;
+import com.google.android.collect.Lists;
+
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+
+/**
+ * Watches for updates that may be interesting to the keyguard, and provides
+ * the up to date information as well as a registration for callbacks that care
+ * to be updated.
+ *
+ * Note: under time crunch, this has been extended to include some stuff that
+ * doesn't really belong here. see {@link #handleBatteryUpdate} where it shutdowns
+ * the device, and {@link #getFailedUnlockAttempts()}, {@link #reportFailedAttempt()}
+ * and {@link #clearFailedUnlockAttempts()}. Maybe we should rename this 'KeyguardContext'...
+ */
+public class KeyguardUpdateMonitor {
+
+ private static final String TAG = "KeyguardUpdateMonitor";
+ private static final boolean DEBUG = false;
+ private static final boolean DEBUG_SIM_STATES = DEBUG || false;
+ private static final int FAILED_BIOMETRIC_UNLOCK_ATTEMPTS_BEFORE_BACKUP = 3;
+ private static final int LOW_BATTERY_THRESHOLD = 20;
+
+ // Callback messages
+ private static final int MSG_TIME_UPDATE = 301;
+ private static final int MSG_BATTERY_UPDATE = 302;
+ private static final int MSG_CARRIER_INFO_UPDATE = 303;
+ private static final int MSG_SIM_STATE_CHANGE = 304;
+ private static final int MSG_RINGER_MODE_CHANGED = 305;
+ 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;
+ private static final int MSG_DPM_STATE_CHANGED = 309;
+ private static final int MSG_USER_SWITCHING = 310;
+ private static final int MSG_USER_REMOVED = 311;
+ private static final int MSG_KEYGUARD_VISIBILITY_CHANGED = 312;
+ protected static final int MSG_BOOT_COMPLETED = 313;
+ private static final int MSG_USER_SWITCH_COMPLETE = 314;
+
+
+ private static KeyguardUpdateMonitor sInstance;
+
+ private final Context mContext;
+
+ // Telephony state
+ private IccCardConstants.State mSimState = IccCardConstants.State.READY;
+ private CharSequence mTelephonyPlmn;
+ private CharSequence mTelephonySpn;
+ private int mRingMode;
+ private int mPhoneState;
+ private boolean mKeyguardIsVisible;
+ private boolean mBootCompleted;
+
+ // Device provisioning state
+ private boolean mDeviceProvisioned;
+
+ // Battery status
+ private BatteryStatus mBatteryStatus;
+
+ // Password attempts
+ private int mFailedAttempts = 0;
+ private int mFailedBiometricUnlockAttempts = 0;
+
+ private boolean mAlternateUnlockEnabled;
+
+ private boolean mClockVisible;
+
+ private final ArrayList<WeakReference<KeyguardUpdateMonitorCallback>>
+ mCallbacks = Lists.newArrayList();
+ private ContentObserver mDeviceProvisionedObserver;
+
+ private final Handler mHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case MSG_TIME_UPDATE:
+ handleTimeUpdate();
+ break;
+ case MSG_BATTERY_UPDATE:
+ handleBatteryUpdate((BatteryStatus) msg.obj);
+ break;
+ case MSG_CARRIER_INFO_UPDATE:
+ handleCarrierInfoUpdate();
+ break;
+ case MSG_SIM_STATE_CHANGE:
+ handleSimStateChange((SimArgs) msg.obj);
+ break;
+ case MSG_RINGER_MODE_CHANGED:
+ handleRingerModeChange(msg.arg1);
+ break;
+ case MSG_PHONE_STATE_CHANGED:
+ handlePhoneStateChanged((String)msg.obj);
+ break;
+ case MSG_CLOCK_VISIBILITY_CHANGED:
+ handleClockVisibilityChanged();
+ break;
+ case MSG_DEVICE_PROVISIONED:
+ handleDeviceProvisioned();
+ break;
+ case MSG_DPM_STATE_CHANGED:
+ handleDevicePolicyManagerStateChanged();
+ break;
+ case MSG_USER_SWITCHING:
+ handleUserSwitching(msg.arg1, (IRemoteCallback)msg.obj);
+ break;
+ case MSG_USER_SWITCH_COMPLETE:
+ handleUserSwitchComplete(msg.arg1);
+ break;
+ case MSG_USER_REMOVED:
+ handleUserRemoved(msg.arg1);
+ break;
+ case MSG_KEYGUARD_VISIBILITY_CHANGED:
+ handleKeyguardVisibilityChanged(msg.arg1);
+ break;
+ case MSG_BOOT_COMPLETED:
+ handleBootCompleted();
+ break;
+
+ }
+ }
+ };
+
+ private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
+
+ public void onReceive(Context context, Intent intent) {
+ final String action = intent.getAction();
+ if (DEBUG) Log.d(TAG, "received broadcast " + action);
+
+ if (Intent.ACTION_TIME_TICK.equals(action)
+ || Intent.ACTION_TIME_CHANGED.equals(action)
+ || Intent.ACTION_TIMEZONE_CHANGED.equals(action)) {
+ mHandler.sendMessage(mHandler.obtainMessage(MSG_TIME_UPDATE));
+ } else if (TelephonyIntents.SPN_STRINGS_UPDATED_ACTION.equals(action)) {
+ mTelephonyPlmn = getTelephonyPlmnFrom(intent);
+ mTelephonySpn = getTelephonySpnFrom(intent);
+ mHandler.sendMessage(mHandler.obtainMessage(MSG_CARRIER_INFO_UPDATE));
+ } else if (Intent.ACTION_BATTERY_CHANGED.equals(action)) {
+ final int status = intent.getIntExtra(EXTRA_STATUS, BATTERY_STATUS_UNKNOWN);
+ final int plugged = intent.getIntExtra(EXTRA_PLUGGED, 0);
+ final int level = intent.getIntExtra(EXTRA_LEVEL, 0);
+ final int health = intent.getIntExtra(EXTRA_HEALTH, BATTERY_HEALTH_UNKNOWN);
+ final Message msg = mHandler.obtainMessage(
+ MSG_BATTERY_UPDATE, new BatteryStatus(status, level, plugged, health));
+ mHandler.sendMessage(msg);
+ } else if (TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(action)) {
+ if (DEBUG_SIM_STATES) {
+ Log.v(TAG, "action " + action + " state" +
+ intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE));
+ }
+ mHandler.sendMessage(mHandler.obtainMessage(
+ MSG_SIM_STATE_CHANGE, SimArgs.fromIntent(intent)));
+ } else if (AudioManager.RINGER_MODE_CHANGED_ACTION.equals(action)) {
+ mHandler.sendMessage(mHandler.obtainMessage(MSG_RINGER_MODE_CHANGED,
+ intent.getIntExtra(AudioManager.EXTRA_RINGER_MODE, -1), 0));
+ } 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));
+ } else if (Intent.ACTION_USER_REMOVED.equals(action)) {
+ mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_REMOVED,
+ intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0), 0));
+ } else if (Intent.ACTION_BOOT_COMPLETED.equals(action)) {
+ mHandler.sendMessage(mHandler.obtainMessage(MSG_BOOT_COMPLETED));
+ }
+ }
+ };
+
+ /**
+ * When we receive a
+ * {@link com.android.internal.telephony.TelephonyIntents#ACTION_SIM_STATE_CHANGED} broadcast,
+ * and then pass a result via our handler to {@link KeyguardUpdateMonitor#handleSimStateChange},
+ * we need a single object to pass to the handler. This class helps decode
+ * the intent and provide a {@link SimCard.State} result.
+ */
+ private static class SimArgs {
+ public final IccCardConstants.State simState;
+
+ SimArgs(IccCardConstants.State state) {
+ simState = state;
+ }
+
+ static SimArgs fromIntent(Intent intent) {
+ IccCardConstants.State state;
+ if (!TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(intent.getAction())) {
+ throw new IllegalArgumentException("only handles intent ACTION_SIM_STATE_CHANGED");
+ }
+ String stateExtra = intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE);
+ if (IccCardConstants.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)) {
+ final String absentReason = intent
+ .getStringExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON);
+
+ if (IccCardConstants.INTENT_VALUE_ABSENT_ON_PERM_DISABLED.equals(
+ absentReason)) {
+ state = IccCardConstants.State.PERM_DISABLED;
+ } else {
+ state = IccCardConstants.State.ABSENT;
+ }
+ } else if (IccCardConstants.INTENT_VALUE_ICC_READY.equals(stateExtra)) {
+ state = IccCardConstants.State.READY;
+ } else if (IccCardConstants.INTENT_VALUE_ICC_LOCKED.equals(stateExtra)) {
+ final String lockedReason = intent
+ .getStringExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON);
+ if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PIN.equals(lockedReason)) {
+ state = IccCardConstants.State.PIN_REQUIRED;
+ } else if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PUK.equals(lockedReason)) {
+ state = IccCardConstants.State.PUK_REQUIRED;
+ } else {
+ state = IccCardConstants.State.UNKNOWN;
+ }
+ } else if (IccCardConstants.INTENT_VALUE_LOCKED_NETWORK.equals(stateExtra)) {
+ state = IccCardConstants.State.NETWORK_LOCKED;
+ } else if (IccCardConstants.INTENT_VALUE_ICC_LOADED.equals(stateExtra)
+ || IccCardConstants.INTENT_VALUE_ICC_IMSI.equals(stateExtra)) {
+ // This is required because telephony doesn't return to "READY" after
+ // these state transitions. See bug 7197471.
+ state = IccCardConstants.State.READY;
+ } else {
+ state = IccCardConstants.State.UNKNOWN;
+ }
+ return new SimArgs(state);
+ }
+
+ public String toString() {
+ return simState.toString();
+ }
+ }
+
+ /* package */ static class BatteryStatus {
+ public final int status;
+ public final int level;
+ public final int plugged;
+ public final int health;
+ public BatteryStatus(int status, int level, int plugged, int health) {
+ this.status = status;
+ this.level = level;
+ this.plugged = plugged;
+ this.health = health;
+ }
+
+ /**
+ * Determine whether the device is plugged in (USB, power, or wireless).
+ * @return true if the device is plugged in.
+ */
+ boolean isPluggedIn() {
+ return plugged == BatteryManager.BATTERY_PLUGGED_AC
+ || plugged == BatteryManager.BATTERY_PLUGGED_USB
+ || plugged == BatteryManager.BATTERY_PLUGGED_WIRELESS;
+ }
+
+ /**
+ * Whether or not the device is charged. Note that some devices never return 100% for
+ * battery level, so this allows either battery level or status to determine if the
+ * battery is charged.
+ * @return true if the device is charged
+ */
+ public boolean isCharged() {
+ return status == BATTERY_STATUS_FULL || level >= 100;
+ }
+
+ /**
+ * Whether battery is low and needs to be charged.
+ * @return true if battery is low
+ */
+ public boolean isBatteryLow() {
+ return level < LOW_BATTERY_THRESHOLD;
+ }
+
+ }
+
+ public static KeyguardUpdateMonitor getInstance(Context context) {
+ if (sInstance == null) {
+ sInstance = new KeyguardUpdateMonitor(context);
+ }
+ return sInstance;
+ }
+
+ private KeyguardUpdateMonitor(Context context) {
+ mContext = context;
+
+ mDeviceProvisioned = isDeviceProvisionedInSettingsDb();
+ // Since device can't be un-provisioned, we only need to register a content observer
+ // to update mDeviceProvisioned when we are...
+ if (!mDeviceProvisioned) {
+ watchForDeviceProvisioning();
+ }
+
+ // Take a guess at initial SIM state, battery status and PLMN until we get an update
+ mSimState = IccCardConstants.State.NOT_READY;
+ mBatteryStatus = new BatteryStatus(BATTERY_STATUS_UNKNOWN, 100, 0, 0);
+ mTelephonyPlmn = getDefaultPlmn();
+
+ // Watch for interesting updates
+ final IntentFilter filter = new IntentFilter();
+ filter.addAction(Intent.ACTION_TIME_TICK);
+ filter.addAction(Intent.ACTION_TIME_CHANGED);
+ filter.addAction(Intent.ACTION_BATTERY_CHANGED);
+ filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
+ filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
+ filter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
+ filter.addAction(TelephonyIntents.SPN_STRINGS_UPDATED_ACTION);
+ filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
+ filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
+ filter.addAction(Intent.ACTION_USER_REMOVED);
+ context.registerReceiver(mBroadcastReceiver, filter);
+
+ final IntentFilter bootCompleteFilter = new IntentFilter();
+ bootCompleteFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
+ bootCompleteFilter.addAction(Intent.ACTION_BOOT_COMPLETED);
+ context.registerReceiver(mBroadcastReceiver, bootCompleteFilter);
+
+ try {
+ ActivityManagerNative.getDefault().registerUserSwitchObserver(
+ new IUserSwitchObserver.Stub() {
+ @Override
+ public void onUserSwitching(int newUserId, IRemoteCallback reply) {
+ mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_SWITCHING,
+ newUserId, 0, reply));
+ }
+ @Override
+ public void onUserSwitchComplete(int newUserId) throws RemoteException {
+ mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_SWITCH_COMPLETE,
+ newUserId));
+ }
+ });
+ } catch (RemoteException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+ private boolean isDeviceProvisionedInSettingsDb() {
+ return Settings.Global.getInt(mContext.getContentResolver(),
+ Settings.Global.DEVICE_PROVISIONED, 0) != 0;
+ }
+
+ private void watchForDeviceProvisioning() {
+ mDeviceProvisionedObserver = new ContentObserver(mHandler) {
+ @Override
+ public void onChange(boolean selfChange) {
+ super.onChange(selfChange);
+ mDeviceProvisioned = isDeviceProvisionedInSettingsDb();
+ if (mDeviceProvisioned) {
+ mHandler.sendMessage(mHandler.obtainMessage(MSG_DEVICE_PROVISIONED));
+ }
+ if (DEBUG) Log.d(TAG, "DEVICE_PROVISIONED state = " + mDeviceProvisioned);
+ }
+ };
+
+ mContext.getContentResolver().registerContentObserver(
+ Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONED),
+ false, mDeviceProvisionedObserver);
+
+ // prevent a race condition between where we check the flag and where we register the
+ // observer by grabbing the value once again...
+ boolean provisioned = isDeviceProvisionedInSettingsDb();
+ if (provisioned != mDeviceProvisioned) {
+ mDeviceProvisioned = provisioned;
+ if (mDeviceProvisioned) {
+ mHandler.sendMessage(mHandler.obtainMessage(MSG_DEVICE_PROVISIONED));
+ }
+ }
+ }
+
+ /**
+ * Handle {@link #MSG_DPM_STATE_CHANGED}
+ */
+ protected void handleDevicePolicyManagerStateChanged() {
+ for (int i = mCallbacks.size() - 1; i >= 0; i--) {
+ KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
+ if (cb != null) {
+ cb.onDevicePolicyManagerStateChanged();
+ }
+ }
+ }
+
+ /**
+ * Handle {@link #MSG_USER_SWITCHING}
+ */
+ protected void handleUserSwitching(int userId, IRemoteCallback reply) {
+ for (int i = 0; i < mCallbacks.size(); i++) {
+ KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
+ if (cb != null) {
+ cb.onUserSwitching(userId);
+ }
+ }
+ setAlternateUnlockEnabled(false);
+ try {
+ reply.sendResult(null);
+ } catch (RemoteException e) {
+ }
+ }
+
+ /**
+ * Handle {@link #MSG_USER_SWITCH_COMPLETE}
+ */
+ protected void handleUserSwitchComplete(int userId) {
+ for (int i = 0; i < mCallbacks.size(); i++) {
+ KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
+ if (cb != null) {
+ cb.onUserSwitchComplete(userId);
+ }
+ }
+ }
+
+ /**
+ * Handle {@link #MSG_BOOT_COMPLETED}
+ */
+ protected void handleBootCompleted() {
+ mBootCompleted = true;
+ for (int i = 0; i < mCallbacks.size(); i++) {
+ KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
+ if (cb != null) {
+ cb.onBootCompleted();
+ }
+ }
+ }
+
+ /**
+ * We need to store this state in the KeyguardUpdateMonitor since this class will not be
+ * destroyed.
+ */
+ public boolean hasBootCompleted() {
+ return mBootCompleted;
+ }
+
+ /**
+ * Handle {@link #MSG_USER_REMOVED}
+ */
+ protected void handleUserRemoved(int userId) {
+ for (int i = 0; i < mCallbacks.size(); i++) {
+ KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
+ if (cb != null) {
+ cb.onUserRemoved(userId);
+ }
+ }
+ }
+
+ /**
+ * Handle {@link #MSG_DEVICE_PROVISIONED}
+ */
+ protected void handleDeviceProvisioned() {
+ for (int i = 0; i < mCallbacks.size(); i++) {
+ KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
+ if (cb != null) {
+ cb.onDeviceProvisioned();
+ }
+ }
+ if (mDeviceProvisionedObserver != null) {
+ // We don't need the observer anymore...
+ mContext.getContentResolver().unregisterContentObserver(mDeviceProvisionedObserver);
+ mDeviceProvisionedObserver = null;
+ }
+ }
+
+ /**
+ * Handle {@link #MSG_PHONE_STATE_CHANGED}
+ */
+ protected void handlePhoneStateChanged(String newState) {
+ if (DEBUG) Log.d(TAG, "handlePhoneStateChanged(" + newState + ")");
+ if (TelephonyManager.EXTRA_STATE_IDLE.equals(newState)) {
+ mPhoneState = TelephonyManager.CALL_STATE_IDLE;
+ } else if (TelephonyManager.EXTRA_STATE_OFFHOOK.equals(newState)) {
+ mPhoneState = TelephonyManager.CALL_STATE_OFFHOOK;
+ } else if (TelephonyManager.EXTRA_STATE_RINGING.equals(newState)) {
+ mPhoneState = TelephonyManager.CALL_STATE_RINGING;
+ }
+ for (int i = 0; i < mCallbacks.size(); i++) {
+ KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
+ if (cb != null) {
+ cb.onPhoneStateChanged(mPhoneState);
+ }
+ }
+ }
+
+ /**
+ * Handle {@link #MSG_RINGER_MODE_CHANGED}
+ */
+ protected void handleRingerModeChange(int mode) {
+ if (DEBUG) Log.d(TAG, "handleRingerModeChange(" + mode + ")");
+ mRingMode = mode;
+ for (int i = 0; i < mCallbacks.size(); i++) {
+ KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
+ if (cb != null) {
+ cb.onRingerModeChanged(mode);
+ }
+ }
+ }
+
+ /**
+ * Handle {@link #MSG_TIME_UPDATE}
+ */
+ private void handleTimeUpdate() {
+ if (DEBUG) Log.d(TAG, "handleTimeUpdate");
+ for (int i = 0; i < mCallbacks.size(); i++) {
+ KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
+ if (cb != null) {
+ cb.onTimeChanged();
+ }
+ }
+ }
+
+ /**
+ * Handle {@link #MSG_BATTERY_UPDATE}
+ */
+ private void handleBatteryUpdate(BatteryStatus status) {
+ if (DEBUG) Log.d(TAG, "handleBatteryUpdate");
+ final boolean batteryUpdateInteresting = isBatteryUpdateInteresting(mBatteryStatus, status);
+ mBatteryStatus = status;
+ if (batteryUpdateInteresting) {
+ for (int i = 0; i < mCallbacks.size(); i++) {
+ KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
+ if (cb != null) {
+ cb.onRefreshBatteryInfo(status);
+ }
+ }
+ }
+ }
+
+ /**
+ * Handle {@link #MSG_CARRIER_INFO_UPDATE}
+ */
+ private void handleCarrierInfoUpdate() {
+ if (DEBUG) Log.d(TAG, "handleCarrierInfoUpdate: plmn = " + mTelephonyPlmn
+ + ", spn = " + mTelephonySpn);
+
+ for (int i = 0; i < mCallbacks.size(); i++) {
+ KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
+ if (cb != null) {
+ cb.onRefreshCarrierInfo(mTelephonyPlmn, mTelephonySpn);
+ }
+ }
+ }
+
+ /**
+ * Handle {@link #MSG_SIM_STATE_CHANGE}
+ */
+ private void handleSimStateChange(SimArgs simArgs) {
+ final IccCardConstants.State state = simArgs.simState;
+
+ if (DEBUG) {
+ Log.d(TAG, "handleSimStateChange: intentValue = " + simArgs + " "
+ + "state resolved to " + state.toString());
+ }
+
+ if (state != IccCardConstants.State.UNKNOWN && state != mSimState) {
+ mSimState = state;
+ for (int i = 0; i < mCallbacks.size(); i++) {
+ KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
+ if (cb != null) {
+ cb.onSimStateChanged(state);
+ }
+ }
+ }
+ }
+
+ /**
+ * Handle {@link #MSG_CLOCK_VISIBILITY_CHANGED}
+ */
+ private void handleClockVisibilityChanged() {
+ if (DEBUG) Log.d(TAG, "handleClockVisibilityChanged()");
+ for (int i = 0; i < mCallbacks.size(); i++) {
+ KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
+ if (cb != null) {
+ cb.onClockVisibilityChanged();
+ }
+ }
+ }
+
+ /**
+ * Handle {@link #MSG_KEYGUARD_VISIBILITY_CHANGED}
+ */
+ private void handleKeyguardVisibilityChanged(int showing) {
+ if (DEBUG) Log.d(TAG, "handleKeyguardVisibilityChanged(" + showing + ")");
+ boolean isShowing = (showing == 1);
+ mKeyguardIsVisible = isShowing;
+ for (int i = 0; i < mCallbacks.size(); i++) {
+ KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
+ if (cb != null) {
+ cb.onKeyguardVisibilityChanged(isShowing);
+ }
+ }
+ }
+
+ public boolean isKeyguardVisible() {
+ return mKeyguardIsVisible;
+ }
+
+ private static boolean isBatteryUpdateInteresting(BatteryStatus old, BatteryStatus current) {
+ final boolean nowPluggedIn = current.isPluggedIn();
+ final boolean wasPluggedIn = old.isPluggedIn();
+ final boolean stateChangedWhilePluggedIn =
+ wasPluggedIn == true && nowPluggedIn == true
+ && (old.status != current.status);
+
+ // change in plug state is always interesting
+ if (wasPluggedIn != nowPluggedIn || stateChangedWhilePluggedIn) {
+ return true;
+ }
+
+ // change in battery level while plugged in
+ if (nowPluggedIn && old.level != current.level) {
+ return true;
+ }
+
+ // change where battery needs charging
+ if (!nowPluggedIn && current.isBatteryLow() && current.level != old.level) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * @param intent The intent with action {@link TelephonyIntents#SPN_STRINGS_UPDATED_ACTION}
+ * @return The string to use for the plmn, or null if it should not be shown.
+ */
+ private CharSequence getTelephonyPlmnFrom(Intent intent) {
+ if (intent.getBooleanExtra(TelephonyIntents.EXTRA_SHOW_PLMN, false)) {
+ final String plmn = intent.getStringExtra(TelephonyIntents.EXTRA_PLMN);
+ return (plmn != null) ? plmn : getDefaultPlmn();
+ }
+ return null;
+ }
+
+ /**
+ * @return The default plmn (no service)
+ */
+ private CharSequence getDefaultPlmn() {
+ return mContext.getResources().getText(R.string.keyguard_carrier_default);
+ }
+
+ /**
+ * @param intent The intent with action {@link Telephony.Intents#SPN_STRINGS_UPDATED_ACTION}
+ * @return The string to use for the plmn, or null if it should not be shown.
+ */
+ private CharSequence getTelephonySpnFrom(Intent intent) {
+ if (intent.getBooleanExtra(TelephonyIntents.EXTRA_SHOW_SPN, false)) {
+ final String spn = intent.getStringExtra(TelephonyIntents.EXTRA_SPN);
+ if (spn != null) {
+ return spn;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Remove the given observer's callback.
+ *
+ * @param callback The callback to remove
+ */
+ public void removeCallback(KeyguardUpdateMonitorCallback callback) {
+ if (DEBUG) Log.v(TAG, "*** unregister callback for " + callback);
+ for (int i = mCallbacks.size() - 1; i >= 0; i--) {
+ if (mCallbacks.get(i).get() == callback) {
+ mCallbacks.remove(i);
+ }
+ }
+ }
+
+ /**
+ * Register to receive notifications about general keyguard information
+ * (see {@link InfoCallback}.
+ * @param callback The callback to register
+ */
+ public void registerCallback(KeyguardUpdateMonitorCallback callback) {
+ if (DEBUG) Log.v(TAG, "*** register callback for " + callback);
+ // Prevent adding duplicate callbacks
+ for (int i = 0; i < mCallbacks.size(); i++) {
+ if (mCallbacks.get(i).get() == callback) {
+ if (DEBUG) Log.e(TAG, "Object tried to add another callback",
+ new Exception("Called by"));
+ return;
+ }
+ }
+ mCallbacks.add(new WeakReference<KeyguardUpdateMonitorCallback>(callback));
+ removeCallback(null); // remove unused references
+ sendUpdates(callback);
+ }
+
+ private void sendUpdates(KeyguardUpdateMonitorCallback callback) {
+ // Notify listener of the current state
+ callback.onRefreshBatteryInfo(mBatteryStatus);
+ callback.onTimeChanged();
+ callback.onRingerModeChanged(mRingMode);
+ callback.onPhoneStateChanged(mPhoneState);
+ callback.onRefreshCarrierInfo(mTelephonyPlmn, mTelephonySpn);
+ callback.onClockVisibilityChanged();
+ callback.onSimStateChanged(mSimState);
+ }
+
+ public void sendKeyguardVisibilityChanged(boolean showing) {
+ if (DEBUG) Log.d(TAG, "sendKeyguardVisibilityChanged(" + showing + ")");
+ Message message = mHandler.obtainMessage(MSG_KEYGUARD_VISIBILITY_CHANGED);
+ message.arg1 = showing ? 1 : 0;
+ message.sendToTarget();
+ }
+
+ public void reportClockVisible(boolean visible) {
+ mClockVisible = visible;
+ mHandler.obtainMessage(MSG_CLOCK_VISIBILITY_CHANGED).sendToTarget();
+ }
+
+ public IccCardConstants.State getSimState() {
+ return mSimState;
+ }
+
+ /**
+ * Report that the user successfully entered the SIM PIN or PUK/SIM PIN so we
+ * have the information earlier than waiting for the intent
+ * broadcast from the telephony code.
+ *
+ * NOTE: Because handleSimStateChange() invokes callbacks immediately without going
+ * through mHandler, this *must* be called from the UI thread.
+ */
+ public void reportSimUnlocked() {
+ handleSimStateChange(new SimArgs(IccCardConstants.State.READY));
+ }
+
+ public CharSequence getTelephonyPlmn() {
+ return mTelephonyPlmn;
+ }
+
+ public CharSequence getTelephonySpn() {
+ return mTelephonySpn;
+ }
+
+ /**
+ * @return Whether the device is provisioned (whether they have gone through
+ * the setup wizard)
+ */
+ public boolean isDeviceProvisioned() {
+ return mDeviceProvisioned;
+ }
+
+ public int getFailedUnlockAttempts() {
+ return mFailedAttempts;
+ }
+
+ public void clearFailedUnlockAttempts() {
+ mFailedAttempts = 0;
+ mFailedBiometricUnlockAttempts = 0;
+ }
+
+ public void reportFailedUnlockAttempt() {
+ mFailedAttempts++;
+ }
+
+ public boolean isClockVisible() {
+ return mClockVisible;
+ }
+
+ public int getPhoneState() {
+ return mPhoneState;
+ }
+
+ public void reportFailedBiometricUnlockAttempt() {
+ mFailedBiometricUnlockAttempts++;
+ }
+
+ public boolean getMaxBiometricUnlockAttemptsReached() {
+ return mFailedBiometricUnlockAttempts >= FAILED_BIOMETRIC_UNLOCK_ATTEMPTS_BEFORE_BACKUP;
+ }
+
+ public boolean isAlternateUnlockEnabled() {
+ return mAlternateUnlockEnabled;
+ }
+
+ public void setAlternateUnlockEnabled(boolean enabled) {
+ mAlternateUnlockEnabled = enabled;
+ }
+
+ public boolean isSimLocked() {
+ return isSimLocked(mSimState);
+ }
+
+ public static boolean isSimLocked(IccCardConstants.State state) {
+ return state == IccCardConstants.State.PIN_REQUIRED
+ || state == IccCardConstants.State.PUK_REQUIRED
+ || state == IccCardConstants.State.PERM_DISABLED;
+ }
+
+ public boolean isSimPinSecure() {
+ return isSimPinSecure(mSimState);
+ }
+
+ public static boolean isSimPinSecure(IccCardConstants.State state) {
+ final IccCardConstants.State simState = state;
+ return (simState == IccCardConstants.State.PIN_REQUIRED
+ || simState == IccCardConstants.State.PUK_REQUIRED
+ || simState == IccCardConstants.State.PERM_DISABLED);
+ }
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
new file mode 100644
index 0000000..12ffcc3
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
@@ -0,0 +1,115 @@
+/*
+ * 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.keyguard;
+
+import android.app.admin.DevicePolicyManager;
+import android.media.AudioManager;
+
+import com.android.internal.telephony.IccCardConstants;
+
+/**
+ * Callback for general information relevant to lock screen.
+ */
+class KeyguardUpdateMonitorCallback {
+ /**
+ * Called when the battery status changes, e.g. when plugged in or unplugged, charge
+ * level, etc. changes.
+ *
+ * @param status current battery status
+ */
+ void onRefreshBatteryInfo(KeyguardUpdateMonitor.BatteryStatus status) { }
+
+ /**
+ * Called once per minute or when the time changes.
+ */
+ void onTimeChanged() { }
+
+ /**
+ * Called when the carrier PLMN or SPN changes.
+ *
+ * @param plmn The operator name of the registered network. May be null if it shouldn't
+ * be displayed.
+ * @param spn The service provider name. May be null if it shouldn't be displayed.
+ */
+ void onRefreshCarrierInfo(CharSequence plmn, CharSequence spn) { }
+
+ /**
+ * Called when the ringer mode changes.
+ * @param state the current ringer state, as defined in
+ * {@link AudioManager#RINGER_MODE_CHANGED_ACTION}
+ */
+ void onRingerModeChanged(int state) { }
+
+ /**
+ * Called when the phone state changes. String will be one of:
+ * {@link TelephonyManager#EXTRA_STATE_IDLE}
+ * {@link TelephonyManager@EXTRA_STATE_RINGING}
+ * {@link TelephonyManager#EXTRA_STATE_OFFHOOK
+ */
+ void onPhoneStateChanged(int phoneState) { }
+
+ /**
+ * Called when the visibility of the keyguard changes.
+ * @param showing Indicates if the keyguard is now visible.
+ */
+ void onKeyguardVisibilityChanged(boolean showing) { }
+
+ /**
+ * Called when visibility of lockscreen clock changes, such as when
+ * obscured by a widget.
+ */
+ void onClockVisibilityChanged() { }
+
+ /**
+ * 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() { }
+
+ /**
+ * Called when the user change begins.
+ */
+ void onUserSwitching(int userId) { }
+
+ /**
+ * Called when the user change is complete.
+ */
+ void onUserSwitchComplete(int userId) { }
+
+ /**
+ * Called when the SIM state changes.
+ * @param simState
+ */
+ void onSimStateChanged(IccCardConstants.State simState) { }
+
+ /**
+ * Called when a user is removed.
+ */
+ void onUserRemoved(int userId) { }
+
+ /**
+ * Called when boot completed.
+ *
+ * Note, this callback will only be received if boot complete occurs after registering with
+ * KeyguardUpdateMonitor.
+ */
+ void onBootCompleted() { }
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardViewBase.java b/packages/Keyguard/src/com/android/keyguard/KeyguardViewBase.java
new file mode 100644
index 0000000..200fb3c
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardViewBase.java
@@ -0,0 +1,263 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.keyguard;
+
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.ColorFilter;
+import android.graphics.PixelFormat;
+import android.graphics.PorterDuff;
+import android.graphics.drawable.Drawable;
+import android.media.AudioManager;
+import android.media.IAudioService;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.telephony.TelephonyManager;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.util.Slog;
+import android.view.KeyEvent;
+import android.widget.FrameLayout;
+
+/**
+ * Base class for keyguard view. {@link #reset} is where you should
+ * reset the state of your view. Use the {@link KeyguardViewCallback} via
+ * {@link #getCallback()} to send information back (such as poking the wake lock,
+ * or finishing the keyguard).
+ *
+ * Handles intercepting of media keys that still work when the keyguard is
+ * showing.
+ */
+public abstract class KeyguardViewBase extends FrameLayout {
+
+ private static final int BACKGROUND_COLOR = 0x70000000;
+ private AudioManager mAudioManager;
+ private TelephonyManager mTelephonyManager = null;
+ protected KeyguardViewMediator.ViewMediatorCallback mViewMediatorCallback;
+
+ // Whether the volume keys should be handled by keyguard. If true, then
+ // they will be handled here for specific media types such as music, otherwise
+ // the audio service will bring up the volume dialog.
+ private static final boolean KEYGUARD_MANAGES_VOLUME = true;
+
+ // This is a faster way to draw the background on devices without hardware acceleration
+ private static final Drawable mBackgroundDrawable = new Drawable() {
+ @Override
+ public void draw(Canvas canvas) {
+ canvas.drawColor(BACKGROUND_COLOR, PorterDuff.Mode.SRC);
+ }
+
+ @Override
+ public void setAlpha(int alpha) {
+ }
+
+ @Override
+ public void setColorFilter(ColorFilter cf) {
+ }
+
+ @Override
+ public int getOpacity() {
+ return PixelFormat.TRANSLUCENT;
+ }
+ };
+
+ public KeyguardViewBase(Context context) {
+ this(context, null);
+ }
+
+ public KeyguardViewBase(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ resetBackground();
+ }
+
+ public void resetBackground() {
+ setBackground(mBackgroundDrawable);
+ }
+
+ /**
+ * Called when you need to reset the state of your view.
+ */
+ abstract public void reset();
+
+ /**
+ * Called when the screen turned off.
+ */
+ abstract public void onScreenTurnedOff();
+
+ /**
+ * Called when the screen turned on.
+ */
+ abstract public void onScreenTurnedOn();
+
+ /**
+ * Called when the view needs to be shown.
+ */
+ abstract public void show();
+
+ /**
+ * Called when a key has woken the device to give us a chance to adjust our
+ * state according the the key. We are responsible for waking the device
+ * (by poking the wake lock) once we are ready.
+ *
+ * The 'Tq' suffix is per the documentation in {@link android.view.WindowManagerPolicy}.
+ * Be sure not to take any action that takes a long time; any significant
+ * action should be posted to a handler.
+ *
+ * @param keyCode The wake key, which may be relevant for configuring the
+ * keyguard. May be {@link KeyEvent#KEYCODE_UNKNOWN} if waking for a reason
+ * other than a key press.
+ */
+ abstract public void wakeWhenReadyTq(int keyCode);
+
+ /**
+ * Verify that the user can get past the keyguard securely. This is called,
+ * for example, when the phone disables the keyguard but then wants to launch
+ * something else that requires secure access.
+ *
+ * The result will be propogated back via {@link KeyguardViewCallback#keyguardDone(boolean)}
+ */
+ abstract public void verifyUnlock();
+
+ /**
+ * Called before this view is being removed.
+ */
+ abstract public void cleanUp();
+
+ /**
+ * Gets the desired user activity timeout in milliseconds, or -1 if the
+ * default should be used.
+ */
+ abstract public long getUserActivityTimeout();
+
+ @Override
+ public boolean dispatchKeyEvent(KeyEvent event) {
+ if (interceptMediaKey(event)) {
+ return true;
+ }
+ return super.dispatchKeyEvent(event);
+ }
+
+ /**
+ * Allows the media keys to work when the keyguard is showing.
+ * The media keys should be of no interest to the actual keyguard view(s),
+ * so intercepting them here should not be of any harm.
+ * @param event The key event
+ * @return whether the event was consumed as a media key.
+ */
+ private boolean interceptMediaKey(KeyEvent event) {
+ final int keyCode = event.getKeyCode();
+ if (event.getAction() == KeyEvent.ACTION_DOWN) {
+ switch (keyCode) {
+ case KeyEvent.KEYCODE_MEDIA_PLAY:
+ case KeyEvent.KEYCODE_MEDIA_PAUSE:
+ case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
+ /* Suppress PLAY/PAUSE toggle when phone is ringing or
+ * in-call to avoid music playback */
+ if (mTelephonyManager == null) {
+ mTelephonyManager = (TelephonyManager) getContext().getSystemService(
+ Context.TELEPHONY_SERVICE);
+ }
+ if (mTelephonyManager != null &&
+ mTelephonyManager.getCallState() != TelephonyManager.CALL_STATE_IDLE) {
+ return true; // suppress key event
+ }
+ case KeyEvent.KEYCODE_MUTE:
+ case KeyEvent.KEYCODE_HEADSETHOOK:
+ case KeyEvent.KEYCODE_MEDIA_STOP:
+ case KeyEvent.KEYCODE_MEDIA_NEXT:
+ case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
+ case KeyEvent.KEYCODE_MEDIA_REWIND:
+ case KeyEvent.KEYCODE_MEDIA_RECORD:
+ case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD: {
+ handleMediaKeyEvent(event);
+ return true;
+ }
+
+ case KeyEvent.KEYCODE_VOLUME_UP:
+ case KeyEvent.KEYCODE_VOLUME_DOWN:
+ case KeyEvent.KEYCODE_VOLUME_MUTE: {
+ if (KEYGUARD_MANAGES_VOLUME) {
+ synchronized (this) {
+ if (mAudioManager == null) {
+ mAudioManager = (AudioManager) getContext().getSystemService(
+ Context.AUDIO_SERVICE);
+ }
+ }
+ // Volume buttons should only function for music (local or remote).
+ // TODO: Actually handle MUTE.
+ mAudioManager.adjustLocalOrRemoteStreamVolume(
+ AudioManager.STREAM_MUSIC,
+ keyCode == KeyEvent.KEYCODE_VOLUME_UP
+ ? AudioManager.ADJUST_RAISE
+ : AudioManager.ADJUST_LOWER);
+ // Don't execute default volume behavior
+ return true;
+ } else {
+ return false;
+ }
+ }
+ }
+ } else if (event.getAction() == KeyEvent.ACTION_UP) {
+ switch (keyCode) {
+ case KeyEvent.KEYCODE_MUTE:
+ case KeyEvent.KEYCODE_HEADSETHOOK:
+ case KeyEvent.KEYCODE_MEDIA_PLAY:
+ case KeyEvent.KEYCODE_MEDIA_PAUSE:
+ case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
+ case KeyEvent.KEYCODE_MEDIA_STOP:
+ case KeyEvent.KEYCODE_MEDIA_NEXT:
+ case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
+ case KeyEvent.KEYCODE_MEDIA_REWIND:
+ case KeyEvent.KEYCODE_MEDIA_RECORD:
+ case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD: {
+ handleMediaKeyEvent(event);
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ void handleMediaKeyEvent(KeyEvent keyEvent) {
+ IAudioService audioService = IAudioService.Stub.asInterface(
+ ServiceManager.checkService(Context.AUDIO_SERVICE));
+ if (audioService != null) {
+ try {
+ audioService.dispatchMediaKeyEvent(keyEvent);
+ } catch (RemoteException e) {
+ Log.e("KeyguardViewBase", "dispatchMediaKeyEvent threw exception " + e);
+ }
+ } else {
+ Slog.w("KeyguardViewBase", "Unable to find IAudioService for media key event");
+ }
+ }
+
+ @Override
+ public void dispatchSystemUiVisibilityChanged(int visibility) {
+ super.dispatchSystemUiVisibilityChanged(visibility);
+
+ if (!(mContext instanceof Activity)) {
+ setSystemUiVisibility(STATUS_BAR_DISABLE_BACK);
+ }
+ }
+
+ public void setViewMediatorCallback(
+ KeyguardViewMediator.ViewMediatorCallback viewMediatorCallback) {
+ mViewMediatorCallback = viewMediatorCallback;
+ }
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardViewManager.java b/packages/Keyguard/src/com/android/keyguard/KeyguardViewManager.java
new file mode 100644
index 0000000..ef3fa6e
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardViewManager.java
@@ -0,0 +1,457 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.keyguard;
+
+import com.android.internal.policy.IKeyguardShowCallback;
+import com.android.internal.widget.LockPatternUtils;
+
+import android.app.Activity;
+import android.app.ActivityManager;
+import android.appwidget.AppWidgetManager;
+import android.content.Context;
+import android.content.pm.ActivityInfo;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.graphics.PixelFormat;
+import android.graphics.Rect;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.Parcelable;
+import android.os.RemoteException;
+import android.os.SystemProperties;
+import android.util.Log;
+import android.util.Slog;
+import android.util.SparseArray;
+import android.view.KeyEvent;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewManager;
+import android.view.WindowManager;
+import android.widget.FrameLayout;
+
+/**
+ * Manages creating, showing, hiding and resetting the keyguard. Calls back
+ * via {@link KeyguardViewMediator.ViewMediatorCallback} to poke
+ * the wake lock and report that the keyguard is done, which is in turn,
+ * reported to this class by the current {@link KeyguardViewBase}.
+ */
+public class KeyguardViewManager {
+ private final static boolean DEBUG = KeyguardViewMediator.DEBUG;
+ private static String TAG = "KeyguardViewManager";
+ public static boolean USE_UPPER_CASE = true;
+ public final static String IS_SWITCHING_USER = "is_switching_user";
+
+ // Timeout used for keypresses
+ static final int DIGIT_PRESS_WAKE_MILLIS = 5000;
+
+ private final Context mContext;
+ private final ViewManager mViewManager;
+ private final KeyguardViewMediator.ViewMediatorCallback mViewMediatorCallback;
+
+ private WindowManager.LayoutParams mWindowLayoutParams;
+ private boolean mNeedsInput = false;
+
+ private FrameLayout mKeyguardHost;
+ private KeyguardHostView mKeyguardView;
+
+ private boolean mScreenOn = false;
+ private LockPatternUtils mLockPatternUtils;
+
+ public interface ShowListener {
+ void onShown(IBinder windowToken);
+ };
+
+ /**
+ * @param context Used to create views.
+ * @param viewManager Keyguard will be attached to this.
+ * @param callback Used to notify of changes.
+ * @param lockPatternUtils
+ */
+ public KeyguardViewManager(Context context, ViewManager viewManager,
+ KeyguardViewMediator.ViewMediatorCallback callback,
+ LockPatternUtils lockPatternUtils) {
+ mContext = context;
+ mViewManager = viewManager;
+ mViewMediatorCallback = callback;
+ mLockPatternUtils = lockPatternUtils;
+ }
+
+ /**
+ * Show the keyguard. Will handle creating and attaching to the view manager
+ * lazily.
+ */
+ public synchronized void show(Bundle options) {
+ if (DEBUG) Log.d(TAG, "show(); mKeyguardView==" + mKeyguardView);
+
+ boolean enableScreenRotation = shouldEnableScreenRotation();
+
+ maybeCreateKeyguardLocked(enableScreenRotation, false, options);
+ maybeEnableScreenRotation(enableScreenRotation);
+
+ // Disable common aspects of the system/status/navigation bars that are not appropriate or
+ // useful on any keyguard screen but can be re-shown by dialogs or SHOW_WHEN_LOCKED
+ // activities. Other disabled bits are handled by the KeyguardViewMediator talking
+ // directly to the status bar service.
+ final int visFlags = View.STATUS_BAR_DISABLE_HOME;
+ if (DEBUG) Log.v(TAG, "show:setSystemUiVisibility(" + Integer.toHexString(visFlags)+")");
+ mKeyguardHost.setSystemUiVisibility(visFlags);
+
+ mViewManager.updateViewLayout(mKeyguardHost, mWindowLayoutParams);
+ mKeyguardHost.setVisibility(View.VISIBLE);
+ mKeyguardView.show();
+ mKeyguardView.requestFocus();
+ }
+
+ private boolean shouldEnableScreenRotation() {
+ Resources res = mContext.getResources();
+ return SystemProperties.getBoolean("lockscreen.rot_override",false)
+ || res.getBoolean(R.bool.config_enableLockScreenRotation);
+ }
+
+ class ViewManagerHost extends FrameLayout {
+ public ViewManagerHost(Context context) {
+ super(context);
+ setFitsSystemWindows(true);
+ }
+
+ @Override
+ protected boolean fitSystemWindows(Rect insets) {
+ Log.v("TAG", "bug 7643792: fitSystemWindows(" + insets.toShortString() + ")");
+ return super.fitSystemWindows(insets);
+ }
+
+ @Override
+ protected void onConfigurationChanged(Configuration newConfig) {
+ super.onConfigurationChanged(newConfig);
+ if (mKeyguardHost.getVisibility() == View.VISIBLE) {
+ // only propagate configuration messages if we're currently showing
+ maybeCreateKeyguardLocked(shouldEnableScreenRotation(), true, null);
+ } else {
+ if (DEBUG) Log.v(TAG, "onConfigurationChanged: view not visible");
+ }
+ }
+
+ @Override
+ public boolean dispatchKeyEvent(KeyEvent event) {
+ if (mKeyguardView != null) {
+ // Always process back and menu keys, regardless of focus
+ if (event.getAction() == KeyEvent.ACTION_DOWN) {
+ int keyCode = event.getKeyCode();
+ if (keyCode == KeyEvent.KEYCODE_BACK && mKeyguardView.handleBackKey()) {
+ return true;
+ } else if (keyCode == KeyEvent.KEYCODE_MENU && mKeyguardView.handleMenuKey()) {
+ return true;
+ }
+ }
+ // Always process media keys, regardless of focus
+ if (mKeyguardView.dispatchKeyEvent(event)) {
+ return true;
+ }
+ }
+ return super.dispatchKeyEvent(event);
+ }
+ }
+
+ SparseArray<Parcelable> mStateContainer = new SparseArray<Parcelable>();
+
+ private void maybeCreateKeyguardLocked(boolean enableScreenRotation, boolean force,
+ Bundle options) {
+ final boolean isActivity = (mContext instanceof Activity); // for test activity
+
+ if (mKeyguardHost != null) {
+ mKeyguardHost.saveHierarchyState(mStateContainer);
+ }
+
+ if (mKeyguardHost == null) {
+ if (DEBUG) Log.d(TAG, "keyguard host is null, creating it...");
+
+ mKeyguardHost = new ViewManagerHost(mContext);
+
+ int flags = WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
+ | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR
+ | WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN
+ | WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
+
+ if (!mNeedsInput) {
+ flags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
+ }
+ if (ActivityManager.isHighEndGfx()) {
+ flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
+ }
+
+ final int stretch = ViewGroup.LayoutParams.MATCH_PARENT;
+ final int type = WindowManager.LayoutParams.TYPE_KEYGUARD;
+ WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
+ stretch, stretch, type, flags, PixelFormat.TRANSLUCENT);
+ lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
+ lp.windowAnimations = R.style.Animation_LockScreen;
+ if (ActivityManager.isHighEndGfx()) {
+ lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
+ lp.privateFlags |=
+ WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_HARDWARE_ACCELERATED;
+ }
+ lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SET_NEEDS_MENU_KEY;
+ if (isActivity) {
+ lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
+ }
+ lp.inputFeatures |= WindowManager.LayoutParams.INPUT_FEATURE_DISABLE_USER_ACTIVITY;
+ lp.setTitle(isActivity ? "KeyguardMock" : "Keyguard");
+ mWindowLayoutParams = lp;
+ mViewManager.addView(mKeyguardHost, lp);
+ }
+
+ if (force || mKeyguardView == null) {
+ inflateKeyguardView(options);
+ mKeyguardView.requestFocus();
+ }
+ updateUserActivityTimeoutInWindowLayoutParams();
+ mViewManager.updateViewLayout(mKeyguardHost, mWindowLayoutParams);
+
+ mKeyguardHost.restoreHierarchyState(mStateContainer);
+ }
+
+ private void inflateKeyguardView(Bundle options) {
+ View v = mKeyguardHost.findViewById(R.id.keyguard_host_view);
+ if (v != null) {
+ mKeyguardHost.removeView(v);
+ }
+ // TODO: Remove once b/7094175 is fixed
+ if (false) Slog.d(TAG, "inflateKeyguardView: b/7094175 mContext.config="
+ + mContext.getResources().getConfiguration());
+ final LayoutInflater inflater = LayoutInflater.from(mContext);
+ View view = inflater.inflate(R.layout.keyguard_host_view, mKeyguardHost, true);
+ mKeyguardView = (KeyguardHostView) view.findViewById(R.id.keyguard_host_view);
+ mKeyguardView.setLockPatternUtils(mLockPatternUtils);
+ mKeyguardView.setViewMediatorCallback(mViewMediatorCallback);
+ mKeyguardView.initializeSwitchingUserState(options != null &&
+ options.getBoolean(IS_SWITCHING_USER));
+
+ // HACK
+ // The keyguard view will have set up window flags in onFinishInflate before we set
+ // the view mediator callback. Make sure it knows the correct IME state.
+ if (mViewMediatorCallback != null) {
+ KeyguardPasswordView kpv = (KeyguardPasswordView) mKeyguardView.findViewById(
+ R.id.keyguard_password_view);
+
+ if (kpv != null) {
+ mViewMediatorCallback.setNeedsInput(kpv.needsInput());
+ }
+ }
+
+ if (options != null) {
+ int widgetToShow = options.getInt(LockPatternUtils.KEYGUARD_SHOW_APPWIDGET,
+ AppWidgetManager.INVALID_APPWIDGET_ID);
+ if (widgetToShow != AppWidgetManager.INVALID_APPWIDGET_ID) {
+ mKeyguardView.goToWidget(widgetToShow);
+ }
+ }
+ }
+
+ public void updateUserActivityTimeout() {
+ updateUserActivityTimeoutInWindowLayoutParams();
+ mViewManager.updateViewLayout(mKeyguardHost, mWindowLayoutParams);
+ }
+
+ private void updateUserActivityTimeoutInWindowLayoutParams() {
+ // Use the user activity timeout requested by the keyguard view, if any.
+ if (mKeyguardView != null) {
+ long timeout = mKeyguardView.getUserActivityTimeout();
+ if (timeout >= 0) {
+ mWindowLayoutParams.userActivityTimeout = timeout;
+ return;
+ }
+ }
+
+ // Otherwise, use the default timeout.
+ mWindowLayoutParams.userActivityTimeout = KeyguardViewMediator.AWAKE_INTERVAL_DEFAULT_MS;
+ }
+
+ private void maybeEnableScreenRotation(boolean enableScreenRotation) {
+ // TODO: move this outside
+ if (enableScreenRotation) {
+ if (DEBUG) Log.d(TAG, "Rotation sensor for lock screen On!");
+ mWindowLayoutParams.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_USER;
+ } else {
+ if (DEBUG) Log.d(TAG, "Rotation sensor for lock screen Off!");
+ mWindowLayoutParams.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_NOSENSOR;
+ }
+ mViewManager.updateViewLayout(mKeyguardHost, mWindowLayoutParams);
+ }
+
+ public void setNeedsInput(boolean needsInput) {
+ mNeedsInput = needsInput;
+ if (mWindowLayoutParams != null) {
+ if (needsInput) {
+ mWindowLayoutParams.flags &=
+ ~WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
+ } else {
+ mWindowLayoutParams.flags |=
+ WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
+ }
+
+ try {
+ mViewManager.updateViewLayout(mKeyguardHost, mWindowLayoutParams);
+ } catch (java.lang.IllegalArgumentException e) {
+ // TODO: Ensure this method isn't called on views that are changing...
+ Log.w(TAG,"Can't update input method on " + mKeyguardHost + " window not attached");
+ }
+ }
+ }
+
+ /**
+ * Reset the state of the view.
+ */
+ public synchronized void reset(Bundle options) {
+ if (DEBUG) Log.d(TAG, "reset()");
+ // User might have switched, check if we need to go back to keyguard
+ // TODO: It's preferable to stay and show the correct lockscreen or unlock if none
+ maybeCreateKeyguardLocked(shouldEnableScreenRotation(), true, options);
+ }
+
+ public synchronized void onScreenTurnedOff() {
+ if (DEBUG) Log.d(TAG, "onScreenTurnedOff()");
+ mScreenOn = false;
+ if (mKeyguardView != null) {
+ mKeyguardView.onScreenTurnedOff();
+ }
+ }
+
+ public synchronized void onScreenTurnedOn(final IKeyguardShowCallback callback) {
+ if (DEBUG) Log.d(TAG, "onScreenTurnedOn()");
+ mScreenOn = true;
+ if (mKeyguardView != null) {
+ mKeyguardView.onScreenTurnedOn();
+
+ // Caller should wait for this window to be shown before turning
+ // on the screen.
+ if (callback != null) {
+ if (mKeyguardHost.getVisibility() == View.VISIBLE) {
+ // Keyguard may be in the process of being shown, but not yet
+ // updated with the window manager... give it a chance to do so.
+ mKeyguardHost.post(new Runnable() {
+ @Override
+ public void run() {
+ IBinder token = null;
+ if (mKeyguardHost.getVisibility() == View.VISIBLE) {
+ token = mKeyguardHost.getWindowToken();
+ }
+ try {
+ callback.onShown(token);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Exception calling onShown():", e);
+ }
+ }
+ });
+ } else {
+ try {
+ callback.onShown(null);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Exception calling onShown():", e);
+ }
+ }
+ }
+ } else if (callback != null) {
+ try {
+ callback.onShown(null);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Exception calling onShown():", e);
+ }
+ }
+ }
+
+ public synchronized void verifyUnlock() {
+ if (DEBUG) Log.d(TAG, "verifyUnlock()");
+ show(null);
+ mKeyguardView.verifyUnlock();
+ }
+
+ /**
+ * A key has woken the device. We use this to potentially adjust the state
+ * of the lock screen based on the key.
+ *
+ * The 'Tq' suffix is per the documentation in {@link android.view.WindowManagerPolicy}.
+ * Be sure not to take any action that takes a long time; any significant
+ * action should be posted to a handler.
+ *
+ * @param keyCode The wake key. May be {@link KeyEvent#KEYCODE_UNKNOWN} if waking
+ * for a reason other than a key press.
+ */
+ public boolean wakeWhenReadyTq(int keyCode) {
+ if (DEBUG) Log.d(TAG, "wakeWhenReady(" + keyCode + ")");
+ if (mKeyguardView != null) {
+ mKeyguardView.wakeWhenReadyTq(keyCode);
+ return true;
+ }
+ Log.w(TAG, "mKeyguardView is null in wakeWhenReadyTq");
+ return false;
+ }
+
+ /**
+ * Hides the keyguard view
+ */
+ public synchronized void hide() {
+ if (DEBUG) Log.d(TAG, "hide()");
+
+ if (mKeyguardHost != null) {
+ mKeyguardHost.setVisibility(View.GONE);
+
+ // We really only want to preserve keyguard state for configuration changes. Hence
+ // we should clear state of widgets (e.g. Music) when we hide keyguard so it can
+ // start with a fresh state when we return.
+ mStateContainer.clear();
+
+ // Don't do this right away, so we can let the view continue to animate
+ // as it goes away.
+ if (mKeyguardView != null) {
+ final KeyguardViewBase lastView = mKeyguardView;
+ mKeyguardView = null;
+ mKeyguardHost.postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ synchronized (KeyguardViewManager.this) {
+ lastView.cleanUp();
+ mKeyguardHost.removeView(lastView);
+ }
+ }
+ }, 500);
+ }
+ }
+ }
+
+ /**
+ * Dismisses the keyguard by going to the next screen or making it gone.
+ */
+ public synchronized void dismiss() {
+ if (mScreenOn) {
+ mKeyguardView.dismiss();
+ }
+ }
+
+ /**
+ * @return Whether the keyguard is showing
+ */
+ public synchronized boolean isShowing() {
+ return (mKeyguardHost != null && mKeyguardHost.getVisibility() == View.VISIBLE);
+ }
+
+ public void showAssistant() {
+ if (mKeyguardView != null) {
+ mKeyguardView.showAssistant();
+ }
+ }
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardViewMediator.java b/packages/Keyguard/src/com/android/keyguard/KeyguardViewMediator.java
new file mode 100644
index 0000000..0146781
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardViewMediator.java
@@ -0,0 +1,1457 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.keyguard;
+
+import com.android.internal.policy.IKeyguardExitCallback;
+import com.android.internal.policy.IKeyguardShowCallback;
+import static android.provider.Settings.System.SCREEN_OFF_TIMEOUT;
+
+import android.app.Activity;
+import android.app.ActivityManagerNative;
+import android.app.AlarmManager;
+import android.app.PendingIntent;
+import android.app.SearchManager;
+import android.app.StatusBarManager;
+import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.media.AudioManager;
+import android.media.SoundPool;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.os.PowerManager;
+import android.os.RemoteException;
+import android.os.SystemClock;
+import android.os.SystemProperties;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.provider.Settings;
+import android.telephony.TelephonyManager;
+import android.util.EventLog;
+import android.util.Log;
+import android.util.Slog;
+import android.view.KeyEvent;
+import android.view.WindowManager;
+import android.view.WindowManagerPolicy;
+
+import com.android.internal.telephony.IccCardConstants;
+import com.android.internal.widget.LockPatternUtils;
+
+
+/**
+ * Mediates requests related to the keyguard. This includes queries about the
+ * state of the keyguard, power management events that effect whether the keyguard
+ * should be shown or reset, callbacks to the phone window manager to notify
+ * it of when the keyguard is showing, and events from the keyguard view itself
+ * stating that the keyguard was succesfully unlocked.
+ *
+ * Note that the keyguard view is shown when the screen is off (as appropriate)
+ * so that once the screen comes on, it will be ready immediately.
+ *
+ * Example queries about the keyguard:
+ * - is {movement, key} one that should wake the keygaurd?
+ * - is the keyguard showing?
+ * - are input events restricted due to the state of the keyguard?
+ *
+ * Callbacks to the phone window manager:
+ * - the keyguard is showing
+ *
+ * Example external events that translate to keyguard view changes:
+ * - screen turned off -> reset the keyguard, and show it so it will be ready
+ * next time the screen turns on
+ * - keyboard is slid open -> if the keyguard is not secure, hide it
+ *
+ * Events from the keyguard view:
+ * - user succesfully unlocked keyguard -> hide keyguard view, and no longer
+ * restrict input events.
+ *
+ * Note: in addition to normal power managment events that effect the state of
+ * whether the keyguard should be showing, external apps and services may request
+ * that the keyguard be disabled via {@link #setKeyguardEnabled(boolean)}. When
+ * false, this will override all other conditions for turning on the keyguard.
+ *
+ * Threading and synchronization:
+ * This class is created by the initialization routine of the {@link WindowManagerPolicy},
+ * and runs on its thread. The keyguard UI is created from that thread in the
+ * constructor of this class. The apis may be called from other threads, including the
+ * {@link com.android.server.input.InputManagerService}'s and {@link android.view.WindowManager}'s.
+ * Therefore, methods on this class are synchronized, and any action that is pointed
+ * directly to the keyguard UI is posted to a {@link Handler} to ensure it is taken on the UI
+ * thread of the keyguard.
+ */
+public class KeyguardViewMediator {
+ private static final int KEYGUARD_DISPLAY_TIMEOUT_DELAY_DEFAULT = 30000;
+ final static boolean DEBUG = false;
+ private final static boolean DBG_WAKE = false;
+
+ private final static String TAG = "KeyguardViewMediator";
+
+ private static final String DELAYED_KEYGUARD_ACTION =
+ "com.android.internal.policy.impl.PhoneWindowManager.DELAYED_KEYGUARD";
+
+ // used for handler messages
+ private static final int SHOW = 2;
+ private static final int HIDE = 3;
+ private static final int RESET = 4;
+ private static final int VERIFY_UNLOCK = 5;
+ private static final int NOTIFY_SCREEN_OFF = 6;
+ private static final int NOTIFY_SCREEN_ON = 7;
+ private static final int WAKE_WHEN_READY = 8;
+ private static final int KEYGUARD_DONE = 9;
+ private static final int KEYGUARD_DONE_DRAWING = 10;
+ private static final int KEYGUARD_DONE_AUTHENTICATING = 11;
+ private static final int SET_HIDDEN = 12;
+ private static final int KEYGUARD_TIMEOUT = 13;
+ private static final int SHOW_ASSISTANT = 14;
+
+ /**
+ * The default amount of time we stay awake (used for all key input)
+ */
+ protected static final int AWAKE_INTERVAL_DEFAULT_MS = 10000;
+
+ /**
+ * How long to wait after the screen turns off due to timeout before
+ * turning on the keyguard (i.e, the user has this much time to turn
+ * the screen back on without having to face the keyguard).
+ */
+ private static final int KEYGUARD_LOCK_AFTER_DELAY_DEFAULT = 5000;
+
+ /**
+ * How long we'll wait for the {@link ViewMediatorCallback#keyguardDoneDrawing()}
+ * callback before unblocking a call to {@link #setKeyguardEnabled(boolean)}
+ * that is reenabling the keyguard.
+ */
+ private static final int KEYGUARD_DONE_DRAWING_TIMEOUT_MS = 2000;
+
+ /**
+ * Allow the user to expand the status bar when the keyguard is engaged
+ * (without a pattern or password).
+ */
+ private static final boolean ENABLE_INSECURE_STATUS_BAR_EXPAND = true;
+
+ /** The stream type that the lock sounds are tied to. */
+ private int mMasterStreamType;
+
+ private Context mContext;
+ private AlarmManager mAlarmManager;
+ private AudioManager mAudioManager;
+ private StatusBarManager mStatusBarManager;
+ private boolean mShowLockIcon;
+ private boolean mShowingLockIcon;
+ private boolean mSwitchingUser;
+
+ private boolean mSystemReady;
+
+ // Whether the next call to playSounds() should be skipped. Defaults to
+ // true because the first lock (on boot) should be silent.
+ private boolean mSuppressNextLockSound = true;
+
+
+ /** High level access to the power manager for WakeLocks */
+ private PowerManager mPM;
+
+ /** UserManager for querying number of users */
+ private UserManager mUserManager;
+
+ /** SearchManager for determining whether or not search assistant is available */
+ private SearchManager mSearchManager;
+
+ /**
+ * Used to keep the device awake while to ensure the keyguard finishes opening before
+ * we sleep.
+ */
+ private PowerManager.WakeLock mShowKeyguardWakeLock;
+
+ /**
+ * Does not turn on screen, held while a call to {@link KeyguardViewManager#wakeWhenReadyTq(int)}
+ * is called to make sure the device doesn't sleep before it has a chance to poke
+ * the wake lock.
+ * @see #wakeWhenReady(int)
+ */
+ private PowerManager.WakeLock mWakeAndHandOff;
+
+ private KeyguardViewManager mKeyguardViewManager;
+
+ // these are protected by synchronized (this)
+
+ /**
+ * External apps (like the phone app) can tell us to disable the keygaurd.
+ */
+ private boolean mExternallyEnabled = true;
+
+ /**
+ * Remember if an external call to {@link #setKeyguardEnabled} with value
+ * false caused us to hide the keyguard, so that we need to reshow it once
+ * the keygaurd is reenabled with another call with value true.
+ */
+ private boolean mNeedToReshowWhenReenabled = false;
+
+ // cached value of whether we are showing (need to know this to quickly
+ // answer whether the input should be restricted)
+ private boolean mShowing = false;
+
+ // true if the keyguard is hidden by another window
+ private boolean mHidden = false;
+
+ /**
+ * Helps remember whether the screen has turned on since the last time
+ * it turned off due to timeout. see {@link #onScreenTurnedOff(int)}
+ */
+ private int mDelayedShowingSequence;
+
+ /**
+ * If the user has disabled the keyguard, then requests to exit, this is
+ * how we'll ultimately let them know whether it was successful. We use this
+ * var being non-null as an indicator that there is an in progress request.
+ */
+ private IKeyguardExitCallback mExitSecureCallback;
+
+ // the properties of the keyguard
+
+ private KeyguardUpdateMonitor mUpdateMonitor;
+
+ private boolean mScreenOn;
+
+ // last known state of the cellular connection
+ private String mPhoneState = TelephonyManager.EXTRA_STATE_IDLE;
+
+ /**
+ * we send this intent when the keyguard is dismissed.
+ */
+ private static final Intent USER_PRESENT_INTENT = new Intent(Intent.ACTION_USER_PRESENT)
+ .addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING
+ | Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
+
+ /**
+ * {@link #setKeyguardEnabled} waits on this condition when it reenables
+ * the keyguard.
+ */
+ private boolean mWaitingUntilKeyguardVisible = false;
+ private LockPatternUtils mLockPatternUtils;
+ private boolean mKeyguardDonePending = false;
+
+ private SoundPool mLockSounds;
+ private int mLockSoundId;
+ private int mUnlockSoundId;
+ private int mLockSoundStreamId;
+
+ /**
+ * The volume applied to the lock/unlock sounds.
+ */
+ private final float mLockSoundVolume;
+
+ /**
+ * The callback used by the keyguard view to tell the {@link KeyguardViewMediator}
+ * various things.
+ */
+ public interface ViewMediatorCallback {
+
+ /**
+ * Wake the device immediately.
+ */
+ void wakeUp();
+
+ /**
+ * Reports user activity and requests that the screen stay on.
+ */
+ void userActivity();
+
+ /**
+ * Reports user activity and requests that the screen stay on for at least
+ * the specified amount of time.
+ * @param millis The amount of time in millis. This value is currently ignored.
+ */
+ void userActivity(long millis);
+
+ /**
+ * Report that the keyguard is done.
+ * @param authenticated Whether the user securely got past the keyguard.
+ * the only reason for this to be false is if the keyguard was instructed
+ * to appear temporarily to verify the user is supposed to get past the
+ * keyguard, and the user fails to do so.
+ */
+ void keyguardDone(boolean authenticated);
+
+ /**
+ * Report that the keyguard is done drawing.
+ */
+ void keyguardDoneDrawing();
+
+ /**
+ * Tell ViewMediator that the current view needs IME input
+ * @param needsInput
+ */
+ void setNeedsInput(boolean needsInput);
+
+ /**
+ * Tell view mediator that the keyguard view's desired user activity timeout
+ * has changed and needs to be reapplied to the window.
+ */
+ void onUserActivityTimeoutChanged();
+
+ /**
+ * Report that the keyguard is dismissable, pending the next keyguardDone call.
+ */
+ void keyguardDonePending();
+ }
+
+ KeyguardUpdateMonitorCallback mUpdateCallback = new KeyguardUpdateMonitorCallback() {
+
+ @Override
+ public void onUserSwitching(int userId) {
+ // Note that the mLockPatternUtils user has already been updated from setCurrentUser.
+ // We need to force a reset of the views, since lockNow (called by
+ // ActivityManagerService) will not reconstruct the keyguard if it is already showing.
+ synchronized (KeyguardViewMediator.this) {
+ mSwitchingUser = true;
+ resetStateLocked(null);
+ adjustStatusBarLocked();
+ // Disable face unlock when the user switches.
+ KeyguardUpdateMonitor.getInstance(mContext).setAlternateUnlockEnabled(false);
+ }
+ }
+
+ @Override
+ public void onUserSwitchComplete(int userId) {
+ mSwitchingUser = false;
+ }
+
+ @Override
+ public void onUserRemoved(int userId) {
+ mLockPatternUtils.removeUser(userId);
+ }
+
+ @Override
+ void onPhoneStateChanged(int phoneState) {
+ synchronized (KeyguardViewMediator.this) {
+ if (TelephonyManager.CALL_STATE_IDLE == phoneState // call ending
+ && !mScreenOn // screen off
+ && mExternallyEnabled) { // not disabled by any app
+
+ // note: this is a way to gracefully reenable the keyguard when the call
+ // ends and the screen is off without always reenabling the keyguard
+ // each time the screen turns off while in call (and having an occasional ugly
+ // flicker while turning back on the screen and disabling the keyguard again).
+ if (DEBUG) Log.d(TAG, "screen is off and call ended, let's make sure the "
+ + "keyguard is showing");
+ doKeyguardLocked(null);
+ }
+ }
+ };
+
+ @Override
+ public void onClockVisibilityChanged() {
+ adjustStatusBarLocked();
+ }
+
+ @Override
+ public void onDeviceProvisioned() {
+ sendUserPresentBroadcast();
+ }
+
+ @Override
+ public void onSimStateChanged(IccCardConstants.State simState) {
+ if (DEBUG) Log.d(TAG, "onSimStateChanged: " + simState);
+
+ switch (simState) {
+ case NOT_READY:
+ case ABSENT:
+ // only force lock screen in case of missing sim if user hasn't
+ // gone through setup wizard
+ synchronized (this) {
+ if (!mUpdateMonitor.isDeviceProvisioned()) {
+ if (!isShowing()) {
+ if (DEBUG) Log.d(TAG, "ICC_ABSENT isn't showing,"
+ + " we need to show the keyguard since the "
+ + "device isn't provisioned yet.");
+ doKeyguardLocked(null);
+ } else {
+ resetStateLocked(null);
+ }
+ }
+ }
+ break;
+ case PIN_REQUIRED:
+ case PUK_REQUIRED:
+ synchronized (this) {
+ if (!isShowing()) {
+ if (DEBUG) Log.d(TAG, "INTENT_VALUE_ICC_LOCKED and keygaurd isn't "
+ + "showing; need to show keyguard so user can enter sim pin");
+ doKeyguardLocked(null);
+ } else {
+ resetStateLocked(null);
+ }
+ }
+ break;
+ case PERM_DISABLED:
+ synchronized (this) {
+ if (!isShowing()) {
+ if (DEBUG) Log.d(TAG, "PERM_DISABLED and "
+ + "keygaurd isn't showing.");
+ doKeyguardLocked(null);
+ } else {
+ if (DEBUG) Log.d(TAG, "PERM_DISABLED, resetStateLocked to"
+ + "show permanently disabled message in lockscreen.");
+ resetStateLocked(null);
+ }
+ }
+ break;
+ case READY:
+ synchronized (this) {
+ if (isShowing()) {
+ resetStateLocked(null);
+ }
+ }
+ break;
+ }
+ }
+
+ };
+
+ ViewMediatorCallback mViewMediatorCallback = new ViewMediatorCallback() {
+ public void wakeUp() {
+ KeyguardViewMediator.this.wakeUp();
+ }
+
+ public void userActivity() {
+ KeyguardViewMediator.this.userActivity();
+ }
+
+ public void userActivity(long holdMs) {
+ KeyguardViewMediator.this.userActivity(holdMs);
+ }
+
+ public void keyguardDone(boolean authenticated) {
+ KeyguardViewMediator.this.keyguardDone(authenticated, true);
+ }
+
+ public void keyguardDoneDrawing() {
+ mHandler.sendEmptyMessage(KEYGUARD_DONE_DRAWING);
+ }
+
+ @Override
+ public void setNeedsInput(boolean needsInput) {
+ mKeyguardViewManager.setNeedsInput(needsInput);
+ }
+
+ @Override
+ public void onUserActivityTimeoutChanged() {
+ mKeyguardViewManager.updateUserActivityTimeout();
+ }
+
+ @Override
+ public void keyguardDonePending() {
+ mKeyguardDonePending = true;
+ }
+ };
+
+ public void wakeUp() {
+ mPM.wakeUp(SystemClock.uptimeMillis());
+ }
+
+ private void userActivity() {
+ userActivity(AWAKE_INTERVAL_DEFAULT_MS);
+ }
+
+ public void userActivity(long holdMs) {
+ // We ignore the hold time. Eventually we should remove it.
+ // Instead, the keyguard window has an explicit user activity timeout set on it.
+ mPM.userActivity(SystemClock.uptimeMillis(), false);
+ }
+
+ /**
+ * Construct a KeyguardViewMediator
+ * @param context
+ * @param lockPatternUtils optional mock interface for LockPatternUtils
+ */
+ public KeyguardViewMediator(Context context, LockPatternUtils lockPatternUtils) {
+ mContext = context;
+ mPM = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
+ mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
+ mShowKeyguardWakeLock = mPM.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "show keyguard");
+ mShowKeyguardWakeLock.setReferenceCounted(false);
+
+ mWakeAndHandOff = mPM.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "keyguardWakeAndHandOff");
+ mWakeAndHandOff.setReferenceCounted(false);
+
+ mContext.registerReceiver(mBroadcastReceiver, new IntentFilter(DELAYED_KEYGUARD_ACTION));
+
+ mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
+
+ mUpdateMonitor = KeyguardUpdateMonitor.getInstance(context);
+
+ mLockPatternUtils = lockPatternUtils != null
+ ? lockPatternUtils : new LockPatternUtils(mContext);
+ mLockPatternUtils.setCurrentUser(UserHandle.USER_OWNER);
+
+ WindowManager wm = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
+
+ mKeyguardViewManager = new KeyguardViewManager(context, wm, mViewMediatorCallback,
+ mLockPatternUtils);
+
+ final ContentResolver cr = mContext.getContentResolver();
+ mShowLockIcon = (Settings.System.getInt(cr, "show_status_bar_lock", 0) == 1);
+
+ mScreenOn = mPM.isScreenOn();
+
+ mLockSounds = new SoundPool(1, AudioManager.STREAM_SYSTEM, 0);
+ String soundPath = Settings.Global.getString(cr, Settings.Global.LOCK_SOUND);
+ if (soundPath != null) {
+ mLockSoundId = mLockSounds.load(soundPath, 1);
+ }
+ if (soundPath == null || mLockSoundId == 0) {
+ Log.w(TAG, "failed to load lock sound from " + soundPath);
+ }
+ soundPath = Settings.Global.getString(cr, Settings.Global.UNLOCK_SOUND);
+ if (soundPath != null) {
+ mUnlockSoundId = mLockSounds.load(soundPath, 1);
+ }
+ if (soundPath == null || mUnlockSoundId == 0) {
+ Log.w(TAG, "failed to load unlock sound from " + soundPath);
+ }
+ int lockSoundDefaultAttenuation = context.getResources().getInteger(
+ com.android.internal.R.integer.config_lockSoundVolumeDb);
+ mLockSoundVolume = (float)Math.pow(10, (float)lockSoundDefaultAttenuation/20);
+ }
+
+ /**
+ * Let us know that the system is ready after startup.
+ */
+ public void onSystemReady() {
+ mSearchManager = (SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE);
+ synchronized (this) {
+ if (DEBUG) Log.d(TAG, "onSystemReady");
+ mSystemReady = true;
+ mUpdateMonitor.registerCallback(mUpdateCallback);
+
+ // Suppress biometric unlock right after boot until things have settled if it is the
+ // selected security method, otherwise unsuppress it. It must be unsuppressed if it is
+ // not the selected security method for the following reason: if the user starts
+ // without a screen lock selected, the biometric unlock would be suppressed the first
+ // time they try to use it.
+ //
+ // Note that the biometric unlock will still not show if it is not the selected method.
+ // Calling setAlternateUnlockEnabled(true) simply says don't suppress it if it is the
+ // selected method.
+ if (mLockPatternUtils.usingBiometricWeak()
+ && mLockPatternUtils.isBiometricWeakInstalled()) {
+ if (DEBUG) Log.d(TAG, "suppressing biometric unlock during boot");
+ mUpdateMonitor.setAlternateUnlockEnabled(false);
+ } else {
+ mUpdateMonitor.setAlternateUnlockEnabled(true);
+ }
+
+ doKeyguardLocked(null);
+ }
+ // Most services aren't available until the system reaches the ready state, so we
+ // send it here when the device first boots.
+ maybeSendUserPresentBroadcast();
+ }
+
+ /**
+ * Called to let us know the screen was turned off.
+ * @param why either {@link WindowManagerPolicy#OFF_BECAUSE_OF_USER},
+ * {@link WindowManagerPolicy#OFF_BECAUSE_OF_TIMEOUT} or
+ * {@link WindowManagerPolicy#OFF_BECAUSE_OF_PROX_SENSOR}.
+ */
+ public void onScreenTurnedOff(int why) {
+ synchronized (this) {
+ mScreenOn = false;
+ if (DEBUG) Log.d(TAG, "onScreenTurnedOff(" + why + ")");
+
+ mKeyguardDonePending = false;
+
+ // Lock immediately based on setting if secure (user has a pin/pattern/password).
+ // This also "locks" the device when not secure to provide easy access to the
+ // camera while preventing unwanted input.
+ final boolean lockImmediately =
+ mLockPatternUtils.getPowerButtonInstantlyLocks() || !mLockPatternUtils.isSecure();
+
+ if (mExitSecureCallback != null) {
+ if (DEBUG) Log.d(TAG, "pending exit secure callback cancelled");
+ try {
+ mExitSecureCallback.onKeyguardExitResult(false);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Failed to call onKeyguardExitResult(false)", e);
+ }
+ mExitSecureCallback = null;
+ if (!mExternallyEnabled) {
+ hideLocked();
+ }
+ } else if (mShowing) {
+ notifyScreenOffLocked();
+ resetStateLocked(null);
+ } else if (why == WindowManagerPolicy.OFF_BECAUSE_OF_TIMEOUT
+ || (why == WindowManagerPolicy.OFF_BECAUSE_OF_USER && !lockImmediately)) {
+ doKeyguardLaterLocked();
+ } else if (why == WindowManagerPolicy.OFF_BECAUSE_OF_PROX_SENSOR) {
+ // Do not enable the keyguard if the prox sensor forced the screen off.
+ } else {
+ doKeyguardLocked(null);
+ }
+ }
+ }
+
+ private void doKeyguardLaterLocked() {
+ // if the screen turned off because of timeout or the user hit the power button
+ // and we don't need to lock immediately, set an alarm
+ // to enable it a little bit later (i.e, give the user a chance
+ // to turn the screen back on within a certain window without
+ // having to unlock the screen)
+ final ContentResolver cr = mContext.getContentResolver();
+
+ // From DisplaySettings
+ long displayTimeout = Settings.System.getInt(cr, SCREEN_OFF_TIMEOUT,
+ KEYGUARD_DISPLAY_TIMEOUT_DELAY_DEFAULT);
+
+ // From SecuritySettings
+ final long lockAfterTimeout = Settings.Secure.getInt(cr,
+ Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT,
+ KEYGUARD_LOCK_AFTER_DELAY_DEFAULT);
+
+ // From DevicePolicyAdmin
+ final long policyTimeout = mLockPatternUtils.getDevicePolicyManager()
+ .getMaximumTimeToLock(null, mLockPatternUtils.getCurrentUser());
+
+ long timeout;
+ if (policyTimeout > 0) {
+ // policy in effect. Make sure we don't go beyond policy limit.
+ displayTimeout = Math.max(displayTimeout, 0); // ignore negative values
+ timeout = Math.min(policyTimeout - displayTimeout, lockAfterTimeout);
+ } else {
+ timeout = lockAfterTimeout;
+ }
+
+ if (timeout <= 0) {
+ // Lock now
+ mSuppressNextLockSound = true;
+ doKeyguardLocked(null);
+ } else {
+ // Lock in the future
+ long when = SystemClock.elapsedRealtime() + timeout;
+ Intent intent = new Intent(DELAYED_KEYGUARD_ACTION);
+ intent.putExtra("seq", mDelayedShowingSequence);
+ PendingIntent sender = PendingIntent.getBroadcast(mContext,
+ 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
+ mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, when, sender);
+ if (DEBUG) Log.d(TAG, "setting alarm to turn off keyguard, seq = "
+ + mDelayedShowingSequence);
+ }
+ }
+
+ private void cancelDoKeyguardLaterLocked() {
+ mDelayedShowingSequence++;
+ }
+
+ /**
+ * Let's us know the screen was turned on.
+ */
+ public void onScreenTurnedOn(IKeyguardShowCallback callback) {
+ synchronized (this) {
+ mScreenOn = true;
+ cancelDoKeyguardLaterLocked();
+ if (DEBUG) Log.d(TAG, "onScreenTurnedOn, seq = " + mDelayedShowingSequence);
+ if (callback != null) {
+ notifyScreenOnLocked(callback);
+ }
+ }
+ maybeSendUserPresentBroadcast();
+ }
+
+ private void maybeSendUserPresentBroadcast() {
+ if (mSystemReady && mLockPatternUtils.isLockScreenDisabled()
+ && mUserManager.getUsers(true).size() == 1) {
+ // Lock screen is disabled because the user has set the preference to "None".
+ // In this case, send out ACTION_USER_PRESENT here instead of in
+ // handleKeyguardDone()
+ sendUserPresentBroadcast();
+ }
+ }
+
+ /**
+ * A dream started. We should lock after the usual screen-off lock timeout but only
+ * if there is a secure lock pattern.
+ */
+ public void onDreamingStarted() {
+ synchronized (this) {
+ if (mScreenOn && mLockPatternUtils.isSecure()) {
+ doKeyguardLaterLocked();
+ }
+ }
+ }
+
+ /**
+ * A dream stopped.
+ */
+ public void onDreamingStopped() {
+ synchronized (this) {
+ if (mScreenOn) {
+ cancelDoKeyguardLaterLocked();
+ }
+ }
+ }
+
+ /**
+ * Same semantics as {@link WindowManagerPolicy#enableKeyguard}; provide
+ * a way for external stuff to override normal keyguard behavior. For instance
+ * the phone app disables the keyguard when it receives incoming calls.
+ */
+ public void setKeyguardEnabled(boolean enabled) {
+ synchronized (this) {
+ if (DEBUG) Log.d(TAG, "setKeyguardEnabled(" + enabled + ")");
+
+ mExternallyEnabled = enabled;
+
+ if (!enabled && mShowing) {
+ if (mExitSecureCallback != null) {
+ if (DEBUG) Log.d(TAG, "in process of verifyUnlock request, ignoring");
+ // we're in the process of handling a request to verify the user
+ // can get past the keyguard. ignore extraneous requests to disable / reenable
+ return;
+ }
+
+ // hiding keyguard that is showing, remember to reshow later
+ if (DEBUG) Log.d(TAG, "remembering to reshow, hiding keyguard, "
+ + "disabling status bar expansion");
+ mNeedToReshowWhenReenabled = true;
+ hideLocked();
+ } else if (enabled && mNeedToReshowWhenReenabled) {
+ // reenabled after previously hidden, reshow
+ if (DEBUG) Log.d(TAG, "previously hidden, reshowing, reenabling "
+ + "status bar expansion");
+ mNeedToReshowWhenReenabled = false;
+
+ if (mExitSecureCallback != null) {
+ if (DEBUG) Log.d(TAG, "onKeyguardExitResult(false), resetting");
+ try {
+ mExitSecureCallback.onKeyguardExitResult(false);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Failed to call onKeyguardExitResult(false)", e);
+ }
+ mExitSecureCallback = null;
+ resetStateLocked(null);
+ } else {
+ showLocked(null);
+
+ // block until we know the keygaurd is done drawing (and post a message
+ // to unblock us after a timeout so we don't risk blocking too long
+ // and causing an ANR).
+ mWaitingUntilKeyguardVisible = true;
+ mHandler.sendEmptyMessageDelayed(KEYGUARD_DONE_DRAWING, KEYGUARD_DONE_DRAWING_TIMEOUT_MS);
+ if (DEBUG) Log.d(TAG, "waiting until mWaitingUntilKeyguardVisible is false");
+ while (mWaitingUntilKeyguardVisible) {
+ try {
+ wait();
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ }
+ }
+ if (DEBUG) Log.d(TAG, "done waiting for mWaitingUntilKeyguardVisible");
+ }
+ }
+ }
+ }
+
+ /**
+ * @see android.app.KeyguardManager#exitKeyguardSecurely
+ */
+ public void verifyUnlock(IKeyguardExitCallback callback) {
+ synchronized (this) {
+ if (DEBUG) Log.d(TAG, "verifyUnlock");
+ if (!mUpdateMonitor.isDeviceProvisioned()) {
+ // don't allow this api when the device isn't provisioned
+ if (DEBUG) Log.d(TAG, "ignoring because device isn't provisioned");
+ try {
+ callback.onKeyguardExitResult(false);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Failed to call onKeyguardExitResult(false)", e);
+ }
+ } else if (mExternallyEnabled) {
+ // this only applies when the user has externally disabled the
+ // keyguard. this is unexpected and means the user is not
+ // using the api properly.
+ Log.w(TAG, "verifyUnlock called when not externally disabled");
+ try {
+ callback.onKeyguardExitResult(false);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Failed to call onKeyguardExitResult(false)", e);
+ }
+ } else if (mExitSecureCallback != null) {
+ // already in progress with someone else
+ try {
+ callback.onKeyguardExitResult(false);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Failed to call onKeyguardExitResult(false)", e);
+ }
+ } else {
+ mExitSecureCallback = callback;
+ verifyUnlockLocked();
+ }
+ }
+ }
+
+ /**
+ * Is the keyguard currently showing?
+ */
+ public boolean isShowing() {
+ return mShowing;
+ }
+
+ /**
+ * Is the keyguard currently showing and not being force hidden?
+ */
+ public boolean isShowingAndNotHidden() {
+ return mShowing && !mHidden;
+ }
+
+ /**
+ * Notify us when the keyguard is hidden by another window
+ */
+ public void setHidden(boolean isHidden) {
+ if (DEBUG) Log.d(TAG, "setHidden " + isHidden);
+ mUpdateMonitor.sendKeyguardVisibilityChanged(!isHidden);
+ mHandler.removeMessages(SET_HIDDEN);
+ Message msg = mHandler.obtainMessage(SET_HIDDEN, (isHidden ? 1 : 0), 0);
+ mHandler.sendMessage(msg);
+ }
+
+ /**
+ * Handles SET_HIDDEN message sent by setHidden()
+ */
+ private void handleSetHidden(boolean isHidden) {
+ synchronized (KeyguardViewMediator.this) {
+ if (mHidden != isHidden) {
+ mHidden = isHidden;
+ updateActivityLockScreenState();
+ adjustStatusBarLocked();
+ }
+ }
+ }
+
+ /**
+ * Used by PhoneWindowManager to enable the keyguard due to a user activity timeout.
+ * This must be safe to call from any thread and with any window manager locks held.
+ */
+ public void doKeyguardTimeout(Bundle options) {
+ mHandler.removeMessages(KEYGUARD_TIMEOUT);
+ Message msg = mHandler.obtainMessage(KEYGUARD_TIMEOUT, options);
+ mHandler.sendMessage(msg);
+ }
+
+ /**
+ * Given the state of the keyguard, is the input restricted?
+ * Input is restricted when the keyguard is showing, or when the keyguard
+ * was suppressed by an app that disabled the keyguard or we haven't been provisioned yet.
+ */
+ public boolean isInputRestricted() {
+ return mShowing || mNeedToReshowWhenReenabled || !mUpdateMonitor.isDeviceProvisioned();
+ }
+
+ /**
+ * Enable the keyguard if the settings are appropriate.
+ */
+ private void doKeyguardLocked(Bundle options) {
+ // if another app is disabling us, don't show
+ if (!mExternallyEnabled) {
+ if (DEBUG) Log.d(TAG, "doKeyguard: not showing because externally disabled");
+
+ // note: we *should* set mNeedToReshowWhenReenabled=true here, but that makes
+ // for an occasional ugly flicker in this situation:
+ // 1) receive a call with the screen on (no keyguard) or make a call
+ // 2) screen times out
+ // 3) user hits key to turn screen back on
+ // instead, we reenable the keyguard when we know the screen is off and the call
+ // ends (see the broadcast receiver below)
+ // TODO: clean this up when we have better support at the window manager level
+ // for apps that wish to be on top of the keyguard
+ return;
+ }
+
+ // if the keyguard is already showing, don't bother
+ if (mKeyguardViewManager.isShowing()) {
+ if (DEBUG) Log.d(TAG, "doKeyguard: not showing because it is already showing");
+ return;
+ }
+
+ // if the setup wizard hasn't run yet, don't show
+ final boolean requireSim = !SystemProperties.getBoolean("keyguard.no_require_sim",
+ false);
+ final boolean provisioned = mUpdateMonitor.isDeviceProvisioned();
+ final IccCardConstants.State state = mUpdateMonitor.getSimState();
+ final boolean lockedOrMissing = state.isPinLocked()
+ || ((state == IccCardConstants.State.ABSENT
+ || state == IccCardConstants.State.PERM_DISABLED)
+ && requireSim);
+
+ if (!lockedOrMissing && !provisioned) {
+ if (DEBUG) Log.d(TAG, "doKeyguard: not showing because device isn't provisioned"
+ + " and the sim is not locked or missing");
+ return;
+ }
+
+ if (mUserManager.getUsers(true).size() < 2
+ && mLockPatternUtils.isLockScreenDisabled() && !lockedOrMissing) {
+ if (DEBUG) Log.d(TAG, "doKeyguard: not showing because lockscreen is off");
+ return;
+ }
+
+ if (DEBUG) Log.d(TAG, "doKeyguard: showing the lock screen");
+ showLocked(options);
+ }
+
+ /**
+ * Dismiss the keyguard through the security layers.
+ */
+ public void dismiss() {
+ if (mShowing && !mHidden) {
+ mKeyguardViewManager.dismiss();
+ }
+ }
+
+ /**
+ * Send message to keyguard telling it to reset its state.
+ * @param options options about how to show the keyguard
+ * @see #handleReset()
+ */
+ private void resetStateLocked(Bundle options) {
+ if (DEBUG) Log.d(TAG, "resetStateLocked");
+ Message msg = mHandler.obtainMessage(RESET, options);
+ mHandler.sendMessage(msg);
+ }
+
+ /**
+ * Send message to keyguard telling it to verify unlock
+ * @see #handleVerifyUnlock()
+ */
+ private void verifyUnlockLocked() {
+ if (DEBUG) Log.d(TAG, "verifyUnlockLocked");
+ mHandler.sendEmptyMessage(VERIFY_UNLOCK);
+ }
+
+
+ /**
+ * Send a message to keyguard telling it the screen just turned on.
+ * @see #onScreenTurnedOff(int)
+ * @see #handleNotifyScreenOff
+ */
+ private void notifyScreenOffLocked() {
+ if (DEBUG) Log.d(TAG, "notifyScreenOffLocked");
+ mHandler.sendEmptyMessage(NOTIFY_SCREEN_OFF);
+ }
+
+ /**
+ * Send a message to keyguard telling it the screen just turned on.
+ * @see #onScreenTurnedOn()
+ * @see #handleNotifyScreenOn
+ */
+ private void notifyScreenOnLocked(IKeyguardShowCallback result) {
+ if (DEBUG) Log.d(TAG, "notifyScreenOnLocked");
+ Message msg = mHandler.obtainMessage(NOTIFY_SCREEN_ON, result);
+ mHandler.sendMessage(msg);
+ }
+
+ /**
+ * Send message to keyguard telling it about a wake key so it can adjust
+ * its state accordingly and then poke the wake lock when it is ready.
+ * @param keyCode The wake key.
+ * @see #handleWakeWhenReady
+ * @see #onWakeKeyWhenKeyguardShowing(int)
+ */
+ private void wakeWhenReady(int keyCode) {
+ if (DBG_WAKE) Log.d(TAG, "wakeWhenReady(" + keyCode + ")");
+
+ /**
+ * acquire the handoff lock that will keep the cpu running. this will
+ * be released once the keyguard has set itself up and poked the other wakelock
+ * in {@link #handleWakeWhenReady(int)}
+ */
+ mWakeAndHandOff.acquire();
+
+ Message msg = mHandler.obtainMessage(WAKE_WHEN_READY, keyCode, 0);
+ mHandler.sendMessage(msg);
+ }
+
+ /**
+ * Send message to keyguard telling it to show itself
+ * @see #handleShow()
+ */
+ private void showLocked(Bundle options) {
+ if (DEBUG) Log.d(TAG, "showLocked");
+ // ensure we stay awake until we are finished displaying the keyguard
+ mShowKeyguardWakeLock.acquire();
+ Message msg = mHandler.obtainMessage(SHOW, options);
+ mHandler.sendMessage(msg);
+ }
+
+ /**
+ * Send message to keyguard telling it to hide itself
+ * @see #handleHide()
+ */
+ private void hideLocked() {
+ if (DEBUG) Log.d(TAG, "hideLocked");
+ Message msg = mHandler.obtainMessage(HIDE);
+ mHandler.sendMessage(msg);
+ }
+
+ public boolean isSecure() {
+ return mLockPatternUtils.isSecure()
+ || KeyguardUpdateMonitor.getInstance(mContext).isSimPinSecure();
+ }
+
+ /**
+ * Update the newUserId. Call while holding WindowManagerService lock.
+ * NOTE: Should only be called by KeyguardViewMediator in response to the user id changing.
+ *
+ * @param newUserId The id of the incoming user.
+ */
+ public void setCurrentUser(int newUserId) {
+ mLockPatternUtils.setCurrentUser(newUserId);
+ }
+
+ private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (DELAYED_KEYGUARD_ACTION.equals(intent.getAction())) {
+ final int sequence = intent.getIntExtra("seq", 0);
+ if (DEBUG) Log.d(TAG, "received DELAYED_KEYGUARD_ACTION with seq = "
+ + sequence + ", mDelayedShowingSequence = " + mDelayedShowingSequence);
+ synchronized (KeyguardViewMediator.this) {
+ if (mDelayedShowingSequence == sequence) {
+ // Don't play lockscreen SFX if the screen went off due to timeout.
+ mSuppressNextLockSound = true;
+ doKeyguardLocked(null);
+ }
+ }
+ }
+ }
+ };
+
+ /**
+ * When a key is received when the screen is off and the keyguard is showing,
+ * we need to decide whether to actually turn on the screen, and if so, tell
+ * the keyguard to prepare itself and poke the wake lock when it is ready.
+ *
+ * The 'Tq' suffix is per the documentation in {@link WindowManagerPolicy}.
+ * Be sure not to take any action that takes a long time; any significant
+ * action should be posted to a handler.
+ *
+ * @param keyCode The keycode of the key that woke the device
+ */
+ public void onWakeKeyWhenKeyguardShowing(int keyCode) {
+ if (DEBUG) Log.d(TAG, "onWakeKeyWhenKeyguardShowing(" + keyCode + ")");
+
+ // give the keyguard view manager a chance to adjust the state of the
+ // keyguard based on the key that woke the device before poking
+ // the wake lock
+ wakeWhenReady(keyCode);
+ }
+
+ /**
+ * When a wake motion such as an external mouse movement is received when the screen
+ * is off and the keyguard is showing, we need to decide whether to actually turn
+ * on the screen, and if so, tell the keyguard to prepare itself and poke the wake
+ * lock when it is ready.
+ *
+ * The 'Tq' suffix is per the documentation in {@link WindowManagerPolicy}.
+ * Be sure not to take any action that takes a long time; any significant
+ * action should be posted to a handler.
+ */
+ public void onWakeMotionWhenKeyguardShowing() {
+ if (DEBUG) Log.d(TAG, "onWakeMotionWhenKeyguardShowing()");
+
+ // give the keyguard view manager a chance to adjust the state of the
+ // keyguard based on the key that woke the device before poking
+ // the wake lock
+ wakeWhenReady(KeyEvent.KEYCODE_UNKNOWN);
+ }
+
+ public void keyguardDone(boolean authenticated, boolean wakeup) {
+ mKeyguardDonePending = false;
+ synchronized (this) {
+ EventLog.writeEvent(70000, 2);
+ if (DEBUG) Log.d(TAG, "keyguardDone(" + authenticated + ")");
+ Message msg = mHandler.obtainMessage(KEYGUARD_DONE);
+ msg.arg1 = wakeup ? 1 : 0;
+ mHandler.sendMessage(msg);
+
+ if (authenticated) {
+ mUpdateMonitor.clearFailedUnlockAttempts();
+ }
+
+ if (mExitSecureCallback != null) {
+ try {
+ mExitSecureCallback.onKeyguardExitResult(authenticated);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Failed to call onKeyguardExitResult(" + authenticated + ")", e);
+ }
+
+ mExitSecureCallback = null;
+
+ if (authenticated) {
+ // after succesfully exiting securely, no need to reshow
+ // the keyguard when they've released the lock
+ mExternallyEnabled = true;
+ mNeedToReshowWhenReenabled = false;
+ }
+ }
+ }
+ }
+
+ /**
+ * This handler will be associated with the policy thread, which will also
+ * be the UI thread of the keyguard. Since the apis of the policy, and therefore
+ * this class, can be called by other threads, any action that directly
+ * interacts with the keyguard ui should be posted to this handler, rather
+ * than called directly.
+ */
+ private Handler mHandler = new Handler(Looper.myLooper(), null, true /*async*/) {
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case SHOW:
+ handleShow((Bundle) msg.obj);
+ return ;
+ case HIDE:
+ handleHide();
+ return ;
+ case RESET:
+ handleReset((Bundle) msg.obj);
+ return ;
+ case VERIFY_UNLOCK:
+ handleVerifyUnlock();
+ return;
+ case NOTIFY_SCREEN_OFF:
+ handleNotifyScreenOff();
+ return;
+ case NOTIFY_SCREEN_ON:
+ handleNotifyScreenOn((IKeyguardShowCallback) msg.obj);
+ return;
+ case WAKE_WHEN_READY:
+ handleWakeWhenReady(msg.arg1);
+ return;
+ case KEYGUARD_DONE:
+ handleKeyguardDone(msg.arg1 != 0);
+ return;
+ case KEYGUARD_DONE_DRAWING:
+ handleKeyguardDoneDrawing();
+ return;
+ case KEYGUARD_DONE_AUTHENTICATING:
+ keyguardDone(true, true);
+ return;
+ case SET_HIDDEN:
+ handleSetHidden(msg.arg1 != 0);
+ break;
+ case KEYGUARD_TIMEOUT:
+ synchronized (KeyguardViewMediator.this) {
+ doKeyguardLocked((Bundle) msg.obj);
+ }
+ break;
+ case SHOW_ASSISTANT:
+ handleShowAssistant();
+ break;
+ }
+ }
+ };
+
+ /**
+ * @see #keyguardDone
+ * @see #KEYGUARD_DONE
+ */
+ private void handleKeyguardDone(boolean wakeup) {
+ if (DEBUG) Log.d(TAG, "handleKeyguardDone");
+ handleHide();
+ if (wakeup) {
+ wakeUp();
+ }
+
+ sendUserPresentBroadcast();
+ }
+
+ private void sendUserPresentBroadcast() {
+ final UserHandle currentUser = new UserHandle(mLockPatternUtils.getCurrentUser());
+ mContext.sendBroadcastAsUser(USER_PRESENT_INTENT, currentUser);
+ }
+
+ /**
+ * @see #keyguardDoneDrawing
+ * @see #KEYGUARD_DONE_DRAWING
+ */
+ private void handleKeyguardDoneDrawing() {
+ synchronized(this) {
+ if (DEBUG) Log.d(TAG, "handleKeyguardDoneDrawing");
+ if (mWaitingUntilKeyguardVisible) {
+ if (DEBUG) Log.d(TAG, "handleKeyguardDoneDrawing: notifying mWaitingUntilKeyguardVisible");
+ mWaitingUntilKeyguardVisible = false;
+ notifyAll();
+
+ // there will usually be two of these sent, one as a timeout, and one
+ // as a result of the callback, so remove any remaining messages from
+ // the queue
+ mHandler.removeMessages(KEYGUARD_DONE_DRAWING);
+ }
+ }
+ }
+
+ private void playSounds(boolean locked) {
+ // User feedback for keyguard.
+
+ if (mSuppressNextLockSound) {
+ mSuppressNextLockSound = false;
+ return;
+ }
+
+ final ContentResolver cr = mContext.getContentResolver();
+ if (Settings.System.getInt(cr, Settings.System.LOCKSCREEN_SOUNDS_ENABLED, 1) == 1) {
+ final int whichSound = locked
+ ? mLockSoundId
+ : mUnlockSoundId;
+ mLockSounds.stop(mLockSoundStreamId);
+ // Init mAudioManager
+ if (mAudioManager == null) {
+ mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
+ if (mAudioManager == null) return;
+ mMasterStreamType = mAudioManager.getMasterStreamType();
+ }
+ // If the stream is muted, don't play the sound
+ if (mAudioManager.isStreamMute(mMasterStreamType)) return;
+
+ mLockSoundStreamId = mLockSounds.play(whichSound,
+ mLockSoundVolume, mLockSoundVolume, 1/*priortiy*/, 0/*loop*/, 1.0f/*rate*/);
+ }
+ }
+
+ private void updateActivityLockScreenState() {
+ try {
+ ActivityManagerNative.getDefault().setLockScreenShown(
+ mShowing && !mHidden);
+ } catch (RemoteException e) {
+ }
+ }
+
+ /**
+ * Handle message sent by {@link #showLocked}.
+ * @see #SHOW
+ */
+ private void handleShow(Bundle options) {
+ synchronized (KeyguardViewMediator.this) {
+ if (!mSystemReady) {
+ if (DEBUG) Log.d(TAG, "ignoring handleShow because system is not ready.");
+ return;
+ } else {
+ if (DEBUG) Log.d(TAG, "handleShow");
+ }
+
+ mKeyguardViewManager.show(options);
+ mShowing = true;
+ mKeyguardDonePending = false;
+ updateActivityLockScreenState();
+ adjustStatusBarLocked();
+ userActivity();
+ try {
+ ActivityManagerNative.getDefault().closeSystemDialogs("lock");
+ } catch (RemoteException e) {
+ }
+
+ // Do this at the end to not slow down display of the keyguard.
+ playSounds(true);
+
+ mShowKeyguardWakeLock.release();
+ }
+ }
+
+ /**
+ * Handle message sent by {@link #hideLocked()}
+ * @see #HIDE
+ */
+ private void handleHide() {
+ synchronized (KeyguardViewMediator.this) {
+ if (DEBUG) Log.d(TAG, "handleHide");
+ if (mWakeAndHandOff.isHeld()) {
+ Log.w(TAG, "attempt to hide the keyguard while waking, ignored");
+ return;
+ }
+
+ // only play "unlock" noises if not on a call (since the incall UI
+ // disables the keyguard)
+ if (TelephonyManager.EXTRA_STATE_IDLE.equals(mPhoneState)) {
+ playSounds(false);
+ }
+
+ mKeyguardViewManager.hide();
+ mShowing = false;
+ mKeyguardDonePending = false;
+ updateActivityLockScreenState();
+ adjustStatusBarLocked();
+ }
+ }
+
+ private void adjustStatusBarLocked() {
+ if (mStatusBarManager == null) {
+ mStatusBarManager = (StatusBarManager)
+ mContext.getSystemService(Context.STATUS_BAR_SERVICE);
+ }
+ if (mStatusBarManager == null) {
+ Log.w(TAG, "Could not get status bar manager");
+ } else {
+ if (mShowLockIcon) {
+ // Give feedback to user when secure keyguard is active and engaged
+ if (mShowing && isSecure()) {
+ if (!mShowingLockIcon) {
+ String contentDescription = mContext.getString(
+ com.android.internal.R.string.status_bar_device_locked);
+ mStatusBarManager.setIcon("secure",
+ com.android.internal.R.drawable.stat_sys_secure, 0,
+ contentDescription);
+ mShowingLockIcon = true;
+ }
+ } else {
+ if (mShowingLockIcon) {
+ mStatusBarManager.removeIcon("secure");
+ mShowingLockIcon = false;
+ }
+ }
+ }
+
+ // Disable aspects of the system/status/navigation bars that must not be re-enabled by
+ // windows that appear on top, ever
+ int flags = StatusBarManager.DISABLE_NONE;
+ if (mShowing) {
+ // Permanently disable components not available when keyguard is enabled
+ // (like recents). Temporary enable/disable (e.g. the "back" button) are
+ // done in KeyguardHostView.
+ flags |= StatusBarManager.DISABLE_RECENT;
+ if (isSecure() || !ENABLE_INSECURE_STATUS_BAR_EXPAND) {
+ // showing secure lockscreen; disable expanding.
+ flags |= StatusBarManager.DISABLE_EXPAND;
+ }
+ if (isSecure()) {
+ // showing secure lockscreen; disable ticker.
+ flags |= StatusBarManager.DISABLE_NOTIFICATION_TICKER;
+ }
+ if (!isAssistantAvailable()) {
+ flags |= StatusBarManager.DISABLE_SEARCH;
+ }
+ }
+
+ if (DEBUG) {
+ Log.d(TAG, "adjustStatusBarLocked: mShowing=" + mShowing + " mHidden=" + mHidden
+ + " isSecure=" + isSecure() + " --> flags=0x" + Integer.toHexString(flags));
+ }
+
+ if (!(mContext instanceof Activity)) {
+ mStatusBarManager.disable(flags);
+ }
+ }
+ }
+
+ /**
+ * Handle message sent by {@link #wakeWhenReady(int)}
+ * @param keyCode The key that woke the device.
+ * @see #WAKE_WHEN_READY
+ */
+ private void handleWakeWhenReady(int keyCode) {
+ synchronized (KeyguardViewMediator.this) {
+ if (DBG_WAKE) Log.d(TAG, "handleWakeWhenReady(" + keyCode + ")");
+
+ // this should result in a call to 'poke wakelock' which will set a timeout
+ // on releasing the wakelock
+ if (!mKeyguardViewManager.wakeWhenReadyTq(keyCode)) {
+ // poke wakelock ourselves if keyguard is no longer active
+ Log.w(TAG, "mKeyguardViewManager.wakeWhenReadyTq did not poke wake lock, so poke it ourselves");
+ userActivity();
+ }
+
+ /**
+ * Now that the keyguard is ready and has poked the wake lock, we can
+ * release the handoff wakelock
+ */
+ mWakeAndHandOff.release();
+ }
+ }
+
+ /**
+ * Handle message sent by {@link #resetStateLocked(Bundle)}
+ * @see #RESET
+ */
+ private void handleReset(Bundle options) {
+ if (options == null) {
+ options = new Bundle();
+ }
+ options.putBoolean(KeyguardViewManager.IS_SWITCHING_USER, mSwitchingUser);
+ synchronized (KeyguardViewMediator.this) {
+ if (DEBUG) Log.d(TAG, "handleReset");
+ mKeyguardViewManager.reset(options);
+ }
+ }
+
+ /**
+ * Handle message sent by {@link #verifyUnlock}
+ * @see #VERIFY_UNLOCK
+ */
+ private void handleVerifyUnlock() {
+ synchronized (KeyguardViewMediator.this) {
+ if (DEBUG) Log.d(TAG, "handleVerifyUnlock");
+ mKeyguardViewManager.verifyUnlock();
+ mShowing = true;
+ updateActivityLockScreenState();
+ }
+ }
+
+ /**
+ * Handle message sent by {@link #notifyScreenOffLocked()}
+ * @see #NOTIFY_SCREEN_OFF
+ */
+ private void handleNotifyScreenOff() {
+ synchronized (KeyguardViewMediator.this) {
+ if (DEBUG) Log.d(TAG, "handleNotifyScreenOff");
+ mKeyguardViewManager.onScreenTurnedOff();
+ }
+ }
+
+ /**
+ * Handle message sent by {@link #notifyScreenOnLocked()}
+ * @see #NOTIFY_SCREEN_ON
+ */
+ private void handleNotifyScreenOn(IKeyguardShowCallback callback) {
+ synchronized (KeyguardViewMediator.this) {
+ if (DEBUG) Log.d(TAG, "handleNotifyScreenOn");
+ mKeyguardViewManager.onScreenTurnedOn(callback);
+ }
+ }
+
+ public boolean isDismissable() {
+ return mKeyguardDonePending || !isSecure();
+ }
+
+ public void showAssistant() {
+ Message msg = mHandler.obtainMessage(SHOW_ASSISTANT);
+ mHandler.sendMessage(msg);
+ }
+
+ public void handleShowAssistant() {
+ mKeyguardViewManager.showAssistant();
+ }
+
+ private boolean isAssistantAvailable() {
+ return mSearchManager != null
+ && mSearchManager.getAssistIntent(mContext, false, UserHandle.USER_CURRENT) != null;
+ }
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardViewStateManager.java b/packages/Keyguard/src/com/android/keyguard/KeyguardViewStateManager.java
new file mode 100644
index 0000000..880fddd
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardViewStateManager.java
@@ -0,0 +1,333 @@
+/*
+ * 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.keyguard;
+
+import android.appwidget.AppWidgetManager;
+import android.os.Handler;
+import android.os.Looper;
+import android.view.View;
+
+public class KeyguardViewStateManager implements
+ SlidingChallengeLayout.OnChallengeScrolledListener,
+ ChallengeLayout.OnBouncerStateChangedListener {
+
+ private KeyguardWidgetPager mKeyguardWidgetPager;
+ private ChallengeLayout mChallengeLayout;
+ private KeyguardHostView mKeyguardHostView;
+ private int[] mTmpPoint = new int[2];
+ private int[] mTmpLoc = new int[2];
+
+ private KeyguardSecurityView mKeyguardSecurityContainer;
+ private static final int SCREEN_ON_HINT_DURATION = 1000;
+ private static final int SCREEN_ON_RING_HINT_DELAY = 300;
+ Handler mMainQueue = new Handler(Looper.myLooper());
+
+ // transport control states
+ static final int TRANSPORT_GONE = 0;
+ static final int TRANSPORT_INVISIBLE = 1;
+ static final int TRANSPORT_VISIBLE = 2;
+
+ private int mTransportState = TRANSPORT_GONE;
+
+ int mLastScrollState = SlidingChallengeLayout.SCROLL_STATE_IDLE;
+
+ // Paged view state
+ private int mPageListeningToSlider = -1;
+ private int mCurrentPage = -1;
+ private int mPageIndexOnPageBeginMoving = -1;
+
+ int mChallengeTop = 0;
+
+ public KeyguardViewStateManager(KeyguardHostView hostView) {
+ mKeyguardHostView = hostView;
+ }
+
+ public void setPagedView(KeyguardWidgetPager pagedView) {
+ mKeyguardWidgetPager = pagedView;
+ updateEdgeSwiping();
+ }
+
+ public void setChallengeLayout(ChallengeLayout layout) {
+ mChallengeLayout = layout;
+ updateEdgeSwiping();
+ }
+
+ private void updateEdgeSwiping() {
+ if (mChallengeLayout != null && mKeyguardWidgetPager != null) {
+ if (mChallengeLayout.isChallengeOverlapping()) {
+ mKeyguardWidgetPager.setOnlyAllowEdgeSwipes(true);
+ } else {
+ mKeyguardWidgetPager.setOnlyAllowEdgeSwipes(false);
+ }
+ }
+ }
+
+ public boolean isChallengeShowing() {
+ if (mChallengeLayout != null) {
+ return mChallengeLayout.isChallengeShowing();
+ }
+ return false;
+ }
+
+ public boolean isChallengeOverlapping() {
+ if (mChallengeLayout != null) {
+ return mChallengeLayout.isChallengeOverlapping();
+ }
+ return false;
+ }
+
+ public void setSecurityViewContainer(KeyguardSecurityView container) {
+ mKeyguardSecurityContainer = container;
+ }
+
+ public void showBouncer(boolean show) {
+ mChallengeLayout.showBouncer();
+ }
+
+ public boolean isBouncing() {
+ return mChallengeLayout.isBouncing();
+ }
+
+ public void fadeOutSecurity(int duration) {
+ ((View) mKeyguardSecurityContainer).animate().alpha(0).setDuration(duration);
+ }
+
+ public void fadeInSecurity(int duration) {
+ ((View) mKeyguardSecurityContainer).animate().alpha(1f).setDuration(duration);
+ }
+
+ public void onPageBeginMoving() {
+ if (mChallengeLayout.isChallengeOverlapping() &&
+ mChallengeLayout instanceof SlidingChallengeLayout) {
+ SlidingChallengeLayout scl = (SlidingChallengeLayout) mChallengeLayout;
+ scl.fadeOutChallenge();
+ mPageIndexOnPageBeginMoving = mKeyguardWidgetPager.getCurrentPage();
+ }
+ // We use mAppWidgetToShow to show a particular widget after you add it--
+ // once the user swipes a page we clear that behavior
+ if (mKeyguardHostView != null) {
+ mKeyguardHostView.clearAppWidgetToShow();
+ mKeyguardHostView.setOnDismissAction(null);
+ }
+ if (mHideHintsRunnable != null) {
+ mMainQueue.removeCallbacks(mHideHintsRunnable);
+ mHideHintsRunnable = null;
+ }
+ }
+
+ public void onPageEndMoving() {
+ mPageIndexOnPageBeginMoving = -1;
+ }
+
+ public void onPageSwitching(View newPage, int newPageIndex) {
+ if (mKeyguardWidgetPager != null && mChallengeLayout instanceof SlidingChallengeLayout) {
+ boolean isCameraPage = newPage instanceof CameraWidgetFrame;
+ ((SlidingChallengeLayout) mChallengeLayout).setChallengeInteractive(!isCameraPage);
+ }
+
+ // If the page we're settling to is the same as we started on, and the action of
+ // moving the page hid the security, we restore it immediately.
+ if (mPageIndexOnPageBeginMoving == mKeyguardWidgetPager.getNextPage() &&
+ mChallengeLayout instanceof SlidingChallengeLayout) {
+ SlidingChallengeLayout scl = (SlidingChallengeLayout) mChallengeLayout;
+ scl.fadeInChallenge();
+ mKeyguardWidgetPager.setWidgetToResetOnPageFadeOut(-1);
+ }
+ mPageIndexOnPageBeginMoving = -1;
+ }
+
+ public void onPageSwitched(View newPage, int newPageIndex) {
+ // Reset the previous page size and ensure the current page is sized appropriately.
+ // We only modify the page state if it is not currently under control by the slider.
+ // This prevents conflicts.
+
+ // If the page hasn't switched, don't bother with any of this
+ if (mCurrentPage == newPageIndex) return;
+
+ if (mKeyguardWidgetPager != null && mChallengeLayout != null) {
+ KeyguardWidgetFrame prevPage = mKeyguardWidgetPager.getWidgetPageAt(mCurrentPage);
+ if (prevPage != null && mCurrentPage != mPageListeningToSlider && mCurrentPage
+ != mKeyguardWidgetPager.getWidgetToResetOnPageFadeOut()) {
+ prevPage.resetSize();
+ }
+
+ KeyguardWidgetFrame newCurPage = mKeyguardWidgetPager.getWidgetPageAt(newPageIndex);
+ boolean challengeOverlapping = mChallengeLayout.isChallengeOverlapping();
+ if (challengeOverlapping && !newCurPage.isSmall()
+ && mPageListeningToSlider != newPageIndex) {
+ newCurPage.shrinkWidget();
+ }
+ }
+
+ mCurrentPage = newPageIndex;
+ }
+
+ private int getChallengeTopRelativeToFrame(KeyguardWidgetFrame frame, int top) {
+ mTmpPoint[0] = 0;
+ mTmpPoint[1] = top;
+ mapPoint((View) mChallengeLayout, frame, mTmpPoint);
+ return mTmpPoint[1];
+ }
+
+ /**
+ * Simple method to map a point from one view's coordinates to another's. Note: this method
+ * doesn't account for transforms, so if the views will be transformed, this should not be used.
+ *
+ * @param fromView The view to which the point is relative
+ * @param toView The view into which the point should be mapped
+ * @param pt The point
+ */
+ private void mapPoint(View fromView, View toView, int pt[]) {
+ fromView.getLocationInWindow(mTmpLoc);
+
+ int x = mTmpLoc[0];
+ int y = mTmpLoc[1];
+
+ toView.getLocationInWindow(mTmpLoc);
+ int vX = mTmpLoc[0];
+ int vY = mTmpLoc[1];
+
+ pt[0] += x - vX;
+ pt[1] += y - vY;
+ }
+
+ private void userActivity() {
+ if (mKeyguardHostView != null) {
+ mKeyguardHostView.onUserActivityTimeoutChanged();
+ mKeyguardHostView.userActivity();
+ }
+ }
+
+ @Override
+ public void onScrollStateChanged(int scrollState) {
+ if (mKeyguardWidgetPager == null || mChallengeLayout == null) return;
+
+ boolean challengeOverlapping = mChallengeLayout.isChallengeOverlapping();
+
+ if (scrollState == SlidingChallengeLayout.SCROLL_STATE_IDLE) {
+ KeyguardWidgetFrame frame = mKeyguardWidgetPager.getWidgetPageAt(mPageListeningToSlider);
+ if (frame == null) return;
+
+ if (!challengeOverlapping) {
+ if (!mKeyguardWidgetPager.isPageMoving()) {
+ frame.resetSize();
+ userActivity();
+ } else {
+ mKeyguardWidgetPager.setWidgetToResetOnPageFadeOut(mPageListeningToSlider);
+ }
+ }
+ if (frame.isSmall()) {
+ // This is to make sure that if the scroller animation gets cut off midway
+ // that the frame doesn't stay in a partial down position.
+ frame.setFrameHeight(frame.getSmallFrameHeight());
+ }
+ if (scrollState != SlidingChallengeLayout.SCROLL_STATE_FADING) {
+ frame.hideFrame(this);
+ }
+ updateEdgeSwiping();
+
+ if (mChallengeLayout.isChallengeShowing()) {
+ mKeyguardSecurityContainer.onResume(KeyguardSecurityView.VIEW_REVEALED);
+ } else {
+ mKeyguardSecurityContainer.onPause();
+ }
+ mPageListeningToSlider = -1;
+ } else if (mLastScrollState == SlidingChallengeLayout.SCROLL_STATE_IDLE) {
+ // Whether dragging or settling, if the last state was idle, we use this signal
+ // to update the current page who will receive events from the sliding challenge.
+ // We resize the frame as appropriate.
+ mPageListeningToSlider = mKeyguardWidgetPager.getNextPage();
+ KeyguardWidgetFrame frame = mKeyguardWidgetPager.getWidgetPageAt(mPageListeningToSlider);
+ if (frame == null) return;
+
+ // Skip showing the frame and shrinking the widget if we are
+ if (!mChallengeLayout.isBouncing()) {
+ if (scrollState != SlidingChallengeLayout.SCROLL_STATE_FADING) {
+ frame.showFrame(this);
+ }
+
+ // As soon as the security begins sliding, the widget becomes small (if it wasn't
+ // small to begin with).
+ if (!frame.isSmall()) {
+ // We need to fetch the final page, in case the pages are in motion.
+ mPageListeningToSlider = mKeyguardWidgetPager.getNextPage();
+ frame.shrinkWidget(false);
+ }
+ } else {
+ if (!frame.isSmall()) {
+ // We need to fetch the final page, in case the pages are in motion.
+ mPageListeningToSlider = mKeyguardWidgetPager.getNextPage();
+ }
+ }
+
+ // View is on the move. Pause the security view until it completes.
+ mKeyguardSecurityContainer.onPause();
+ }
+ mLastScrollState = scrollState;
+ }
+
+ @Override
+ public void onScrollPositionChanged(float scrollPosition, int challengeTop) {
+ mChallengeTop = challengeTop;
+ KeyguardWidgetFrame frame = mKeyguardWidgetPager.getWidgetPageAt(mPageListeningToSlider);
+ if (frame != null && mLastScrollState != SlidingChallengeLayout.SCROLL_STATE_FADING) {
+ frame.adjustFrame(getChallengeTopRelativeToFrame(frame, mChallengeTop));
+ }
+ }
+
+ private Runnable mHideHintsRunnable = new Runnable() {
+ @Override
+ public void run() {
+ if (mKeyguardWidgetPager != null) {
+ mKeyguardWidgetPager.hideOutlinesAndSidePages();
+ }
+ }
+ };
+
+ public void showUsabilityHints() {
+ mMainQueue.postDelayed( new Runnable() {
+ @Override
+ public void run() {
+ mKeyguardSecurityContainer.showUsabilityHint();
+ }
+ } , SCREEN_ON_RING_HINT_DELAY);
+ mKeyguardWidgetPager.showInitialPageHints();
+ if (mHideHintsRunnable != null) {
+ mMainQueue.postDelayed(mHideHintsRunnable, SCREEN_ON_HINT_DURATION);
+ }
+ }
+
+ public void setTransportState(int state) {
+ mTransportState = state;
+ }
+
+ public int getTransportState() {
+ return mTransportState;
+ }
+
+ // ChallengeLayout.OnBouncerStateChangedListener
+ @Override
+ public void onBouncerStateChanged(boolean bouncerActive) {
+ if (bouncerActive) {
+ mKeyguardWidgetPager.zoomOutToBouncer();
+ } else {
+ mKeyguardWidgetPager.zoomInFromBouncer();
+ if (mKeyguardHostView != null) {
+ mKeyguardHostView.setOnDismissAction(null);
+ }
+ }
+ }
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardWidgetCarousel.java b/packages/Keyguard/src/com/android/keyguard/KeyguardWidgetCarousel.java
new file mode 100644
index 0000000..98b31b7
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardWidgetCarousel.java
@@ -0,0 +1,288 @@
+/*
+ * 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.keyguard;
+
+import android.animation.Animator;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
+import android.animation.PropertyValuesHolder;
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.animation.AccelerateInterpolator;
+import android.view.animation.DecelerateInterpolator;
+import android.view.animation.Interpolator;
+
+import java.util.ArrayList;
+
+public class KeyguardWidgetCarousel extends KeyguardWidgetPager {
+
+ private float mAdjacentPagesAngle;
+ private static float MAX_SCROLL_PROGRESS = 1.3f;
+ private static float CAMERA_DISTANCE = 10000;
+ protected AnimatorSet mChildrenTransformsAnimator;
+ float[] mTmpTransform = new float[3];
+
+ public KeyguardWidgetCarousel(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public KeyguardWidgetCarousel(Context context) {
+ this(context, null, 0);
+ }
+
+ public KeyguardWidgetCarousel(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ mAdjacentPagesAngle = context.getResources().getInteger(R.integer.kg_carousel_angle);
+ }
+
+ protected float getMaxScrollProgress() {
+ return MAX_SCROLL_PROGRESS;
+ }
+
+ public float getAlphaForPage(int screenCenter, int index, boolean showSidePages) {
+ View child = getChildAt(index);
+ if (child == null) return 0f;
+
+ boolean inVisibleRange = index >= getNextPage() - 1 && index <= getNextPage() + 1;
+ float scrollProgress = getScrollProgress(screenCenter, child, index);
+
+ if (isOverScrollChild(index, scrollProgress)) {
+ return 1.0f;
+ } else if ((showSidePages && inVisibleRange) || index == getNextPage()) {
+ scrollProgress = getBoundedScrollProgress(screenCenter, child, index);
+ float alpha = 1.0f - 1.0f * Math.abs(scrollProgress / MAX_SCROLL_PROGRESS);
+ return alpha;
+ } else {
+ return 0f;
+ }
+ }
+
+ public float getOutlineAlphaForPage(int screenCenter, int index, boolean showSidePages) {
+ boolean inVisibleRange = index >= getNextPage() - 1 && index <= getNextPage() + 1;
+ if (inVisibleRange) {
+ return super.getOutlineAlphaForPage(screenCenter, index, showSidePages);
+ } else {
+ return 0f;
+ }
+ }
+
+ private void updatePageAlphaValues(int screenCenter) {
+ if (mChildrenOutlineFadeAnimation != null) {
+ mChildrenOutlineFadeAnimation.cancel();
+ mChildrenOutlineFadeAnimation = null;
+ }
+ boolean showSidePages = mShowingInitialHints || isPageMoving();
+ if (!isReordering(false)) {
+ for (int i = 0; i < getChildCount(); i++) {
+ KeyguardWidgetFrame child = getWidgetPageAt(i);
+ if (child != null) {
+ float outlineAlpha = getOutlineAlphaForPage(screenCenter, i, showSidePages);
+ float contentAlpha = getAlphaForPage(screenCenter, i,showSidePages);
+ child.setBackgroundAlpha(outlineAlpha);
+ child.setContentAlpha(contentAlpha);
+ }
+ }
+ }
+ }
+
+ public void showInitialPageHints() {
+ mShowingInitialHints = true;
+ int count = getChildCount();
+ for (int i = 0; i < count; i++) {
+ boolean inVisibleRange = i >= getNextPage() - 1 && i <= getNextPage() + 1;
+ KeyguardWidgetFrame child = getWidgetPageAt(i);
+ if (inVisibleRange) {
+ child.setBackgroundAlpha(KeyguardWidgetFrame.OUTLINE_ALPHA_MULTIPLIER);
+ child.setContentAlpha(1f);
+ } else {
+ child.setBackgroundAlpha(0f);
+ child.setContentAlpha(0f);
+ }
+ }
+ }
+
+ @Override
+ protected void screenScrolled(int screenCenter) {
+ mScreenCenter = screenCenter;
+ updatePageAlphaValues(screenCenter);
+ if (isReordering(false)) return;
+ for (int i = 0; i < getChildCount(); i++) {
+ KeyguardWidgetFrame v = getWidgetPageAt(i);
+ float scrollProgress = getScrollProgress(screenCenter, v, i);
+ float boundedProgress = getBoundedScrollProgress(screenCenter, v, i);
+ if (v == mDragView || v == null) continue;
+ v.setCameraDistance(CAMERA_DISTANCE);
+
+ if (isOverScrollChild(i, scrollProgress)) {
+ v.setRotationY(- OVERSCROLL_MAX_ROTATION * scrollProgress);
+ v.setOverScrollAmount(Math.abs(scrollProgress), scrollProgress < 0);
+ } else {
+ int width = v.getMeasuredWidth();
+ float pivotX = (width / 2f) + boundedProgress * (width / 2f);
+ float pivotY = v.getMeasuredHeight() / 2;
+ float rotationY = - mAdjacentPagesAngle * boundedProgress;
+ v.setPivotX(pivotX);
+ v.setPivotY(pivotY);
+ v.setRotationY(rotationY);
+ v.setOverScrollAmount(0f, false);
+ }
+ float alpha = v.getAlpha();
+ // If the view has 0 alpha, we set it to be invisible so as to prevent
+ // it from accepting touches
+ if (alpha == 0) {
+ v.setVisibility(INVISIBLE);
+ } else if (v.getVisibility() != VISIBLE) {
+ v.setVisibility(VISIBLE);
+ }
+ }
+ }
+
+ void animatePagesToNeutral() {
+ if (mChildrenTransformsAnimator != null) {
+ mChildrenTransformsAnimator.cancel();
+ mChildrenTransformsAnimator = null;
+ }
+
+ int count = getChildCount();
+ PropertyValuesHolder alpha;
+ PropertyValuesHolder outlineAlpha;
+ PropertyValuesHolder rotationY;
+ ArrayList<Animator> anims = new ArrayList<Animator>();
+
+ for (int i = 0; i < count; i++) {
+ KeyguardWidgetFrame child = getWidgetPageAt(i);
+ boolean inVisibleRange = (i >= mCurrentPage - 1 && i <= mCurrentPage + 1);
+ if (!inVisibleRange) {
+ child.setRotationY(0f);
+ }
+ alpha = PropertyValuesHolder.ofFloat("contentAlpha", 1.0f);
+ outlineAlpha = PropertyValuesHolder.ofFloat("backgroundAlpha",
+ KeyguardWidgetFrame.OUTLINE_ALPHA_MULTIPLIER);
+ rotationY = PropertyValuesHolder.ofFloat("rotationY", 0f);
+ ObjectAnimator a = ObjectAnimator.ofPropertyValuesHolder(child, alpha, outlineAlpha, rotationY);
+ child.setVisibility(VISIBLE);
+ if (!inVisibleRange) {
+ a.setInterpolator(mSlowFadeInterpolator);
+ }
+ anims.add(a);
+ }
+
+ int duration = REORDERING_ZOOM_IN_OUT_DURATION;
+ mChildrenTransformsAnimator = new AnimatorSet();
+ mChildrenTransformsAnimator.playTogether(anims);
+
+ mChildrenTransformsAnimator.setDuration(duration);
+ mChildrenTransformsAnimator.start();
+ }
+
+ private void getTransformForPage(int screenCenter, int index, float[] transform) {
+ View child = getChildAt(index);
+ float boundedProgress = getBoundedScrollProgress(screenCenter, child, index);
+ float rotationY = - mAdjacentPagesAngle * boundedProgress;
+ int width = child.getMeasuredWidth();
+ float pivotX = (width / 2f) + boundedProgress * (width / 2f);
+ float pivotY = child.getMeasuredHeight() / 2;
+
+ transform[0] = pivotX;
+ transform[1] = pivotY;
+ transform[2] = rotationY;
+ }
+
+ Interpolator mFastFadeInterpolator = new Interpolator() {
+ Interpolator mInternal = new DecelerateInterpolator(1.5f);
+ float mFactor = 2.5f;
+ @Override
+ public float getInterpolation(float input) {
+ return mInternal.getInterpolation(Math.min(mFactor * input, 1f));
+ }
+ };
+
+ Interpolator mSlowFadeInterpolator = new Interpolator() {
+ Interpolator mInternal = new AccelerateInterpolator(1.5f);
+ float mFactor = 1.3f;
+ @Override
+ public float getInterpolation(float input) {
+ input -= (1 - 1 / mFactor);
+ input = mFactor * Math.max(input, 0f);
+ return mInternal.getInterpolation(input);
+ }
+ };
+
+ void animatePagesToCarousel() {
+ if (mChildrenTransformsAnimator != null) {
+ mChildrenTransformsAnimator.cancel();
+ mChildrenTransformsAnimator = null;
+ }
+
+ int count = getChildCount();
+ PropertyValuesHolder alpha;
+ PropertyValuesHolder outlineAlpha;
+ PropertyValuesHolder rotationY;
+ PropertyValuesHolder pivotX;
+ PropertyValuesHolder pivotY;
+ ArrayList<Animator> anims = new ArrayList<Animator>();
+
+ for (int i = 0; i < count; i++) {
+ KeyguardWidgetFrame child = getWidgetPageAt(i);
+ float finalAlpha = getAlphaForPage(mScreenCenter, i, true);
+ float finalOutlineAlpha = getOutlineAlphaForPage(mScreenCenter, i, true);
+ getTransformForPage(mScreenCenter, i, mTmpTransform);
+
+ boolean inVisibleRange = (i >= mCurrentPage - 1 && i <= mCurrentPage + 1);
+
+ ObjectAnimator a;
+ alpha = PropertyValuesHolder.ofFloat("contentAlpha", finalAlpha);
+ outlineAlpha = PropertyValuesHolder.ofFloat("backgroundAlpha", finalOutlineAlpha);
+ pivotX = PropertyValuesHolder.ofFloat("pivotX", mTmpTransform[0]);
+ pivotY = PropertyValuesHolder.ofFloat("pivotY", mTmpTransform[1]);
+ rotationY = PropertyValuesHolder.ofFloat("rotationY", mTmpTransform[2]);
+
+ if (inVisibleRange) {
+ // for the central pages we animate into a rotated state
+ a = ObjectAnimator.ofPropertyValuesHolder(child, alpha, outlineAlpha,
+ pivotX, pivotY, rotationY);
+ } else {
+ a = ObjectAnimator.ofPropertyValuesHolder(child, alpha, outlineAlpha);
+ a.setInterpolator(mFastFadeInterpolator);
+ }
+ anims.add(a);
+ }
+
+ int duration = REORDERING_ZOOM_IN_OUT_DURATION;
+ mChildrenTransformsAnimator = new AnimatorSet();
+ mChildrenTransformsAnimator.playTogether(anims);
+
+ mChildrenTransformsAnimator.setDuration(duration);
+ mChildrenTransformsAnimator.start();
+ }
+
+ protected void reorderStarting() {
+ mViewStateManager.fadeOutSecurity(REORDERING_ZOOM_IN_OUT_DURATION);
+ animatePagesToNeutral();
+ }
+
+ protected boolean zoomIn(final Runnable onCompleteRunnable) {
+ animatePagesToCarousel();
+ return super.zoomIn(onCompleteRunnable);
+ }
+
+ @Override
+ protected void onEndReordering() {
+ super.onEndReordering();
+ mViewStateManager.fadeInSecurity(REORDERING_ZOOM_IN_OUT_DURATION);
+ }
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardWidgetFrame.java b/packages/Keyguard/src/com/android/keyguard/KeyguardWidgetFrame.java
new file mode 100644
index 0000000..81f6221
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardWidgetFrame.java
@@ -0,0 +1,527 @@
+/*
+ * 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.keyguard;
+
+import android.animation.Animator;
+import android.animation.ObjectAnimator;
+import android.animation.PropertyValuesHolder;
+import android.appwidget.AppWidgetHostView;
+import android.appwidget.AppWidgetManager;
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Canvas;
+import android.graphics.LinearGradient;
+import android.graphics.Paint;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffXfermode;
+import android.graphics.Rect;
+import android.graphics.Shader;
+import android.graphics.drawable.Drawable;
+import android.os.Handler;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.view.View;
+import android.widget.FrameLayout;
+
+public class KeyguardWidgetFrame extends FrameLayout {
+ private final static PorterDuffXfermode sAddBlendMode =
+ new PorterDuffXfermode(PorterDuff.Mode.ADD);
+
+ static final float OUTLINE_ALPHA_MULTIPLIER = 0.6f;
+ static final int HOVER_OVER_DELETE_DROP_TARGET_OVERLAY_COLOR = 0x99FF0000;
+
+ // Temporarily disable this for the time being until we know why the gfx is messing up
+ static final boolean ENABLE_HOVER_OVER_DELETE_DROP_TARGET_OVERLAY = true;
+
+ private int mGradientColor;
+ private LinearGradient mForegroundGradient;
+ private LinearGradient mLeftToRightGradient;
+ private LinearGradient mRightToLeftGradient;
+ private Paint mGradientPaint = new Paint();
+ boolean mLeftToRight = true;
+
+ private float mOverScrollAmount = 0f;
+ private final Rect mForegroundRect = new Rect();
+ private int mForegroundAlpha = 0;
+ private CheckLongPressHelper mLongPressHelper;
+ private Animator mFrameFade;
+ private boolean mIsSmall = false;
+ private Handler mWorkerHandler;
+
+ private float mBackgroundAlpha;
+ private float mContentAlpha;
+ private float mBackgroundAlphaMultiplier = 1.0f;
+ private Drawable mBackgroundDrawable;
+ private Rect mBackgroundRect = new Rect();
+
+ // These variables are all needed in order to size things properly before we're actually
+ // measured.
+ private int mSmallWidgetHeight;
+ private int mSmallFrameHeight;
+ private boolean mWidgetLockedSmall = false;
+ private int mMaxChallengeTop = -1;
+ private int mFrameStrokeAdjustment;
+ private boolean mPerformAppWidgetSizeUpdateOnBootComplete;
+
+ // This will hold the width value before we've actually been measured
+ private int mFrameHeight;
+
+ private boolean mIsHoveringOverDeleteDropTarget;
+
+ // Multiple callers may try and adjust the alpha of the frame. When a caller shows
+ // the outlines, we give that caller control, and nobody else can fade them out.
+ // This prevents animation conflicts.
+ private Object mBgAlphaController;
+
+ public KeyguardWidgetFrame(Context context) {
+ this(context, null, 0);
+ }
+
+ public KeyguardWidgetFrame(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public KeyguardWidgetFrame(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+
+ mLongPressHelper = new CheckLongPressHelper(this);
+
+ Resources res = context.getResources();
+ // TODO: this padding should really correspond to the padding embedded in the background
+ // drawable (ie. outlines).
+ float density = res.getDisplayMetrics().density;
+ int padding = (int) (res.getDisplayMetrics().density * 8);
+ setPadding(padding, padding, padding, padding);
+
+ mFrameStrokeAdjustment = 2 + (int) (2 * density);
+
+ // This will be overriden on phones based on the current security mode, however on tablets
+ // we need to specify a height.
+ mSmallWidgetHeight =
+ res.getDimensionPixelSize(R.dimen.kg_small_widget_height);
+ mBackgroundDrawable = res.getDrawable(R.drawable.kg_widget_bg_padded);
+ mGradientColor = res.getColor(R.color.kg_widget_pager_gradient);
+ mGradientPaint.setXfermode(sAddBlendMode);
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ cancelLongPress();
+ KeyguardUpdateMonitor.getInstance(mContext).removeCallback(mUpdateMonitorCallbacks);
+
+ }
+
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mUpdateMonitorCallbacks);
+ }
+
+ private KeyguardUpdateMonitorCallback mUpdateMonitorCallbacks =
+ new KeyguardUpdateMonitorCallback() {
+ @Override
+ public void onBootCompleted() {
+ if (mPerformAppWidgetSizeUpdateOnBootComplete) {
+ performAppWidgetSizeCallbacksIfNecessary();
+ mPerformAppWidgetSizeUpdateOnBootComplete = false;
+ }
+ }
+ };
+
+ void setIsHoveringOverDeleteDropTarget(boolean isHovering) {
+ if (ENABLE_HOVER_OVER_DELETE_DROP_TARGET_OVERLAY) {
+ if (mIsHoveringOverDeleteDropTarget != isHovering) {
+ mIsHoveringOverDeleteDropTarget = isHovering;
+ invalidate();
+ }
+ }
+ }
+
+ @Override
+ public boolean onInterceptTouchEvent(MotionEvent ev) {
+ // Watch for longpress events at this level to make sure
+ // users can always pick up this widget
+ switch (ev.getAction()) {
+ case MotionEvent.ACTION_DOWN:
+ mLongPressHelper.postCheckForLongPress(ev);
+ break;
+ case MotionEvent.ACTION_MOVE:
+ mLongPressHelper.onMove(ev);
+ break;
+ case MotionEvent.ACTION_POINTER_DOWN:
+ case MotionEvent.ACTION_UP:
+ case MotionEvent.ACTION_CANCEL:
+ mLongPressHelper.cancelLongPress();
+ break;
+ }
+
+ // Otherwise continue letting touch events fall through to children
+ return false;
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent ev) {
+ // Watch for longpress events at this level to make sure
+ // users can always pick up this widget
+ switch (ev.getAction()) {
+ case MotionEvent.ACTION_MOVE:
+ mLongPressHelper.onMove(ev);
+ break;
+ case MotionEvent.ACTION_POINTER_DOWN:
+ case MotionEvent.ACTION_UP:
+ case MotionEvent.ACTION_CANCEL:
+ mLongPressHelper.cancelLongPress();
+ break;
+ }
+
+ // We return true here to ensure that we will get cancel / up signal
+ // even if none of our children have requested touch.
+ return true;
+ }
+
+ @Override
+ public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) {
+ super.requestDisallowInterceptTouchEvent(disallowIntercept);
+ cancelLongPress();
+ }
+
+ @Override
+ public void cancelLongPress() {
+ super.cancelLongPress();
+ mLongPressHelper.cancelLongPress();
+ }
+
+
+ private void drawGradientOverlay(Canvas c) {
+ mGradientPaint.setShader(mForegroundGradient);
+ mGradientPaint.setAlpha(mForegroundAlpha);
+ c.drawRect(mForegroundRect, mGradientPaint);
+ }
+
+ private void drawHoveringOverDeleteOverlay(Canvas c) {
+ if (mIsHoveringOverDeleteDropTarget) {
+ c.drawColor(HOVER_OVER_DELETE_DROP_TARGET_OVERLAY_COLOR);
+ }
+ }
+
+ protected void drawBg(Canvas canvas) {
+ if (mBackgroundAlpha > 0.0f) {
+ Drawable bg = mBackgroundDrawable;
+
+ bg.setAlpha((int) (mBackgroundAlpha * mBackgroundAlphaMultiplier * 255));
+ bg.setBounds(mBackgroundRect);
+ bg.draw(canvas);
+ }
+ }
+
+ @Override
+ protected void dispatchDraw(Canvas canvas) {
+ if (ENABLE_HOVER_OVER_DELETE_DROP_TARGET_OVERLAY) {
+ canvas.save();
+ }
+ drawBg(canvas);
+ super.dispatchDraw(canvas);
+ drawGradientOverlay(canvas);
+ if (ENABLE_HOVER_OVER_DELETE_DROP_TARGET_OVERLAY) {
+ drawHoveringOverDeleteOverlay(canvas);
+ canvas.restore();
+ }
+ }
+
+ /**
+ * Because this view has fading outlines, it is essential that we enable hardware
+ * layers on the content (child) so that updating the alpha of the outlines doesn't
+ * result in the content layer being recreated.
+ */
+ public void enableHardwareLayersForContent() {
+ View widget = getContent();
+ if (widget != null) {
+ widget.setLayerType(LAYER_TYPE_HARDWARE, null);
+ }
+ }
+
+ /**
+ * Because this view has fading outlines, it is essential that we enable hardware
+ * layers on the content (child) so that updating the alpha of the outlines doesn't
+ * result in the content layer being recreated.
+ */
+ public void disableHardwareLayersForContent() {
+ View widget = getContent();
+ if (widget != null) {
+ widget.setLayerType(LAYER_TYPE_NONE, null);
+ }
+ }
+
+ public void enableHardwareLayers() {
+ setLayerType(LAYER_TYPE_HARDWARE, null);
+ }
+
+ public void disableHardwareLayers() {
+ setLayerType(LAYER_TYPE_NONE, null);
+ }
+
+ public View getContent() {
+ return getChildAt(0);
+ }
+
+ public int getContentAppWidgetId() {
+ View content = getContent();
+ if (content instanceof AppWidgetHostView) {
+ return ((AppWidgetHostView) content).getAppWidgetId();
+ } else if (content instanceof KeyguardStatusView) {
+ return ((KeyguardStatusView) content).getAppWidgetId();
+ } else {
+ return AppWidgetManager.INVALID_APPWIDGET_ID;
+ }
+ }
+
+ public float getBackgroundAlpha() {
+ return mBackgroundAlpha;
+ }
+
+ public void setBackgroundAlphaMultiplier(float multiplier) {
+ if (Float.compare(mBackgroundAlphaMultiplier, multiplier) != 0) {
+ mBackgroundAlphaMultiplier = multiplier;
+ invalidate();
+ }
+ }
+
+ public float getBackgroundAlphaMultiplier() {
+ return mBackgroundAlphaMultiplier;
+ }
+
+ public void setBackgroundAlpha(float alpha) {
+ if (Float.compare(mBackgroundAlpha, alpha) != 0) {
+ mBackgroundAlpha = alpha;
+ invalidate();
+ }
+ }
+
+ public float getContentAlpha() {
+ return mContentAlpha;
+ }
+
+ public void setContentAlpha(float alpha) {
+ mContentAlpha = alpha;
+ View content = getContent();
+ if (content != null) {
+ content.setAlpha(alpha);
+ }
+ }
+
+ /**
+ * Depending on whether the security is up, the widget size needs to change
+ *
+ * @param height The height of the widget, -1 for full height
+ */
+ private void setWidgetHeight(int height) {
+ boolean needLayout = false;
+ View widget = getContent();
+ if (widget != null) {
+ LayoutParams lp = (LayoutParams) widget.getLayoutParams();
+ if (lp.height != height) {
+ needLayout = true;
+ lp.height = height;
+ }
+ }
+ if (needLayout) {
+ requestLayout();
+ }
+ }
+
+ public void setMaxChallengeTop(int top) {
+ boolean dirty = mMaxChallengeTop != top;
+ mMaxChallengeTop = top;
+ mSmallWidgetHeight = top - getPaddingTop();
+ mSmallFrameHeight = top + getPaddingBottom();
+ if (dirty && mIsSmall) {
+ setWidgetHeight(mSmallWidgetHeight);
+ setFrameHeight(mSmallFrameHeight);
+ } else if (dirty && mWidgetLockedSmall) {
+ setWidgetHeight(mSmallWidgetHeight);
+ }
+ }
+
+ public boolean isSmall() {
+ return mIsSmall;
+ }
+
+ public void adjustFrame(int challengeTop) {
+ int frameHeight = challengeTop + getPaddingBottom();
+ setFrameHeight(frameHeight);
+ }
+
+ public void shrinkWidget(boolean alsoShrinkFrame) {
+ mIsSmall = true;
+ setWidgetHeight(mSmallWidgetHeight);
+
+ if (alsoShrinkFrame) {
+ setFrameHeight(mSmallFrameHeight);
+ }
+ }
+
+ public int getSmallFrameHeight() {
+ return mSmallFrameHeight;
+ }
+
+ public void shrinkWidget() {
+ shrinkWidget(true);
+ }
+
+ public void setWidgetLockedSmall(boolean locked) {
+ if (locked) {
+ setWidgetHeight(mSmallWidgetHeight);
+ }
+ mWidgetLockedSmall = locked;
+ }
+
+ public void resetSize() {
+ mIsSmall = false;
+ if (!mWidgetLockedSmall) {
+ setWidgetHeight(LayoutParams.MATCH_PARENT);
+ }
+ setFrameHeight(getMeasuredHeight());
+ }
+
+ public void setFrameHeight(int height) {
+ mFrameHeight = height;
+ mBackgroundRect.set(0, 0, getMeasuredWidth(), Math.min(mFrameHeight, getMeasuredHeight()));
+ mForegroundRect.set(mFrameStrokeAdjustment, mFrameStrokeAdjustment,getMeasuredWidth() -
+ mFrameStrokeAdjustment, Math.min(getMeasuredHeight(), mFrameHeight) -
+ mFrameStrokeAdjustment);
+ updateGradient();
+ invalidate();
+ }
+
+ public void hideFrame(Object caller) {
+ fadeFrame(caller, false, 0f, KeyguardWidgetPager.CHILDREN_OUTLINE_FADE_OUT_DURATION);
+ }
+
+ public void showFrame(Object caller) {
+ fadeFrame(caller, true, OUTLINE_ALPHA_MULTIPLIER,
+ KeyguardWidgetPager.CHILDREN_OUTLINE_FADE_IN_DURATION);
+ }
+
+ public void fadeFrame(Object caller, boolean takeControl, float alpha, int duration) {
+ if (takeControl) {
+ mBgAlphaController = caller;
+ }
+
+ if (mBgAlphaController != caller && mBgAlphaController != null) {
+ return;
+ }
+
+ if (mFrameFade != null) {
+ mFrameFade.cancel();
+ mFrameFade = null;
+ }
+ PropertyValuesHolder bgAlpha = PropertyValuesHolder.ofFloat("backgroundAlpha", alpha);
+ mFrameFade = ObjectAnimator.ofPropertyValuesHolder(this, bgAlpha);
+ mFrameFade.setDuration(duration);
+ mFrameFade.start();
+ }
+
+ private void updateGradient() {
+ float x0 = mLeftToRight ? 0 : mForegroundRect.width();
+ float x1 = mLeftToRight ? mForegroundRect.width(): 0;
+ mLeftToRightGradient = new LinearGradient(x0, 0f, x1, 0f,
+ mGradientColor, 0, Shader.TileMode.CLAMP);
+ mRightToLeftGradient = new LinearGradient(x1, 0f, x0, 0f,
+ mGradientColor, 0, Shader.TileMode.CLAMP);
+ }
+
+ @Override
+ protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+ super.onSizeChanged(w, h, oldw, oldh);
+
+ if (!mIsSmall) {
+ mFrameHeight = h;
+ }
+
+ // mFrameStrokeAdjustment is a cludge to prevent the overlay from drawing outside the
+ // rounded rect background.
+ mForegroundRect.set(mFrameStrokeAdjustment, mFrameStrokeAdjustment,
+ w - mFrameStrokeAdjustment, Math.min(h, mFrameHeight) - mFrameStrokeAdjustment);
+
+ mBackgroundRect.set(0, 0, getMeasuredWidth(), Math.min(h, mFrameHeight));
+ updateGradient();
+ invalidate();
+ }
+
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ performAppWidgetSizeCallbacksIfNecessary();
+ }
+
+ private void performAppWidgetSizeCallbacksIfNecessary() {
+ View content = getContent();
+ if (!(content instanceof AppWidgetHostView)) return;
+
+ if (!KeyguardUpdateMonitor.getInstance(mContext).hasBootCompleted()) {
+ mPerformAppWidgetSizeUpdateOnBootComplete = true;
+ return;
+ }
+
+ // TODO: there's no reason to force the AppWidgetHostView to catch duplicate size calls.
+ // We can do that even more cheaply here. It's not an issue right now since we're in the
+ // system process and hence no binder calls.
+ AppWidgetHostView awhv = (AppWidgetHostView) content;
+ float density = getResources().getDisplayMetrics().density;
+
+ int width = (int) (content.getMeasuredWidth() / density);
+ int height = (int) (content.getMeasuredHeight() / density);
+ awhv.updateAppWidgetSize(null, width, height, width, height, true);
+ }
+
+ void setOverScrollAmount(float r, boolean left) {
+ if (Float.compare(mOverScrollAmount, r) != 0) {
+ mOverScrollAmount = r;
+ mForegroundGradient = left ? mLeftToRightGradient : mRightToLeftGradient;
+ mForegroundAlpha = (int) Math.round((0.5f * r * 255));
+
+ // We bump up the alpha of the outline to hide the fact that the overlay is drawing
+ // over the rounded part of the frame.
+ float bgAlpha = Math.min(OUTLINE_ALPHA_MULTIPLIER + r * (1 - OUTLINE_ALPHA_MULTIPLIER),
+ 1f);
+ setBackgroundAlpha(bgAlpha);
+ invalidate();
+ }
+ }
+
+ public void onActive(boolean isActive) {
+ // hook for subclasses
+ }
+
+ public boolean onUserInteraction(MotionEvent event) {
+ // hook for subclasses
+ return false;
+ }
+
+ public void onBouncerShowing(boolean showing) {
+ // hook for subclasses
+ }
+
+ public void setWorkerHandler(Handler workerHandler) {
+ mWorkerHandler = workerHandler;
+ }
+
+ public Handler getWorkerHandler() {
+ return mWorkerHandler;
+ }
+
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardWidgetPager.java b/packages/Keyguard/src/com/android/keyguard/KeyguardWidgetPager.java
new file mode 100644
index 0000000..0d92e11
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardWidgetPager.java
@@ -0,0 +1,920 @@
+/*
+ * 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.keyguard;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
+import android.animation.PropertyValuesHolder;
+import android.animation.TimeInterpolator;
+import android.appwidget.AppWidgetHostView;
+import android.appwidget.AppWidgetManager;
+import android.appwidget.AppWidgetProviderInfo;
+import android.content.Context;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.text.format.DateFormat;
+import android.util.AttributeSet;
+import android.util.Slog;
+import android.view.Gravity;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.View.OnLongClickListener;
+import android.view.ViewGroup;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityManager;
+import android.view.animation.DecelerateInterpolator;
+import android.widget.FrameLayout;
+import android.widget.TextClock;
+
+import com.android.internal.widget.LockPatternUtils;
+
+import java.util.ArrayList;
+import java.util.TimeZone;
+
+public class KeyguardWidgetPager extends PagedView implements PagedView.PageSwitchListener,
+ OnLongClickListener, ChallengeLayout.OnBouncerStateChangedListener {
+
+ ZInterpolator mZInterpolator = new ZInterpolator(0.5f);
+ private static float CAMERA_DISTANCE = 10000;
+ protected static float OVERSCROLL_MAX_ROTATION = 30;
+ private static final boolean PERFORM_OVERSCROLL_ROTATION = true;
+
+ private static final int FLAG_HAS_LOCAL_HOUR = 0x1;
+ private static final int FLAG_HAS_LOCAL_MINUTE = 0x2;
+
+ protected KeyguardViewStateManager mViewStateManager;
+ private LockPatternUtils mLockPatternUtils;
+
+ // Related to the fading in / out background outlines
+ public static final int CHILDREN_OUTLINE_FADE_OUT_DURATION = 375;
+ public static final int CHILDREN_OUTLINE_FADE_IN_DURATION = 100;
+ protected AnimatorSet mChildrenOutlineFadeAnimation;
+ protected int mScreenCenter;
+ private boolean mHasMeasure = false;
+ boolean showHintsAfterLayout = false;
+
+ private static final long CUSTOM_WIDGET_USER_ACTIVITY_TIMEOUT = 30000;
+ private static final String TAG = "KeyguardWidgetPager";
+ private boolean mCenterSmallWidgetsVertically;
+
+ private int mPage = 0;
+ private Callbacks mCallbacks;
+
+ private int mWidgetToResetAfterFadeOut;
+ protected boolean mShowingInitialHints = false;
+
+ // A temporary handle to the Add-Widget view
+ private View mAddWidgetView;
+ private int mLastWidthMeasureSpec;
+ private int mLastHeightMeasureSpec;
+
+ // Bouncer
+ private int mBouncerZoomInOutDuration = 250;
+ private float BOUNCER_SCALE_FACTOR = 0.67f;
+
+ // Background worker thread: used here for persistence, also made available to widget frames
+ private final HandlerThread mBackgroundWorkerThread;
+ private final Handler mBackgroundWorkerHandler;
+
+ public KeyguardWidgetPager(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public KeyguardWidgetPager(Context context) {
+ this(null, null, 0);
+ }
+
+ public KeyguardWidgetPager(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ if (getImportantForAccessibility() == View.IMPORTANT_FOR_ACCESSIBILITY_AUTO) {
+ setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);
+ }
+
+ setPageSwitchListener(this);
+
+ mBackgroundWorkerThread = new HandlerThread("KeyguardWidgetPager Worker");
+ mBackgroundWorkerThread.start();
+ mBackgroundWorkerHandler = new Handler(mBackgroundWorkerThread.getLooper());
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+
+ // Clean up the worker thread
+ mBackgroundWorkerThread.quit();
+ }
+
+ public void setViewStateManager(KeyguardViewStateManager viewStateManager) {
+ mViewStateManager = viewStateManager;
+ }
+
+ public void setLockPatternUtils(LockPatternUtils l) {
+ mLockPatternUtils = l;
+ }
+
+ @Override
+ public void onPageSwitching(View newPage, int newPageIndex) {
+ if (mViewStateManager != null) {
+ mViewStateManager.onPageSwitching(newPage, newPageIndex);
+ }
+ }
+
+ @Override
+ public void onPageSwitched(View newPage, int newPageIndex) {
+ boolean showingClock = false;
+ if (newPage instanceof ViewGroup) {
+ ViewGroup vg = (ViewGroup) newPage;
+ if (vg.getChildAt(0) instanceof KeyguardStatusView) {
+ showingClock = true;
+ }
+ }
+
+ if (newPage != null &&
+ findClockInHierarchy(newPage) == (FLAG_HAS_LOCAL_HOUR | FLAG_HAS_LOCAL_MINUTE)) {
+ showingClock = true;
+ }
+
+ // Disable the status bar clock if we're showing the default status widget
+ if (showingClock) {
+ setSystemUiVisibility(getSystemUiVisibility() | View.STATUS_BAR_DISABLE_CLOCK);
+ } else {
+ setSystemUiVisibility(getSystemUiVisibility() & ~View.STATUS_BAR_DISABLE_CLOCK);
+ }
+
+ // Extend the display timeout if the user switches pages
+ if (mPage != newPageIndex) {
+ int oldPageIndex = mPage;
+ mPage = newPageIndex;
+ userActivity();
+ KeyguardWidgetFrame oldWidgetPage = getWidgetPageAt(oldPageIndex);
+ if (oldWidgetPage != null) {
+ oldWidgetPage.onActive(false);
+ }
+ KeyguardWidgetFrame newWidgetPage = getWidgetPageAt(newPageIndex);
+ if (newWidgetPage != null) {
+ newWidgetPage.onActive(true);
+ newWidgetPage.requestAccessibilityFocus();
+ }
+ if (mParent != null && AccessibilityManager.getInstance(mContext).isEnabled()) {
+ AccessibilityEvent event = AccessibilityEvent.obtain(
+ AccessibilityEvent.TYPE_VIEW_SCROLLED);
+ onInitializeAccessibilityEvent(event);
+ onPopulateAccessibilityEvent(event);
+ mParent.requestSendAccessibilityEvent(this, event);
+ }
+ }
+ if (mViewStateManager != null) {
+ mViewStateManager.onPageSwitched(newPage, newPageIndex);
+ }
+ }
+
+ @Override
+ public void sendAccessibilityEvent(int eventType) {
+ if (eventType != AccessibilityEvent.TYPE_VIEW_SCROLLED || isPageMoving()) {
+ super.sendAccessibilityEvent(eventType);
+ }
+ }
+
+ private void updateWidgetFramesImportantForAccessibility() {
+ final int pageCount = getPageCount();
+ for (int i = 0; i < pageCount; i++) {
+ KeyguardWidgetFrame frame = getWidgetPageAt(i);
+ updateWidgetFrameImportantForAccessibility(frame);
+ }
+ }
+
+ private void updateWidgetFrameImportantForAccessibility(KeyguardWidgetFrame frame) {
+ if (frame.getContentAlpha() <= 0) {
+ frame.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO);
+ } else {
+ frame.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);
+ }
+ }
+
+ private void userActivity() {
+ if (mCallbacks != null) {
+ mCallbacks.onUserActivityTimeoutChanged();
+ mCallbacks.userActivity();
+ }
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent ev) {
+ return captureUserInteraction(ev) || super.onTouchEvent(ev);
+ }
+
+ @Override
+ public boolean onInterceptTouchEvent(MotionEvent ev) {
+ return captureUserInteraction(ev) || super.onInterceptTouchEvent(ev);
+ }
+
+ private boolean captureUserInteraction(MotionEvent ev) {
+ KeyguardWidgetFrame currentWidgetPage = getWidgetPageAt(getCurrentPage());
+ return currentWidgetPage != null && currentWidgetPage.onUserInteraction(ev);
+ }
+
+ public void showPagingFeedback() {
+ // Nothing yet.
+ }
+
+ public long getUserActivityTimeout() {
+ View page = getPageAt(mPage);
+ if (page instanceof ViewGroup) {
+ ViewGroup vg = (ViewGroup) page;
+ View view = vg.getChildAt(0);
+ if (!(view instanceof KeyguardStatusView)
+ && !(view instanceof KeyguardMultiUserSelectorView)) {
+ return CUSTOM_WIDGET_USER_ACTIVITY_TIMEOUT;
+ }
+ }
+ return -1;
+ }
+
+ public void setCallbacks(Callbacks callbacks) {
+ mCallbacks = callbacks;
+ }
+
+ public interface Callbacks {
+ public void userActivity();
+ public void onUserActivityTimeoutChanged();
+ public void onAddView(View v);
+ public void onRemoveView(View v, boolean deletePermanently);
+ public void onRemoveViewAnimationCompleted();
+ }
+
+ public void addWidget(View widget) {
+ addWidget(widget, -1);
+ }
+
+ public void onRemoveView(View v, final boolean deletePermanently) {
+ final int appWidgetId = ((KeyguardWidgetFrame) v).getContentAppWidgetId();
+ if (mCallbacks != null) {
+ mCallbacks.onRemoveView(v, deletePermanently);
+ }
+ mBackgroundWorkerHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ mLockPatternUtils.removeAppWidget(appWidgetId);
+ }
+ });
+ }
+
+ @Override
+ public void onRemoveViewAnimationCompleted() {
+ if (mCallbacks != null) {
+ mCallbacks.onRemoveViewAnimationCompleted();
+ }
+ }
+
+ public void onAddView(View v, final int index) {
+ final int appWidgetId = ((KeyguardWidgetFrame) v).getContentAppWidgetId();
+ final int[] pagesRange = new int[mTempVisiblePagesRange.length];
+ getVisiblePages(pagesRange);
+ boundByReorderablePages(true, pagesRange);
+ if (mCallbacks != null) {
+ mCallbacks.onAddView(v);
+ }
+ // Subtract from the index to take into account pages before the reorderable
+ // pages (e.g. the "add widget" page)
+ mBackgroundWorkerHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ mLockPatternUtils.addAppWidget(appWidgetId, index - pagesRange[0]);
+ }
+ });
+ }
+
+ /*
+ * We wrap widgets in a special frame which handles drawing the over scroll foreground.
+ */
+ public void addWidget(View widget, int pageIndex) {
+ KeyguardWidgetFrame frame;
+ // All views contained herein should be wrapped in a KeyguardWidgetFrame
+ if (!(widget instanceof KeyguardWidgetFrame)) {
+ frame = new KeyguardWidgetFrame(getContext());
+ FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT,
+ LayoutParams.MATCH_PARENT);
+ lp.gravity = Gravity.TOP;
+
+ // The framework adds a default padding to AppWidgetHostView. We don't need this padding
+ // for the Keyguard, so we override it to be 0.
+ widget.setPadding(0, 0, 0, 0);
+ frame.addView(widget, lp);
+
+ // We set whether or not this widget supports vertical resizing.
+ if (widget instanceof AppWidgetHostView) {
+ AppWidgetHostView awhv = (AppWidgetHostView) widget;
+ AppWidgetProviderInfo info = awhv.getAppWidgetInfo();
+ if ((info.resizeMode & AppWidgetProviderInfo.RESIZE_VERTICAL) != 0) {
+ frame.setWidgetLockedSmall(false);
+ } else {
+ // Lock the widget to be small.
+ frame.setWidgetLockedSmall(true);
+ if (mCenterSmallWidgetsVertically) {
+ lp.gravity = Gravity.CENTER;
+ }
+ }
+ }
+ } else {
+ frame = (KeyguardWidgetFrame) widget;
+ }
+
+ ViewGroup.LayoutParams pageLp = new ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
+ frame.setOnLongClickListener(this);
+ frame.setWorkerHandler(mBackgroundWorkerHandler);
+
+ if (pageIndex == -1) {
+ addView(frame, pageLp);
+ } else {
+ addView(frame, pageIndex, pageLp);
+ }
+
+ // Update the frame content description.
+ View content = (widget == frame) ? frame.getContent() : widget;
+ if (content != null) {
+ String contentDescription = mContext.getString(
+ R.string.keyguard_accessibility_widget,
+ content.getContentDescription());
+ frame.setContentDescription(contentDescription);
+ }
+ updateWidgetFrameImportantForAccessibility(frame);
+ }
+
+ /**
+ * Use addWidget() instead.
+ * @deprecated
+ */
+ @Override
+ public void addView(View child, int index) {
+ enforceKeyguardWidgetFrame(child);
+ super.addView(child, index);
+ }
+
+ /**
+ * Use addWidget() instead.
+ * @deprecated
+ */
+ @Override
+ public void addView(View child, int width, int height) {
+ enforceKeyguardWidgetFrame(child);
+ super.addView(child, width, height);
+ }
+
+ /**
+ * Use addWidget() instead.
+ * @deprecated
+ */
+ @Override
+ public void addView(View child, LayoutParams params) {
+ enforceKeyguardWidgetFrame(child);
+ super.addView(child, params);
+ }
+
+ /**
+ * Use addWidget() instead.
+ * @deprecated
+ */
+ @Override
+ public void addView(View child, int index, LayoutParams params) {
+ enforceKeyguardWidgetFrame(child);
+ super.addView(child, index, params);
+ }
+
+ private void enforceKeyguardWidgetFrame(View child) {
+ if (!(child instanceof KeyguardWidgetFrame)) {
+ throw new IllegalArgumentException(
+ "KeyguardWidgetPager children must be KeyguardWidgetFrames");
+ }
+ }
+
+ public KeyguardWidgetFrame getWidgetPageAt(int index) {
+ // This is always a valid cast as we've guarded the ability to
+ return (KeyguardWidgetFrame) getChildAt(index);
+ }
+
+ protected void onUnhandledTap(MotionEvent ev) {
+ showPagingFeedback();
+ }
+
+ @Override
+ protected void onPageBeginMoving() {
+ if (mViewStateManager != null) {
+ mViewStateManager.onPageBeginMoving();
+ }
+ if (!isReordering(false)) {
+ showOutlinesAndSidePages();
+ }
+ userActivity();
+ }
+
+ @Override
+ protected void onPageEndMoving() {
+ if (mViewStateManager != null) {
+ mViewStateManager.onPageEndMoving();
+ }
+
+ // In the reordering case, the pages will be faded appropriately on completion
+ // of the zoom in animation.
+ if (!isReordering(false)) {
+ hideOutlinesAndSidePages();
+ }
+ }
+
+ protected void enablePageContentLayers() {
+ int children = getChildCount();
+ for (int i = 0; i < children; i++) {
+ getWidgetPageAt(i).enableHardwareLayersForContent();
+ }
+ }
+
+ protected void disablePageContentLayers() {
+ int children = getChildCount();
+ for (int i = 0; i < children; i++) {
+ getWidgetPageAt(i).disableHardwareLayersForContent();
+ }
+ }
+
+ /*
+ * This interpolator emulates the rate at which the perceived scale of an object changes
+ * as its distance from a camera increases. When this interpolator is applied to a scale
+ * animation on a view, it evokes the sense that the object is shrinking due to moving away
+ * from the camera.
+ */
+ static class ZInterpolator implements TimeInterpolator {
+ private float focalLength;
+
+ public ZInterpolator(float foc) {
+ focalLength = foc;
+ }
+
+ public float getInterpolation(float input) {
+ return (1.0f - focalLength / (focalLength + input)) /
+ (1.0f - focalLength / (focalLength + 1.0f));
+ }
+ }
+
+ @Override
+ protected void overScroll(float amount) {
+ acceleratedOverScroll(amount);
+ }
+
+ float backgroundAlphaInterpolator(float r) {
+ return Math.min(1f, r);
+ }
+
+ private void updatePageAlphaValues(int screenCenter) {
+ }
+
+ public float getAlphaForPage(int screenCenter, int index, boolean showSidePages) {
+ if (showSidePages) {
+ return 1f;
+ } else {
+ return index == mCurrentPage ? 1.0f : 0f;
+ }
+ }
+
+ public float getOutlineAlphaForPage(int screenCenter, int index, boolean showSidePages) {
+ if (showSidePages) {
+ return getAlphaForPage(screenCenter, index, showSidePages)
+ * KeyguardWidgetFrame.OUTLINE_ALPHA_MULTIPLIER;
+ } else {
+ return 0f;
+ }
+ }
+
+ protected boolean isOverScrollChild(int index, float scrollProgress) {
+ boolean isInOverscroll = mOverScrollX < 0 || mOverScrollX > mMaxScrollX;
+ return (isInOverscroll && (index == 0 && scrollProgress < 0 ||
+ index == getChildCount() - 1 && scrollProgress > 0));
+ }
+
+ @Override
+ protected void screenScrolled(int screenCenter) {
+ mScreenCenter = screenCenter;
+ updatePageAlphaValues(screenCenter);
+ for (int i = 0; i < getChildCount(); i++) {
+ KeyguardWidgetFrame v = getWidgetPageAt(i);
+ if (v == mDragView) continue;
+ if (v != null) {
+ float scrollProgress = getScrollProgress(screenCenter, v, i);
+
+ v.setCameraDistance(mDensity * CAMERA_DISTANCE);
+
+ if (isOverScrollChild(i, scrollProgress) && PERFORM_OVERSCROLL_ROTATION) {
+ float pivotX = v.getMeasuredWidth() / 2;
+ float pivotY = v.getMeasuredHeight() / 2;
+ v.setPivotX(pivotX);
+ v.setPivotY(pivotY);
+ v.setRotationY(- OVERSCROLL_MAX_ROTATION * scrollProgress);
+ v.setOverScrollAmount(Math.abs(scrollProgress), scrollProgress < 0);
+ } else {
+ v.setRotationY(0f);
+ v.setOverScrollAmount(0, false);
+ }
+
+ float alpha = v.getAlpha();
+ // If the view has 0 alpha, we set it to be invisible so as to prevent
+ // it from accepting touches
+ if (alpha == 0) {
+ v.setVisibility(INVISIBLE);
+ } else if (v.getVisibility() != VISIBLE) {
+ v.setVisibility(VISIBLE);
+ }
+ }
+ }
+ }
+
+ public boolean isWidgetPage(int pageIndex) {
+ if (pageIndex < 0 || pageIndex >= getChildCount()) {
+ return false;
+ }
+ View v = getChildAt(pageIndex);
+ if (v != null && v instanceof KeyguardWidgetFrame) {
+ KeyguardWidgetFrame kwf = (KeyguardWidgetFrame) v;
+ return kwf.getContentAppWidgetId() != AppWidgetManager.INVALID_APPWIDGET_ID;
+ }
+ return false;
+ }
+
+ /**
+ * Returns the bounded set of pages that are re-orderable. The range is fully inclusive.
+ */
+ @Override
+ void boundByReorderablePages(boolean isReordering, int[] range) {
+ if (isReordering) {
+ // Remove non-widget pages from the range
+ while (range[1] >= range[0] && !isWidgetPage(range[1])) {
+ range[1]--;
+ }
+ while (range[0] <= range[1] && !isWidgetPage(range[0])) {
+ range[0]++;
+ }
+ }
+ }
+
+ protected void reorderStarting() {
+ showOutlinesAndSidePages();
+ }
+
+ @Override
+ protected void onStartReordering() {
+ super.onStartReordering();
+ enablePageContentLayers();
+ reorderStarting();
+ }
+
+ @Override
+ protected void onEndReordering() {
+ super.onEndReordering();
+ hideOutlinesAndSidePages();
+ }
+
+ void showOutlinesAndSidePages() {
+ animateOutlinesAndSidePages(true);
+ }
+
+ void hideOutlinesAndSidePages() {
+ animateOutlinesAndSidePages(false);
+ }
+
+ public void showInitialPageHints() {
+ mShowingInitialHints = true;
+ int count = getChildCount();
+ for (int i = 0; i < count; i++) {
+ KeyguardWidgetFrame child = getWidgetPageAt(i);
+ if (i != mCurrentPage) {
+ child.setBackgroundAlpha(KeyguardWidgetFrame.OUTLINE_ALPHA_MULTIPLIER);
+ child.setContentAlpha(0f);
+ } else {
+ child.setBackgroundAlpha(0f);
+ child.setContentAlpha(1f);
+ }
+ }
+ }
+
+ @Override
+ void setCurrentPage(int currentPage) {
+ super.setCurrentPage(currentPage);
+ updateWidgetFramesImportantForAccessibility();
+ }
+
+ @Override
+ public void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ mHasMeasure = false;
+ }
+
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ mLastWidthMeasureSpec = widthMeasureSpec;
+ mLastHeightMeasureSpec = heightMeasureSpec;
+
+ int maxChallengeTop = -1;
+ View parent = (View) getParent();
+ boolean challengeShowing = false;
+ // Widget pages need to know where the top of the sliding challenge is so that they
+ // now how big the widget should be when the challenge is up. We compute it here and
+ // then propagate it to each of our children.
+ if (parent.getParent() instanceof SlidingChallengeLayout) {
+ SlidingChallengeLayout scl = (SlidingChallengeLayout) parent.getParent();
+ int top = scl.getMaxChallengeTop();
+
+ // This is a bit evil, but we need to map a coordinate relative to the SCL into a
+ // coordinate relative to our children, hence we subtract the top padding.s
+ maxChallengeTop = top - getPaddingTop();
+ challengeShowing = scl.isChallengeShowing();
+
+ int count = getChildCount();
+ for (int i = 0; i < count; i++) {
+ KeyguardWidgetFrame frame = getWidgetPageAt(i);
+ frame.setMaxChallengeTop(maxChallengeTop);
+ // On the very first measure pass, if the challenge is showing, we need to make sure
+ // that the widget on the current page is small.
+ if (challengeShowing && i == mCurrentPage && !mHasMeasure) {
+ frame.shrinkWidget();
+ }
+ }
+ }
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ mHasMeasure = true;
+ }
+
+ void animateOutlinesAndSidePages(final boolean show) {
+ animateOutlinesAndSidePages(show, -1);
+ }
+
+ public void setWidgetToResetOnPageFadeOut(int widget) {
+ mWidgetToResetAfterFadeOut = widget;
+ }
+
+ public int getWidgetToResetOnPageFadeOut() {
+ return mWidgetToResetAfterFadeOut;
+ }
+
+ void animateOutlinesAndSidePages(final boolean show, int duration) {
+ if (mChildrenOutlineFadeAnimation != null) {
+ mChildrenOutlineFadeAnimation.cancel();
+ mChildrenOutlineFadeAnimation = null;
+ }
+ int count = getChildCount();
+ PropertyValuesHolder alpha;
+ ArrayList<Animator> anims = new ArrayList<Animator>();
+
+ if (duration == -1) {
+ duration = show ? CHILDREN_OUTLINE_FADE_IN_DURATION :
+ CHILDREN_OUTLINE_FADE_OUT_DURATION;
+ }
+
+ int curPage = getNextPage();
+ for (int i = 0; i < count; i++) {
+ float finalContentAlpha;
+ if (show) {
+ finalContentAlpha = getAlphaForPage(mScreenCenter, i, true);
+ } else if (!show && i == curPage) {
+ finalContentAlpha = 1f;
+ } else {
+ finalContentAlpha = 0f;
+ }
+ KeyguardWidgetFrame child = getWidgetPageAt(i);
+
+ alpha = PropertyValuesHolder.ofFloat("contentAlpha", finalContentAlpha);
+ ObjectAnimator a = ObjectAnimator.ofPropertyValuesHolder(child, alpha);
+ anims.add(a);
+
+ float finalOutlineAlpha = show ? getOutlineAlphaForPage(mScreenCenter, i, true) : 0f;
+ child.fadeFrame(this, show, finalOutlineAlpha, duration);
+ }
+
+ mChildrenOutlineFadeAnimation = new AnimatorSet();
+ mChildrenOutlineFadeAnimation.playTogether(anims);
+
+ mChildrenOutlineFadeAnimation.setDuration(duration);
+ mChildrenOutlineFadeAnimation.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationStart(Animator animation) {
+ if (show) {
+ enablePageContentLayers();
+ }
+ }
+
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ if (!show) {
+ disablePageContentLayers();
+ KeyguardWidgetFrame frame = getWidgetPageAt(mWidgetToResetAfterFadeOut);
+ if (frame != null && !(frame == getWidgetPageAt(mCurrentPage) &&
+ mViewStateManager.isChallengeOverlapping())) {
+ frame.resetSize();
+ }
+ mWidgetToResetAfterFadeOut = -1;
+ mShowingInitialHints = false;
+ }
+ updateWidgetFramesImportantForAccessibility();
+ }
+ });
+ mChildrenOutlineFadeAnimation.start();
+ }
+
+ @Override
+ public boolean onLongClick(View v) {
+ // Disallow long pressing to reorder if the challenge is showing
+ boolean isChallengeOverlapping = mViewStateManager.isChallengeShowing() &&
+ mViewStateManager.isChallengeOverlapping();
+ if (!isChallengeOverlapping && startReordering()) {
+ return true;
+ }
+ return false;
+ }
+
+ public void removeWidget(View view) {
+ if (view instanceof KeyguardWidgetFrame) {
+ removeView(view);
+ } else {
+ // Assume view was wrapped by a KeyguardWidgetFrame in KeyguardWidgetPager#addWidget().
+ // This supports legacy hard-coded "widgets" like KeyguardTransportControlView.
+ int pos = getWidgetPageIndex(view);
+ if (pos != -1) {
+ KeyguardWidgetFrame frame = (KeyguardWidgetFrame) getChildAt(pos);
+ frame.removeView(view);
+ removeView(frame);
+ } else {
+ Slog.w(TAG, "removeWidget() can't find:" + view);
+ }
+ }
+ }
+
+ public int getWidgetPageIndex(View view) {
+ if (view instanceof KeyguardWidgetFrame) {
+ return indexOfChild(view);
+ } else {
+ // View was wrapped by a KeyguardWidgetFrame by KeyguardWidgetPager#addWidget()
+ return indexOfChild((KeyguardWidgetFrame)view.getParent());
+ }
+ }
+
+ @Override
+ protected void setPageHoveringOverDeleteDropTarget(int viewIndex, boolean isHovering) {
+ KeyguardWidgetFrame child = getWidgetPageAt(viewIndex);
+ child.setIsHoveringOverDeleteDropTarget(isHovering);
+ }
+
+ // ChallengeLayout.OnBouncerStateChangedListener
+ @Override
+ public void onBouncerStateChanged(boolean bouncerActive) {
+ if (bouncerActive) {
+ zoomOutToBouncer();
+ } else {
+ zoomInFromBouncer();
+ }
+ }
+
+ void setBouncerAnimationDuration(int duration) {
+ mBouncerZoomInOutDuration = duration;
+ }
+
+ // Zoom in after the bouncer is dismissed
+ void zoomInFromBouncer() {
+ if (mZoomInOutAnim != null && mZoomInOutAnim.isRunning()) {
+ mZoomInOutAnim.cancel();
+ }
+ final View currentPage = getPageAt(getCurrentPage());
+ if (currentPage.getScaleX() < 1f || currentPage.getScaleY() < 1f) {
+ mZoomInOutAnim = new AnimatorSet();
+ mZoomInOutAnim.playTogether(
+ ObjectAnimator.ofFloat(currentPage, "scaleX", 1f),
+ ObjectAnimator.ofFloat(currentPage , "scaleY", 1f));
+ mZoomInOutAnim.setDuration(mBouncerZoomInOutDuration);
+ mZoomInOutAnim.setInterpolator(new DecelerateInterpolator(1.5f));
+ mZoomInOutAnim.start();
+ }
+ if (currentPage instanceof KeyguardWidgetFrame) {
+ ((KeyguardWidgetFrame)currentPage).onBouncerShowing(false);
+ }
+ }
+
+ // Zoom out after the bouncer is initiated
+ void zoomOutToBouncer() {
+ if (mZoomInOutAnim != null && mZoomInOutAnim.isRunning()) {
+ mZoomInOutAnim.cancel();
+ }
+ int curPage = getCurrentPage();
+ View currentPage = getPageAt(curPage);
+ if (shouldSetTopAlignedPivotForWidget(curPage)) {
+ currentPage.setPivotY(0);
+ // Note: we are working around the issue that setting the x-pivot to the same value as it
+ // was does not actually work.
+ currentPage.setPivotX(0);
+ currentPage.setPivotX(currentPage.getMeasuredWidth() / 2);
+ }
+ if (!(currentPage.getScaleX() < 1f || currentPage.getScaleY() < 1f)) {
+ mZoomInOutAnim = new AnimatorSet();
+ mZoomInOutAnim.playTogether(
+ ObjectAnimator.ofFloat(currentPage, "scaleX", BOUNCER_SCALE_FACTOR),
+ ObjectAnimator.ofFloat(currentPage, "scaleY", BOUNCER_SCALE_FACTOR));
+ mZoomInOutAnim.setDuration(mBouncerZoomInOutDuration);
+ mZoomInOutAnim.setInterpolator(new DecelerateInterpolator(1.5f));
+ mZoomInOutAnim.start();
+ }
+ if (currentPage instanceof KeyguardWidgetFrame) {
+ ((KeyguardWidgetFrame)currentPage).onBouncerShowing(true);
+ }
+ }
+
+ void setAddWidgetEnabled(boolean enabled) {
+ if (mAddWidgetView != null && enabled) {
+ addView(mAddWidgetView, 0);
+ // We need to force measure the PagedView so that the calls to update the scroll
+ // position below work
+ measure(mLastWidthMeasureSpec, mLastHeightMeasureSpec);
+ // Bump up the current page to account for the addition of the new page
+ setCurrentPage(mCurrentPage + 1);
+ mAddWidgetView = null;
+ } else if (mAddWidgetView == null && !enabled) {
+ View addWidget = findViewById(R.id.keyguard_add_widget);
+ if (addWidget != null) {
+ mAddWidgetView = addWidget;
+ removeView(addWidget);
+ }
+ }
+ }
+
+ boolean isAddPage(int pageIndex) {
+ View v = getChildAt(pageIndex);
+ return v != null && v.getId() == R.id.keyguard_add_widget;
+ }
+
+ boolean isCameraPage(int pageIndex) {
+ View v = getChildAt(pageIndex);
+ return v != null && v instanceof CameraWidgetFrame;
+ }
+
+ @Override
+ protected boolean shouldSetTopAlignedPivotForWidget(int childIndex) {
+ return !isCameraPage(childIndex) && super.shouldSetTopAlignedPivotForWidget(childIndex);
+ }
+
+ /**
+ * Search given {@link View} hierarchy for {@link TextClock} instances that
+ * show various time components. Returns combination of
+ * {@link #FLAG_HAS_LOCAL_HOUR} and {@link #FLAG_HAS_LOCAL_MINUTE}.
+ */
+ private static int findClockInHierarchy(View view) {
+ if (view instanceof TextClock) {
+ return getClockFlags((TextClock) view);
+ } else if (view instanceof ViewGroup) {
+ int flags = 0;
+ final ViewGroup group = (ViewGroup) view;
+ final int size = group.getChildCount();
+ for (int i = 0; i < size; i++) {
+ flags |= findClockInHierarchy(group.getChildAt(i));
+ }
+ return flags;
+ } else {
+ return 0;
+ }
+ }
+
+ /**
+ * Return combination of {@link #FLAG_HAS_LOCAL_HOUR} and
+ * {@link #FLAG_HAS_LOCAL_MINUTE} describing the time represented described
+ * by the given {@link TextClock}.
+ */
+ private static int getClockFlags(TextClock clock) {
+ int flags = 0;
+
+ final String timeZone = clock.getTimeZone();
+ if (timeZone != null && !TimeZone.getDefault().equals(TimeZone.getTimeZone(timeZone))) {
+ // Ignore clocks showing another timezone
+ return 0;
+ }
+
+ final CharSequence format = clock.getFormat();
+ final char hour = clock.is24HourModeEnabled() ? DateFormat.HOUR_OF_DAY
+ : DateFormat.HOUR;
+
+ if (DateFormat.hasDesignator(format, hour)) {
+ flags |= FLAG_HAS_LOCAL_HOUR;
+ }
+ if (DateFormat.hasDesignator(format, DateFormat.MINUTE)) {
+ flags |= FLAG_HAS_LOCAL_MINUTE;
+ }
+
+ return flags;
+ }
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/LiftToActivateListener.java b/packages/Keyguard/src/com/android/keyguard/LiftToActivateListener.java
new file mode 100644
index 0000000..e59602b
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/LiftToActivateListener.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.keyguard;
+
+import android.content.Context;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.accessibility.AccessibilityManager;
+
+/**
+ * Hover listener that implements lift-to-activate interaction for
+ * accessibility. May be added to multiple views.
+ */
+class LiftToActivateListener implements View.OnHoverListener {
+ /** Manager used to query accessibility enabled state. */
+ private final AccessibilityManager mAccessibilityManager;
+
+ private boolean mCachedClickableState;
+
+ public LiftToActivateListener(Context context) {
+ mAccessibilityManager = (AccessibilityManager) context.getSystemService(
+ Context.ACCESSIBILITY_SERVICE);
+ }
+
+ @Override
+ public boolean onHover(View v, MotionEvent event) {
+ // When touch exploration is turned on, lifting a finger while
+ // inside the view bounds should perform a click action.
+ if (mAccessibilityManager.isEnabled()
+ && mAccessibilityManager.isTouchExplorationEnabled()) {
+ switch (event.getActionMasked()) {
+ case MotionEvent.ACTION_HOVER_ENTER:
+ // Lift-to-type temporarily disables double-tap
+ // activation by setting the view as not clickable.
+ mCachedClickableState = v.isClickable();
+ v.setClickable(false);
+ break;
+ case MotionEvent.ACTION_HOVER_EXIT:
+ final int x = (int) event.getX();
+ final int y = (int) event.getY();
+ if ((x > v.getPaddingLeft()) && (y > v.getPaddingTop())
+ && (x < v.getWidth() - v.getPaddingRight())
+ && (y < v.getHeight() - v.getPaddingBottom())) {
+ v.performClick();
+ }
+ v.setClickable(mCachedClickableState);
+ break;
+ }
+ }
+
+ // Pass the event to View.onHoverEvent() to handle accessibility.
+ v.onHoverEvent(event);
+
+ // Consume the event so it doesn't fall through to other views.
+ return true;
+ }
+} \ No newline at end of file
diff --git a/packages/Keyguard/src/com/android/keyguard/MultiPaneChallengeLayout.java b/packages/Keyguard/src/com/android/keyguard/MultiPaneChallengeLayout.java
new file mode 100644
index 0000000..8fd39c0
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/MultiPaneChallengeLayout.java
@@ -0,0 +1,564 @@
+/*
+ * 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.keyguard;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ObjectAnimator;
+import android.content.Context;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.graphics.Rect;
+import android.util.AttributeSet;
+import android.util.DisplayMetrics;
+import android.view.Gravity;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.LinearLayout;
+
+public class MultiPaneChallengeLayout extends ViewGroup implements ChallengeLayout {
+ private static final String TAG = "MultiPaneChallengeLayout";
+
+ final int mOrientation;
+ private boolean mIsBouncing;
+
+ public static final int HORIZONTAL = LinearLayout.HORIZONTAL;
+ public static final int VERTICAL = LinearLayout.VERTICAL;
+ public static final int ANIMATE_BOUNCE_DURATION = 350;
+
+ private KeyguardSecurityContainer mChallengeView;
+ private View mUserSwitcherView;
+ private View mScrimView;
+ private OnBouncerStateChangedListener mBouncerListener;
+
+ private final Rect mTempRect = new Rect();
+ private final Rect mZeroPadding = new Rect();
+
+ private final DisplayMetrics mDisplayMetrics;
+
+ private final OnClickListener mScrimClickListener = new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ hideBouncer();
+ }
+ };
+
+ public MultiPaneChallengeLayout(Context context) {
+ this(context, null);
+ }
+
+ public MultiPaneChallengeLayout(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public MultiPaneChallengeLayout(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+
+ final TypedArray a = context.obtainStyledAttributes(attrs,
+ R.styleable.MultiPaneChallengeLayout, defStyleAttr, 0);
+ mOrientation = a.getInt(R.styleable.MultiPaneChallengeLayout_android_orientation,
+ HORIZONTAL);
+ a.recycle();
+
+ final Resources res = getResources();
+ mDisplayMetrics = res.getDisplayMetrics();
+
+ setSystemUiVisibility(SYSTEM_UI_FLAG_LAYOUT_STABLE);
+ }
+
+ @Override
+ public boolean isChallengeShowing() {
+ return true;
+ }
+
+ @Override
+ public boolean isChallengeOverlapping() {
+ return false;
+ }
+
+ @Override
+ public void showChallenge(boolean b) {
+ }
+
+ @Override
+ public int getBouncerAnimationDuration() {
+ return ANIMATE_BOUNCE_DURATION;
+ }
+
+ @Override
+ public void showBouncer() {
+ if (mIsBouncing) return;
+ mIsBouncing = true;
+ if (mScrimView != null) {
+ if (mChallengeView != null) {
+ mChallengeView.showBouncer(ANIMATE_BOUNCE_DURATION);
+ }
+
+ Animator anim = ObjectAnimator.ofFloat(mScrimView, "alpha", 1f);
+ anim.setDuration(ANIMATE_BOUNCE_DURATION);
+ anim.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationStart(Animator animation) {
+ mScrimView.setVisibility(VISIBLE);
+ }
+ });
+ anim.start();
+ }
+ if (mBouncerListener != null) {
+ mBouncerListener.onBouncerStateChanged(true);
+ }
+ }
+
+ @Override
+ public void hideBouncer() {
+ if (!mIsBouncing) return;
+ mIsBouncing = false;
+ if (mScrimView != null) {
+ if (mChallengeView != null) {
+ mChallengeView.hideBouncer(ANIMATE_BOUNCE_DURATION);
+ }
+
+ Animator anim = ObjectAnimator.ofFloat(mScrimView, "alpha", 0f);
+ anim.setDuration(ANIMATE_BOUNCE_DURATION);
+ anim.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mScrimView.setVisibility(INVISIBLE);
+ }
+ });
+ anim.start();
+ }
+ if (mBouncerListener != null) {
+ mBouncerListener.onBouncerStateChanged(false);
+ }
+ }
+
+ @Override
+ public boolean isBouncing() {
+ return mIsBouncing;
+ }
+
+ @Override
+ public void setOnBouncerStateChangedListener(OnBouncerStateChangedListener listener) {
+ mBouncerListener = listener;
+ }
+
+ @Override
+ public void requestChildFocus(View child, View focused) {
+ if (mIsBouncing && child != mChallengeView) {
+ // Clear out of the bouncer if the user tries to move focus outside of
+ // the security challenge view.
+ hideBouncer();
+ }
+ super.requestChildFocus(child, focused);
+ }
+
+ void setScrimView(View scrim) {
+ if (mScrimView != null) {
+ mScrimView.setOnClickListener(null);
+ }
+ mScrimView = scrim;
+ mScrimView.setAlpha(mIsBouncing ? 1.0f : 0.0f);
+ mScrimView.setVisibility(mIsBouncing ? VISIBLE : INVISIBLE);
+ mScrimView.setFocusable(true);
+ mScrimView.setOnClickListener(mScrimClickListener);
+ }
+
+ private int getVirtualHeight(LayoutParams lp, int height, int heightUsed) {
+ int virtualHeight = height;
+ final View root = getRootView();
+ if (root != null) {
+ // This calculation is super dodgy and relies on several assumptions.
+ // Specifically that the root of the window will be padded in for insets
+ // and that the window is LAYOUT_IN_SCREEN.
+ virtualHeight = mDisplayMetrics.heightPixels - root.getPaddingTop();
+ }
+ if (lp.childType == LayoutParams.CHILD_TYPE_WIDGET ||
+ lp.childType == LayoutParams.CHILD_TYPE_USER_SWITCHER) {
+ // Always measure the widget pager/user switcher as if there were no IME insets
+ // on the window. We want to avoid resizing widgets when possible as it can
+ // be ugly/expensive. This lets us simply clip them instead.
+ return virtualHeight - heightUsed;
+ } else if (lp.childType == LayoutParams.CHILD_TYPE_PAGE_DELETE_DROP_TARGET) {
+ return height;
+ }
+ return Math.min(virtualHeight - heightUsed, height);
+ }
+
+ @Override
+ protected void onMeasure(final int widthSpec, final int heightSpec) {
+ if (MeasureSpec.getMode(widthSpec) != MeasureSpec.EXACTLY ||
+ MeasureSpec.getMode(heightSpec) != MeasureSpec.EXACTLY) {
+ throw new IllegalArgumentException(
+ "MultiPaneChallengeLayout must be measured with an exact size");
+ }
+
+ final int width = MeasureSpec.getSize(widthSpec);
+ final int height = MeasureSpec.getSize(heightSpec);
+ setMeasuredDimension(width, height);
+
+ int widthUsed = 0;
+ int heightUsed = 0;
+
+ // First pass. Find the challenge view and measure the user switcher,
+ // which consumes space in the layout.
+ mChallengeView = null;
+ mUserSwitcherView = null;
+ final int count = getChildCount();
+ for (int i = 0; i < count; i++) {
+ final View child = getChildAt(i);
+ final LayoutParams lp = (LayoutParams) child.getLayoutParams();
+
+ if (lp.childType == LayoutParams.CHILD_TYPE_CHALLENGE) {
+ if (mChallengeView != null) {
+ throw new IllegalStateException(
+ "There may only be one child of type challenge");
+ }
+ if (!(child instanceof KeyguardSecurityContainer)) {
+ throw new IllegalArgumentException(
+ "Challenge must be a KeyguardSecurityContainer");
+ }
+ mChallengeView = (KeyguardSecurityContainer) child;
+ } else if (lp.childType == LayoutParams.CHILD_TYPE_USER_SWITCHER) {
+ if (mUserSwitcherView != null) {
+ throw new IllegalStateException(
+ "There may only be one child of type userSwitcher");
+ }
+ mUserSwitcherView = child;
+
+ if (child.getVisibility() == GONE) continue;
+
+ int adjustedWidthSpec = widthSpec;
+ int adjustedHeightSpec = heightSpec;
+ if (lp.maxWidth >= 0) {
+ adjustedWidthSpec = MeasureSpec.makeMeasureSpec(
+ Math.min(lp.maxWidth, width), MeasureSpec.EXACTLY);
+ }
+ if (lp.maxHeight >= 0) {
+ adjustedHeightSpec = MeasureSpec.makeMeasureSpec(
+ Math.min(lp.maxHeight, height), MeasureSpec.EXACTLY);
+ }
+ // measureChildWithMargins will resolve layout direction for the LayoutParams
+ measureChildWithMargins(child, adjustedWidthSpec, 0, adjustedHeightSpec, 0);
+
+ // Only subtract out space from one dimension. Favor vertical.
+ // Offset by 1.5x to add some balance along the other edge.
+ if (Gravity.isVertical(lp.gravity)) {
+ heightUsed += child.getMeasuredHeight() * 1.5f;
+ } else if (Gravity.isHorizontal(lp.gravity)) {
+ widthUsed += child.getMeasuredWidth() * 1.5f;
+ }
+ } else if (lp.childType == LayoutParams.CHILD_TYPE_SCRIM) {
+ setScrimView(child);
+ child.measure(widthSpec, heightSpec);
+ }
+ }
+
+ // Second pass. Measure everything that's left.
+ for (int i = 0; i < count; i++) {
+ final View child = getChildAt(i);
+ final LayoutParams lp = (LayoutParams) child.getLayoutParams();
+
+ if (lp.childType == LayoutParams.CHILD_TYPE_USER_SWITCHER ||
+ lp.childType == LayoutParams.CHILD_TYPE_SCRIM ||
+ child.getVisibility() == GONE) {
+ // Don't need to measure GONE children, and the user switcher was already measured.
+ continue;
+ }
+
+ final int virtualHeight = getVirtualHeight(lp, height, heightUsed);
+
+ int adjustedWidthSpec;
+ int adjustedHeightSpec;
+ if (lp.centerWithinArea > 0) {
+ if (mOrientation == HORIZONTAL) {
+ adjustedWidthSpec = MeasureSpec.makeMeasureSpec(
+ (int) ((width - widthUsed) * lp.centerWithinArea + 0.5f),
+ MeasureSpec.EXACTLY);
+ adjustedHeightSpec = MeasureSpec.makeMeasureSpec(
+ virtualHeight, MeasureSpec.EXACTLY);
+ } else {
+ adjustedWidthSpec = MeasureSpec.makeMeasureSpec(
+ width - widthUsed, MeasureSpec.EXACTLY);
+ adjustedHeightSpec = MeasureSpec.makeMeasureSpec(
+ (int) (virtualHeight * lp.centerWithinArea + 0.5f),
+ MeasureSpec.EXACTLY);
+ }
+ } else {
+ adjustedWidthSpec = MeasureSpec.makeMeasureSpec(
+ width - widthUsed, MeasureSpec.EXACTLY);
+ adjustedHeightSpec = MeasureSpec.makeMeasureSpec(
+ virtualHeight, MeasureSpec.EXACTLY);
+ }
+ if (lp.maxWidth >= 0) {
+ adjustedWidthSpec = MeasureSpec.makeMeasureSpec(
+ Math.min(lp.maxWidth, MeasureSpec.getSize(adjustedWidthSpec)),
+ MeasureSpec.EXACTLY);
+ }
+ if (lp.maxHeight >= 0) {
+ adjustedHeightSpec = MeasureSpec.makeMeasureSpec(
+ Math.min(lp.maxHeight, MeasureSpec.getSize(adjustedHeightSpec)),
+ MeasureSpec.EXACTLY);
+ }
+
+ measureChildWithMargins(child, adjustedWidthSpec, 0, adjustedHeightSpec, 0);
+ }
+ }
+
+ @Override
+ protected void onLayout(boolean changed, int l, int t, int r, int b) {
+ final Rect padding = mTempRect;
+ padding.left = getPaddingLeft();
+ padding.top = getPaddingTop();
+ padding.right = getPaddingRight();
+ padding.bottom = getPaddingBottom();
+ final int width = r - l;
+ final int height = b - t;
+
+ // Reserve extra space in layout for the user switcher by modifying
+ // local padding during this layout pass
+ if (mUserSwitcherView != null && mUserSwitcherView.getVisibility() != GONE) {
+ layoutWithGravity(width, height, mUserSwitcherView, padding, true);
+ }
+
+ final int count = getChildCount();
+ for (int i = 0; i < count; i++) {
+ final View child = getChildAt(i);
+ LayoutParams lp = (LayoutParams) child.getLayoutParams();
+
+ // We did the user switcher above if we have one.
+ if (child == mUserSwitcherView || child.getVisibility() == GONE) continue;
+
+ if (child == mScrimView) {
+ child.layout(0, 0, width, height);
+ continue;
+ } else if (lp.childType == LayoutParams.CHILD_TYPE_PAGE_DELETE_DROP_TARGET) {
+ layoutWithGravity(width, height, child, mZeroPadding, false);
+ continue;
+ }
+
+ layoutWithGravity(width, height, child, padding, false);
+ }
+ }
+
+ private void layoutWithGravity(int width, int height, View child, Rect padding,
+ boolean adjustPadding) {
+ final LayoutParams lp = (LayoutParams) child.getLayoutParams();
+
+ final int heightUsed = padding.top + padding.bottom - getPaddingTop() - getPaddingBottom();
+ height = getVirtualHeight(lp, height, heightUsed);
+
+ final int gravity = Gravity.getAbsoluteGravity(lp.gravity, getLayoutDirection());
+
+ final boolean fixedLayoutSize = lp.centerWithinArea > 0;
+ final boolean fixedLayoutHorizontal = fixedLayoutSize && mOrientation == HORIZONTAL;
+ final boolean fixedLayoutVertical = fixedLayoutSize && mOrientation == VERTICAL;
+
+ final int adjustedWidth;
+ final int adjustedHeight;
+ if (fixedLayoutHorizontal) {
+ final int paddedWidth = width - padding.left - padding.right;
+ adjustedWidth = (int) (paddedWidth * lp.centerWithinArea + 0.5f);
+ adjustedHeight = height;
+ } else if (fixedLayoutVertical) {
+ final int paddedHeight = height - getPaddingTop() - getPaddingBottom();
+ adjustedWidth = width;
+ adjustedHeight = (int) (paddedHeight * lp.centerWithinArea + 0.5f);
+ } else {
+ adjustedWidth = width;
+ adjustedHeight = height;
+ }
+
+ final boolean isVertical = Gravity.isVertical(gravity);
+ final boolean isHorizontal = Gravity.isHorizontal(gravity);
+ final int childWidth = child.getMeasuredWidth();
+ final int childHeight = child.getMeasuredHeight();
+
+ int left = padding.left;
+ int top = padding.top;
+ int right = left + childWidth;
+ int bottom = top + childHeight;
+ switch (gravity & Gravity.VERTICAL_GRAVITY_MASK) {
+ case Gravity.TOP:
+ top = fixedLayoutVertical ?
+ padding.top + (adjustedHeight - childHeight) / 2 : padding.top;
+ bottom = top + childHeight;
+ if (adjustPadding && isVertical) {
+ padding.top = bottom;
+ padding.bottom += childHeight / 2;
+ }
+ break;
+ case Gravity.BOTTOM:
+ bottom = fixedLayoutVertical
+ ? padding.top + height - (adjustedHeight - childHeight) / 2
+ : padding.top + height;
+ top = bottom - childHeight;
+ if (adjustPadding && isVertical) {
+ padding.bottom = height - top;
+ padding.top += childHeight / 2;
+ }
+ break;
+ case Gravity.CENTER_VERTICAL:
+ top = padding.top + (height - childHeight) / 2;
+ bottom = top + childHeight;
+ break;
+ }
+ switch (gravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
+ case Gravity.LEFT:
+ left = fixedLayoutHorizontal ?
+ padding.left + (adjustedWidth - childWidth) / 2 : padding.left;
+ right = left + childWidth;
+ if (adjustPadding && isHorizontal && !isVertical) {
+ padding.left = right;
+ padding.right += childWidth / 2;
+ }
+ break;
+ case Gravity.RIGHT:
+ right = fixedLayoutHorizontal
+ ? width - padding.right - (adjustedWidth - childWidth) / 2
+ : width - padding.right;
+ left = right - childWidth;
+ if (adjustPadding && isHorizontal && !isVertical) {
+ padding.right = width - left;
+ padding.left += childWidth / 2;
+ }
+ break;
+ case Gravity.CENTER_HORIZONTAL:
+ final int paddedWidth = width - padding.left - padding.right;
+ left = (paddedWidth - childWidth) / 2;
+ right = left + childWidth;
+ break;
+ }
+ child.layout(left, top, right, bottom);
+ }
+
+ @Override
+ public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) {
+ return new LayoutParams(getContext(), attrs, this);
+ }
+
+ @Override
+ protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
+ return p instanceof LayoutParams ? new LayoutParams((LayoutParams) p) :
+ p instanceof MarginLayoutParams ? new LayoutParams((MarginLayoutParams) p) :
+ new LayoutParams(p);
+ }
+
+ @Override
+ protected ViewGroup.LayoutParams generateDefaultLayoutParams() {
+ return new LayoutParams();
+ }
+
+ @Override
+ protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
+ return p instanceof LayoutParams;
+ }
+
+ public static class LayoutParams extends MarginLayoutParams {
+
+ public float centerWithinArea = 0;
+
+ public int childType = 0;
+
+ public static final int CHILD_TYPE_NONE = 0;
+ public static final int CHILD_TYPE_WIDGET = 1;
+ public static final int CHILD_TYPE_CHALLENGE = 2;
+ public static final int CHILD_TYPE_USER_SWITCHER = 3;
+ public static final int CHILD_TYPE_SCRIM = 4;
+ public static final int CHILD_TYPE_PAGE_DELETE_DROP_TARGET = 7;
+
+ public int gravity = Gravity.NO_GRAVITY;
+
+ public int maxWidth = -1;
+ public int maxHeight = -1;
+
+ public LayoutParams() {
+ this(WRAP_CONTENT, WRAP_CONTENT);
+ }
+
+ LayoutParams(Context c, AttributeSet attrs, MultiPaneChallengeLayout parent) {
+ super(c, attrs);
+
+ final TypedArray a = c.obtainStyledAttributes(attrs,
+ R.styleable.MultiPaneChallengeLayout_Layout);
+
+ centerWithinArea = a.getFloat(
+ R.styleable.MultiPaneChallengeLayout_Layout_layout_centerWithinArea, 0);
+ childType = a.getInt(R.styleable.MultiPaneChallengeLayout_Layout_layout_childType,
+ CHILD_TYPE_NONE);
+ gravity = a.getInt(R.styleable.MultiPaneChallengeLayout_Layout_layout_gravity,
+ Gravity.NO_GRAVITY);
+ maxWidth = a.getDimensionPixelSize(
+ R.styleable.MultiPaneChallengeLayout_Layout_layout_maxWidth, -1);
+ maxHeight = a.getDimensionPixelSize(
+ R.styleable.MultiPaneChallengeLayout_Layout_layout_maxHeight, -1);
+
+ // Default gravity settings based on type and parent orientation
+ if (gravity == Gravity.NO_GRAVITY) {
+ if (parent.mOrientation == HORIZONTAL) {
+ switch (childType) {
+ case CHILD_TYPE_WIDGET:
+ gravity = Gravity.LEFT | Gravity.CENTER_VERTICAL;
+ break;
+ case CHILD_TYPE_CHALLENGE:
+ gravity = Gravity.RIGHT | Gravity.CENTER_VERTICAL;
+ break;
+ case CHILD_TYPE_USER_SWITCHER:
+ gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL;
+ break;
+ }
+ } else {
+ switch (childType) {
+ case CHILD_TYPE_WIDGET:
+ gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL;
+ break;
+ case CHILD_TYPE_CHALLENGE:
+ gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL;
+ break;
+ case CHILD_TYPE_USER_SWITCHER:
+ gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL;
+ break;
+ }
+ }
+ }
+
+ a.recycle();
+ }
+
+ public LayoutParams(int width, int height) {
+ super(width, height);
+ }
+
+ public LayoutParams(ViewGroup.LayoutParams source) {
+ super(source);
+ }
+
+ public LayoutParams(MarginLayoutParams source) {
+ super(source);
+ }
+
+ public LayoutParams(LayoutParams source) {
+ this((MarginLayoutParams) source);
+
+ centerWithinArea = source.centerWithinArea;
+ childType = source.childType;
+ gravity = source.gravity;
+ maxWidth = source.maxWidth;
+ maxHeight = source.maxHeight;
+ }
+ }
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/NumPadKey.java b/packages/Keyguard/src/com/android/keyguard/NumPadKey.java
new file mode 100644
index 0000000..532670f
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/NumPadKey.java
@@ -0,0 +1,127 @@
+/*
+ * 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.keyguard;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.text.SpannableStringBuilder;
+import android.text.style.TextAppearanceSpan;
+import android.util.AttributeSet;
+import android.view.HapticFeedbackConstants;
+import android.view.View;
+import android.widget.Button;
+import android.widget.TextView;
+
+import com.android.internal.widget.LockPatternUtils;
+
+public class NumPadKey extends Button {
+ // list of "ABC", etc per digit, starting with '0'
+ static String sKlondike[];
+
+ int mDigit = -1;
+ int mTextViewResId;
+ TextView mTextView = null;
+ boolean mEnableHaptics;
+
+ private View.OnClickListener mListener = new View.OnClickListener() {
+ @Override
+ public void onClick(View thisView) {
+ if (mTextView == null) {
+ if (mTextViewResId > 0) {
+ final View v = NumPadKey.this.getRootView().findViewById(mTextViewResId);
+ if (v != null && v instanceof TextView) {
+ mTextView = (TextView) v;
+ }
+ }
+ }
+ // check for time-based lockouts
+ if (mTextView != null && mTextView.isEnabled()) {
+ mTextView.append(String.valueOf(mDigit));
+ }
+ doHapticKeyClick();
+ }
+ };
+
+ public NumPadKey(Context context) {
+ this(context, null);
+ }
+
+ public NumPadKey(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public NumPadKey(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+
+ TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.NumPadKey);
+ mDigit = a.getInt(R.styleable.NumPadKey_digit, mDigit);
+ setTextViewResId(a.getResourceId(R.styleable.NumPadKey_textView, 0));
+
+ setOnClickListener(mListener);
+ setOnHoverListener(new LiftToActivateListener(context));
+ setAccessibilityDelegate(new ObscureSpeechDelegate(context));
+
+ mEnableHaptics = new LockPatternUtils(context).isTactileFeedbackEnabled();
+
+ SpannableStringBuilder builder = new SpannableStringBuilder();
+ builder.append(String.valueOf(mDigit));
+ if (mDigit >= 0) {
+ if (sKlondike == null) {
+ sKlondike = context.getResources().getStringArray(
+ R.array.lockscreen_num_pad_klondike);
+ }
+ if (sKlondike != null && sKlondike.length > mDigit) {
+ final String extra = sKlondike[mDigit];
+ final int extraLen = extra.length();
+ if (extraLen > 0) {
+ builder.append(" ");
+ builder.append(extra);
+ builder.setSpan(
+ new TextAppearanceSpan(context, R.style.TextAppearance_NumPadKey_Klondike),
+ builder.length()-extraLen, builder.length(), 0);
+ }
+ }
+ }
+ setText(builder);
+ }
+
+ @Override
+ public void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+
+ // Reset the "announced headset" flag when detached.
+ ObscureSpeechDelegate.sAnnouncedHeadset = false;
+ }
+
+ public void setTextView(TextView tv) {
+ mTextView = tv;
+ }
+
+ public void setTextViewResId(int resId) {
+ mTextView = null;
+ mTextViewResId = resId;
+ }
+
+ // Cause a VIRTUAL_KEY vibration
+ public void doHapticKeyClick() {
+ if (mEnableHaptics) {
+ performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY,
+ HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING
+ | HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING);
+ }
+ }
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/ObscureSpeechDelegate.java b/packages/Keyguard/src/com/android/keyguard/ObscureSpeechDelegate.java
new file mode 100644
index 0000000..573122a
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/ObscureSpeechDelegate.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.keyguard;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.media.AudioManager;
+import android.provider.Settings;
+import android.view.View;
+import android.view.View.AccessibilityDelegate;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityNodeInfo;
+
+import com.android.internal.R;
+
+/**
+ * Accessibility delegate that obscures speech for a view when the user has
+ * not turned on the "speak passwords" preference and is not listening
+ * through headphones.
+ */
+class ObscureSpeechDelegate extends AccessibilityDelegate {
+ /** Whether any client has announced the "headset" notification. */
+ static boolean sAnnouncedHeadset = false;
+
+ private final ContentResolver mContentResolver;
+ private final AudioManager mAudioManager;
+
+ public ObscureSpeechDelegate(Context context) {
+ mContentResolver = context.getContentResolver();
+ mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+ }
+
+ @Override
+ public void sendAccessibilityEvent(View host, int eventType) {
+ super.sendAccessibilityEvent(host, eventType);
+
+ // Play the "headset required" announcement the first time the user
+ // places accessibility focus on a key.
+ if ((eventType == AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED)
+ && !sAnnouncedHeadset && shouldObscureSpeech()) {
+ sAnnouncedHeadset = true;
+ host.announceForAccessibility(host.getContext().getString(
+ R.string.keyboard_headset_required_to_hear_password));
+ }
+ }
+
+ @Override
+ public void onPopulateAccessibilityEvent(View host, AccessibilityEvent event) {
+ super.onPopulateAccessibilityEvent(host, event);
+
+ if ((event.getEventType() != AccessibilityEvent.TYPE_ANNOUNCEMENT)
+ && shouldObscureSpeech()) {
+ event.getText().clear();
+ event.setContentDescription(host.getContext().getString(
+ R.string.keyboard_password_character_no_headset));
+ }
+ }
+
+ @Override
+ public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
+ super.onInitializeAccessibilityNodeInfo(host, info);
+
+ if (shouldObscureSpeech()) {
+ final Context ctx = host.getContext();
+ info.setText(null);
+ info.setContentDescription(
+ ctx.getString(R.string.keyboard_password_character_no_headset));
+ }
+ }
+
+ @SuppressWarnings("deprecation")
+ private boolean shouldObscureSpeech() {
+ // The user can optionally force speaking passwords.
+ if (Settings.Secure.getInt(mContentResolver,
+ Settings.Secure.ACCESSIBILITY_SPEAK_PASSWORD, 0) != 0) {
+ return false;
+ }
+
+ // Always speak if the user is listening through headphones.
+ if (mAudioManager.isWiredHeadsetOn() || mAudioManager.isBluetoothA2dpOn()) {
+ return false;
+ }
+
+ // Don't speak since this key is used to type a password.
+ return true;
+ }
+} \ No newline at end of file
diff --git a/packages/Keyguard/src/com/android/keyguard/PagedView.java b/packages/Keyguard/src/com/android/keyguard/PagedView.java
new file mode 100644
index 0000000..5c2413a
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/PagedView.java
@@ -0,0 +1,2562 @@
+/*
+ * 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.keyguard;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
+import android.animation.TimeInterpolator;
+import android.animation.ValueAnimator;
+import android.animation.ValueAnimator.AnimatorUpdateListener;
+import android.content.Context;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.graphics.Canvas;
+import android.graphics.Matrix;
+import android.graphics.PointF;
+import android.graphics.Rect;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.AttributeSet;
+import android.util.DisplayMetrics;
+import android.util.Log;
+import android.view.InputDevice;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+import android.view.VelocityTracker;
+import android.view.View;
+import android.view.ViewConfiguration;
+import android.view.ViewGroup;
+import android.view.ViewParent;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityManager;
+import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.animation.AnimationUtils;
+import android.view.animation.DecelerateInterpolator;
+import android.view.animation.Interpolator;
+import android.view.animation.LinearInterpolator;
+import android.widget.Scroller;
+
+import java.util.ArrayList;
+
+/**
+ * An abstraction of the original Workspace which supports browsing through a
+ * sequential list of "pages"
+ */
+public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarchyChangeListener {
+ private static final String TAG = "WidgetPagedView";
+ private static final boolean DEBUG = false;
+ protected static final int INVALID_PAGE = -1;
+
+ // the min drag distance for a fling to register, to prevent random page shifts
+ private static final int MIN_LENGTH_FOR_FLING = 25;
+
+ protected static final int PAGE_SNAP_ANIMATION_DURATION = 750;
+ protected static final int SLOW_PAGE_SNAP_ANIMATION_DURATION = 950;
+ protected static final float NANOTIME_DIV = 1000000000.0f;
+
+ private static final float OVERSCROLL_ACCELERATE_FACTOR = 2;
+ private static final float OVERSCROLL_DAMP_FACTOR = 0.14f;
+
+ private static final float RETURN_TO_ORIGINAL_PAGE_THRESHOLD = 0.33f;
+ // The page is moved more than halfway, automatically move to the next page on touch up.
+ private static final float SIGNIFICANT_MOVE_THRESHOLD = 0.4f;
+
+ // The following constants need to be scaled based on density. The scaled versions will be
+ // assigned to the corresponding member variables below.
+ private static final int FLING_THRESHOLD_VELOCITY = 500;
+ private static final int MIN_SNAP_VELOCITY = 1500;
+ private static final int MIN_FLING_VELOCITY = 250;
+
+ // We are disabling touch interaction of the widget region for factory ROM.
+ private static final boolean DISABLE_TOUCH_INTERACTION = false;
+ private static final boolean DISABLE_TOUCH_SIDE_PAGES = true;
+ private static final boolean DISABLE_FLING_TO_DELETE = false;
+
+ static final int AUTOMATIC_PAGE_SPACING = -1;
+
+ protected int mFlingThresholdVelocity;
+ protected int mMinFlingVelocity;
+ protected int mMinSnapVelocity;
+
+ protected float mDensity;
+ protected float mSmoothingTime;
+ protected float mTouchX;
+
+ protected boolean mFirstLayout = true;
+
+ protected int mCurrentPage;
+ protected int mChildCountOnLastMeasure;
+
+ protected int mNextPage = INVALID_PAGE;
+ protected int mMaxScrollX;
+ protected Scroller mScroller;
+ private VelocityTracker mVelocityTracker;
+
+ private float mParentDownMotionX;
+ private float mParentDownMotionY;
+ private float mDownMotionX;
+ private float mDownMotionY;
+ private float mDownScrollX;
+ protected float mLastMotionX;
+ protected float mLastMotionXRemainder;
+ protected float mLastMotionY;
+ protected float mTotalMotionX;
+ private int mLastScreenCenter = -1;
+ private int[] mChildOffsets;
+ private int[] mChildRelativeOffsets;
+ private int[] mChildOffsetsWithLayoutScale;
+
+ protected final static int TOUCH_STATE_REST = 0;
+ protected final static int TOUCH_STATE_SCROLLING = 1;
+ protected final static int TOUCH_STATE_PREV_PAGE = 2;
+ protected final static int TOUCH_STATE_NEXT_PAGE = 3;
+ protected final static int TOUCH_STATE_REORDERING = 4;
+
+ protected final static float ALPHA_QUANTIZE_LEVEL = 0.0001f;
+
+ protected int mTouchState = TOUCH_STATE_REST;
+ protected boolean mForceScreenScrolled = false;
+
+ protected OnLongClickListener mLongClickListener;
+
+ protected int mTouchSlop;
+ private int mPagingTouchSlop;
+ private int mMaximumVelocity;
+ private int mMinimumWidth;
+ protected int mPageSpacing;
+ protected int mCellCountX = 0;
+ protected int mCellCountY = 0;
+ protected boolean mAllowOverScroll = true;
+ protected int mUnboundedScrollX;
+ protected int[] mTempVisiblePagesRange = new int[2];
+ protected boolean mForceDrawAllChildrenNextFrame;
+
+ // mOverScrollX is equal to getScrollX() when we're within the normal scroll range. Otherwise
+ // it is equal to the scaled overscroll position. We use a separate value so as to prevent
+ // the screens from continuing to translate beyond the normal bounds.
+ protected int mOverScrollX;
+
+ // parameter that adjusts the layout to be optimized for pages with that scale factor
+ protected float mLayoutScale = 1.0f;
+
+ protected static final int INVALID_POINTER = -1;
+
+ protected int mActivePointerId = INVALID_POINTER;
+
+ private PageSwitchListener mPageSwitchListener;
+
+ protected ArrayList<Boolean> mDirtyPageContent;
+
+ // If true, syncPages and syncPageItems will be called to refresh pages
+ protected boolean mContentIsRefreshable = true;
+
+ // If true, modify alpha of neighboring pages as user scrolls left/right
+ protected boolean mFadeInAdjacentScreens = false;
+
+ // It true, use a different slop parameter (pagingTouchSlop = 2 * touchSlop) for deciding
+ // to switch to a new page
+ protected boolean mUsePagingTouchSlop = true;
+
+ // If true, the subclass should directly update scrollX itself in its computeScroll method
+ // (SmoothPagedView does this)
+ protected boolean mDeferScrollUpdate = false;
+
+ protected boolean mIsPageMoving = false;
+
+ // All syncs and layout passes are deferred until data is ready.
+ protected boolean mIsDataReady = true;
+
+ // Scrolling indicator
+ private ValueAnimator mScrollIndicatorAnimator;
+ private View mScrollIndicator;
+ private int mScrollIndicatorPaddingLeft;
+ private int mScrollIndicatorPaddingRight;
+ private boolean mShouldShowScrollIndicator = false;
+ private boolean mShouldShowScrollIndicatorImmediately = false;
+ protected static final int sScrollIndicatorFadeInDuration = 150;
+ protected static final int sScrollIndicatorFadeOutDuration = 650;
+ protected static final int sScrollIndicatorFlashDuration = 650;
+
+ // The viewport whether the pages are to be contained (the actual view may be larger than the
+ // viewport)
+ private Rect mViewport = new Rect();
+
+ // Reordering
+ // We use the min scale to determine how much to expand the actually PagedView measured
+ // dimensions such that when we are zoomed out, the view is not clipped
+ private int REORDERING_DROP_REPOSITION_DURATION = 200;
+ protected int REORDERING_REORDER_REPOSITION_DURATION = 300;
+ protected int REORDERING_ZOOM_IN_OUT_DURATION = 250;
+ private int REORDERING_SIDE_PAGE_HOVER_TIMEOUT = 300;
+ private float REORDERING_SIDE_PAGE_BUFFER_PERCENTAGE = 0.1f;
+ private long REORDERING_DELETE_DROP_TARGET_FADE_DURATION = 150;
+ private float mMinScale = 1f;
+ protected View mDragView;
+ protected AnimatorSet mZoomInOutAnim;
+ private Runnable mSidePageHoverRunnable;
+ private int mSidePageHoverIndex = -1;
+ // This variable's scope is only for the duration of startReordering() and endReordering()
+ private boolean mReorderingStarted = false;
+ // This variable's scope is for the duration of startReordering() and after the zoomIn()
+ // animation after endReordering()
+ private boolean mIsReordering;
+ // The runnable that settles the page after snapToPage and animateDragViewToOriginalPosition
+ private int NUM_ANIMATIONS_RUNNING_BEFORE_ZOOM_OUT = 2;
+ private int mPostReorderingPreZoomInRemainingAnimationCount;
+ private Runnable mPostReorderingPreZoomInRunnable;
+
+ // Edge swiping
+ private boolean mOnlyAllowEdgeSwipes = false;
+ private boolean mDownEventOnEdge = false;
+ private int mEdgeSwipeRegionSize = 0;
+
+ // Convenience/caching
+ private Matrix mTmpInvMatrix = new Matrix();
+ private float[] mTmpPoint = new float[2];
+ private Rect mTmpRect = new Rect();
+ private Rect mAltTmpRect = new Rect();
+
+ // Fling to delete
+ private int FLING_TO_DELETE_FADE_OUT_DURATION = 350;
+ private float FLING_TO_DELETE_FRICTION = 0.035f;
+ // The degrees specifies how much deviation from the up vector to still consider a fling "up"
+ private float FLING_TO_DELETE_MAX_FLING_DEGREES = 65f;
+ protected int mFlingToDeleteThresholdVelocity = -1400;
+ // Drag to delete
+ private boolean mDeferringForDelete = false;
+ private int DELETE_SLIDE_IN_SIDE_PAGE_DURATION = 250;
+ private int DRAG_TO_DELETE_FADE_OUT_DURATION = 350;
+
+ // Drop to delete
+ private View mDeleteDropTarget;
+
+ // Bouncer
+ private boolean mTopAlignPageWhenShrinkingForBouncer = false;
+
+ public interface PageSwitchListener {
+ void onPageSwitching(View newPage, int newPageIndex);
+ void onPageSwitched(View newPage, int newPageIndex);
+ }
+
+ public PagedView(Context context) {
+ this(context, null);
+ }
+
+ public PagedView(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public PagedView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ TypedArray a = context.obtainStyledAttributes(attrs,
+ R.styleable.PagedView, defStyle, 0);
+ setPageSpacing(a.getDimensionPixelSize(R.styleable.PagedView_pageSpacing, 0));
+ mScrollIndicatorPaddingLeft =
+ a.getDimensionPixelSize(R.styleable.PagedView_scrollIndicatorPaddingLeft, 0);
+ mScrollIndicatorPaddingRight =
+ a.getDimensionPixelSize(R.styleable.PagedView_scrollIndicatorPaddingRight, 0);
+ a.recycle();
+
+ Resources r = getResources();
+ mEdgeSwipeRegionSize = r.getDimensionPixelSize(R.dimen.kg_edge_swipe_region_size);
+ mTopAlignPageWhenShrinkingForBouncer =
+ r.getBoolean(R.bool.kg_top_align_page_shrink_on_bouncer_visible);
+
+ setHapticFeedbackEnabled(false);
+ init();
+ }
+
+ /**
+ * Initializes various states for this workspace.
+ */
+ protected void init() {
+ mDirtyPageContent = new ArrayList<Boolean>();
+ mDirtyPageContent.ensureCapacity(32);
+ mScroller = new Scroller(getContext(), new ScrollInterpolator());
+ mCurrentPage = 0;
+
+ final ViewConfiguration configuration = ViewConfiguration.get(getContext());
+ mTouchSlop = configuration.getScaledTouchSlop();
+ mPagingTouchSlop = configuration.getScaledPagingTouchSlop();
+ mMaximumVelocity = configuration.getScaledMaximumFlingVelocity();
+ mDensity = getResources().getDisplayMetrics().density;
+
+ // Scale the fling-to-delete threshold by the density
+ mFlingToDeleteThresholdVelocity =
+ (int) (mFlingToDeleteThresholdVelocity * mDensity);
+
+ mFlingThresholdVelocity = (int) (FLING_THRESHOLD_VELOCITY * mDensity);
+ mMinFlingVelocity = (int) (MIN_FLING_VELOCITY * mDensity);
+ mMinSnapVelocity = (int) (MIN_SNAP_VELOCITY * mDensity);
+ setOnHierarchyChangeListener(this);
+ }
+
+ void setDeleteDropTarget(View v) {
+ mDeleteDropTarget = v;
+ }
+
+ // Convenience methods to map points from self to parent and vice versa
+ float[] mapPointFromViewToParent(View v, float x, float y) {
+ mTmpPoint[0] = x;
+ mTmpPoint[1] = y;
+ v.getMatrix().mapPoints(mTmpPoint);
+ mTmpPoint[0] += v.getLeft();
+ mTmpPoint[1] += v.getTop();
+ return mTmpPoint;
+ }
+ float[] mapPointFromParentToView(View v, float x, float y) {
+ mTmpPoint[0] = x - v.getLeft();
+ mTmpPoint[1] = y - v.getTop();
+ v.getMatrix().invert(mTmpInvMatrix);
+ mTmpInvMatrix.mapPoints(mTmpPoint);
+ return mTmpPoint;
+ }
+
+ void updateDragViewTranslationDuringDrag() {
+ float x = mLastMotionX - mDownMotionX + getScrollX() - mDownScrollX;
+ float y = mLastMotionY - mDownMotionY;
+ mDragView.setTranslationX(x);
+ mDragView.setTranslationY(y);
+
+ if (DEBUG) Log.d(TAG, "PagedView.updateDragViewTranslationDuringDrag(): " + x + ", " + y);
+ }
+
+ public void setMinScale(float f) {
+ mMinScale = f;
+ requestLayout();
+ }
+
+ @Override
+ public void setScaleX(float scaleX) {
+ super.setScaleX(scaleX);
+ if (isReordering(true)) {
+ float[] p = mapPointFromParentToView(this, mParentDownMotionX, mParentDownMotionY);
+ mLastMotionX = p[0];
+ mLastMotionY = p[1];
+ updateDragViewTranslationDuringDrag();
+ }
+ }
+
+ // Convenience methods to get the actual width/height of the PagedView (since it is measured
+ // to be larger to account for the minimum possible scale)
+ int getViewportWidth() {
+ return mViewport.width();
+ }
+ int getViewportHeight() {
+ return mViewport.height();
+ }
+
+ // Convenience methods to get the offset ASSUMING that we are centering the pages in the
+ // PagedView both horizontally and vertically
+ int getViewportOffsetX() {
+ return (getMeasuredWidth() - getViewportWidth()) / 2;
+ }
+ int getViewportOffsetY() {
+ return (getMeasuredHeight() - getViewportHeight()) / 2;
+ }
+
+ public void setPageSwitchListener(PageSwitchListener pageSwitchListener) {
+ mPageSwitchListener = pageSwitchListener;
+ if (mPageSwitchListener != null) {
+ mPageSwitchListener.onPageSwitched(getPageAt(mCurrentPage), mCurrentPage);
+ }
+ }
+
+ /**
+ * Called by subclasses to mark that data is ready, and that we can begin loading and laying
+ * out pages.
+ */
+ protected void setDataIsReady() {
+ mIsDataReady = true;
+ }
+
+ protected boolean isDataReady() {
+ return mIsDataReady;
+ }
+
+ /**
+ * Returns the index of the currently displayed page.
+ *
+ * @return The index of the currently displayed page.
+ */
+ int getCurrentPage() {
+ return mCurrentPage;
+ }
+
+ int getNextPage() {
+ return (mNextPage != INVALID_PAGE) ? mNextPage : mCurrentPage;
+ }
+
+ int getPageCount() {
+ return getChildCount();
+ }
+
+ View getPageAt(int index) {
+ return getChildAt(index);
+ }
+
+ protected int indexToPage(int index) {
+ return index;
+ }
+
+ /**
+ * Updates the scroll of the current page immediately to its final scroll position. We use this
+ * in CustomizePagedView to allow tabs to share the same PagedView while resetting the scroll of
+ * the previous tab page.
+ */
+ protected void updateCurrentPageScroll() {
+ int offset = getChildOffset(mCurrentPage);
+ int relOffset = getRelativeChildOffset(mCurrentPage);
+ int newX = offset - relOffset;
+ scrollTo(newX, 0);
+ mScroller.setFinalX(newX);
+ mScroller.forceFinished(true);
+ }
+
+ /**
+ * Sets the current page.
+ */
+ void setCurrentPage(int currentPage) {
+ notifyPageSwitching(currentPage);
+ if (!mScroller.isFinished()) {
+ mScroller.abortAnimation();
+ }
+ // don't introduce any checks like mCurrentPage == currentPage here-- if we change the
+ // the default
+ if (getChildCount() == 0) {
+ return;
+ }
+
+ mForceScreenScrolled = true;
+ mCurrentPage = Math.max(0, Math.min(currentPage, getPageCount() - 1));
+ updateCurrentPageScroll();
+ updateScrollingIndicator();
+ notifyPageSwitched();
+ invalidate();
+ }
+
+ public void setOnlyAllowEdgeSwipes(boolean enable) {
+ mOnlyAllowEdgeSwipes = enable;
+ }
+
+ protected void notifyPageSwitching(int whichPage) {
+ if (mPageSwitchListener != null) {
+ mPageSwitchListener.onPageSwitching(getPageAt(whichPage), whichPage);
+ }
+ }
+
+ protected void notifyPageSwitched() {
+ if (mPageSwitchListener != null) {
+ mPageSwitchListener.onPageSwitched(getPageAt(mCurrentPage), mCurrentPage);
+ }
+ }
+
+ protected void pageBeginMoving() {
+ if (!mIsPageMoving) {
+ mIsPageMoving = true;
+ onPageBeginMoving();
+ }
+ }
+
+ protected void pageEndMoving() {
+ if (mIsPageMoving) {
+ mIsPageMoving = false;
+ onPageEndMoving();
+ }
+ }
+
+ protected boolean isPageMoving() {
+ return mIsPageMoving;
+ }
+
+ // a method that subclasses can override to add behavior
+ protected void onPageBeginMoving() {
+ }
+
+ // a method that subclasses can override to add behavior
+ protected void onPageEndMoving() {
+ }
+
+ /**
+ * Registers the specified listener on each page contained in this workspace.
+ *
+ * @param l The listener used to respond to long clicks.
+ */
+ @Override
+ public void setOnLongClickListener(OnLongClickListener l) {
+ mLongClickListener = l;
+ final int count = getPageCount();
+ for (int i = 0; i < count; i++) {
+ getPageAt(i).setOnLongClickListener(l);
+ }
+ }
+
+ @Override
+ public void scrollBy(int x, int y) {
+ scrollTo(mUnboundedScrollX + x, getScrollY() + y);
+ }
+
+ @Override
+ public void scrollTo(int x, int y) {
+ mUnboundedScrollX = x;
+
+ if (x < 0) {
+ super.scrollTo(0, y);
+ if (mAllowOverScroll) {
+ overScroll(x);
+ }
+ } else if (x > mMaxScrollX) {
+ super.scrollTo(mMaxScrollX, y);
+ if (mAllowOverScroll) {
+ overScroll(x - mMaxScrollX);
+ }
+ } else {
+ mOverScrollX = x;
+ super.scrollTo(x, y);
+ }
+
+ mTouchX = x;
+ mSmoothingTime = System.nanoTime() / NANOTIME_DIV;
+
+ // Update the last motion events when scrolling
+ if (isReordering(true)) {
+ float[] p = mapPointFromParentToView(this, mParentDownMotionX, mParentDownMotionY);
+ mLastMotionX = p[0];
+ mLastMotionY = p[1];
+ updateDragViewTranslationDuringDrag();
+ }
+ }
+
+ // we moved this functionality to a helper function so SmoothPagedView can reuse it
+ protected boolean computeScrollHelper() {
+ if (mScroller.computeScrollOffset()) {
+ // Don't bother scrolling if the page does not need to be moved
+ if (getScrollX() != mScroller.getCurrX()
+ || getScrollY() != mScroller.getCurrY()
+ || mOverScrollX != mScroller.getCurrX()) {
+ scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
+ }
+ invalidate();
+ return true;
+ } else if (mNextPage != INVALID_PAGE) {
+ mCurrentPage = Math.max(0, Math.min(mNextPage, getPageCount() - 1));
+ mNextPage = INVALID_PAGE;
+ notifyPageSwitched();
+
+ // We don't want to trigger a page end moving unless the page has settled
+ // and the user has stopped scrolling
+ if (mTouchState == TOUCH_STATE_REST) {
+ pageEndMoving();
+ }
+
+ onPostReorderingAnimationCompleted();
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public void computeScroll() {
+ computeScrollHelper();
+ }
+
+ protected boolean shouldSetTopAlignedPivotForWidget(int childIndex) {
+ return mTopAlignPageWhenShrinkingForBouncer;
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ if (!mIsDataReady || getChildCount() == 0) {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ return;
+ }
+
+ // We measure the dimensions of the PagedView to be larger than the pages so that when we
+ // zoom out (and scale down), the view is still contained in the parent
+ View parent = (View) getParent();
+ int widthMode = MeasureSpec.getMode(widthMeasureSpec);
+ int widthSize = MeasureSpec.getSize(widthMeasureSpec);
+ int heightMode = MeasureSpec.getMode(heightMeasureSpec);
+ int heightSize = MeasureSpec.getSize(heightMeasureSpec);
+ // NOTE: We multiply by 1.5f to account for the fact that depending on the offset of the
+ // viewport, we can be at most one and a half screens offset once we scale down
+ DisplayMetrics dm = getResources().getDisplayMetrics();
+ int maxSize = Math.max(dm.widthPixels, dm.heightPixels);
+ int parentWidthSize = (int) (1.5f * maxSize);
+ int parentHeightSize = maxSize;
+ int scaledWidthSize = (int) (parentWidthSize / mMinScale);
+ int scaledHeightSize = (int) (parentHeightSize / mMinScale);
+ mViewport.set(0, 0, widthSize, heightSize);
+
+ if (widthMode == MeasureSpec.UNSPECIFIED || heightMode == MeasureSpec.UNSPECIFIED) {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ return;
+ }
+
+ // Return early if we aren't given a proper dimension
+ if (widthSize <= 0 || heightSize <= 0) {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ return;
+ }
+
+ /* Allow the height to be set as WRAP_CONTENT. This allows the particular case
+ * of the All apps view on XLarge displays to not take up more space then it needs. Width
+ * is still not allowed to be set as WRAP_CONTENT since many parts of the code expect
+ * each page to have the same width.
+ */
+ final int verticalPadding = getPaddingTop() + getPaddingBottom();
+ final int horizontalPadding = getPaddingLeft() + getPaddingRight();
+
+ // The children are given the same width and height as the workspace
+ // unless they were set to WRAP_CONTENT
+ if (DEBUG) Log.d(TAG, "PagedView.onMeasure(): " + widthSize + ", " + heightSize);
+ if (DEBUG) Log.d(TAG, "PagedView.scaledSize: " + scaledWidthSize + ", " + scaledHeightSize);
+ if (DEBUG) Log.d(TAG, "PagedView.parentSize: " + parentWidthSize + ", " + parentHeightSize);
+ if (DEBUG) Log.d(TAG, "PagedView.horizontalPadding: " + horizontalPadding);
+ if (DEBUG) Log.d(TAG, "PagedView.verticalPadding: " + verticalPadding);
+ final int childCount = getChildCount();
+ for (int i = 0; i < childCount; i++) {
+ // disallowing padding in paged view (just pass 0)
+ final View child = getPageAt(i);
+ final LayoutParams lp = (LayoutParams) child.getLayoutParams();
+
+ int childWidthMode;
+ if (lp.width == LayoutParams.WRAP_CONTENT) {
+ childWidthMode = MeasureSpec.AT_MOST;
+ } else {
+ childWidthMode = MeasureSpec.EXACTLY;
+ }
+
+ int childHeightMode;
+ if (lp.height == LayoutParams.WRAP_CONTENT) {
+ childHeightMode = MeasureSpec.AT_MOST;
+ } else {
+ childHeightMode = MeasureSpec.EXACTLY;
+ }
+
+ final int childWidthMeasureSpec =
+ MeasureSpec.makeMeasureSpec(widthSize - horizontalPadding, childWidthMode);
+ final int childHeightMeasureSpec =
+ MeasureSpec.makeMeasureSpec(heightSize - verticalPadding, childHeightMode);
+
+ child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
+ }
+ setMeasuredDimension(scaledWidthSize, scaledHeightSize);
+
+ // We can't call getChildOffset/getRelativeChildOffset until we set the measured dimensions.
+ // We also wait until we set the measured dimensions before flushing the cache as well, to
+ // ensure that the cache is filled with good values.
+ invalidateCachedOffsets();
+
+ if (mChildCountOnLastMeasure != getChildCount() && !mDeferringForDelete) {
+ setCurrentPage(mCurrentPage);
+ }
+ mChildCountOnLastMeasure = getChildCount();
+
+ if (childCount > 0) {
+ if (DEBUG) Log.d(TAG, "getRelativeChildOffset(): " + getViewportWidth() + ", "
+ + getChildWidth(0));
+
+ // Calculate the variable page spacing if necessary
+ if (mPageSpacing == AUTOMATIC_PAGE_SPACING) {
+ // The gap between pages in the PagedView should be equal to the gap from the page
+ // to the edge of the screen (so it is not visible in the current screen). To
+ // account for unequal padding on each side of the paged view, we take the maximum
+ // of the left/right gap and use that as the gap between each page.
+ int offset = getRelativeChildOffset(0);
+ int spacing = Math.max(offset, widthSize - offset -
+ getChildAt(0).getMeasuredWidth());
+ setPageSpacing(spacing);
+ }
+ }
+
+ updateScrollingIndicatorPosition();
+
+ if (childCount > 0) {
+ mMaxScrollX = getChildOffset(childCount - 1) - getRelativeChildOffset(childCount - 1);
+ } else {
+ mMaxScrollX = 0;
+ }
+ }
+
+ public void setPageSpacing(int pageSpacing) {
+ mPageSpacing = pageSpacing;
+ invalidateCachedOffsets();
+ }
+
+ @Override
+ protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+ if (!mIsDataReady || getChildCount() == 0) {
+ return;
+ }
+
+ if (DEBUG) Log.d(TAG, "PagedView.onLayout()");
+ final int childCount = getChildCount();
+
+ int offsetX = getViewportOffsetX();
+ int offsetY = getViewportOffsetY();
+
+ // Update the viewport offsets
+ mViewport.offset(offsetX, offsetY);
+
+ int childLeft = offsetX + getRelativeChildOffset(0);
+ for (int i = 0; i < childCount; i++) {
+ final View child = getPageAt(i);
+ int childTop = offsetY + getPaddingTop();
+ if (child.getVisibility() != View.GONE) {
+ final int childWidth = getScaledMeasuredWidth(child);
+ final int childHeight = child.getMeasuredHeight();
+
+ if (DEBUG) Log.d(TAG, "\tlayout-child" + i + ": " + childLeft + ", " + childTop);
+ child.layout(childLeft, childTop,
+ childLeft + child.getMeasuredWidth(), childTop + childHeight);
+ childLeft += childWidth + mPageSpacing;
+ }
+ }
+
+ if (mFirstLayout && mCurrentPage >= 0 && mCurrentPage < getChildCount()) {
+ setHorizontalScrollBarEnabled(false);
+ updateCurrentPageScroll();
+ setHorizontalScrollBarEnabled(true);
+ mFirstLayout = false;
+ }
+ }
+
+ protected void screenScrolled(int screenCenter) {
+ }
+
+ @Override
+ public void onChildViewAdded(View parent, View child) {
+ // This ensures that when children are added, they get the correct transforms / alphas
+ // in accordance with any scroll effects.
+ mForceScreenScrolled = true;
+ invalidate();
+ invalidateCachedOffsets();
+ }
+
+ @Override
+ public void onChildViewRemoved(View parent, View child) {
+ mForceScreenScrolled = true;
+ }
+
+ protected void invalidateCachedOffsets() {
+ int count = getChildCount();
+ if (count == 0) {
+ mChildOffsets = null;
+ mChildRelativeOffsets = null;
+ mChildOffsetsWithLayoutScale = null;
+ return;
+ }
+
+ mChildOffsets = new int[count];
+ mChildRelativeOffsets = new int[count];
+ mChildOffsetsWithLayoutScale = new int[count];
+ for (int i = 0; i < count; i++) {
+ mChildOffsets[i] = -1;
+ mChildRelativeOffsets[i] = -1;
+ mChildOffsetsWithLayoutScale[i] = -1;
+ }
+ }
+
+ protected int getChildOffset(int index) {
+ if (index < 0 || index > getChildCount() - 1) return 0;
+
+ int[] childOffsets = Float.compare(mLayoutScale, 1f) == 0 ?
+ mChildOffsets : mChildOffsetsWithLayoutScale;
+
+ if (childOffsets != null && childOffsets[index] != -1) {
+ return childOffsets[index];
+ } else {
+ if (getChildCount() == 0)
+ return 0;
+
+ int offset = getRelativeChildOffset(0);
+ for (int i = 0; i < index; ++i) {
+ offset += getScaledMeasuredWidth(getPageAt(i)) + mPageSpacing;
+ }
+ if (childOffsets != null) {
+ childOffsets[index] = offset;
+ }
+ return offset;
+ }
+ }
+
+ protected int getRelativeChildOffset(int index) {
+ if (index < 0 || index > getChildCount() - 1) return 0;
+
+ if (mChildRelativeOffsets != null && mChildRelativeOffsets[index] != -1) {
+ return mChildRelativeOffsets[index];
+ } else {
+ final int padding = getPaddingLeft() + getPaddingRight();
+ final int offset = getPaddingLeft() +
+ (getViewportWidth() - padding - getChildWidth(index)) / 2;
+ if (mChildRelativeOffsets != null) {
+ mChildRelativeOffsets[index] = offset;
+ }
+ return offset;
+ }
+ }
+
+ protected int getScaledMeasuredWidth(View child) {
+ // This functions are called enough times that it actually makes a difference in the
+ // profiler -- so just inline the max() here
+ final int measuredWidth = child.getMeasuredWidth();
+ final int minWidth = mMinimumWidth;
+ final int maxWidth = (minWidth > measuredWidth) ? minWidth : measuredWidth;
+ return (int) (maxWidth * mLayoutScale + 0.5f);
+ }
+
+ void boundByReorderablePages(boolean isReordering, int[] range) {
+ // Do nothing
+ }
+
+ // TODO: Fix this
+ protected void getVisiblePages(int[] range) {
+ range[0] = 0;
+ range[1] = getPageCount() - 1;
+
+ /*
+ final int pageCount = getChildCount();
+
+ if (pageCount > 0) {
+ final int screenWidth = getViewportWidth();
+ int leftScreen = 0;
+ int rightScreen = 0;
+ int offsetX = getViewportOffsetX() + getScrollX();
+ View currPage = getPageAt(leftScreen);
+ while (leftScreen < pageCount - 1 &&
+ currPage.getX() + currPage.getWidth() -
+ currPage.getPaddingRight() < offsetX) {
+ leftScreen++;
+ currPage = getPageAt(leftScreen);
+ }
+ rightScreen = leftScreen;
+ currPage = getPageAt(rightScreen + 1);
+ while (rightScreen < pageCount - 1 &&
+ currPage.getX() - currPage.getPaddingLeft() < offsetX + screenWidth) {
+ rightScreen++;
+ currPage = getPageAt(rightScreen + 1);
+ }
+
+ // TEMP: this is a hacky way to ensure that animations to new pages are not clipped
+ // because we don't draw them while scrolling?
+ range[0] = Math.max(0, leftScreen - 1);
+ range[1] = Math.min(rightScreen + 1, getChildCount() - 1);
+ } else {
+ range[0] = -1;
+ range[1] = -1;
+ }
+ */
+ }
+
+ protected boolean shouldDrawChild(View child) {
+ return child.getAlpha() > 0;
+ }
+
+ @Override
+ protected void dispatchDraw(Canvas canvas) {
+ int halfScreenSize = getViewportWidth() / 2;
+ // mOverScrollX is equal to getScrollX() when we're within the normal scroll range.
+ // Otherwise it is equal to the scaled overscroll position.
+ int screenCenter = mOverScrollX + halfScreenSize;
+
+ if (screenCenter != mLastScreenCenter || mForceScreenScrolled) {
+ // set mForceScreenScrolled before calling screenScrolled so that screenScrolled can
+ // set it for the next frame
+ mForceScreenScrolled = false;
+ screenScrolled(screenCenter);
+ mLastScreenCenter = screenCenter;
+ }
+
+ // Find out which screens are visible; as an optimization we only call draw on them
+ final int pageCount = getChildCount();
+ if (pageCount > 0) {
+ getVisiblePages(mTempVisiblePagesRange);
+ final int leftScreen = mTempVisiblePagesRange[0];
+ final int rightScreen = mTempVisiblePagesRange[1];
+ if (leftScreen != -1 && rightScreen != -1) {
+ final long drawingTime = getDrawingTime();
+ // Clip to the bounds
+ canvas.save();
+ canvas.clipRect(getScrollX(), getScrollY(), getScrollX() + getRight() - getLeft(),
+ getScrollY() + getBottom() - getTop());
+
+ // Draw all the children, leaving the drag view for last
+ for (int i = pageCount - 1; i >= 0; i--) {
+ final View v = getPageAt(i);
+ if (v == mDragView) continue;
+ if (mForceDrawAllChildrenNextFrame ||
+ (leftScreen <= i && i <= rightScreen && shouldDrawChild(v))) {
+ drawChild(canvas, v, drawingTime);
+ }
+ }
+ // Draw the drag view on top (if there is one)
+ if (mDragView != null) {
+ drawChild(canvas, mDragView, drawingTime);
+ }
+
+ mForceDrawAllChildrenNextFrame = false;
+ canvas.restore();
+ }
+ }
+ }
+
+ @Override
+ public boolean requestChildRectangleOnScreen(View child, Rect rectangle, boolean immediate) {
+ int page = indexToPage(indexOfChild(child));
+ if (page != mCurrentPage || !mScroller.isFinished()) {
+ snapToPage(page);
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ protected boolean onRequestFocusInDescendants(int direction, Rect previouslyFocusedRect) {
+ int focusablePage;
+ if (mNextPage != INVALID_PAGE) {
+ focusablePage = mNextPage;
+ } else {
+ focusablePage = mCurrentPage;
+ }
+ View v = getPageAt(focusablePage);
+ if (v != null) {
+ return v.requestFocus(direction, previouslyFocusedRect);
+ }
+ return false;
+ }
+
+ @Override
+ public boolean dispatchUnhandledMove(View focused, int direction) {
+ if (direction == View.FOCUS_LEFT) {
+ if (getCurrentPage() > 0) {
+ snapToPage(getCurrentPage() - 1);
+ return true;
+ }
+ } else if (direction == View.FOCUS_RIGHT) {
+ if (getCurrentPage() < getPageCount() - 1) {
+ snapToPage(getCurrentPage() + 1);
+ return true;
+ }
+ }
+ return super.dispatchUnhandledMove(focused, direction);
+ }
+
+ @Override
+ public void addFocusables(ArrayList<View> views, int direction, int focusableMode) {
+ if (mCurrentPage >= 0 && mCurrentPage < getPageCount()) {
+ getPageAt(mCurrentPage).addFocusables(views, direction, focusableMode);
+ }
+ if (direction == View.FOCUS_LEFT) {
+ if (mCurrentPage > 0) {
+ getPageAt(mCurrentPage - 1).addFocusables(views, direction, focusableMode);
+ }
+ } else if (direction == View.FOCUS_RIGHT){
+ if (mCurrentPage < getPageCount() - 1) {
+ getPageAt(mCurrentPage + 1).addFocusables(views, direction, focusableMode);
+ }
+ }
+ }
+
+ /**
+ * If one of our descendant views decides that it could be focused now, only
+ * pass that along if it's on the current page.
+ *
+ * This happens when live folders requery, and if they're off page, they
+ * end up calling requestFocus, which pulls it on page.
+ */
+ @Override
+ public void focusableViewAvailable(View focused) {
+ View current = getPageAt(mCurrentPage);
+ View v = focused;
+ while (true) {
+ if (v == current) {
+ super.focusableViewAvailable(focused);
+ return;
+ }
+ if (v == this) {
+ return;
+ }
+ ViewParent parent = v.getParent();
+ if (parent instanceof View) {
+ v = (View)v.getParent();
+ } else {
+ return;
+ }
+ }
+ }
+
+ /**
+ * Return true if a tap at (x, y) should trigger a flip to the previous page.
+ */
+ protected boolean hitsPreviousPage(float x, float y) {
+ return (x < getViewportOffsetX() + getRelativeChildOffset(mCurrentPage) - mPageSpacing);
+ }
+
+ /**
+ * Return true if a tap at (x, y) should trigger a flip to the next page.
+ */
+ protected boolean hitsNextPage(float x, float y) {
+ return (x > (getViewportOffsetX() + getViewportWidth() - getRelativeChildOffset(mCurrentPage) + mPageSpacing));
+ }
+
+ /** Returns whether x and y originated within the buffered viewport */
+ private boolean isTouchPointInViewportWithBuffer(int x, int y) {
+ mTmpRect.set(mViewport.left - mViewport.width() / 2, mViewport.top,
+ mViewport.right + mViewport.width() / 2, mViewport.bottom);
+ return mTmpRect.contains(x, y);
+ }
+
+ /** Returns whether x and y originated within the current page view bounds */
+ private boolean isTouchPointInCurrentPage(int x, int y) {
+ View v = getPageAt(getCurrentPage());
+ if (v != null) {
+ mTmpRect.set((v.getLeft() - getScrollX()), 0, (v.getRight() - getScrollX()),
+ v.getBottom());
+ return mTmpRect.contains(x, y);
+ }
+ return false;
+ }
+
+ @Override
+ public boolean onInterceptTouchEvent(MotionEvent ev) {
+ if (DISABLE_TOUCH_INTERACTION) {
+ return false;
+ }
+
+ /*
+ * This method JUST determines whether we want to intercept the motion.
+ * If we return true, onTouchEvent will be called and we do the actual
+ * scrolling there.
+ */
+ acquireVelocityTrackerAndAddMovement(ev);
+
+ // Skip touch handling if there are no pages to swipe
+ if (getChildCount() <= 0) return super.onInterceptTouchEvent(ev);
+
+ /*
+ * Shortcut the most recurring case: the user is in the dragging
+ * state and he is moving his finger. We want to intercept this
+ * motion.
+ */
+ final int action = ev.getAction();
+ if ((action == MotionEvent.ACTION_MOVE) &&
+ (mTouchState == TOUCH_STATE_SCROLLING)) {
+ return true;
+ }
+
+ switch (action & MotionEvent.ACTION_MASK) {
+ case MotionEvent.ACTION_MOVE: {
+ /*
+ * mIsBeingDragged == false, otherwise the shortcut would have caught it. Check
+ * whether the user has moved far enough from his original down touch.
+ */
+ if (mActivePointerId != INVALID_POINTER) {
+ determineScrollingStart(ev);
+ break;
+ }
+ // if mActivePointerId is INVALID_POINTER, then we must have missed an ACTION_DOWN
+ // event. in that case, treat the first occurence of a move event as a ACTION_DOWN
+ // i.e. fall through to the next case (don't break)
+ // (We sometimes miss ACTION_DOWN events in Workspace because it ignores all events
+ // while it's small- this was causing a crash before we checked for INVALID_POINTER)
+ }
+
+ case MotionEvent.ACTION_DOWN: {
+ final float x = ev.getX();
+ final float y = ev.getY();
+ // Remember location of down touch
+ mDownMotionX = x;
+ mDownMotionY = y;
+ mDownScrollX = getScrollX();
+ mLastMotionX = x;
+ mLastMotionY = y;
+ float[] p = mapPointFromViewToParent(this, x, y);
+ mParentDownMotionX = p[0];
+ mParentDownMotionY = p[1];
+ mLastMotionXRemainder = 0;
+ mTotalMotionX = 0;
+ mActivePointerId = ev.getPointerId(0);
+
+ // Determine if the down event is within the threshold to be an edge swipe
+ int leftEdgeBoundary = getViewportOffsetX() + mEdgeSwipeRegionSize;
+ int rightEdgeBoundary = getMeasuredWidth() - getViewportOffsetX() - mEdgeSwipeRegionSize;
+ if ((mDownMotionX <= leftEdgeBoundary || mDownMotionX >= rightEdgeBoundary)) {
+ mDownEventOnEdge = true;
+ }
+
+ /*
+ * If being flinged and user touches the screen, initiate drag;
+ * otherwise don't. mScroller.isFinished should be false when
+ * being flinged.
+ */
+ final int xDist = Math.abs(mScroller.getFinalX() - mScroller.getCurrX());
+ final boolean finishedScrolling = (mScroller.isFinished() || xDist < mTouchSlop);
+ if (finishedScrolling) {
+ mTouchState = TOUCH_STATE_REST;
+ mScroller.abortAnimation();
+ } else {
+ if (isTouchPointInViewportWithBuffer((int) mDownMotionX, (int) mDownMotionY)) {
+ mTouchState = TOUCH_STATE_SCROLLING;
+ } else {
+ mTouchState = TOUCH_STATE_REST;
+ }
+ }
+
+ // check if this can be the beginning of a tap on the side of the pages
+ // to scroll the current page
+ if (!DISABLE_TOUCH_SIDE_PAGES) {
+ if (mTouchState != TOUCH_STATE_PREV_PAGE && mTouchState != TOUCH_STATE_NEXT_PAGE) {
+ if (getChildCount() > 0) {
+ if (hitsPreviousPage(x, y)) {
+ mTouchState = TOUCH_STATE_PREV_PAGE;
+ } else if (hitsNextPage(x, y)) {
+ mTouchState = TOUCH_STATE_NEXT_PAGE;
+ }
+ }
+ }
+ }
+ break;
+ }
+
+ case MotionEvent.ACTION_UP:
+ case MotionEvent.ACTION_CANCEL:
+ resetTouchState();
+ // Just intercept the touch event on up if we tap outside the strict viewport
+ if (!isTouchPointInCurrentPage((int) mLastMotionX, (int) mLastMotionY)) {
+ return true;
+ }
+ break;
+
+ case MotionEvent.ACTION_POINTER_UP:
+ onSecondaryPointerUp(ev);
+ releaseVelocityTracker();
+ break;
+ }
+
+ /*
+ * The only time we want to intercept motion events is if we are in the
+ * drag mode.
+ */
+ return mTouchState != TOUCH_STATE_REST;
+ }
+
+ protected void determineScrollingStart(MotionEvent ev) {
+ determineScrollingStart(ev, 1.0f);
+ }
+
+ /*
+ * Determines if we should change the touch state to start scrolling after the
+ * user moves their touch point too far.
+ */
+ protected void determineScrollingStart(MotionEvent ev, float touchSlopScale) {
+ // Disallow scrolling if we don't have a valid pointer index
+ final int pointerIndex = ev.findPointerIndex(mActivePointerId);
+ if (pointerIndex == -1) return;
+
+ // Disallow scrolling if we started the gesture from outside the viewport
+ final float x = ev.getX(pointerIndex);
+ final float y = ev.getY(pointerIndex);
+ if (!isTouchPointInViewportWithBuffer((int) x, (int) y)) return;
+
+ // If we're only allowing edge swipes, we break out early if the down event wasn't
+ // at the edge.
+ if (mOnlyAllowEdgeSwipes && !mDownEventOnEdge) return;
+
+ final int xDiff = (int) Math.abs(x - mLastMotionX);
+ final int yDiff = (int) Math.abs(y - mLastMotionY);
+
+ final int touchSlop = Math.round(touchSlopScale * mTouchSlop);
+ boolean xPaged = xDiff > mPagingTouchSlop;
+ boolean xMoved = xDiff > touchSlop;
+ boolean yMoved = yDiff > touchSlop;
+
+ if (xMoved || xPaged || yMoved) {
+ if (mUsePagingTouchSlop ? xPaged : xMoved) {
+ // Scroll if the user moved far enough along the X axis
+ mTouchState = TOUCH_STATE_SCROLLING;
+ mTotalMotionX += Math.abs(mLastMotionX - x);
+ mLastMotionX = x;
+ mLastMotionXRemainder = 0;
+ mTouchX = getViewportOffsetX() + getScrollX();
+ mSmoothingTime = System.nanoTime() / NANOTIME_DIV;
+ pageBeginMoving();
+ }
+ }
+ }
+
+ protected float getMaxScrollProgress() {
+ return 1.0f;
+ }
+
+ protected float getBoundedScrollProgress(int screenCenter, View v, int page) {
+ final int halfScreenSize = getViewportWidth() / 2;
+
+ screenCenter = Math.min(mScrollX + halfScreenSize, screenCenter);
+ screenCenter = Math.max(halfScreenSize, screenCenter);
+
+ return getScrollProgress(screenCenter, v, page);
+ }
+
+ protected float getScrollProgress(int screenCenter, View v, int page) {
+ final int halfScreenSize = getViewportWidth() / 2;
+
+ int totalDistance = getScaledMeasuredWidth(v) + mPageSpacing;
+ int delta = screenCenter - (getChildOffset(page) -
+ getRelativeChildOffset(page) + halfScreenSize);
+
+ float scrollProgress = delta / (totalDistance * 1.0f);
+ scrollProgress = Math.min(scrollProgress, getMaxScrollProgress());
+ scrollProgress = Math.max(scrollProgress, - getMaxScrollProgress());
+ return scrollProgress;
+ }
+
+ // This curve determines how the effect of scrolling over the limits of the page dimishes
+ // as the user pulls further and further from the bounds
+ private float overScrollInfluenceCurve(float f) {
+ f -= 1.0f;
+ return f * f * f + 1.0f;
+ }
+
+ protected void acceleratedOverScroll(float amount) {
+ int screenSize = getViewportWidth();
+
+ // We want to reach the max over scroll effect when the user has
+ // over scrolled half the size of the screen
+ float f = OVERSCROLL_ACCELERATE_FACTOR * (amount / screenSize);
+
+ if (f == 0) return;
+
+ // Clamp this factor, f, to -1 < f < 1
+ if (Math.abs(f) >= 1) {
+ f /= Math.abs(f);
+ }
+
+ int overScrollAmount = (int) Math.round(f * screenSize);
+ if (amount < 0) {
+ mOverScrollX = overScrollAmount;
+ super.scrollTo(0, getScrollY());
+ } else {
+ mOverScrollX = mMaxScrollX + overScrollAmount;
+ super.scrollTo(mMaxScrollX, getScrollY());
+ }
+ invalidate();
+ }
+
+ protected void dampedOverScroll(float amount) {
+ int screenSize = getViewportWidth();
+
+ float f = (amount / screenSize);
+
+ if (f == 0) return;
+ f = f / (Math.abs(f)) * (overScrollInfluenceCurve(Math.abs(f)));
+
+ // Clamp this factor, f, to -1 < f < 1
+ if (Math.abs(f) >= 1) {
+ f /= Math.abs(f);
+ }
+
+ int overScrollAmount = (int) Math.round(OVERSCROLL_DAMP_FACTOR * f * screenSize);
+ if (amount < 0) {
+ mOverScrollX = overScrollAmount;
+ super.scrollTo(0, getScrollY());
+ } else {
+ mOverScrollX = mMaxScrollX + overScrollAmount;
+ super.scrollTo(mMaxScrollX, getScrollY());
+ }
+ invalidate();
+ }
+
+ protected void overScroll(float amount) {
+ dampedOverScroll(amount);
+ }
+
+ protected float maxOverScroll() {
+ // Using the formula in overScroll, assuming that f = 1.0 (which it should generally not
+ // exceed). Used to find out how much extra wallpaper we need for the over scroll effect
+ float f = 1.0f;
+ f = f / (Math.abs(f)) * (overScrollInfluenceCurve(Math.abs(f)));
+ return OVERSCROLL_DAMP_FACTOR * f;
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent ev) {
+ if (DISABLE_TOUCH_INTERACTION) {
+ return false;
+ }
+
+ // Skip touch handling if there are no pages to swipe
+ if (getChildCount() <= 0) return super.onTouchEvent(ev);
+
+ acquireVelocityTrackerAndAddMovement(ev);
+
+ final int action = ev.getAction();
+
+ switch (action & MotionEvent.ACTION_MASK) {
+ case MotionEvent.ACTION_DOWN:
+ /*
+ * If being flinged and user touches, stop the fling. isFinished
+ * will be false if being flinged.
+ */
+ if (!mScroller.isFinished()) {
+ mScroller.abortAnimation();
+ }
+
+ // Remember where the motion event started
+ mDownMotionX = mLastMotionX = ev.getX();
+ mDownMotionY = mLastMotionY = ev.getY();
+ mDownScrollX = getScrollX();
+ float[] p = mapPointFromViewToParent(this, mLastMotionX, mLastMotionY);
+ mParentDownMotionX = p[0];
+ mParentDownMotionY = p[1];
+ mLastMotionXRemainder = 0;
+ mTotalMotionX = 0;
+ mActivePointerId = ev.getPointerId(0);
+
+ // Determine if the down event is within the threshold to be an edge swipe
+ int leftEdgeBoundary = getViewportOffsetX() + mEdgeSwipeRegionSize;
+ int rightEdgeBoundary = getMeasuredWidth() - getViewportOffsetX() - mEdgeSwipeRegionSize;
+ if ((mDownMotionX <= leftEdgeBoundary || mDownMotionX >= rightEdgeBoundary)) {
+ mDownEventOnEdge = true;
+ }
+
+ if (mTouchState == TOUCH_STATE_SCROLLING) {
+ pageBeginMoving();
+ }
+ break;
+
+ case MotionEvent.ACTION_MOVE:
+ if (mTouchState == TOUCH_STATE_SCROLLING) {
+ // Scroll to follow the motion event
+ final int pointerIndex = ev.findPointerIndex(mActivePointerId);
+ final float x = ev.getX(pointerIndex);
+ final float deltaX = mLastMotionX + mLastMotionXRemainder - x;
+
+ mTotalMotionX += Math.abs(deltaX);
+
+ // Only scroll and update mLastMotionX if we have moved some discrete amount. We
+ // keep the remainder because we are actually testing if we've moved from the last
+ // scrolled position (which is discrete).
+ if (Math.abs(deltaX) >= 1.0f) {
+ mTouchX += deltaX;
+ mSmoothingTime = System.nanoTime() / NANOTIME_DIV;
+ if (!mDeferScrollUpdate) {
+ scrollBy((int) deltaX, 0);
+ if (DEBUG) Log.d(TAG, "onTouchEvent().Scrolling: " + deltaX);
+ } else {
+ invalidate();
+ }
+ mLastMotionX = x;
+ mLastMotionXRemainder = deltaX - (int) deltaX;
+ } else {
+ awakenScrollBars();
+ }
+ } else if (mTouchState == TOUCH_STATE_REORDERING) {
+ // Update the last motion position
+ mLastMotionX = ev.getX();
+ mLastMotionY = ev.getY();
+
+ // Update the parent down so that our zoom animations take this new movement into
+ // account
+ float[] pt = mapPointFromViewToParent(this, mLastMotionX, mLastMotionY);
+ mParentDownMotionX = pt[0];
+ mParentDownMotionY = pt[1];
+ updateDragViewTranslationDuringDrag();
+
+ // Find the closest page to the touch point
+ final int dragViewIndex = indexOfChild(mDragView);
+ int bufferSize = (int) (REORDERING_SIDE_PAGE_BUFFER_PERCENTAGE *
+ getViewportWidth());
+ int leftBufferEdge = (int) (mapPointFromViewToParent(this, mViewport.left, 0)[0]
+ + bufferSize);
+ int rightBufferEdge = (int) (mapPointFromViewToParent(this, mViewport.right, 0)[0]
+ - bufferSize);
+
+ // Change the drag view if we are hovering over the drop target
+ boolean isHoveringOverDelete = isHoveringOverDeleteDropTarget(
+ (int) mParentDownMotionX, (int) mParentDownMotionY);
+ setPageHoveringOverDeleteDropTarget(dragViewIndex, isHoveringOverDelete);
+
+ if (DEBUG) Log.d(TAG, "leftBufferEdge: " + leftBufferEdge);
+ if (DEBUG) Log.d(TAG, "rightBufferEdge: " + rightBufferEdge);
+ if (DEBUG) Log.d(TAG, "mLastMotionX: " + mLastMotionX);
+ if (DEBUG) Log.d(TAG, "mLastMotionY: " + mLastMotionY);
+ if (DEBUG) Log.d(TAG, "mParentDownMotionX: " + mParentDownMotionX);
+ if (DEBUG) Log.d(TAG, "mParentDownMotionY: " + mParentDownMotionY);
+
+ float parentX = mParentDownMotionX;
+ int pageIndexToSnapTo = -1;
+ if (parentX < leftBufferEdge && dragViewIndex > 0) {
+ pageIndexToSnapTo = dragViewIndex - 1;
+ } else if (parentX > rightBufferEdge && dragViewIndex < getChildCount() - 1) {
+ pageIndexToSnapTo = dragViewIndex + 1;
+ }
+
+ final int pageUnderPointIndex = pageIndexToSnapTo;
+ if (pageUnderPointIndex > -1 && !isHoveringOverDelete) {
+ mTempVisiblePagesRange[0] = 0;
+ mTempVisiblePagesRange[1] = getPageCount() - 1;
+ boundByReorderablePages(true, mTempVisiblePagesRange);
+ if (mTempVisiblePagesRange[0] <= pageUnderPointIndex &&
+ pageUnderPointIndex <= mTempVisiblePagesRange[1] &&
+ pageUnderPointIndex != mSidePageHoverIndex && mScroller.isFinished()) {
+ mSidePageHoverIndex = pageUnderPointIndex;
+ mSidePageHoverRunnable = new Runnable() {
+ @Override
+ public void run() {
+ // Update the down scroll position to account for the fact that the
+ // current page is moved
+ mDownScrollX = getChildOffset(pageUnderPointIndex)
+ - getRelativeChildOffset(pageUnderPointIndex);
+
+ // Setup the scroll to the correct page before we swap the views
+ snapToPage(pageUnderPointIndex);
+
+ // For each of the pages between the paged view and the drag view,
+ // animate them from the previous position to the new position in
+ // the layout (as a result of the drag view moving in the layout)
+ int shiftDelta = (dragViewIndex < pageUnderPointIndex) ? -1 : 1;
+ int lowerIndex = (dragViewIndex < pageUnderPointIndex) ?
+ dragViewIndex + 1 : pageUnderPointIndex;
+ int upperIndex = (dragViewIndex > pageUnderPointIndex) ?
+ dragViewIndex - 1 : pageUnderPointIndex;
+ for (int i = lowerIndex; i <= upperIndex; ++i) {
+ View v = getChildAt(i);
+ // dragViewIndex < pageUnderPointIndex, so after we remove the
+ // drag view all subsequent views to pageUnderPointIndex will
+ // shift down.
+ int oldX = getViewportOffsetX() + getChildOffset(i);
+ int newX = getViewportOffsetX() + getChildOffset(i + shiftDelta);
+
+ // Animate the view translation from its old position to its new
+ // position
+ AnimatorSet anim = (AnimatorSet) v.getTag();
+ if (anim != null) {
+ anim.cancel();
+ }
+
+ v.setTranslationX(oldX - newX);
+ anim = new AnimatorSet();
+ anim.setDuration(REORDERING_REORDER_REPOSITION_DURATION);
+ anim.playTogether(
+ ObjectAnimator.ofFloat(v, "translationX", 0f));
+ anim.start();
+ v.setTag(anim);
+ }
+
+ removeView(mDragView);
+ onRemoveView(mDragView, false);
+ addView(mDragView, pageUnderPointIndex);
+ onAddView(mDragView, pageUnderPointIndex);
+ mSidePageHoverIndex = -1;
+ }
+ };
+ postDelayed(mSidePageHoverRunnable, REORDERING_SIDE_PAGE_HOVER_TIMEOUT);
+ }
+ } else {
+ removeCallbacks(mSidePageHoverRunnable);
+ mSidePageHoverIndex = -1;
+ }
+ } else {
+ determineScrollingStart(ev);
+ }
+ break;
+
+ case MotionEvent.ACTION_UP:
+ if (mTouchState == TOUCH_STATE_SCROLLING) {
+ final int activePointerId = mActivePointerId;
+ final int pointerIndex = ev.findPointerIndex(activePointerId);
+ final float x = ev.getX(pointerIndex);
+ final VelocityTracker velocityTracker = mVelocityTracker;
+ velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
+ int velocityX = (int) velocityTracker.getXVelocity(activePointerId);
+ final int deltaX = (int) (x - mDownMotionX);
+ final int pageWidth = getScaledMeasuredWidth(getPageAt(mCurrentPage));
+ boolean isSignificantMove = Math.abs(deltaX) > pageWidth *
+ SIGNIFICANT_MOVE_THRESHOLD;
+
+ mTotalMotionX += Math.abs(mLastMotionX + mLastMotionXRemainder - x);
+
+ boolean isFling = mTotalMotionX > MIN_LENGTH_FOR_FLING &&
+ Math.abs(velocityX) > mFlingThresholdVelocity;
+
+ // In the case that the page is moved far to one direction and then is flung
+ // in the opposite direction, we use a threshold to determine whether we should
+ // just return to the starting page, or if we should skip one further.
+ boolean returnToOriginalPage = false;
+ if (Math.abs(deltaX) > pageWidth * RETURN_TO_ORIGINAL_PAGE_THRESHOLD &&
+ Math.signum(velocityX) != Math.signum(deltaX) && isFling) {
+ returnToOriginalPage = true;
+ }
+
+ int finalPage;
+ // We give flings precedence over large moves, which is why we short-circuit our
+ // test for a large move if a fling has been registered. That is, a large
+ // move to the left and fling to the right will register as a fling to the right.
+ if (((isSignificantMove && deltaX > 0 && !isFling) ||
+ (isFling && velocityX > 0)) && mCurrentPage > 0) {
+ finalPage = returnToOriginalPage ? mCurrentPage : mCurrentPage - 1;
+ snapToPageWithVelocity(finalPage, velocityX);
+ } else if (((isSignificantMove && deltaX < 0 && !isFling) ||
+ (isFling && velocityX < 0)) &&
+ mCurrentPage < getChildCount() - 1) {
+ finalPage = returnToOriginalPage ? mCurrentPage : mCurrentPage + 1;
+ snapToPageWithVelocity(finalPage, velocityX);
+ } else {
+ snapToDestination();
+ }
+ } else if (mTouchState == TOUCH_STATE_PREV_PAGE) {
+ // at this point we have not moved beyond the touch slop
+ // (otherwise mTouchState would be TOUCH_STATE_SCROLLING), so
+ // we can just page
+ int nextPage = Math.max(0, mCurrentPage - 1);
+ if (nextPage != mCurrentPage) {
+ snapToPage(nextPage);
+ } else {
+ snapToDestination();
+ }
+ } else if (mTouchState == TOUCH_STATE_NEXT_PAGE) {
+ // at this point we have not moved beyond the touch slop
+ // (otherwise mTouchState would be TOUCH_STATE_SCROLLING), so
+ // we can just page
+ int nextPage = Math.min(getChildCount() - 1, mCurrentPage + 1);
+ if (nextPage != mCurrentPage) {
+ snapToPage(nextPage);
+ } else {
+ snapToDestination();
+ }
+ } else if (mTouchState == TOUCH_STATE_REORDERING) {
+ // Update the last motion position
+ mLastMotionX = ev.getX();
+ mLastMotionY = ev.getY();
+
+ // Update the parent down so that our zoom animations take this new movement into
+ // account
+ float[] pt = mapPointFromViewToParent(this, mLastMotionX, mLastMotionY);
+ mParentDownMotionX = pt[0];
+ mParentDownMotionY = pt[1];
+ updateDragViewTranslationDuringDrag();
+ boolean handledFling = false;
+ if (!DISABLE_FLING_TO_DELETE) {
+ // Check the velocity and see if we are flinging-to-delete
+ PointF flingToDeleteVector = isFlingingToDelete();
+ if (flingToDeleteVector != null) {
+ onFlingToDelete(flingToDeleteVector);
+ handledFling = true;
+ }
+ }
+ if (!handledFling && isHoveringOverDeleteDropTarget((int) mParentDownMotionX,
+ (int) mParentDownMotionY)) {
+ onDropToDelete();
+ }
+ } else {
+ onUnhandledTap(ev);
+ }
+
+ // Remove the callback to wait for the side page hover timeout
+ removeCallbacks(mSidePageHoverRunnable);
+ // End any intermediate reordering states
+ resetTouchState();
+ break;
+
+ case MotionEvent.ACTION_CANCEL:
+ if (mTouchState == TOUCH_STATE_SCROLLING) {
+ snapToDestination();
+ }
+ resetTouchState();
+ break;
+
+ case MotionEvent.ACTION_POINTER_UP:
+ onSecondaryPointerUp(ev);
+ break;
+ }
+
+ return true;
+ }
+
+ //public abstract void onFlingToDelete(View v);
+ public abstract void onRemoveView(View v, boolean deletePermanently);
+ public abstract void onRemoveViewAnimationCompleted();
+ public abstract void onAddView(View v, int index);
+
+ private void resetTouchState() {
+ releaseVelocityTracker();
+ endReordering();
+ mTouchState = TOUCH_STATE_REST;
+ mActivePointerId = INVALID_POINTER;
+ mDownEventOnEdge = false;
+ }
+
+ protected void onUnhandledTap(MotionEvent ev) {}
+
+ @Override
+ public boolean onGenericMotionEvent(MotionEvent event) {
+ if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) {
+ switch (event.getAction()) {
+ case MotionEvent.ACTION_SCROLL: {
+ // Handle mouse (or ext. device) by shifting the page depending on the scroll
+ final float vscroll;
+ final float hscroll;
+ if ((event.getMetaState() & KeyEvent.META_SHIFT_ON) != 0) {
+ vscroll = 0;
+ hscroll = event.getAxisValue(MotionEvent.AXIS_VSCROLL);
+ } else {
+ vscroll = -event.getAxisValue(MotionEvent.AXIS_VSCROLL);
+ hscroll = event.getAxisValue(MotionEvent.AXIS_HSCROLL);
+ }
+ if (hscroll != 0 || vscroll != 0) {
+ if (hscroll > 0 || vscroll > 0) {
+ scrollRight();
+ } else {
+ scrollLeft();
+ }
+ return true;
+ }
+ }
+ }
+ }
+ return super.onGenericMotionEvent(event);
+ }
+
+ private void acquireVelocityTrackerAndAddMovement(MotionEvent ev) {
+ if (mVelocityTracker == null) {
+ mVelocityTracker = VelocityTracker.obtain();
+ }
+ mVelocityTracker.addMovement(ev);
+ }
+
+ private void releaseVelocityTracker() {
+ if (mVelocityTracker != null) {
+ mVelocityTracker.recycle();
+ mVelocityTracker = null;
+ }
+ }
+
+ private void onSecondaryPointerUp(MotionEvent ev) {
+ final int pointerIndex = (ev.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) >>
+ MotionEvent.ACTION_POINTER_INDEX_SHIFT;
+ final int pointerId = ev.getPointerId(pointerIndex);
+ if (pointerId == mActivePointerId) {
+ // This was our active pointer going up. Choose a new
+ // active pointer and adjust accordingly.
+ // TODO: Make this decision more intelligent.
+ final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
+ mLastMotionX = mDownMotionX = ev.getX(newPointerIndex);
+ mLastMotionY = ev.getY(newPointerIndex);
+ mLastMotionXRemainder = 0;
+ mActivePointerId = ev.getPointerId(newPointerIndex);
+ if (mVelocityTracker != null) {
+ mVelocityTracker.clear();
+ }
+ }
+ }
+
+ @Override
+ public void requestChildFocus(View child, View focused) {
+ super.requestChildFocus(child, focused);
+ int page = indexToPage(indexOfChild(child));
+ if (page >= 0 && page != getCurrentPage() && !isInTouchMode()) {
+ snapToPage(page);
+ }
+ }
+
+ protected int getChildIndexForRelativeOffset(int relativeOffset) {
+ final int childCount = getChildCount();
+ int left;
+ int right;
+ for (int i = 0; i < childCount; ++i) {
+ left = getRelativeChildOffset(i);
+ right = (left + getScaledMeasuredWidth(getPageAt(i)));
+ if (left <= relativeOffset && relativeOffset <= right) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ protected int getChildWidth(int index) {
+ // This functions are called enough times that it actually makes a difference in the
+ // profiler -- so just inline the max() here
+ final int measuredWidth = getPageAt(index).getMeasuredWidth();
+ final int minWidth = mMinimumWidth;
+ return (minWidth > measuredWidth) ? minWidth : measuredWidth;
+ }
+
+ int getPageNearestToPoint(float x) {
+ int index = 0;
+ for (int i = 0; i < getChildCount(); ++i) {
+ if (x < getChildAt(i).getRight() - getScrollX()) {
+ return index;
+ } else {
+ index++;
+ }
+ }
+ return Math.min(index, getChildCount() - 1);
+ }
+
+ int getPageNearestToCenterOfScreen() {
+ int minDistanceFromScreenCenter = Integer.MAX_VALUE;
+ int minDistanceFromScreenCenterIndex = -1;
+ int screenCenter = getViewportOffsetX() + getScrollX() + (getViewportWidth() / 2);
+ final int childCount = getChildCount();
+ for (int i = 0; i < childCount; ++i) {
+ View layout = (View) getPageAt(i);
+ int childWidth = getScaledMeasuredWidth(layout);
+ int halfChildWidth = (childWidth / 2);
+ int childCenter = getViewportOffsetX() + getChildOffset(i) + halfChildWidth;
+ int distanceFromScreenCenter = Math.abs(childCenter - screenCenter);
+ if (distanceFromScreenCenter < minDistanceFromScreenCenter) {
+ minDistanceFromScreenCenter = distanceFromScreenCenter;
+ minDistanceFromScreenCenterIndex = i;
+ }
+ }
+ return minDistanceFromScreenCenterIndex;
+ }
+
+ protected void snapToDestination() {
+ snapToPage(getPageNearestToCenterOfScreen(), PAGE_SNAP_ANIMATION_DURATION);
+ }
+
+ private static class ScrollInterpolator implements Interpolator {
+ public ScrollInterpolator() {
+ }
+
+ public float getInterpolation(float t) {
+ t -= 1.0f;
+ return t*t*t*t*t + 1;
+ }
+ }
+
+ // We want the duration of the page snap animation to be influenced by the distance that
+ // the screen has to travel, however, we don't want this duration to be effected in a
+ // purely linear fashion. Instead, we use this method to moderate the effect that the distance
+ // of travel has on the overall snap duration.
+ float distanceInfluenceForSnapDuration(float f) {
+ f -= 0.5f; // center the values about 0.
+ f *= 0.3f * Math.PI / 2.0f;
+ return (float) Math.sin(f);
+ }
+
+ protected void snapToPageWithVelocity(int whichPage, int velocity) {
+ whichPage = Math.max(0, Math.min(whichPage, getChildCount() - 1));
+ int halfScreenSize = getViewportWidth() / 2;
+
+ if (DEBUG) Log.d(TAG, "snapToPage.getChildOffset(): " + getChildOffset(whichPage));
+ if (DEBUG) Log.d(TAG, "snapToPageWithVelocity.getRelativeChildOffset(): "
+ + getViewportWidth() + ", " + getChildWidth(whichPage));
+ final int newX = getChildOffset(whichPage) - getRelativeChildOffset(whichPage);
+ int delta = newX - mUnboundedScrollX;
+ int duration = 0;
+
+ if (Math.abs(velocity) < mMinFlingVelocity) {
+ // If the velocity is low enough, then treat this more as an automatic page advance
+ // as opposed to an apparent physical response to flinging
+ snapToPage(whichPage, PAGE_SNAP_ANIMATION_DURATION);
+ return;
+ }
+
+ // Here we compute a "distance" that will be used in the computation of the overall
+ // snap duration. This is a function of the actual distance that needs to be traveled;
+ // we keep this value close to half screen size in order to reduce the variance in snap
+ // duration as a function of the distance the page needs to travel.
+ float distanceRatio = Math.min(1f, 1.0f * Math.abs(delta) / (2 * halfScreenSize));
+ float distance = halfScreenSize + halfScreenSize *
+ distanceInfluenceForSnapDuration(distanceRatio);
+
+ velocity = Math.abs(velocity);
+ velocity = Math.max(mMinSnapVelocity, velocity);
+
+ // we want the page's snap velocity to approximately match the velocity at which the
+ // user flings, so we scale the duration by a value near to the derivative of the scroll
+ // interpolator at zero, ie. 5. We use 4 to make it a little slower.
+ duration = 4 * Math.round(1000 * Math.abs(distance / velocity));
+
+ snapToPage(whichPage, delta, duration);
+ }
+
+ protected void snapToPage(int whichPage) {
+ snapToPage(whichPage, PAGE_SNAP_ANIMATION_DURATION);
+ }
+ protected void snapToPageImmediately(int whichPage) {
+ snapToPage(whichPage, PAGE_SNAP_ANIMATION_DURATION, true);
+ }
+
+ protected void snapToPage(int whichPage, int duration) {
+ snapToPage(whichPage, duration, false);
+ }
+ protected void snapToPage(int whichPage, int duration, boolean immediate) {
+ whichPage = Math.max(0, Math.min(whichPage, getPageCount() - 1));
+
+ if (DEBUG) Log.d(TAG, "snapToPage.getChildOffset(): " + getChildOffset(whichPage));
+ if (DEBUG) Log.d(TAG, "snapToPage.getRelativeChildOffset(): " + getViewportWidth() + ", "
+ + getChildWidth(whichPage));
+ int newX = getChildOffset(whichPage) - getRelativeChildOffset(whichPage);
+ final int sX = mUnboundedScrollX;
+ final int delta = newX - sX;
+ snapToPage(whichPage, delta, duration, immediate);
+ }
+
+ protected void snapToPage(int whichPage, int delta, int duration) {
+ snapToPage(whichPage, delta, duration, false);
+ }
+ protected void snapToPage(int whichPage, int delta, int duration, boolean immediate) {
+ mNextPage = whichPage;
+ notifyPageSwitching(whichPage);
+ View focusedChild = getFocusedChild();
+ if (focusedChild != null && whichPage != mCurrentPage &&
+ focusedChild == getPageAt(mCurrentPage)) {
+ focusedChild.clearFocus();
+ }
+
+ pageBeginMoving();
+ awakenScrollBars(duration);
+ if (immediate) {
+ duration = 0;
+ } else if (duration == 0) {
+ duration = Math.abs(delta);
+ }
+
+ if (!mScroller.isFinished()) mScroller.abortAnimation();
+ mScroller.startScroll(mUnboundedScrollX, 0, delta, 0, duration);
+
+ notifyPageSwitched();
+
+ // Trigger a compute() to finish switching pages if necessary
+ if (immediate) {
+ computeScroll();
+ }
+
+ mForceScreenScrolled = true;
+ invalidate();
+ }
+
+ public void scrollLeft() {
+ if (mScroller.isFinished()) {
+ if (mCurrentPage > 0) snapToPage(mCurrentPage - 1);
+ } else {
+ if (mNextPage > 0) snapToPage(mNextPage - 1);
+ }
+ }
+
+ public void scrollRight() {
+ if (mScroller.isFinished()) {
+ if (mCurrentPage < getChildCount() -1) snapToPage(mCurrentPage + 1);
+ } else {
+ if (mNextPage < getChildCount() -1) snapToPage(mNextPage + 1);
+ }
+ }
+
+ public int getPageForView(View v) {
+ int result = -1;
+ if (v != null) {
+ ViewParent vp = v.getParent();
+ int count = getChildCount();
+ for (int i = 0; i < count; i++) {
+ if (vp == getPageAt(i)) {
+ return i;
+ }
+ }
+ }
+ return result;
+ }
+
+ public static class SavedState extends BaseSavedState {
+ int currentPage = -1;
+
+ SavedState(Parcelable superState) {
+ super(superState);
+ }
+
+ private SavedState(Parcel in) {
+ super(in);
+ currentPage = in.readInt();
+ }
+
+ @Override
+ public void writeToParcel(Parcel out, int flags) {
+ super.writeToParcel(out, flags);
+ out.writeInt(currentPage);
+ }
+
+ public static final Parcelable.Creator<SavedState> CREATOR =
+ new Parcelable.Creator<SavedState>() {
+ public SavedState createFromParcel(Parcel in) {
+ return new SavedState(in);
+ }
+
+ public SavedState[] newArray(int size) {
+ return new SavedState[size];
+ }
+ };
+ }
+
+ protected View getScrollingIndicator() {
+ return null;
+ }
+
+ protected boolean isScrollingIndicatorEnabled() {
+ return false;
+ }
+
+ Runnable hideScrollingIndicatorRunnable = new Runnable() {
+ @Override
+ public void run() {
+ hideScrollingIndicator(false);
+ }
+ };
+
+ protected void flashScrollingIndicator(boolean animated) {
+ removeCallbacks(hideScrollingIndicatorRunnable);
+ showScrollingIndicator(!animated);
+ postDelayed(hideScrollingIndicatorRunnable, sScrollIndicatorFlashDuration);
+ }
+
+ protected void showScrollingIndicator(boolean immediately) {
+ mShouldShowScrollIndicator = true;
+ mShouldShowScrollIndicatorImmediately = true;
+ if (getChildCount() <= 1) return;
+ if (!isScrollingIndicatorEnabled()) return;
+
+ mShouldShowScrollIndicator = false;
+ getScrollingIndicator();
+ if (mScrollIndicator != null) {
+ // Fade the indicator in
+ updateScrollingIndicatorPosition();
+ mScrollIndicator.setVisibility(View.VISIBLE);
+ cancelScrollingIndicatorAnimations();
+ if (immediately) {
+ mScrollIndicator.setAlpha(1f);
+ } else {
+ mScrollIndicatorAnimator = ObjectAnimator.ofFloat(mScrollIndicator, "alpha", 1f);
+ mScrollIndicatorAnimator.setDuration(sScrollIndicatorFadeInDuration);
+ mScrollIndicatorAnimator.start();
+ }
+ }
+ }
+
+ protected void cancelScrollingIndicatorAnimations() {
+ if (mScrollIndicatorAnimator != null) {
+ mScrollIndicatorAnimator.cancel();
+ }
+ }
+
+ protected void hideScrollingIndicator(boolean immediately) {
+ if (getChildCount() <= 1) return;
+ if (!isScrollingIndicatorEnabled()) return;
+
+ getScrollingIndicator();
+ if (mScrollIndicator != null) {
+ // Fade the indicator out
+ updateScrollingIndicatorPosition();
+ cancelScrollingIndicatorAnimations();
+ if (immediately) {
+ mScrollIndicator.setVisibility(View.INVISIBLE);
+ mScrollIndicator.setAlpha(0f);
+ } else {
+ mScrollIndicatorAnimator = ObjectAnimator.ofFloat(mScrollIndicator, "alpha", 0f);
+ mScrollIndicatorAnimator.setDuration(sScrollIndicatorFadeOutDuration);
+ mScrollIndicatorAnimator.addListener(new AnimatorListenerAdapter() {
+ private boolean cancelled = false;
+ @Override
+ public void onAnimationCancel(android.animation.Animator animation) {
+ cancelled = true;
+ }
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ if (!cancelled) {
+ mScrollIndicator.setVisibility(View.INVISIBLE);
+ }
+ }
+ });
+ mScrollIndicatorAnimator.start();
+ }
+ }
+ }
+
+ /**
+ * To be overridden by subclasses to determine whether the scroll indicator should stretch to
+ * fill its space on the track or not.
+ */
+ protected boolean hasElasticScrollIndicator() {
+ return true;
+ }
+
+ private void updateScrollingIndicator() {
+ if (getChildCount() <= 1) return;
+ if (!isScrollingIndicatorEnabled()) return;
+
+ getScrollingIndicator();
+ if (mScrollIndicator != null) {
+ updateScrollingIndicatorPosition();
+ }
+ if (mShouldShowScrollIndicator) {
+ showScrollingIndicator(mShouldShowScrollIndicatorImmediately);
+ }
+ }
+
+ private void updateScrollingIndicatorPosition() {
+ if (!isScrollingIndicatorEnabled()) return;
+ if (mScrollIndicator == null) return;
+ int numPages = getChildCount();
+ int pageWidth = getViewportWidth();
+ int lastChildIndex = Math.max(0, getChildCount() - 1);
+ int maxScrollX = getChildOffset(lastChildIndex) - getRelativeChildOffset(lastChildIndex);
+ int trackWidth = pageWidth - mScrollIndicatorPaddingLeft - mScrollIndicatorPaddingRight;
+ int indicatorWidth = mScrollIndicator.getMeasuredWidth() -
+ mScrollIndicator.getPaddingLeft() - mScrollIndicator.getPaddingRight();
+
+ float offset = Math.max(0f, Math.min(1f, (float) getScrollX() / maxScrollX));
+ int indicatorSpace = trackWidth / numPages;
+ int indicatorPos = (int) (offset * (trackWidth - indicatorSpace)) + mScrollIndicatorPaddingLeft;
+ if (hasElasticScrollIndicator()) {
+ if (mScrollIndicator.getMeasuredWidth() != indicatorSpace) {
+ mScrollIndicator.getLayoutParams().width = indicatorSpace;
+ mScrollIndicator.requestLayout();
+ }
+ } else {
+ int indicatorCenterOffset = indicatorSpace / 2 - indicatorWidth / 2;
+ indicatorPos += indicatorCenterOffset;
+ }
+ mScrollIndicator.setTranslationX(indicatorPos);
+ }
+
+ // Animate the drag view back to the original position
+ void animateDragViewToOriginalPosition() {
+ if (mDragView != null) {
+ AnimatorSet anim = new AnimatorSet();
+ anim.setDuration(REORDERING_DROP_REPOSITION_DURATION);
+ anim.playTogether(
+ ObjectAnimator.ofFloat(mDragView, "translationX", 0f),
+ ObjectAnimator.ofFloat(mDragView, "translationY", 0f));
+ anim.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ onPostReorderingAnimationCompleted();
+ }
+ });
+ anim.start();
+ }
+ }
+
+ // "Zooms out" the PagedView to reveal more side pages
+ protected boolean zoomOut() {
+ if (mZoomInOutAnim != null && mZoomInOutAnim.isRunning()) {
+ mZoomInOutAnim.cancel();
+ }
+
+ if (!(getScaleX() < 1f || getScaleY() < 1f)) {
+ mZoomInOutAnim = new AnimatorSet();
+ mZoomInOutAnim.setDuration(REORDERING_ZOOM_IN_OUT_DURATION);
+ mZoomInOutAnim.playTogether(
+ ObjectAnimator.ofFloat(this, "scaleX", mMinScale),
+ ObjectAnimator.ofFloat(this, "scaleY", mMinScale));
+ mZoomInOutAnim.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationStart(Animator animation) {
+ // Show the delete drop target
+ if (mDeleteDropTarget != null) {
+ mDeleteDropTarget.setVisibility(View.VISIBLE);
+ mDeleteDropTarget.animate().alpha(1f)
+ .setDuration(REORDERING_DELETE_DROP_TARGET_FADE_DURATION)
+ .setListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationStart(Animator animation) {
+ mDeleteDropTarget.setAlpha(0f);
+ }
+ });
+ }
+ }
+ });
+ mZoomInOutAnim.start();
+ return true;
+ }
+ return false;
+ }
+
+ protected void onStartReordering() {
+ if (AccessibilityManager.getInstance(mContext).isEnabled()) {
+ announceForAccessibility(mContext.getString(
+ R.string.keyguard_accessibility_widget_reorder_start));
+ }
+
+ // Set the touch state to reordering (allows snapping to pages, dragging a child, etc.)
+ mTouchState = TOUCH_STATE_REORDERING;
+ mIsReordering = true;
+
+ // Mark all the non-widget pages as invisible
+ getVisiblePages(mTempVisiblePagesRange);
+ boundByReorderablePages(true, mTempVisiblePagesRange);
+ for (int i = 0; i < getPageCount(); ++i) {
+ if (i < mTempVisiblePagesRange[0] || i > mTempVisiblePagesRange[1]) {
+ getPageAt(i).setAlpha(0f);
+ }
+ }
+
+ // We must invalidate to trigger a redraw to update the layers such that the drag view
+ // is always drawn on top
+ invalidate();
+ }
+
+ private void onPostReorderingAnimationCompleted() {
+ // Trigger the callback when reordering has settled
+ --mPostReorderingPreZoomInRemainingAnimationCount;
+ if (mPostReorderingPreZoomInRunnable != null &&
+ mPostReorderingPreZoomInRemainingAnimationCount == 0) {
+ mPostReorderingPreZoomInRunnable.run();
+ mPostReorderingPreZoomInRunnable = null;
+ }
+ }
+
+ protected void onEndReordering() {
+ if (AccessibilityManager.getInstance(mContext).isEnabled()) {
+ announceForAccessibility(mContext.getString(
+ R.string.keyguard_accessibility_widget_reorder_end));
+ }
+ mIsReordering = false;
+
+ // Mark all the non-widget pages as visible again
+ getVisiblePages(mTempVisiblePagesRange);
+ boundByReorderablePages(true, mTempVisiblePagesRange);
+ for (int i = 0; i < getPageCount(); ++i) {
+ if (i < mTempVisiblePagesRange[0] || i > mTempVisiblePagesRange[1]) {
+ getPageAt(i).setAlpha(1f);
+ }
+ }
+ }
+
+ public boolean startReordering() {
+ int dragViewIndex = getPageNearestToCenterOfScreen();
+ mTempVisiblePagesRange[0] = 0;
+ mTempVisiblePagesRange[1] = getPageCount() - 1;
+ boundByReorderablePages(true, mTempVisiblePagesRange);
+ mReorderingStarted = true;
+
+ // Check if we are within the reordering range
+ if (mTempVisiblePagesRange[0] <= dragViewIndex &&
+ dragViewIndex <= mTempVisiblePagesRange[1]) {
+ if (zoomOut()) {
+ // Find the drag view under the pointer
+ mDragView = getChildAt(dragViewIndex);
+
+ onStartReordering();
+ }
+ return true;
+ }
+ return false;
+ }
+
+ boolean isReordering(boolean testTouchState) {
+ boolean state = mIsReordering;
+ if (testTouchState) {
+ state &= (mTouchState == TOUCH_STATE_REORDERING);
+ }
+ return state;
+ }
+ void endReordering() {
+ // For simplicity, we call endReordering sometimes even if reordering was never started.
+ // In that case, we don't want to do anything.
+ if (!mReorderingStarted) return;
+ mReorderingStarted = false;
+
+ // If we haven't flung-to-delete the current child, then we just animate the drag view
+ // back into position
+ final Runnable onCompleteRunnable = new Runnable() {
+ @Override
+ public void run() {
+ onEndReordering();
+ }
+ };
+ if (!mDeferringForDelete) {
+ mPostReorderingPreZoomInRunnable = new Runnable() {
+ public void run() {
+ zoomIn(onCompleteRunnable);
+ };
+ };
+
+ mPostReorderingPreZoomInRemainingAnimationCount =
+ NUM_ANIMATIONS_RUNNING_BEFORE_ZOOM_OUT;
+ // Snap to the current page
+ snapToPage(indexOfChild(mDragView), 0);
+ // Animate the drag view back to the front position
+ animateDragViewToOriginalPosition();
+ } else {
+ // Handled in post-delete-animation-callbacks
+ }
+ }
+
+ // "Zooms in" the PagedView to highlight the current page
+ protected boolean zoomIn(final Runnable onCompleteRunnable) {
+ if (mZoomInOutAnim != null && mZoomInOutAnim.isRunning()) {
+ mZoomInOutAnim.cancel();
+ }
+ if (getScaleX() < 1f || getScaleY() < 1f) {
+ mZoomInOutAnim = new AnimatorSet();
+ mZoomInOutAnim.setDuration(REORDERING_ZOOM_IN_OUT_DURATION);
+ mZoomInOutAnim.playTogether(
+ ObjectAnimator.ofFloat(this, "scaleX", 1f),
+ ObjectAnimator.ofFloat(this, "scaleY", 1f));
+ mZoomInOutAnim.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationStart(Animator animation) {
+ // Hide the delete drop target
+ if (mDeleteDropTarget != null) {
+ mDeleteDropTarget.animate().alpha(0f)
+ .setDuration(REORDERING_DELETE_DROP_TARGET_FADE_DURATION)
+ .setListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mDeleteDropTarget.setVisibility(View.GONE);
+ }
+ });
+ }
+ }
+ @Override
+ public void onAnimationCancel(Animator animation) {
+ mDragView = null;
+ }
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mDragView = null;
+ if (onCompleteRunnable != null) {
+ onCompleteRunnable.run();
+ }
+ }
+ });
+ mZoomInOutAnim.start();
+ return true;
+ } else {
+ if (onCompleteRunnable != null) {
+ onCompleteRunnable.run();
+ }
+ }
+ return false;
+ }
+
+ /*
+ * Flinging to delete - IN PROGRESS
+ */
+ private PointF isFlingingToDelete() {
+ ViewConfiguration config = ViewConfiguration.get(getContext());
+ mVelocityTracker.computeCurrentVelocity(1000, config.getScaledMaximumFlingVelocity());
+
+ if (mVelocityTracker.getYVelocity() < mFlingToDeleteThresholdVelocity) {
+ // Do a quick dot product test to ensure that we are flinging upwards
+ PointF vel = new PointF(mVelocityTracker.getXVelocity(),
+ mVelocityTracker.getYVelocity());
+ PointF upVec = new PointF(0f, -1f);
+ float theta = (float) Math.acos(((vel.x * upVec.x) + (vel.y * upVec.y)) /
+ (vel.length() * upVec.length()));
+ if (theta <= Math.toRadians(FLING_TO_DELETE_MAX_FLING_DEGREES)) {
+ return vel;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Creates an animation from the current drag view along its current velocity vector.
+ * For this animation, the alpha runs for a fixed duration and we update the position
+ * progressively.
+ */
+ private static class FlingAlongVectorAnimatorUpdateListener implements AnimatorUpdateListener {
+ private View mDragView;
+ private PointF mVelocity;
+ private Rect mFrom;
+ private long mPrevTime;
+ private float mFriction;
+
+ private final TimeInterpolator mAlphaInterpolator = new DecelerateInterpolator(0.75f);
+
+ public FlingAlongVectorAnimatorUpdateListener(View dragView, PointF vel, Rect from,
+ long startTime, float friction) {
+ mDragView = dragView;
+ mVelocity = vel;
+ mFrom = from;
+ mPrevTime = startTime;
+ mFriction = 1f - (mDragView.getResources().getDisplayMetrics().density * friction);
+ }
+
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ float t = ((Float) animation.getAnimatedValue()).floatValue();
+ long curTime = AnimationUtils.currentAnimationTimeMillis();
+
+ mFrom.left += (mVelocity.x * (curTime - mPrevTime) / 1000f);
+ mFrom.top += (mVelocity.y * (curTime - mPrevTime) / 1000f);
+
+ mDragView.setTranslationX(mFrom.left);
+ mDragView.setTranslationY(mFrom.top);
+ mDragView.setAlpha(1f - mAlphaInterpolator.getInterpolation(t));
+
+ mVelocity.x *= mFriction;
+ mVelocity.y *= mFriction;
+ mPrevTime = curTime;
+ }
+ };
+
+ private Runnable createPostDeleteAnimationRunnable(final View dragView) {
+ return new Runnable() {
+ @Override
+ public void run() {
+ int dragViewIndex = indexOfChild(dragView);
+
+ // For each of the pages around the drag view, animate them from the previous
+ // position to the new position in the layout (as a result of the drag view moving
+ // in the layout)
+ // NOTE: We can make an assumption here because we have side-bound pages that we
+ // will always have pages to animate in from the left
+ getVisiblePages(mTempVisiblePagesRange);
+ boundByReorderablePages(true, mTempVisiblePagesRange);
+ boolean isLastWidgetPage = (mTempVisiblePagesRange[0] == mTempVisiblePagesRange[1]);
+ boolean slideFromLeft = (isLastWidgetPage ||
+ dragViewIndex > mTempVisiblePagesRange[0]);
+
+ // Setup the scroll to the correct page before we swap the views
+ if (slideFromLeft) {
+ snapToPageImmediately(dragViewIndex - 1);
+ }
+
+ int firstIndex = (isLastWidgetPage ? 0 : mTempVisiblePagesRange[0]);
+ int lastIndex = Math.min(mTempVisiblePagesRange[1], getPageCount() - 1);
+ int lowerIndex = (slideFromLeft ? firstIndex : dragViewIndex + 1 );
+ int upperIndex = (slideFromLeft ? dragViewIndex - 1 : lastIndex);
+ ArrayList<Animator> animations = new ArrayList<Animator>();
+ for (int i = lowerIndex; i <= upperIndex; ++i) {
+ View v = getChildAt(i);
+ // dragViewIndex < pageUnderPointIndex, so after we remove the
+ // drag view all subsequent views to pageUnderPointIndex will
+ // shift down.
+ int oldX = 0;
+ int newX = 0;
+ if (slideFromLeft) {
+ if (i == 0) {
+ // Simulate the page being offscreen with the page spacing
+ oldX = getViewportOffsetX() + getChildOffset(i) - getChildWidth(i)
+ - mPageSpacing;
+ } else {
+ oldX = getViewportOffsetX() + getChildOffset(i - 1);
+ }
+ newX = getViewportOffsetX() + getChildOffset(i);
+ } else {
+ oldX = getChildOffset(i) - getChildOffset(i - 1);
+ newX = 0;
+ }
+
+ // Animate the view translation from its old position to its new
+ // position
+ AnimatorSet anim = (AnimatorSet) v.getTag();
+ if (anim != null) {
+ anim.cancel();
+ }
+
+ // Note: Hacky, but we want to skip any optimizations to not draw completely
+ // hidden views
+ v.setAlpha(Math.max(v.getAlpha(), 0.01f));
+ v.setTranslationX(oldX - newX);
+ anim = new AnimatorSet();
+ anim.playTogether(
+ ObjectAnimator.ofFloat(v, "translationX", 0f),
+ ObjectAnimator.ofFloat(v, "alpha", 1f));
+ animations.add(anim);
+ v.setTag(anim);
+ }
+
+ AnimatorSet slideAnimations = new AnimatorSet();
+ slideAnimations.playTogether(animations);
+ slideAnimations.setDuration(DELETE_SLIDE_IN_SIDE_PAGE_DURATION);
+ slideAnimations.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ final Runnable onCompleteRunnable = new Runnable() {
+ @Override
+ public void run() {
+ mDeferringForDelete = false;
+ onEndReordering();
+ onRemoveViewAnimationCompleted();
+ }
+ };
+ zoomIn(onCompleteRunnable);
+ }
+ });
+ slideAnimations.start();
+
+ removeView(dragView);
+ onRemoveView(dragView, true);
+ }
+ };
+ }
+
+ public void onFlingToDelete(PointF vel) {
+ final long startTime = AnimationUtils.currentAnimationTimeMillis();
+
+ // NOTE: Because it takes time for the first frame of animation to actually be
+ // called and we expect the animation to be a continuation of the fling, we have
+ // to account for the time that has elapsed since the fling finished. And since
+ // we don't have a startDelay, we will always get call to update when we call
+ // start() (which we want to ignore).
+ final TimeInterpolator tInterpolator = new TimeInterpolator() {
+ private int mCount = -1;
+ private long mStartTime;
+ private float mOffset;
+ /* Anonymous inner class ctor */ {
+ mStartTime = startTime;
+ }
+
+ @Override
+ public float getInterpolation(float t) {
+ if (mCount < 0) {
+ mCount++;
+ } else if (mCount == 0) {
+ mOffset = Math.min(0.5f, (float) (AnimationUtils.currentAnimationTimeMillis() -
+ mStartTime) / FLING_TO_DELETE_FADE_OUT_DURATION);
+ mCount++;
+ }
+ return Math.min(1f, mOffset + t);
+ }
+ };
+
+ final Rect from = new Rect();
+ final View dragView = mDragView;
+ from.left = (int) dragView.getTranslationX();
+ from.top = (int) dragView.getTranslationY();
+ AnimatorUpdateListener updateCb = new FlingAlongVectorAnimatorUpdateListener(dragView, vel,
+ from, startTime, FLING_TO_DELETE_FRICTION);
+
+ final Runnable onAnimationEndRunnable = createPostDeleteAnimationRunnable(dragView);
+
+ // Create and start the animation
+ ValueAnimator mDropAnim = new ValueAnimator();
+ mDropAnim.setInterpolator(tInterpolator);
+ mDropAnim.setDuration(FLING_TO_DELETE_FADE_OUT_DURATION);
+ mDropAnim.setFloatValues(0f, 1f);
+ mDropAnim.addUpdateListener(updateCb);
+ mDropAnim.addListener(new AnimatorListenerAdapter() {
+ public void onAnimationEnd(Animator animation) {
+ onAnimationEndRunnable.run();
+ }
+ });
+ mDropAnim.start();
+ mDeferringForDelete = true;
+ }
+
+ /* Drag to delete */
+ private boolean isHoveringOverDeleteDropTarget(int x, int y) {
+ if (mDeleteDropTarget != null) {
+ mAltTmpRect.set(0, 0, 0, 0);
+ View parent = (View) mDeleteDropTarget.getParent();
+ if (parent != null) {
+ parent.getGlobalVisibleRect(mAltTmpRect);
+ }
+ mDeleteDropTarget.getGlobalVisibleRect(mTmpRect);
+ mTmpRect.offset(-mAltTmpRect.left, -mAltTmpRect.top);
+ return mTmpRect.contains(x, y);
+ }
+ return false;
+ }
+
+ protected void setPageHoveringOverDeleteDropTarget(int viewIndex, boolean isHovering) {}
+
+ private void onDropToDelete() {
+ final View dragView = mDragView;
+
+ final float toScale = 0f;
+ final float toAlpha = 0f;
+
+ // Create and start the complex animation
+ ArrayList<Animator> animations = new ArrayList<Animator>();
+ AnimatorSet motionAnim = new AnimatorSet();
+ motionAnim.setInterpolator(new DecelerateInterpolator(2));
+ motionAnim.playTogether(
+ ObjectAnimator.ofFloat(dragView, "scaleX", toScale),
+ ObjectAnimator.ofFloat(dragView, "scaleY", toScale));
+ animations.add(motionAnim);
+
+ AnimatorSet alphaAnim = new AnimatorSet();
+ alphaAnim.setInterpolator(new LinearInterpolator());
+ alphaAnim.playTogether(
+ ObjectAnimator.ofFloat(dragView, "alpha", toAlpha));
+ animations.add(alphaAnim);
+
+ final Runnable onAnimationEndRunnable = createPostDeleteAnimationRunnable(dragView);
+
+ AnimatorSet anim = new AnimatorSet();
+ anim.playTogether(animations);
+ anim.setDuration(DRAG_TO_DELETE_FADE_OUT_DURATION);
+ anim.addListener(new AnimatorListenerAdapter() {
+ public void onAnimationEnd(Animator animation) {
+ onAnimationEndRunnable.run();
+ }
+ });
+ anim.start();
+
+ mDeferringForDelete = true;
+ }
+
+ /* Accessibility */
+ @Override
+ public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
+ super.onInitializeAccessibilityNodeInfo(info);
+ info.setScrollable(getPageCount() > 1);
+ if (getCurrentPage() < getPageCount() - 1) {
+ info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD);
+ }
+ if (getCurrentPage() > 0) {
+ info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD);
+ }
+ }
+
+ @Override
+ public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
+ super.onInitializeAccessibilityEvent(event);
+ event.setScrollable(true);
+ if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_SCROLLED) {
+ event.setFromIndex(mCurrentPage);
+ event.setToIndex(mCurrentPage);
+ event.setItemCount(getChildCount());
+ }
+ }
+
+ @Override
+ public boolean performAccessibilityAction(int action, Bundle arguments) {
+ if (super.performAccessibilityAction(action, arguments)) {
+ return true;
+ }
+ switch (action) {
+ case AccessibilityNodeInfo.ACTION_SCROLL_FORWARD: {
+ if (getCurrentPage() < getPageCount() - 1) {
+ scrollRight();
+ return true;
+ }
+ } break;
+ case AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD: {
+ if (getCurrentPage() > 0) {
+ scrollLeft();
+ return true;
+ }
+ } break;
+ }
+ return false;
+ }
+
+ @Override
+ public boolean onHoverEvent(android.view.MotionEvent event) {
+ return true;
+ }
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/SecurityMessageDisplay.java b/packages/Keyguard/src/com/android/keyguard/SecurityMessageDisplay.java
new file mode 100644
index 0000000..e2f91e3
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/SecurityMessageDisplay.java
@@ -0,0 +1,31 @@
+/*
+ * 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.keyguard;
+
+public interface SecurityMessageDisplay {
+ public void setMessage(CharSequence msg, boolean important);
+
+ public void setMessage(int resId, boolean important);
+
+ public void setMessage(int resId, boolean important, Object... formatArgs);
+
+ public void setTimeout(int timeout_ms);
+
+ public void showBouncer(int animationDuration);
+
+ public void hideBouncer(int animationDuration);
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/SlidingChallengeLayout.java b/packages/Keyguard/src/com/android/keyguard/SlidingChallengeLayout.java
new file mode 100644
index 0000000..05b35a1
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/SlidingChallengeLayout.java
@@ -0,0 +1,1242 @@
+/*
+ * 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.keyguard;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ObjectAnimator;
+import android.content.Context;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.util.AttributeSet;
+import android.util.DisplayMetrics;
+import android.util.FloatProperty;
+import android.util.Log;
+import android.util.Property;
+import android.view.MotionEvent;
+import android.view.VelocityTracker;
+import android.view.View;
+import android.view.ViewConfiguration;
+import android.view.ViewGroup;
+import android.view.accessibility.AccessibilityManager;
+import android.view.animation.Interpolator;
+import android.widget.Scroller;
+
+/**
+ * This layout handles interaction with the sliding security challenge views
+ * that overlay/resize other keyguard contents.
+ */
+public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout {
+ private static final String TAG = "SlidingChallengeLayout";
+ private static final boolean DEBUG = false;
+
+ // The drag handle is measured in dp above & below the top edge of the
+ // challenge view; these parameters change based on whether the challenge
+ // is open or closed.
+ private static final int DRAG_HANDLE_CLOSED_ABOVE = 8; // dp
+ private static final int DRAG_HANDLE_CLOSED_BELOW = 0; // dp
+ private static final int DRAG_HANDLE_OPEN_ABOVE = 8; // dp
+ private static final int DRAG_HANDLE_OPEN_BELOW = 0; // dp
+
+ private static final int HANDLE_ANIMATE_DURATION = 250; // ms
+
+ // Drawn to show the drag handle in closed state; crossfades to the challenge view
+ // when challenge is fully visible
+ private boolean mEdgeCaptured;
+
+ private DisplayMetrics mDisplayMetrics;
+
+ // Initialized during measurement from child layoutparams
+ private View mExpandChallengeView;
+ private KeyguardSecurityContainer mChallengeView;
+ private View mScrimView;
+ private View mWidgetsView;
+
+ // Range: 0 (fully hidden) to 1 (fully visible)
+ private float mChallengeOffset = 1.f;
+ private boolean mChallengeShowing = true;
+ private boolean mChallengeShowingTargetState = true;
+ private boolean mWasChallengeShowing = true;
+ private boolean mIsBouncing = false;
+
+ private final Scroller mScroller;
+ private ObjectAnimator mFader;
+ private int mScrollState;
+ private OnChallengeScrolledListener mScrollListener;
+ private OnBouncerStateChangedListener mBouncerListener;
+
+ public static final int SCROLL_STATE_IDLE = 0;
+ public static final int SCROLL_STATE_DRAGGING = 1;
+ public static final int SCROLL_STATE_SETTLING = 2;
+ public static final int SCROLL_STATE_FADING = 3;
+
+ private static final int CHALLENGE_FADE_OUT_DURATION = 100;
+ private static final int CHALLENGE_FADE_IN_DURATION = 160;
+
+ private static final int MAX_SETTLE_DURATION = 600; // ms
+
+ // ID of the pointer in charge of a current drag
+ private int mActivePointerId = INVALID_POINTER;
+ private static final int INVALID_POINTER = -1;
+
+ // True if the user is currently dragging the slider
+ private boolean mDragging;
+ // True if the user may not drag until a new gesture begins
+ private boolean mBlockDrag;
+
+ private VelocityTracker mVelocityTracker;
+ private int mMinVelocity;
+ private int mMaxVelocity;
+ private float mGestureStartX, mGestureStartY; // where did you first touch the screen?
+ private int mGestureStartChallengeBottom; // where was the challenge at that time?
+
+ private int mDragHandleClosedBelow; // handle hitrect extension into the challenge view
+ private int mDragHandleClosedAbove; // extend the handle's hitrect this far above the line
+ private int mDragHandleOpenBelow; // handle hitrect extension into the challenge view
+ private int mDragHandleOpenAbove; // extend the handle's hitrect this far above the line
+
+ private int mDragHandleEdgeSlop;
+ private int mChallengeBottomBound; // Number of pixels from the top of the challenge view
+ // that should remain on-screen
+
+ private int mTouchSlop;
+ private int mTouchSlopSquare;
+
+ float mHandleAlpha;
+ float mFrameAlpha;
+ float mFrameAnimationTarget = Float.MIN_VALUE;
+ private ObjectAnimator mHandleAnimation;
+ private ObjectAnimator mFrameAnimation;
+
+ private boolean mHasGlowpad;
+
+ // We have an internal and external version, and we and them together.
+ private boolean mChallengeInteractiveExternal = true;
+ private boolean mChallengeInteractiveInternal = true;
+
+ static final Property<SlidingChallengeLayout, Float> HANDLE_ALPHA =
+ new FloatProperty<SlidingChallengeLayout>("handleAlpha") {
+ @Override
+ public void setValue(SlidingChallengeLayout view, float value) {
+ view.mHandleAlpha = value;
+ view.invalidate();
+ }
+
+ @Override
+ public Float get(SlidingChallengeLayout view) {
+ return view.mHandleAlpha;
+ }
+ };
+
+ // True if at least one layout pass has happened since the view was attached.
+ private boolean mHasLayout;
+
+ private static final Interpolator sMotionInterpolator = new Interpolator() {
+ public float getInterpolation(float t) {
+ t -= 1.0f;
+ return t * t * t * t * t + 1.0f;
+ }
+ };
+
+ private static final Interpolator sHandleFadeInterpolator = new Interpolator() {
+ public float getInterpolation(float t) {
+ return t * t;
+ }
+ };
+
+ private final Runnable mEndScrollRunnable = new Runnable () {
+ public void run() {
+ completeChallengeScroll();
+ }
+ };
+
+ private final OnClickListener mScrimClickListener = new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ hideBouncer();
+ }
+ };
+
+ private final OnClickListener mExpandChallengeClickListener = new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ if (!isChallengeShowing()) {
+ showChallenge(true);
+ }
+ }
+ };
+
+ /**
+ * Listener interface that reports changes in scroll state of the challenge area.
+ */
+ public interface OnChallengeScrolledListener {
+ /**
+ * The scroll state itself changed.
+ *
+ * <p>scrollState will be one of the following:</p>
+ *
+ * <ul>
+ * <li><code>SCROLL_STATE_IDLE</code> - The challenge area is stationary.</li>
+ * <li><code>SCROLL_STATE_DRAGGING</code> - The user is actively dragging
+ * the challenge area.</li>
+ * <li><code>SCROLL_STATE_SETTLING</code> - The challenge area is animating
+ * into place.</li>
+ * </ul>
+ *
+ * <p>Do not perform expensive operations (e.g. layout)
+ * while the scroll state is not <code>SCROLL_STATE_IDLE</code>.</p>
+ *
+ * @param scrollState The new scroll state of the challenge area.
+ */
+ public void onScrollStateChanged(int scrollState);
+
+ /**
+ * The precise position of the challenge area has changed.
+ *
+ * <p>NOTE: It is NOT safe to modify layout or call any View methods that may
+ * result in a requestLayout anywhere in your view hierarchy as a result of this call.
+ * It may be called during drawing.</p>
+ *
+ * @param scrollPosition New relative position of the challenge area.
+ * 1.f = fully visible/ready to be interacted with.
+ * 0.f = fully invisible/inaccessible to the user.
+ * @param challengeTop Position of the top edge of the challenge view in px in the
+ * SlidingChallengeLayout's coordinate system.
+ */
+ public void onScrollPositionChanged(float scrollPosition, int challengeTop);
+ }
+
+ public SlidingChallengeLayout(Context context) {
+ this(context, null);
+ }
+
+ public SlidingChallengeLayout(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public SlidingChallengeLayout(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+
+ mScroller = new Scroller(context, sMotionInterpolator);
+
+ final ViewConfiguration vc = ViewConfiguration.get(context);
+ mMinVelocity = vc.getScaledMinimumFlingVelocity();
+ mMaxVelocity = vc.getScaledMaximumFlingVelocity();
+
+ final Resources res = getResources();
+ mDragHandleEdgeSlop = res.getDimensionPixelSize(R.dimen.kg_edge_swipe_region_size);
+
+ mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
+ mTouchSlopSquare = mTouchSlop * mTouchSlop;
+
+ mDisplayMetrics = res.getDisplayMetrics();
+ final float density = mDisplayMetrics.density;
+
+ // top half of the lock icon, plus another 25% to be sure
+ mDragHandleClosedAbove = (int) (DRAG_HANDLE_CLOSED_ABOVE * density + 0.5f);
+ mDragHandleClosedBelow = (int) (DRAG_HANDLE_CLOSED_BELOW * density + 0.5f);
+ mDragHandleOpenAbove = (int) (DRAG_HANDLE_OPEN_ABOVE * density + 0.5f);
+ mDragHandleOpenBelow = (int) (DRAG_HANDLE_OPEN_BELOW * density + 0.5f);
+
+ // how much space to account for in the handle when closed
+ mChallengeBottomBound = res.getDimensionPixelSize(R.dimen.kg_widget_pager_bottom_padding);
+
+ setWillNotDraw(false);
+ setSystemUiVisibility(SYSTEM_UI_FLAG_LAYOUT_STABLE);
+ }
+
+ public void setHandleAlpha(float alpha) {
+ if (mExpandChallengeView != null) {
+ mExpandChallengeView.setAlpha(alpha);
+ }
+ }
+
+ public void setChallengeInteractive(boolean interactive) {
+ mChallengeInteractiveExternal = interactive;
+ if (mExpandChallengeView != null) {
+ mExpandChallengeView.setEnabled(interactive);
+ }
+ }
+
+ void animateHandle(boolean visible) {
+ if (mHandleAnimation != null) {
+ mHandleAnimation.cancel();
+ mHandleAnimation = null;
+ }
+ final float targetAlpha = visible ? 1.f : 0.f;
+ if (targetAlpha == mHandleAlpha) {
+ return;
+ }
+ mHandleAnimation = ObjectAnimator.ofFloat(this, HANDLE_ALPHA, targetAlpha);
+ mHandleAnimation.setInterpolator(sHandleFadeInterpolator);
+ mHandleAnimation.setDuration(HANDLE_ANIMATE_DURATION);
+ mHandleAnimation.start();
+ }
+
+ private void sendInitialListenerUpdates() {
+ if (mScrollListener != null) {
+ int challengeTop = mChallengeView != null ? mChallengeView.getTop() : 0;
+ mScrollListener.onScrollPositionChanged(mChallengeOffset, challengeTop);
+ mScrollListener.onScrollStateChanged(mScrollState);
+ }
+ }
+
+ public void setOnChallengeScrolledListener(OnChallengeScrolledListener listener) {
+ mScrollListener = listener;
+ if (mHasLayout) {
+ sendInitialListenerUpdates();
+ }
+ }
+
+ public void setOnBouncerStateChangedListener(OnBouncerStateChangedListener listener) {
+ mBouncerListener = listener;
+ }
+
+ @Override
+ public void onAttachedToWindow() {
+ super.onAttachedToWindow();
+
+ mHasLayout = false;
+ }
+
+ @Override
+ public void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+
+ removeCallbacks(mEndScrollRunnable);
+ mHasLayout = false;
+ }
+
+ @Override
+ public void requestChildFocus(View child, View focused) {
+ if (mIsBouncing && child != mChallengeView) {
+ // Clear out of the bouncer if the user tries to move focus outside of
+ // the security challenge view.
+ hideBouncer();
+ }
+ super.requestChildFocus(child, focused);
+ }
+
+ // We want the duration of the page snap animation to be influenced by the distance that
+ // the screen has to travel, however, we don't want this duration to be effected in a
+ // purely linear fashion. Instead, we use this method to moderate the effect that the distance
+ // of travel has on the overall snap duration.
+ float distanceInfluenceForSnapDuration(float f) {
+ f -= 0.5f; // center the values about 0.
+ f *= 0.3f * Math.PI / 2.0f;
+ return (float) Math.sin(f);
+ }
+
+ void setScrollState(int state) {
+ if (mScrollState != state) {
+ mScrollState = state;
+
+ animateHandle(state == SCROLL_STATE_IDLE && !mChallengeShowing);
+ if (mScrollListener != null) {
+ mScrollListener.onScrollStateChanged(state);
+ }
+ }
+ }
+
+ void completeChallengeScroll() {
+ setChallengeShowing(mChallengeShowingTargetState);
+ mChallengeOffset = mChallengeShowing ? 1.f : 0.f;
+ setScrollState(SCROLL_STATE_IDLE);
+ mChallengeInteractiveInternal = true;
+ mChallengeView.setLayerType(LAYER_TYPE_NONE, null);
+ }
+
+ void setScrimView(View scrim) {
+ if (mScrimView != null) {
+ mScrimView.setOnClickListener(null);
+ }
+ mScrimView = scrim;
+ mScrimView.setVisibility(mIsBouncing ? VISIBLE : GONE);
+ mScrimView.setFocusable(true);
+ mScrimView.setOnClickListener(mScrimClickListener);
+ }
+
+ /**
+ * Animate the bottom edge of the challenge view to the given position.
+ *
+ * @param y desired final position for the bottom edge of the challenge view in px
+ * @param velocity velocity in
+ */
+ void animateChallengeTo(int y, int velocity) {
+ if (mChallengeView == null) {
+ // Nothing to do.
+ return;
+ }
+
+ cancelTransitionsInProgress();
+
+ mChallengeInteractiveInternal = false;
+ mChallengeView.setLayerType(LAYER_TYPE_HARDWARE, null);
+ final int sy = mChallengeView.getBottom();
+ final int dy = y - sy;
+ if (dy == 0) {
+ completeChallengeScroll();
+ return;
+ }
+
+ setScrollState(SCROLL_STATE_SETTLING);
+
+ final int childHeight = mChallengeView.getHeight();
+ final int halfHeight = childHeight / 2;
+ final float distanceRatio = Math.min(1f, 1.0f * Math.abs(dy) / childHeight);
+ final float distance = halfHeight + halfHeight *
+ distanceInfluenceForSnapDuration(distanceRatio);
+
+ int duration = 0;
+ velocity = Math.abs(velocity);
+ if (velocity > 0) {
+ duration = 4 * Math.round(1000 * Math.abs(distance / velocity));
+ } else {
+ final float childDelta = (float) Math.abs(dy) / childHeight;
+ duration = (int) ((childDelta + 1) * 100);
+ }
+ duration = Math.min(duration, MAX_SETTLE_DURATION);
+
+ mScroller.startScroll(0, sy, 0, dy, duration);
+ postInvalidateOnAnimation();
+ }
+
+ private void setChallengeShowing(boolean showChallenge) {
+ if (mChallengeShowing == showChallenge) {
+ return;
+ }
+ mChallengeShowing = showChallenge;
+
+ if (mExpandChallengeView == null || mChallengeView == null) {
+ // These might not be here yet if we haven't been through layout.
+ // If we haven't, the first layout pass will set everything up correctly
+ // based on mChallengeShowing as set above.
+ return;
+ }
+
+ if (mChallengeShowing) {
+ mExpandChallengeView.setVisibility(View.INVISIBLE);
+ mChallengeView.setVisibility(View.VISIBLE);
+ if (AccessibilityManager.getInstance(mContext).isEnabled()) {
+ mChallengeView.requestAccessibilityFocus();
+ mChallengeView.announceForAccessibility(mContext.getString(
+ R.string.keyguard_accessibility_unlock_area_expanded));
+ }
+ } else {
+ mExpandChallengeView.setVisibility(View.VISIBLE);
+ mChallengeView.setVisibility(View.INVISIBLE);
+ if (AccessibilityManager.getInstance(mContext).isEnabled()) {
+ mExpandChallengeView.requestAccessibilityFocus();
+ mChallengeView.announceForAccessibility(mContext.getString(
+ R.string.keyguard_accessibility_unlock_area_collapsed));
+ }
+ }
+ }
+
+ /**
+ * @return true if the challenge is at all visible.
+ */
+ public boolean isChallengeShowing() {
+ return mChallengeShowing;
+ }
+
+ @Override
+ public boolean isChallengeOverlapping() {
+ return mChallengeShowing;
+ }
+
+ @Override
+ public boolean isBouncing() {
+ return mIsBouncing;
+ }
+
+ @Override
+ public int getBouncerAnimationDuration() {
+ return HANDLE_ANIMATE_DURATION;
+ }
+
+ @Override
+ public void showBouncer() {
+ if (mIsBouncing) return;
+ mWasChallengeShowing = mChallengeShowing;
+ mIsBouncing = true;
+ showChallenge(true);
+ if (mScrimView != null) {
+ Animator anim = ObjectAnimator.ofFloat(mScrimView, "alpha", 1f);
+ anim.setDuration(HANDLE_ANIMATE_DURATION);
+ anim.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationStart(Animator animation) {
+ mScrimView.setVisibility(VISIBLE);
+ }
+ });
+ anim.start();
+ }
+ if (mChallengeView != null) {
+ mChallengeView.showBouncer(HANDLE_ANIMATE_DURATION);
+ }
+
+ if (mBouncerListener != null) {
+ mBouncerListener.onBouncerStateChanged(true);
+ }
+ }
+
+ @Override
+ public void hideBouncer() {
+ if (!mIsBouncing) return;
+ if (!mWasChallengeShowing) showChallenge(false);
+ mIsBouncing = false;
+
+ if (mScrimView != null) {
+ Animator anim = ObjectAnimator.ofFloat(mScrimView, "alpha", 0f);
+ anim.setDuration(HANDLE_ANIMATE_DURATION);
+ anim.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mScrimView.setVisibility(GONE);
+ }
+ });
+ anim.start();
+ }
+ if (mChallengeView != null) {
+ mChallengeView.hideBouncer(HANDLE_ANIMATE_DURATION);
+ }
+ if (mBouncerListener != null) {
+ mBouncerListener.onBouncerStateChanged(false);
+ }
+ }
+
+ private int getChallengeMargin(boolean expanded) {
+ return expanded && mHasGlowpad ? 0 : mDragHandleEdgeSlop;
+ }
+
+ private float getChallengeAlpha() {
+ float x = mChallengeOffset - 1;
+ return x * x * x + 1.f;
+ }
+
+ @Override
+ public void requestDisallowInterceptTouchEvent(boolean allowIntercept) {
+ // We'll intercept whoever we feel like! ...as long as it isn't a challenge view.
+ // If there are one or more pointers in the challenge view before we take over
+ // touch events, onInterceptTouchEvent will set mBlockDrag.
+ }
+
+ @Override
+ public boolean onInterceptTouchEvent(MotionEvent ev) {
+ if (mVelocityTracker == null) {
+ mVelocityTracker = VelocityTracker.obtain();
+ }
+ mVelocityTracker.addMovement(ev);
+
+ final int action = ev.getActionMasked();
+ switch (action) {
+ case MotionEvent.ACTION_DOWN:
+ mGestureStartX = ev.getX();
+ mGestureStartY = ev.getY();
+ mBlockDrag = false;
+ break;
+
+ case MotionEvent.ACTION_CANCEL:
+ case MotionEvent.ACTION_UP:
+ resetTouch();
+ break;
+
+ case MotionEvent.ACTION_MOVE:
+ final int count = ev.getPointerCount();
+ for (int i = 0; i < count; i++) {
+ final float x = ev.getX(i);
+ final float y = ev.getY(i);
+ if (!mIsBouncing && mActivePointerId == INVALID_POINTER
+ && (crossedDragHandle(x, y, mGestureStartY)
+ || (isInChallengeView(x, y) &&
+ mScrollState == SCROLL_STATE_SETTLING))) {
+ mActivePointerId = ev.getPointerId(i);
+ mGestureStartX = x;
+ mGestureStartY = y;
+ mGestureStartChallengeBottom = getChallengeBottom();
+ mDragging = true;
+ mChallengeView.setLayerType(LAYER_TYPE_HARDWARE, null);
+ } else if (mChallengeShowing && isInChallengeView(x, y)) {
+ mBlockDrag = true;
+ }
+ }
+ break;
+ }
+
+ if (mBlockDrag || isChallengeInteractionBlocked()) {
+ mActivePointerId = INVALID_POINTER;
+ mDragging = false;
+ }
+
+ return mDragging;
+ }
+
+ private boolean isChallengeInteractionBlocked() {
+ return !mChallengeInteractiveExternal || !mChallengeInteractiveInternal;
+ }
+
+ private void resetTouch() {
+ mVelocityTracker.recycle();
+ mVelocityTracker = null;
+ mActivePointerId = INVALID_POINTER;
+ mDragging = mBlockDrag = false;
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent ev) {
+ if (mVelocityTracker == null) {
+ mVelocityTracker = VelocityTracker.obtain();
+ }
+ mVelocityTracker.addMovement(ev);
+
+ final int action = ev.getActionMasked();
+ switch (action) {
+ case MotionEvent.ACTION_DOWN:
+ mBlockDrag = false;
+ mGestureStartX = ev.getX();
+ mGestureStartY = ev.getY();
+ break;
+
+ case MotionEvent.ACTION_CANCEL:
+ if (mDragging && !isChallengeInteractionBlocked()) {
+ showChallenge(0);
+ }
+ resetTouch();
+ break;
+
+ case MotionEvent.ACTION_POINTER_UP:
+ if (mActivePointerId != ev.getPointerId(ev.getActionIndex())) {
+ break;
+ }
+ case MotionEvent.ACTION_UP:
+ if (mDragging && !isChallengeInteractionBlocked()) {
+ mVelocityTracker.computeCurrentVelocity(1000, mMaxVelocity);
+ showChallenge((int) mVelocityTracker.getYVelocity(mActivePointerId));
+ }
+ resetTouch();
+ break;
+
+ case MotionEvent.ACTION_MOVE:
+ if (!mDragging && !mBlockDrag && !mIsBouncing) {
+ final int count = ev.getPointerCount();
+ for (int i = 0; i < count; i++) {
+ final float x = ev.getX(i);
+ final float y = ev.getY(i);
+
+ if ((isInDragHandle(x, y) || crossedDragHandle(x, y, mGestureStartY) ||
+ (isInChallengeView(x, y) && mScrollState == SCROLL_STATE_SETTLING))
+ && mActivePointerId == INVALID_POINTER
+ && !isChallengeInteractionBlocked()) {
+ mGestureStartX = x;
+ mGestureStartY = y;
+ mActivePointerId = ev.getPointerId(i);
+ mGestureStartChallengeBottom = getChallengeBottom();
+ mDragging = true;
+ mChallengeView.setLayerType(LAYER_TYPE_HARDWARE, null);
+ break;
+ }
+ }
+ }
+ // Not an else; this can be set above.
+ if (mDragging) {
+ // No-op if already in this state, but set it here in case we arrived
+ // at this point from either intercept or the above.
+ setScrollState(SCROLL_STATE_DRAGGING);
+
+ final int index = ev.findPointerIndex(mActivePointerId);
+ if (index < 0) {
+ // Oops, bogus state. We lost some touch events somewhere.
+ // Just drop it with no velocity and let things settle.
+ resetTouch();
+ showChallenge(0);
+ return true;
+ }
+ final float y = ev.getY(index);
+ final float pos = Math.min(y - mGestureStartY,
+ getLayoutBottom() - mChallengeBottomBound);
+
+ moveChallengeTo(mGestureStartChallengeBottom + (int) pos);
+ }
+ break;
+ }
+ return true;
+ }
+
+ /**
+ * The lifecycle of touch events is subtle and it's very easy to do something
+ * that will cause bugs that will be nasty to track when overriding this method.
+ * Normally one should always override onInterceptTouchEvent instead.
+ *
+ * To put it another way, don't try this at home.
+ */
+ @Override
+ public boolean dispatchTouchEvent(MotionEvent ev) {
+ final int action = ev.getActionMasked();
+ boolean handled = false;
+ if (action == MotionEvent.ACTION_DOWN) {
+ // Defensive programming: if we didn't get the UP or CANCEL, reset anyway.
+ mEdgeCaptured = false;
+ }
+ if (mWidgetsView != null && !mIsBouncing && (mEdgeCaptured || isEdgeSwipeBeginEvent(ev))) {
+ // Normally we would need to do a lot of extra stuff here.
+ // We can only get away with this because we haven't padded in
+ // the widget pager or otherwise transformed it during layout.
+ // We also don't support things like splitting MotionEvents.
+
+ // We set handled to captured even if dispatch is returning false here so that
+ // we don't send a different view a busted or incomplete event stream.
+ handled = mEdgeCaptured |= mWidgetsView.dispatchTouchEvent(ev);
+ }
+
+ if (!handled && !mEdgeCaptured) {
+ handled = super.dispatchTouchEvent(ev);
+ }
+
+ if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
+ mEdgeCaptured = false;
+ }
+
+ return handled;
+ }
+
+ private boolean isEdgeSwipeBeginEvent(MotionEvent ev) {
+ if (ev.getActionMasked() != MotionEvent.ACTION_DOWN) {
+ return false;
+ }
+
+ final float x = ev.getX();
+ return x < mDragHandleEdgeSlop || x >= getWidth() - mDragHandleEdgeSlop;
+ }
+
+ /**
+ * We only want to add additional vertical space to the drag handle when the panel is fully
+ * closed.
+ */
+ private int getDragHandleSizeAbove() {
+ return isChallengeShowing() ? mDragHandleOpenAbove : mDragHandleClosedAbove;
+ }
+ private int getDragHandleSizeBelow() {
+ return isChallengeShowing() ? mDragHandleOpenBelow : mDragHandleClosedBelow;
+ }
+
+ private boolean isInChallengeView(float x, float y) {
+ return isPointInView(x, y, mChallengeView);
+ }
+
+ private boolean isInDragHandle(float x, float y) {
+ return isPointInView(x, y, mExpandChallengeView);
+ }
+
+ private boolean isPointInView(float x, float y, View view) {
+ if (view == null) {
+ return false;
+ }
+ return x >= view.getLeft() && y >= view.getTop()
+ && x < view.getRight() && y < view.getBottom();
+ }
+
+ private boolean crossedDragHandle(float x, float y, float initialY) {
+
+ final int challengeTop = mChallengeView.getTop();
+ final boolean horizOk = x >= 0 && x < getWidth();
+
+ final boolean vertOk;
+ if (mChallengeShowing) {
+ vertOk = initialY < (challengeTop - getDragHandleSizeAbove()) &&
+ y > challengeTop + getDragHandleSizeBelow();
+ } else {
+ vertOk = initialY > challengeTop + getDragHandleSizeBelow() &&
+ y < challengeTop - getDragHandleSizeAbove();
+ }
+ return horizOk && vertOk;
+ }
+
+ private int makeChildMeasureSpec(int maxSize, int childDimen) {
+ final int mode;
+ final int size;
+ switch (childDimen) {
+ case LayoutParams.WRAP_CONTENT:
+ mode = MeasureSpec.AT_MOST;
+ size = maxSize;
+ break;
+ case LayoutParams.MATCH_PARENT:
+ mode = MeasureSpec.EXACTLY;
+ size = maxSize;
+ break;
+ default:
+ mode = MeasureSpec.EXACTLY;
+ size = Math.min(maxSize, childDimen);
+ break;
+ }
+ return MeasureSpec.makeMeasureSpec(size, mode);
+ }
+
+ @Override
+ protected void onMeasure(int widthSpec, int heightSpec) {
+ if (MeasureSpec.getMode(widthSpec) != MeasureSpec.EXACTLY ||
+ MeasureSpec.getMode(heightSpec) != MeasureSpec.EXACTLY) {
+ throw new IllegalArgumentException(
+ "SlidingChallengeLayout must be measured with an exact size");
+ }
+
+ final int width = MeasureSpec.getSize(widthSpec);
+ final int height = MeasureSpec.getSize(heightSpec);
+ setMeasuredDimension(width, height);
+
+ // Find one and only one challenge view.
+ final View oldChallengeView = mChallengeView;
+ final View oldExpandChallengeView = mChallengeView;
+ mChallengeView = null;
+ mExpandChallengeView = null;
+ final int count = getChildCount();
+
+ // First iteration through the children finds special children and sets any associated
+ // state.
+ for (int i = 0; i < count; i++) {
+ final View child = getChildAt(i);
+ final LayoutParams lp = (LayoutParams) child.getLayoutParams();
+ if (lp.childType == LayoutParams.CHILD_TYPE_CHALLENGE) {
+ if (mChallengeView != null) {
+ throw new IllegalStateException(
+ "There may only be one child with layout_isChallenge=\"true\"");
+ }
+ if (!(child instanceof KeyguardSecurityContainer)) {
+ throw new IllegalArgumentException(
+ "Challenge must be a KeyguardSecurityContainer");
+ }
+ mChallengeView = (KeyguardSecurityContainer) child;
+ if (mChallengeView != oldChallengeView) {
+ mChallengeView.setVisibility(mChallengeShowing ? VISIBLE : INVISIBLE);
+ }
+ // We're going to play silly games with the frame's background drawable later.
+ if (!mHasLayout) {
+ // Set up the margin correctly based on our content for the first run.
+ mHasGlowpad = child.findViewById(R.id.keyguard_selector_view) != null;
+ lp.leftMargin = lp.rightMargin = getChallengeMargin(true);
+ }
+ } else if (lp.childType == LayoutParams.CHILD_TYPE_EXPAND_CHALLENGE_HANDLE) {
+ if (mExpandChallengeView != null) {
+ throw new IllegalStateException(
+ "There may only be one child with layout_childType"
+ + "=\"expandChallengeHandle\"");
+ }
+ mExpandChallengeView = child;
+ if (mExpandChallengeView != oldExpandChallengeView) {
+ mExpandChallengeView.setVisibility(mChallengeShowing ? INVISIBLE : VISIBLE);
+ mExpandChallengeView.setOnClickListener(mExpandChallengeClickListener);
+ }
+ } else if (lp.childType == LayoutParams.CHILD_TYPE_SCRIM) {
+ setScrimView(child);
+ } else if (lp.childType == LayoutParams.CHILD_TYPE_WIDGETS) {
+ mWidgetsView = child;
+ }
+ }
+
+ // We want to measure the challenge view first, since the KeyguardWidgetPager
+ // needs to do things its measure pass that are dependent on the challenge view
+ // having been measured.
+ if (mChallengeView != null && mChallengeView.getVisibility() != View.GONE) {
+ // This one's a little funny. If the IME is present - reported in the form
+ // of insets on the root view - we only give the challenge the space it would
+ // have had if the IME wasn't there in order to keep the rest of the layout stable.
+ // We base this on the layout_maxHeight on the challenge view. If it comes out
+ // negative or zero, either we didn't have a maxHeight or we're totally out of space,
+ // so give up and measure as if this rule weren't there.
+ int challengeHeightSpec = heightSpec;
+ final View root = getRootView();
+ if (root != null) {
+ final LayoutParams lp = (LayoutParams) mChallengeView.getLayoutParams();
+ final int specSize = MeasureSpec.getSize(heightSpec);
+ final int windowHeight = mDisplayMetrics.heightPixels - root.getPaddingTop();
+ final int diff = windowHeight - specSize;
+ final int maxChallengeHeight = lp.maxHeight - diff;
+ if (maxChallengeHeight > 0) {
+ challengeHeightSpec = makeChildMeasureSpec(maxChallengeHeight, lp.height);
+ }
+ }
+ measureChildWithMargins(mChallengeView, widthSpec, 0, challengeHeightSpec, 0);
+ }
+
+ // Measure the rest of the children
+ for (int i = 0; i < count; i++) {
+ final View child = getChildAt(i);
+ if (child.getVisibility() == GONE) {
+ continue;
+ }
+ // Don't measure the challenge view twice!
+ if (child == mChallengeView) continue;
+
+ // Measure children. Widget frame measures special, so that we can ignore
+ // insets for the IME.
+ int parentWidthSpec = widthSpec, parentHeightSpec = heightSpec;
+ final LayoutParams lp = (LayoutParams) child.getLayoutParams();
+ if (lp.childType == LayoutParams.CHILD_TYPE_WIDGETS) {
+ final View root = getRootView();
+ if (root != null) {
+ // This calculation is super dodgy and relies on several assumptions.
+ // Specifically that the root of the window will be padded in for insets
+ // and that the window is LAYOUT_IN_SCREEN.
+ final int windowWidth = mDisplayMetrics.widthPixels;
+ final int windowHeight = mDisplayMetrics.heightPixels - root.getPaddingTop();
+ parentWidthSpec = MeasureSpec.makeMeasureSpec(
+ windowWidth, MeasureSpec.EXACTLY);
+ parentHeightSpec = MeasureSpec.makeMeasureSpec(
+ windowHeight, MeasureSpec.EXACTLY);
+ }
+ }
+ measureChildWithMargins(child, parentWidthSpec, 0, parentHeightSpec, 0);
+ }
+ }
+
+ @Override
+ protected void onLayout(boolean changed, int l, int t, int r, int b) {
+ final int paddingLeft = getPaddingLeft();
+ final int paddingTop = getPaddingTop();
+ final int paddingRight = getPaddingRight();
+ final int paddingBottom = getPaddingBottom();
+ final int width = r - l;
+ final int height = b - t;
+
+ final int count = getChildCount();
+ for (int i = 0; i < count; i++) {
+ final View child = getChildAt(i);
+
+ if (child.getVisibility() == GONE) continue;
+
+ final LayoutParams lp = (LayoutParams) child.getLayoutParams();
+
+ if (lp.childType == LayoutParams.CHILD_TYPE_CHALLENGE) {
+ // Challenge views pin to the bottom, offset by a portion of their height,
+ // and center horizontally.
+ final int center = (paddingLeft + width - paddingRight) / 2;
+ final int childWidth = child.getMeasuredWidth();
+ final int childHeight = child.getMeasuredHeight();
+ final int left = center - childWidth / 2;
+ final int layoutBottom = height - paddingBottom - lp.bottomMargin;
+ // We use the top of the challenge view to position the handle, so
+ // we never want less than the handle size showing at the bottom.
+ final int bottom = layoutBottom + (int) ((childHeight - mChallengeBottomBound)
+ * (1 - mChallengeOffset));
+ child.setAlpha(getChallengeAlpha());
+ child.layout(left, bottom - childHeight, left + childWidth, bottom);
+ } else if (lp.childType == LayoutParams.CHILD_TYPE_EXPAND_CHALLENGE_HANDLE) {
+ final int center = (paddingLeft + width - paddingRight) / 2;
+ final int left = center - child.getMeasuredWidth() / 2;
+ final int right = left + child.getMeasuredWidth();
+ final int bottom = height - paddingBottom - lp.bottomMargin;
+ final int top = bottom - child.getMeasuredHeight();
+ child.layout(left, top, right, bottom);
+ } else {
+ // Non-challenge views lay out from the upper left, layered.
+ child.layout(paddingLeft + lp.leftMargin,
+ paddingTop + lp.topMargin,
+ paddingLeft + child.getMeasuredWidth(),
+ paddingTop + child.getMeasuredHeight());
+ }
+ }
+
+ if (!mHasLayout) {
+ mHasLayout = true;
+ }
+ }
+
+ @Override
+ public void draw(Canvas c) {
+ super.draw(c);
+ if (DEBUG) {
+ final Paint debugPaint = new Paint();
+ debugPaint.setColor(0x40FF00CC);
+ // show the isInDragHandle() rect
+ c.drawRect(mDragHandleEdgeSlop,
+ mChallengeView.getTop() - getDragHandleSizeAbove(),
+ getWidth() - mDragHandleEdgeSlop,
+ mChallengeView.getTop() + getDragHandleSizeBelow(),
+ debugPaint);
+ }
+ }
+
+ public void computeScroll() {
+ super.computeScroll();
+
+ if (!mScroller.isFinished()) {
+ if (mChallengeView == null) {
+ // Can't scroll if the view is missing.
+ Log.e(TAG, "Challenge view missing in computeScroll");
+ mScroller.abortAnimation();
+ return;
+ }
+
+ mScroller.computeScrollOffset();
+ moveChallengeTo(mScroller.getCurrY());
+
+ if (mScroller.isFinished()) {
+ post(mEndScrollRunnable);
+ }
+ }
+ }
+
+ private void cancelTransitionsInProgress() {
+ if (!mScroller.isFinished()) {
+ mScroller.abortAnimation();
+ completeChallengeScroll();
+ }
+ if (mFader != null) {
+ mFader.cancel();
+ }
+ }
+
+ public void fadeInChallenge() {
+ fadeChallenge(true);
+ }
+
+ public void fadeOutChallenge() {
+ fadeChallenge(false);
+ }
+
+ public void fadeChallenge(final boolean show) {
+ if (mChallengeView != null) {
+
+ cancelTransitionsInProgress();
+ float alpha = show ? 1f : 0f;
+ int duration = show ? CHALLENGE_FADE_IN_DURATION : CHALLENGE_FADE_OUT_DURATION;
+ mFader = ObjectAnimator.ofFloat(mChallengeView, "alpha", alpha);
+ mFader.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationStart(Animator animation) {
+ onFadeStart(show);
+ }
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ onFadeEnd(show);
+ }
+ });
+ mFader.setDuration(duration);
+ mFader.start();
+ }
+ }
+
+ private int getMaxChallengeBottom() {
+ if (mChallengeView == null) return 0;
+ final int layoutBottom = getLayoutBottom();
+ final int challengeHeight = mChallengeView.getMeasuredHeight();
+
+ return (layoutBottom + challengeHeight - mChallengeBottomBound);
+ }
+
+ private int getMinChallengeBottom() {
+ return getLayoutBottom();
+ }
+
+
+ private void onFadeStart(boolean show) {
+ mChallengeInteractiveInternal = false;
+ mChallengeView.setLayerType(LAYER_TYPE_HARDWARE, null);
+
+ if (show) {
+ moveChallengeTo(getMinChallengeBottom());
+ }
+
+ setScrollState(SCROLL_STATE_FADING);
+ }
+
+ private void onFadeEnd(boolean show) {
+ mChallengeInteractiveInternal = true;
+ setChallengeShowing(show);
+
+ if (!show) {
+ moveChallengeTo(getMaxChallengeBottom());
+ }
+
+ mChallengeView.setLayerType(LAYER_TYPE_NONE, null);
+ mFader = null;
+ setScrollState(SCROLL_STATE_IDLE);
+ }
+
+ public int getMaxChallengeTop() {
+ if (mChallengeView == null) return 0;
+
+ final int layoutBottom = getLayoutBottom();
+ final int challengeHeight = mChallengeView.getMeasuredHeight();
+ return layoutBottom - challengeHeight;
+ }
+
+ /**
+ * Move the bottom edge of mChallengeView to a new position and notify the listener
+ * if it represents a change in position. Changes made through this method will
+ * be stable across layout passes. If this method is called before first layout of
+ * this SlidingChallengeLayout it will have no effect.
+ *
+ * @param bottom New bottom edge in px in this SlidingChallengeLayout's coordinate system.
+ * @return true if the challenge view was moved
+ */
+ private boolean moveChallengeTo(int bottom) {
+ if (mChallengeView == null || !mHasLayout) {
+ return false;
+ }
+
+ final int layoutBottom = getLayoutBottom();
+ final int challengeHeight = mChallengeView.getHeight();
+
+ bottom = Math.max(getMinChallengeBottom(),
+ Math.min(bottom, getMaxChallengeBottom()));
+
+ float offset = 1.f - (float) (bottom - layoutBottom) /
+ (challengeHeight - mChallengeBottomBound);
+ mChallengeOffset = offset;
+ if (offset > 0 && !mChallengeShowing) {
+ setChallengeShowing(true);
+ }
+
+ mChallengeView.layout(mChallengeView.getLeft(),
+ bottom - mChallengeView.getHeight(), mChallengeView.getRight(), bottom);
+
+ mChallengeView.setAlpha(getChallengeAlpha());
+ if (mScrollListener != null) {
+ mScrollListener.onScrollPositionChanged(offset, mChallengeView.getTop());
+ }
+ postInvalidateOnAnimation();
+ return true;
+ }
+
+ /**
+ * The bottom edge of this SlidingChallengeLayout's coordinate system; will coincide with
+ * the bottom edge of mChallengeView when the challenge is fully opened.
+ */
+ private int getLayoutBottom() {
+ final int bottomMargin = (mChallengeView == null)
+ ? 0
+ : ((LayoutParams) mChallengeView.getLayoutParams()).bottomMargin;
+ final int layoutBottom = getMeasuredHeight() - getPaddingBottom() - bottomMargin;
+ return layoutBottom;
+ }
+
+ /**
+ * The bottom edge of mChallengeView; essentially, where the sliding challenge 'is'.
+ */
+ private int getChallengeBottom() {
+ if (mChallengeView == null) return 0;
+
+ return mChallengeView.getBottom();
+ }
+
+ /**
+ * Show or hide the challenge view, animating it if necessary.
+ * @param show true to show, false to hide
+ */
+ public void showChallenge(boolean show) {
+ showChallenge(show, 0);
+ if (!show) {
+ // Block any drags in progress so that callers can use this to disable dragging
+ // for other touch interactions.
+ mBlockDrag = true;
+ }
+ }
+
+ private void showChallenge(int velocity) {
+ boolean show = false;
+ if (Math.abs(velocity) > mMinVelocity) {
+ show = velocity < 0;
+ } else {
+ show = mChallengeOffset >= 0.5f;
+ }
+ showChallenge(show, velocity);
+ }
+
+ private void showChallenge(boolean show, int velocity) {
+ if (mChallengeView == null) {
+ setChallengeShowing(false);
+ return;
+ }
+
+ if (mHasLayout) {
+ mChallengeShowingTargetState = show;
+ final int layoutBottom = getLayoutBottom();
+ animateChallengeTo(show ? layoutBottom :
+ layoutBottom + mChallengeView.getHeight() - mChallengeBottomBound, velocity);
+ }
+ }
+
+ @Override
+ public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) {
+ return new LayoutParams(getContext(), attrs);
+ }
+
+ @Override
+ protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
+ return p instanceof LayoutParams ? new LayoutParams((LayoutParams) p) :
+ p instanceof MarginLayoutParams ? new LayoutParams((MarginLayoutParams) p) :
+ new LayoutParams(p);
+ }
+
+ @Override
+ protected ViewGroup.LayoutParams generateDefaultLayoutParams() {
+ return new LayoutParams();
+ }
+
+ @Override
+ protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
+ return p instanceof LayoutParams;
+ }
+
+ public static class LayoutParams extends MarginLayoutParams {
+ public int childType = CHILD_TYPE_NONE;
+ public static final int CHILD_TYPE_NONE = 0;
+ public static final int CHILD_TYPE_CHALLENGE = 2;
+ public static final int CHILD_TYPE_SCRIM = 4;
+ public static final int CHILD_TYPE_WIDGETS = 5;
+ public static final int CHILD_TYPE_EXPAND_CHALLENGE_HANDLE = 6;
+
+ public int maxHeight;
+
+ public LayoutParams() {
+ this(MATCH_PARENT, WRAP_CONTENT);
+ }
+
+ public LayoutParams(int width, int height) {
+ super(width, height);
+ }
+
+ public LayoutParams(android.view.ViewGroup.LayoutParams source) {
+ super(source);
+ }
+
+ public LayoutParams(MarginLayoutParams source) {
+ super(source);
+ }
+
+ public LayoutParams(LayoutParams source) {
+ super(source);
+
+ childType = source.childType;
+ }
+
+ public LayoutParams(Context c, AttributeSet attrs) {
+ super(c, attrs);
+
+ final TypedArray a = c.obtainStyledAttributes(attrs,
+ R.styleable.SlidingChallengeLayout_Layout);
+ childType = a.getInt(R.styleable.SlidingChallengeLayout_Layout_layout_childType,
+ CHILD_TYPE_NONE);
+ maxHeight = a.getDimensionPixelSize(
+ R.styleable.SlidingChallengeLayout_Layout_layout_maxHeight, 0);
+ a.recycle();
+ }
+ }
+}
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 66080f3..4bb44af 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -1,6 +1,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
package="com.android.systemui"
+ android:sharedUserId="android.uid.systemui"
coreApp="true">
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
@@ -71,6 +72,7 @@
android:hardwareAccelerated="true"
android:label="@string/app_label"
android:icon="@*android:drawable/platlogo"
+ android:process="com.android.systemui"
android:supportsRtl="true">
<!-- Broadcast receiver that gets the broadcast at boot time and starts
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index c40e26d..48edc73 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -189,7 +189,7 @@
<string name="quick_settings_location_label" msgid="3292451598267467545">"الموقع المستخدم"</string>
<string name="quick_settings_media_device_label" msgid="1302906836372603762">"جهاز الوسائط"</string>
<string name="quick_settings_rssi_label" msgid="7725671335550695589">"RSSI"</string>
- <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"مكالمات الطوارئ فقط"</string>
+ <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"مكالمات طوارئ فقط"</string>
<string name="quick_settings_settings_label" msgid="5326556592578065401">"الإعدادات"</string>
<string name="quick_settings_time_label" msgid="4635969182239736408">"الوقت"</string>
<string name="quick_settings_user_label" msgid="5238995632130897840">"أنا"</string>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 8c2dd8e..580bfe7 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -147,7 +147,7 @@
<string name="accessibility_ringer_silent" msgid="9061243307939135383">"Mode silenci."</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"S\'ha omès <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Notificació omesa."</string>
- <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Capa de notificació."</string>
+ <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Àrea de notificacions"</string>
<string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Configuració ràpida."</string>
<string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Aplicacions recents."</string>
<string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Usuari <xliff:g id="USER">%s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index d619de1..0789b29 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -133,7 +133,7 @@
<string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"Wi-Fi"</string>
<string name="accessibility_no_sim" msgid="8274017118472455155">"No hay tarjeta SIM."</string>
<string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Conexión mediante Bluetooth"</string>
- <string name="accessibility_airplane_mode" msgid="834748999790763092">"Modo de avión"</string>
+ <string name="accessibility_airplane_mode" msgid="834748999790763092">"Modo avión"</string>
<!-- String.format failed for translation -->
<!-- no translation found for accessibility_battery_level (7451474187113371965) -->
<skip />
@@ -154,7 +154,7 @@
<string name="accessibility_quick_settings_wifi" msgid="6099781031669728709">"<xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="NETWORK">%2$s</xliff:g>"</string>
<string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Móvil <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string>
<string name="accessibility_quick_settings_battery" msgid="1480931583381408972">"Batería <xliff:g id="STATE">%s</xliff:g>"</string>
- <string name="accessibility_quick_settings_airplane" msgid="4196876722090224753">"Modo de avión <xliff:g id="STATE">%s</xliff:g>"</string>
+ <string name="accessibility_quick_settings_airplane" msgid="4196876722090224753">"Modo avión <xliff:g id="STATE">%s</xliff:g>"</string>
<string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"Bluetooth <xliff:g id="STATE">%s</xliff:g>"</string>
<string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Alarma: <xliff:g id="TIME">%s</xliff:g>"</string>
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"Datos de 2G-3G inhabilitados"</string>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index c454bb1..fff1aa0 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -157,14 +157,14 @@
<string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Alarm ustawiony na <xliff:g id="TIME">%s</xliff:g>."</string>
<string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"Wyłączono transmisję danych 2G/3G"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Wyłączono transmisję danych 4G"</string>
- <string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Wyłączono komórkową transmisję danych"</string>
+ <string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Transmisja danych została wyłączona"</string>
<string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Wyłączono transmisję danych"</string>
- <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Osiągnięto określony limit wykorzystania transmisji danych."\n\n"Jeśli ponownie włączysz przesyłanie danych, operator może naliczyć opłaty."</string>
+ <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Ustawiony limit transmisji danych został osiągnięty."\n\n"Jeśli ponownie włączysz przesyłanie danych, operator może naliczyć dodatkowe opłaty."</string>
<string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Włącz transmisję danych"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Brak internetu"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi: połączono"</string>
<string name="gps_notification_searching_text" msgid="8574247005642736060">"Wyszukiwanie sygnału GPS"</string>
- <string name="gps_notification_found_text" msgid="4619274244146446464">"Lokalizacja ustawiona według GPS"</string>
+ <string name="gps_notification_found_text" msgid="4619274244146446464">"Lokalizacja z GPSa"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Usuń wszystkie powiadomienia."</string>
<string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"O aplikacji"</string>
<string name="close_universe" msgid="3736513750241754348">"Zamknij"</string>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index ccf4fd4..3d0ddd4 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -77,7 +77,7 @@
<string name="use_ptp_button_title" msgid="7517127540301625751">"Установить как камеру (PTP)"</string>
<string name="installer_cd_button_title" msgid="2312667578562201583">"Установить приложение"</string>
<string name="accessibility_back" msgid="567011538994429120">"Назад"</string>
- <string name="accessibility_home" msgid="8217216074895377641">"Главная страница"</string>
+ <string name="accessibility_home" msgid="8217216074895377641">"Домой"</string>
<string name="accessibility_menu" msgid="316839303324695949">"Меню"</string>
<string name="accessibility_recent" msgid="8571350598987952883">"Недавние приложения"</string>
<string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Кнопка переключения способа ввода."</string>
@@ -118,8 +118,8 @@
<string name="accessibility_two_bars" msgid="6437363648385206679">"два деления"</string>
<string name="accessibility_three_bars" msgid="2648241415119396648">"три деления"</string>
<string name="accessibility_signal_full" msgid="9122922886519676839">"надежный сигнал"</string>
- <string name="accessibility_desc_on" msgid="2385254693624345265">"ВКЛ"</string>
- <string name="accessibility_desc_off" msgid="6475508157786853157">"ВЫКЛ"</string>
+ <string name="accessibility_desc_on" msgid="2385254693624345265">"Вкл."</string>
+ <string name="accessibility_desc_off" msgid="6475508157786853157">"Выкл."</string>
<string name="accessibility_desc_connected" msgid="8366256693719499665">"Подключено"</string>
<string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
<string name="accessibility_data_connection_1x" msgid="994133468120244018">"1 X"</string>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index 91214d1..a58c9a0 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -181,7 +181,7 @@
<string name="quick_settings_battery_charged_label" msgid="8865413079414246081">"Laddat"</string>
<string name="quick_settings_bluetooth_label" msgid="6304190285170721401">"Bluetooth"</string>
<string name="quick_settings_bluetooth_multiple_devices_label" msgid="3912245565613684735">"Bluetooth (<xliff:g id="NUMBER">%d</xliff:g> enheter)"</string>
- <string name="quick_settings_bluetooth_off_label" msgid="8159652146149219937">"Bluetooth inaktivt"</string>
+ <string name="quick_settings_bluetooth_off_label" msgid="8159652146149219937">"Bluetooth av"</string>
<string name="quick_settings_brightness_label" msgid="6968372297018755815">"Ljusstyrka"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"Rotera automatiskt"</string>
<string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"Rotationen har låsts"</string>
@@ -196,9 +196,9 @@
<string name="quick_settings_wifi_label" msgid="9135344704899546041">"Wi-Fi"</string>
<string name="quick_settings_wifi_not_connected" msgid="7171904845345573431">"Ej ansluten"</string>
<string name="quick_settings_wifi_no_network" msgid="2221993077220856376">"Inget nätverk"</string>
- <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi är inaktiverat"</string>
- <string name="quick_settings_wifi_display_label" msgid="6893592964463624333">"Wi-Fi visas"</string>
- <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Trådlös visning"</string>
+ <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi av"</string>
+ <string name="quick_settings_wifi_display_label" msgid="6893592964463624333">"Trådlös skärm"</string>
+ <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Trådlös skärm"</string>
<string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Ljusstyrka"</string>
<string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
<string name="status_bar_help_title" msgid="1199237744086469217">"Meddelanden visas här"</string>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 7750e77..f43eabe 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -35,10 +35,10 @@
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Поточні"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"Сповіщення"</string>
<string name="battery_low_title" msgid="2783104807551211639">"Підключіть зарядний пристрій"</string>
- <string name="battery_low_subtitle" msgid="1752040062087829196">"Батарея виснажується."</string>
+ <string name="battery_low_subtitle" msgid="1752040062087829196">"Акумулятор розряджається."</string>
<string name="battery_low_percent_format" msgid="1077244949318261761">"Залишилося <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
<string name="invalid_charger" msgid="4549105996740522523">"Заряджання USB не підтримується."\n"Використовуйте лише наданий у комплекті зарядний пристрій."</string>
- <string name="battery_low_why" msgid="7279169609518386372">"Викор. батареї"</string>
+ <string name="battery_low_why" msgid="7279169609518386372">"Використання акумулятора"</string>
<string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Налаштування"</string>
<string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
<string name="status_bar_settings_airplane" msgid="4879879698500955300">"Режим польоту"</string>
@@ -85,11 +85,11 @@
<string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Збільшення екрана."</string>
<string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth під’єднано."</string>
<string name="accessibility_bluetooth_disconnected" msgid="7416648669976870175">"Bluetooth від’єднано."</string>
- <string name="accessibility_no_battery" msgid="358343022352820946">"Немає заряду батареї."</string>
- <string name="accessibility_battery_one_bar" msgid="7774887721891057523">"Одна смужка заряду батареї."</string>
- <string name="accessibility_battery_two_bars" msgid="8500650438735009973">"Дві смужки заряду батареї."</string>
- <string name="accessibility_battery_three_bars" msgid="2302983330865040446">"Три смужки заряду батареї."</string>
- <string name="accessibility_battery_full" msgid="8909122401720158582">"Повний заряд батареї"</string>
+ <string name="accessibility_no_battery" msgid="358343022352820946">"Акумулятор розряджений."</string>
+ <string name="accessibility_battery_one_bar" msgid="7774887721891057523">"Заряд акумулятора: одна смужка."</string>
+ <string name="accessibility_battery_two_bars" msgid="8500650438735009973">"Заряд акумулятора: дві смужки."</string>
+ <string name="accessibility_battery_three_bars" msgid="2302983330865040446">"Заряд акумулятора: три смужки."</string>
+ <string name="accessibility_battery_full" msgid="8909122401720158582">"Акумулятор заряджений."</string>
<string name="accessibility_no_phone" msgid="4894708937052611281">"Немає сигналу телефону."</string>
<string name="accessibility_phone_one_bar" msgid="687699278132664115">"Одна смужка сигналу телефону."</string>
<string name="accessibility_phone_two_bars" msgid="8384905382804815201">"Дві смужки сигналу телефону."</string>
@@ -134,7 +134,7 @@
<string name="accessibility_no_sim" msgid="8274017118472455155">"Немає SIM-карти."</string>
<string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Прив’язка Bluetooth."</string>
<string name="accessibility_airplane_mode" msgid="834748999790763092">"Режим польоту."</string>
- <string name="accessibility_battery_level" msgid="7451474187113371965">"Відсотків батареї: <xliff:g id="NUMBER">%d</xliff:g>."</string>
+ <string name="accessibility_battery_level" msgid="7451474187113371965">"Заряд акумулятора: <xliff:g id="NUMBER">%d</xliff:g>."</string>
<string name="accessibility_settings_button" msgid="799583911231893380">"Налаштування системи."</string>
<string name="accessibility_notifications_button" msgid="4498000369779421892">"Сповіщення."</string>
<string name="accessibility_remove_notification" msgid="3603099514902182350">"Очистити сповіщення."</string>
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIService.java b/packages/SystemUI/src/com/android/systemui/SystemUIService.java
index 1f3e942..e1aed82 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIService.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIService.java
@@ -20,19 +20,13 @@ import java.io.FileDescriptor;
import java.io.PrintWriter;
import android.app.Service;
-import android.content.BroadcastReceiver;
-import android.content.Context;
import android.content.Intent;
-import android.content.pm.PackageManager;
import android.content.res.Configuration;
-import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;
-import android.os.ServiceManager;
import android.util.Slog;
import android.view.IWindowManager;
import android.view.WindowManagerGlobal;
-import android.view.accessibility.AccessibilityManager;
public class SystemUIService extends Service {
static final String TAG = "SystemUIService";
@@ -69,10 +63,6 @@ public class SystemUIService extends Service {
@Override
public void onCreate() {
- // Tell the accessibility layer that this process will
- // run as the current user, i.e. run across users.
- AccessibilityManager.createAsSharedAcrossUsers(this);
-
// Pick status bar or system bar.
IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
try {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/FixedSizeDrawable.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/FixedSizeDrawable.java
index 8f2f5f9..0e8095c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/FixedSizeDrawable.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/FixedSizeDrawable.java
@@ -60,6 +60,10 @@ public class FixedSizeDrawable extends Drawable {
mDrawable.setAlpha(alpha);
}
+ public int getAlpha() {
+ return mDrawable.getAlpha();
+ }
+
public void setColorFilter(ColorFilter cf) {
mDrawable.setColorFilter(cf);
}