summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/java/android/accounts/ChooseTypeAndAccountActivity.java19
-rw-r--r--core/java/android/animation/ObjectAnimator.java30
-rw-r--r--core/java/android/animation/ValueAnimator.java14
-rw-r--r--core/java/android/app/Activity.java5
-rw-r--r--core/java/android/app/ActivityManager.java184
-rw-r--r--core/java/android/app/ActivityManagerNative.java160
-rw-r--r--core/java/android/app/ActivityThread.java123
-rw-r--r--core/java/android/app/AppOpsManager.java42
-rw-r--r--core/java/android/app/ApplicationThreadNative.java12
-rw-r--r--core/java/android/app/Dialog.java5
-rw-r--r--core/java/android/app/IActivityManager.java41
-rw-r--r--core/java/android/app/IApplicationThread.java4
-rw-r--r--core/java/android/app/LoaderManager.java4
-rw-r--r--core/java/android/appwidget/AppWidgetHost.java8
-rw-r--r--core/java/android/bluetooth/BluetoothGatt.java18
-rw-r--r--core/java/android/bluetooth/BluetoothGattServer.java14
-rw-r--r--core/java/android/bluetooth/BluetoothHeadset.java21
-rwxr-xr-x[-rw-r--r--]core/java/android/bluetooth/IBluetoothHeadset.aidl1
-rw-r--r--core/java/android/content/ContentResolver.java3
-rw-r--r--core/java/android/content/Context.java2
-rw-r--r--core/java/android/content/Intent.java64
-rw-r--r--core/java/android/content/UndoManager.java932
-rw-r--r--core/java/android/content/UndoOperation.java110
-rw-r--r--core/java/android/content/UndoOwner.java55
-rw-r--r--core/java/android/content/pm/ComponentInfo.java11
-rw-r--r--core/java/android/content/pm/KeySet.java34
-rw-r--r--core/java/android/content/pm/PackageParser.java106
-rw-r--r--core/java/android/content/pm/RegisteredServicesCache.java2
-rw-r--r--core/java/android/content/pm/ResolveInfo.java5
-rw-r--r--core/java/android/content/res/AssetFileDescriptor.java4
-rw-r--r--core/java/android/content/res/Resources.java16
-rw-r--r--core/java/android/database/AbstractCursor.java4
-rw-r--r--core/java/android/database/Cursor.java10
-rw-r--r--core/java/android/database/CursorWrapper.java4
-rw-r--r--core/java/android/hardware/Camera.java155
-rw-r--r--core/java/android/inputmethodservice/InputMethodService.java3
-rw-r--r--core/java/android/os/BatteryStats.java99
-rw-r--r--core/java/android/os/Build.java5
-rw-r--r--core/java/android/os/Debug.java150
-rw-r--r--core/java/android/os/Environment.java5
-rw-r--r--core/java/android/os/IPowerManager.aidl2
-rw-r--r--core/java/android/os/Looper.java10
-rw-r--r--core/java/android/os/MessageQueue.java5
-rw-r--r--core/java/android/os/ParcelableParcel.java75
-rw-r--r--core/java/android/os/PowerManager.java10
-rw-r--r--core/java/android/os/Process.java6
-rw-r--r--core/java/android/os/RecoverySystem.java17
-rw-r--r--core/java/android/os/RemoteCallbackList.java16
-rw-r--r--core/java/android/os/StrictMode.java12
-rw-r--r--core/java/android/os/Trace.java2
-rw-r--r--core/java/android/provider/DocumentsContract.java209
-rw-r--r--core/java/android/provider/DrmStore.java211
-rw-r--r--core/java/android/provider/OpenableColumns.java14
-rw-r--r--core/java/android/provider/Settings.java8
-rw-r--r--core/java/android/speech/tts/TtsEngines.java13
-rw-r--r--core/java/android/text/method/ArrowKeyMovementMethod.java2
-rw-r--r--core/java/android/text/method/BaseKeyListener.java2
-rw-r--r--core/java/android/text/method/BaseMovementMethod.java2
-rw-r--r--core/java/android/text/method/DialerKeyListener.java2
-rw-r--r--core/java/android/text/method/LinkMovementMethod.java5
-rw-r--r--core/java/android/text/method/MetaKeyKeyListener.java82
-rw-r--r--core/java/android/text/method/NumberKeyListener.java2
-rw-r--r--core/java/android/text/method/QwertyKeyListener.java2
-rw-r--r--core/java/android/util/ArrayMap.java617
-rw-r--r--core/java/android/util/LongSparseArray.java16
-rw-r--r--core/java/android/util/LongSparseLongArray.java16
-rw-r--r--core/java/android/util/MapCollections.java496
-rw-r--r--core/java/android/util/SparseArray.java62
-rw-r--r--core/java/android/util/SparseBooleanArray.java46
-rw-r--r--core/java/android/util/SparseIntArray.java45
-rw-r--r--core/java/android/util/SparseLongArray.java45
-rw-r--r--core/java/android/view/GLES20Canvas.java75
-rw-r--r--core/java/android/view/GLES20DisplayList.java9
-rw-r--r--core/java/android/view/GLES20RecordingCanvas.java11
-rw-r--r--core/java/android/view/GLES20RenderLayer.java7
-rw-r--r--core/java/android/view/GLES20TextureLayer.java5
-rw-r--r--core/java/android/view/GraphicBuffer.aidl19
-rw-r--r--core/java/android/view/GraphicBuffer.java229
-rw-r--r--core/java/android/view/HardwareLayer.java12
-rw-r--r--core/java/android/view/HardwareRenderer.java208
-rw-r--r--core/java/android/view/IAssetAtlas.aidl54
-rw-r--r--core/java/android/view/IWindowManager.aidl9
-rw-r--r--core/java/android/view/InputEvent.java1
-rw-r--r--core/java/android/view/InputFilter.java6
-rw-r--r--core/java/android/view/Surface.java42
-rw-r--r--core/java/android/view/SurfaceControl.java2
-rw-r--r--core/java/android/view/SurfaceView.java9
-rw-r--r--core/java/android/view/TextureView.java14
-rw-r--r--core/java/android/view/View.java92
-rw-r--r--core/java/android/view/ViewGroup.java88
-rw-r--r--core/java/android/view/ViewRootImpl.java57
-rw-r--r--core/java/android/view/Window.java34
-rw-r--r--core/java/android/view/WindowManager.java8
-rw-r--r--core/java/android/view/WindowManagerPolicy.java15
-rw-r--r--core/java/android/view/accessibility/AccessibilityManager.java54
-rw-r--r--core/java/android/view/inputmethod/BaseInputConnection.java6
-rw-r--r--core/java/android/view/transition/AutoTransition.java34
-rw-r--r--core/java/android/view/transition/Crossfade.java163
-rw-r--r--core/java/android/view/transition/Fade.java209
-rw-r--r--core/java/android/view/transition/Move.java299
-rw-r--r--core/java/android/view/transition/Recolor.java118
-rw-r--r--core/java/android/view/transition/Rotate.java67
-rw-r--r--core/java/android/view/transition/Scene.java191
-rw-r--r--core/java/android/view/transition/Slide.java70
-rw-r--r--core/java/android/view/transition/TextChange.java90
-rw-r--r--core/java/android/view/transition/Transition.java911
-rw-r--r--core/java/android/view/transition/TransitionGroup.java292
-rw-r--r--core/java/android/view/transition/TransitionInflater.java392
-rw-r--r--core/java/android/view/transition/TransitionManager.java261
-rw-r--r--core/java/android/view/transition/TransitionValues.java60
-rw-r--r--core/java/android/view/transition/Visibility.java243
-rw-r--r--core/java/android/view/transition/package.html25
-rw-r--r--core/java/android/widget/AbsListView.java620
-rw-r--r--core/java/android/widget/Editor.java256
-rw-r--r--core/java/android/widget/GridLayout.java59
-rw-r--r--core/java/android/widget/ListView.java35
-rw-r--r--core/java/android/widget/RemoteViewsAdapter.java43
-rw-r--r--core/java/android/widget/ScrollBarDrawable.java6
-rw-r--r--core/java/android/widget/TextClock.java46
-rw-r--r--core/java/android/widget/TextView.java101
-rw-r--r--core/java/android/widget/Toast.java72
-rw-r--r--core/java/com/android/internal/app/ActionBarImpl.java8
-rw-r--r--core/java/com/android/internal/app/ResolverActivity.java51
-rw-r--r--core/java/com/android/internal/content/PackageMonitor.java15
-rw-r--r--core/java/com/android/internal/os/BackgroundThread.java54
-rw-r--r--core/java/com/android/internal/os/BatteryStatsImpl.java110
-rw-r--r--core/java/com/android/internal/os/ProcessStats.java10
-rw-r--r--core/java/com/android/internal/os/ZygoteInit.java13
-rw-r--r--core/java/com/android/internal/policy/IKeyguardExitCallback.aidl20
-rw-r--r--core/java/com/android/internal/policy/IKeyguardService.aidl44
-rw-r--r--core/java/com/android/internal/policy/IKeyguardShowCallback.aidl20
-rw-r--r--core/java/com/android/internal/util/IndentingPrintWriter.java4
-rw-r--r--core/java/com/android/internal/view/RotationPolicy.java21
-rw-r--r--core/java/com/android/internal/widget/ActionBarView.java60
-rw-r--r--core/java/com/android/internal/widget/LockPatternUtils.java14
-rw-r--r--core/java/com/android/internal/widget/TransportControlView.java515
-rw-r--r--core/java/com/android/internal/widget/multiwaveview/TargetDrawable.java30
-rw-r--r--core/jni/Android.mk9
-rw-r--r--core/jni/AndroidRuntime.cpp3
-rw-r--r--core/jni/android/graphics/BitmapFactory.cpp28
-rw-r--r--core/jni/android/graphics/Graphics.cpp19
-rw-r--r--core/jni/android/graphics/GraphicsJNI.h4
-rw-r--r--core/jni/android/graphics/HarfBuzzNGFaceSkia.cpp5
-rw-r--r--core/jni/android/graphics/Paint.cpp9
-rw-r--r--core/jni/android/graphics/TextLayoutCache.cpp57
-rw-r--r--core/jni/android/graphics/TextLayoutCache.h14
-rw-r--r--core/jni/android_hardware_Camera.cpp27
-rw-r--r--core/jni/android_net_wifi_Wifi.cpp4
-rw-r--r--core/jni/android_opengl_EGL14.cpp44
-rw-r--r--core/jni/android_opengl_GLES10.cpp9
-rw-r--r--core/jni/android_opengl_GLES10Ext.cpp11
-rw-r--r--core/jni/android_opengl_GLES11.cpp23
-rw-r--r--core/jni/android_opengl_GLES11Ext.cpp13
-rw-r--r--core/jni/android_opengl_GLES20.cpp37
-rw-r--r--core/jni/android_opengl_GLES30.cpp1
-rw-r--r--core/jni/android_os_Debug.cpp137
-rw-r--r--core/jni/android_os_MessageQueue.cpp8
-rw-r--r--core/jni/android_os_SystemClock.cpp53
-rw-r--r--core/jni/android_util_Binder.cpp5
-rw-r--r--core/jni/android_util_Process.cpp6
-rw-r--r--core/jni/android_view_GLES20Canvas.cpp119
-rw-r--r--core/jni/android_view_GraphicBuffer.cpp331
-rw-r--r--core/jni/android_view_GraphicBuffer.h27
-rw-r--r--core/jni/android_view_HardwareRenderer.cpp14
-rw-r--r--core/jni/android_view_Surface.cpp50
-rw-r--r--core/jni/android_view_TextureView.cpp24
-rw-r--r--core/jni/com_android_internal_content_NativeLibraryHelper.cpp2
-rw-r--r--core/jni/com_google_android_gles_jni_GLImpl.cpp32
-rw-r--r--core/res/AndroidManifest.xml25
-rw-r--r--core/res/res/anim/keyguard_action_assist_enter.xml32
-rw-r--r--core/res/res/anim/keyguard_security_animate_in.xml33
-rw-r--r--core/res/res/anim/keyguard_security_animate_out.xml32
-rw-r--r--core/res/res/anim/keyguard_security_fade_in.xml22
-rw-r--r--core/res/res/anim/keyguard_security_fade_out.xml21
-rw-r--r--core/res/res/anim/toast_bar_enter.xml (renamed from core/res/res/anim/keyguard_action_assist_exit.xml)16
-rw-r--r--core/res/res/anim/toast_bar_exit.xml (renamed from core/res/res/values-land/alias.xml)17
-rw-r--r--core/res/res/drawable-hdpi/ic_facial_backup.pngbin583 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_alarm.pngbin1398 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_camera_activated.pngbin7214 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_camera_normal.pngbin1630 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_emergencycall_normal.pngbin915 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_emergencycall_pressed.pngbin1754 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_forgotpassword_normal.pngbin757 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_forgotpassword_pressed.pngbin1403 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_google_activated.pngbin12152 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_google_focused.pngbin22219 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_google_normal.pngbin12262 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_handle_normal.pngbin7896 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_ime.pngbin202 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_lock_normal.pngbin3020 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_lock_pressed.pngbin8376 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_player_background.9.pngbin129 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_search_activated.pngbin2028 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_search_normal.pngbin2070 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_silent_activated.pngbin7780 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_silent_focused.pngbin12968 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_silent_normal.pngbin5716 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_sim.pngbin4083 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_soundon_activated.pngbin7454 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_soundon_focused.pngbin12774 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_soundon_normal.pngbin5172 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_unlock_activated.pngbin6729 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/ic_lockscreen_unlock_normal.pngbin1376 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/intro_bg.pngbin202336 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/kg_add_widget.pngbin970 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/kg_add_widget_disabled.pngbin1066 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/kg_add_widget_pressed.pngbin1004 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/kg_bouncer_bg_white.9.pngbin546 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/kg_security_grip.9.pngbin140 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/kg_security_lock.pngbin2700 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/kg_security_lock_focused.pngbin2007 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/kg_security_lock_normal.pngbin1385 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/kg_security_lock_pressed.pngbin1511 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/kg_widget_bg_padded.9.pngbin3272 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/kg_widget_delete_drop_target.pngbin1003 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/lockscreen_protection_pattern.pngbin347 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/sym_keyboard_return_holo.pngbin1104 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/toast_bar_bg.9.pngbin0 -> 599 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_facial_backup.pngbin520 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_alarm.pngbin839 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_camera_activated.pngbin4543 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_camera_normal.pngbin1186 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_emergencycall_normal.pngbin660 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_emergencycall_pressed.pngbin1223 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_forgotpassword_normal.pngbin591 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_forgotpassword_pressed.pngbin947 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_google_activated.pngbin7057 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_google_focused.pngbin11446 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_google_normal.pngbin6519 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_handle_normal.pngbin4412 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_ime.pngbin157 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_lock_normal.pngbin1883 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_lock_pressed.pngbin4800 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_player_background.9.pngbin118 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_search_activated.pngbin1937 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_search_normal.pngbin1937 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_silent_activated.pngbin4740 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_silent_focused.pngbin7048 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_silent_normal.pngbin3123 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_sim.pngbin2602 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_soundon_activated.pngbin4538 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_soundon_focused.pngbin7042 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_soundon_normal.pngbin2871 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_unlock_activated.pngbin4237 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/ic_lockscreen_unlock_normal.pngbin1041 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/intro_bg.pngbin90061 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/kg_add_widget.pngbin788 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/kg_add_widget_disabled.pngbin832 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/kg_add_widget_pressed.pngbin809 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/kg_bouncer_bg_white.9.pngbin397 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/kg_security_grip.9.pngbin136 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/kg_security_lock.pngbin1921 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/kg_security_lock_focused.pngbin1391 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/kg_security_lock_normal.pngbin1060 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/kg_security_lock_pressed.pngbin1149 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/kg_widget_bg_padded.9.pngbin3149 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/kg_widget_delete_drop_target.pngbin802 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/lockscreen_protection_pattern.pngbin351 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/sym_keyboard_return_holo.pngbin823 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/toast_bar_bg.9.pngbin0 -> 374 bytes
-rw-r--r--core/res/res/drawable-sw600dp-hdpi/ic_lockscreen_handle_normal.pngbin13316 -> 0 bytes
-rw-r--r--core/res/res/drawable-sw600dp-mdpi/ic_lockscreen_handle_normal.pngbin6774 -> 0 bytes
-rw-r--r--core/res/res/drawable-sw600dp-xhdpi/ic_lockscreen_handle_normal.pngbin21777 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_facial_backup.pngbin841 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_alarm.pngbin2130 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_camera_activated.pngbin10375 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_camera_normal.pngbin2341 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_emergencycall_normal.pngbin1165 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_emergencycall_pressed.pngbin2287 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_forgotpassword_normal.pngbin957 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_forgotpassword_pressed.pngbin1907 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_google_activated.pngbin17254 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_google_focused.pngbin31637 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_google_normal.pngbin18528 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_handle_normal.pngbin11519 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_ime.pngbin217 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_lock_normal.pngbin4173 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_lock_pressed.pngbin12221 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_player_background.9.pngbin144 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_silent_activated.pngbin11182 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_silent_focused.pngbin19515 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_silent_normal.pngbin8633 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_sim.pngbin5201 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_soundon_activated.pngbin10638 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_soundon_focused.pngbin19513 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_soundon_normal.pngbin7698 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_unlock_activated.pngbin9615 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/ic_lockscreen_unlock_normal.pngbin1760 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/intro_bg.pngbin343210 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/kg_add_widget.pngbin1228 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/kg_add_widget_disabled.pngbin1351 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/kg_add_widget_pressed.pngbin1251 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/kg_bouncer_bg_white.9.pngbin775 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/kg_security_grip.9.pngbin149 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/kg_security_lock.pngbin3499 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/kg_security_lock_focused.pngbin2744 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/kg_security_lock_normal.pngbin1843 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/kg_security_lock_pressed.pngbin2021 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/kg_widget_bg_padded.9.pngbin3474 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/kg_widget_delete_drop_target.pngbin1392 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/lockscreen_protection_pattern.pngbin365 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/sym_keyboard_return_holo.pngbin1501 -> 0 bytes
-rw-r--r--core/res/res/drawable-xhdpi/toast_bar_bg.9.pngbin0 -> 814 bytes
-rw-r--r--core/res/res/drawable/ic_lockscreen_camera.xml36
-rw-r--r--core/res/res/drawable/ic_lockscreen_handle.xml30
-rw-r--r--core/res/res/drawable/ic_lockscreen_silent.xml36
-rw-r--r--core/res/res/drawable/ic_lockscreen_soundon.xml36
-rw-r--r--core/res/res/drawable/ic_lockscreen_unlock.xml36
-rw-r--r--core/res/res/drawable/ic_lockscreen_unlock_phantom.xml36
-rw-r--r--core/res/res/drawable/keyguard_add_widget_button.xml21
-rw-r--r--core/res/res/drawable/keyguard_expand_challenge_handle.xml21
-rw-r--r--core/res/res/drawable/lockscreen_emergency_button.xml21
-rw-r--r--core/res/res/drawable/lockscreen_forgot_password_button.xml21
-rw-r--r--core/res/res/drawable/lockscreen_password_field_dark.xml26
-rw-r--r--core/res/res/layout-land/keyguard_glow_pad_container.xml25
-rw-r--r--core/res/res/layout-land/keyguard_host_view.xml80
-rw-r--r--core/res/res/layout-land/keyguard_status_area.xml56
-rw-r--r--core/res/res/layout-land/keyguard_widget_pager.xml30
-rw-r--r--core/res/res/layout-port/keyguard_host_view.xml94
-rw-r--r--core/res/res/layout-port/keyguard_status_area.xml59
-rw-r--r--core/res/res/layout-port/keyguard_widget_pager.xml31
-rw-r--r--core/res/res/layout-sw600dp-port/keyguard_host_view.xml82
-rw-r--r--core/res/res/layout-sw600dp-port/keyguard_status_area.xml56
-rw-r--r--core/res/res/layout-sw600dp/keyguard_glow_pad_container.xml24
-rw-r--r--core/res/res/layout-sw600dp/keyguard_navigation.xml21
-rw-r--r--core/res/res/layout-sw600dp/keyguard_sim_puk_pin_navigation.xml21
-rw-r--r--core/res/res/layout-sw600dp/keyguard_transport_control.xml111
-rw-r--r--core/res/res/layout/keyguard_account_view.xml87
-rw-r--r--core/res/res/layout/keyguard_add_widget.xml42
-rw-r--r--core/res/res/layout/keyguard_emergency_carrier_area.xml76
-rw-r--r--core/res/res/layout/keyguard_emergency_carrier_area_empty.xml31
-rw-r--r--core/res/res/layout/keyguard_face_unlock_view.xml78
-rw-r--r--core/res/res/layout/keyguard_glow_pad_container.xml26
-rw-r--r--core/res/res/layout/keyguard_glow_pad_view.xml46
-rw-r--r--core/res/res/layout/keyguard_message_area.xml33
-rw-r--r--core/res/res/layout/keyguard_message_area_large.xml31
-rw-r--r--core/res/res/layout/keyguard_multi_user_avatar.xml45
-rw-r--r--core/res/res/layout/keyguard_multi_user_selector.xml39
-rw-r--r--core/res/res/layout/keyguard_multi_user_selector_widget.xml26
-rw-r--r--core/res/res/layout/keyguard_password_view.xml104
-rw-r--r--core/res/res/layout/keyguard_pattern_view.xml78
-rw-r--r--core/res/res/layout/keyguard_pin_view.xml224
-rw-r--r--core/res/res/layout/keyguard_selector_view.xml64
-rw-r--r--core/res/res/layout/keyguard_sim_pin_view.xml230
-rw-r--r--core/res/res/layout/keyguard_sim_puk_pin_account_navigation.xml21
-rw-r--r--core/res/res/layout/keyguard_sim_puk_view.xml230
-rw-r--r--core/res/res/layout/keyguard_status_view.xml67
-rw-r--r--core/res/res/layout/keyguard_transport_control_view.xml112
-rw-r--r--core/res/res/layout/keyguard_widget_remove_drop_target.xml33
-rw-r--r--core/res/res/layout/toast_bar.xml70
-rw-r--r--core/res/res/values-af/strings.xml6
-rw-r--r--core/res/res/values-am/strings.xml6
-rw-r--r--core/res/res/values-ar/strings.xml6
-rw-r--r--core/res/res/values-be/strings.xml6
-rw-r--r--core/res/res/values-bg/strings.xml6
-rw-r--r--core/res/res/values-ca/strings.xml6
-rw-r--r--core/res/res/values-cs/strings.xml6
-rw-r--r--core/res/res/values-da/strings.xml6
-rw-r--r--core/res/res/values-de/strings.xml6
-rw-r--r--core/res/res/values-el/strings.xml6
-rw-r--r--core/res/res/values-en-rGB/strings.xml6
-rw-r--r--core/res/res/values-es-rUS/strings.xml6
-rw-r--r--core/res/res/values-es/strings.xml6
-rw-r--r--core/res/res/values-et/strings.xml6
-rw-r--r--core/res/res/values-fa/strings.xml6
-rw-r--r--core/res/res/values-fi/strings.xml6
-rw-r--r--core/res/res/values-fr/strings.xml6
-rw-r--r--core/res/res/values-hi/strings.xml6
-rw-r--r--core/res/res/values-hr/strings.xml6
-rw-r--r--core/res/res/values-hu/strings.xml6
-rw-r--r--core/res/res/values-in/strings.xml6
-rw-r--r--core/res/res/values-it/strings.xml6
-rw-r--r--core/res/res/values-iw/strings.xml6
-rw-r--r--core/res/res/values-ja/strings.xml6
-rw-r--r--core/res/res/values-ko/strings.xml6
-rw-r--r--core/res/res/values-land/arrays.xml50
-rw-r--r--core/res/res/values-lt/strings.xml6
-rw-r--r--core/res/res/values-lv/strings.xml6
-rw-r--r--core/res/res/values-ms/strings.xml6
-rw-r--r--core/res/res/values-nb/strings.xml6
-rw-r--r--core/res/res/values-nl/strings.xml6
-rw-r--r--core/res/res/values-pl/strings.xml6
-rw-r--r--core/res/res/values-port/alias.xml23
-rw-r--r--core/res/res/values-pt-rPT/strings.xml6
-rw-r--r--core/res/res/values-pt/strings.xml6
-rw-r--r--core/res/res/values-rm/strings.xml12
-rw-r--r--core/res/res/values-ro/strings.xml6
-rw-r--r--core/res/res/values-ru/strings.xml6
-rw-r--r--core/res/res/values-sk/strings.xml6
-rw-r--r--core/res/res/values-sl/strings.xml6
-rw-r--r--core/res/res/values-sr/strings.xml6
-rw-r--r--core/res/res/values-sv/strings.xml6
-rw-r--r--core/res/res/values-sw/strings.xml6
-rw-r--r--core/res/res/values-sw600dp-land/arrays.xml50
-rw-r--r--core/res/res/values-sw600dp/alias.xml23
-rw-r--r--core/res/res/values-th/strings.xml6
-rw-r--r--core/res/res/values-tl/strings.xml6
-rw-r--r--core/res/res/values-tr/strings.xml6
-rw-r--r--core/res/res/values-uk/strings.xml6
-rw-r--r--core/res/res/values-vi/strings.xml6
-rw-r--r--core/res/res/values-zh-rCN/strings.xml6
-rw-r--r--core/res/res/values-zh-rTW/strings.xml6
-rw-r--r--core/res/res/values-zu/strings.xml6
-rw-r--r--core/res/res/values/arrays.xml71
-rw-r--r--core/res/res/values/attrs.xml26
-rw-r--r--core/res/res/values/attrs_manifest.xml8
-rw-r--r--core/res/res/values/public.xml11
-rw-r--r--core/res/res/values/strings.xml17
-rw-r--r--core/res/res/values/styles.xml6
-rw-r--r--core/res/res/values/symbols.xml205
410 files changed, 10826 insertions, 5344 deletions
diff --git a/core/java/android/accounts/ChooseTypeAndAccountActivity.java b/core/java/android/accounts/ChooseTypeAndAccountActivity.java
index 58eb66f..82c2159 100644
--- a/core/java/android/accounts/ChooseTypeAndAccountActivity.java
+++ b/core/java/android/accounts/ChooseTypeAndAccountActivity.java
@@ -29,6 +29,7 @@ import android.os.UserManager;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
+import android.view.Window;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
@@ -127,6 +128,7 @@ public class ChooseTypeAndAccountActivity extends Activity
private int mCallingUid;
private String mCallingPackage;
private boolean mDisallowAddAccounts;
+ private boolean mDontShowPicker;
@Override
public void onCreate(Bundle savedInstanceState) {
@@ -189,11 +191,23 @@ public class ChooseTypeAndAccountActivity extends Activity
mSetOfRelevantAccountTypes = getReleventAccountTypes(intent);
mAlwaysPromptForAccount = intent.getBooleanExtra(EXTRA_ALWAYS_PROMPT_FOR_ACCOUNT, false);
mDescriptionOverride = intent.getStringExtra(EXTRA_DESCRIPTION_TEXT_OVERRIDE);
+
+ // Need to do this once here to request the window feature. Can't do it in onResume
+ mAccounts = getAcceptableAccountChoices(AccountManager.get(this));
+ if (mAccounts.isEmpty()
+ && mDisallowAddAccounts) {
+ requestWindowFeature(Window.FEATURE_NO_TITLE);
+ setContentView(R.layout.app_not_authorized);
+ mDontShowPicker = true;
+ }
}
@Override
protected void onResume() {
super.onResume();
+
+ if (mDontShowPicker) return;
+
final AccountManager accountManager = AccountManager.get(this);
mAccounts = getAcceptableAccountChoices(accountManager);
@@ -206,11 +220,6 @@ public class ChooseTypeAndAccountActivity extends Activity
// If there are no relevant accounts and only one relevant account type go directly to
// add account. Otherwise let the user choose.
if (mAccounts.isEmpty()) {
- if (mDisallowAddAccounts) {
- setContentView(R.layout.app_not_authorized);
- setTitle(R.string.error_message_title);
- return;
- }
if (mSetOfRelevantAccountTypes.size() == 1) {
runAddAccountForAuthenticator(mSetOfRelevantAccountTypes.iterator().next());
} else {
diff --git a/core/java/android/animation/ObjectAnimator.java b/core/java/android/animation/ObjectAnimator.java
index 173ee73..9c88ccf 100644
--- a/core/java/android/animation/ObjectAnimator.java
+++ b/core/java/android/animation/ObjectAnimator.java
@@ -123,9 +123,37 @@ public final class ObjectAnimator extends ValueAnimator {
* in a call to the function <code>setFoo()</code> on the target object. If either
* <code>valueFrom</code> or <code>valueTo</code> is null, then a getter function will
* also be derived and called.
+ *
+ * <p>If this animator was created with a {@link Property} object instead of the
+ * string name of a property, then this method will return the {@link
+ * Property#getName() name} of that Property object instead. If this animator was
+ * created with one or more {@link PropertyValuesHolder} objects, then this method
+ * will return the {@link PropertyValuesHolder#getPropertyName() name} of that
+ * object (if there was just one) or a comma-separated list of all of the
+ * names (if there are more than one).</p>
*/
public String getPropertyName() {
- return mPropertyName;
+ String propertyName = null;
+ if (mPropertyName != null) {
+ propertyName = mPropertyName;
+ } else if (mProperty != null) {
+ propertyName = mProperty.getName();
+ } else if (mValues != null && mValues.length > 0) {
+ for (int i = 0; i < mValues.length; ++i) {
+ if (i == 0) {
+ propertyName = "";
+ } else {
+ propertyName += ",";
+ }
+ propertyName += mValues[i].getPropertyName();
+ }
+ }
+ return propertyName;
+ }
+
+ @Override
+ String getNameForTrace() {
+ return "animator:" + getPropertyName();
}
/**
diff --git a/core/java/android/animation/ValueAnimator.java b/core/java/android/animation/ValueAnimator.java
index cb44264..f8ae616 100644
--- a/core/java/android/animation/ValueAnimator.java
+++ b/core/java/android/animation/ValueAnimator.java
@@ -869,7 +869,7 @@ public class ValueAnimator extends Animator {
*
* <p>If this ValueAnimator has only one set of values being animated between, this evaluator
* will be used for that set. If there are several sets of values being animated, which is
- * the case if PropertyValuesHOlder objects were set on the ValueAnimator, then the evaluator
+ * the case if PropertyValuesHolder objects were set on the ValueAnimator, then the evaluator
* is assigned just to the first PropertyValuesHolder object.</p>
*
* @param value the evaluator to be used this animation
@@ -1024,7 +1024,7 @@ public class ValueAnimator extends Animator {
mStarted = false;
mStartListenersCalled = false;
mPlayingBackwards = false;
- Trace.asyncTraceEnd(Trace.TRACE_TAG_VIEW, "animator",
+ Trace.asyncTraceEnd(Trace.TRACE_TAG_VIEW, getNameForTrace(),
System.identityHashCode(this));
}
@@ -1033,7 +1033,7 @@ public class ValueAnimator extends Animator {
* called on the UI thread.
*/
private void startAnimation(AnimationHandler handler) {
- Trace.asyncTraceBegin(Trace.TRACE_TAG_VIEW, "animator",
+ Trace.asyncTraceBegin(Trace.TRACE_TAG_VIEW, getNameForTrace(),
System.identityHashCode(this));
initAnimation();
handler.mAnimations.add(this);
@@ -1045,6 +1045,14 @@ public class ValueAnimator extends Animator {
}
/**
+ * Returns the name of this animator for debugging purposes.
+ */
+ String getNameForTrace() {
+ return "animator";
+ }
+
+
+ /**
* Internal function called to process an animation frame on an animation that is currently
* sleeping through its <code>startDelay</code> phase. The return value indicates whether it
* should be woken up and put on the active animations queue.
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 6b5df7f..7f2f744 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -1877,9 +1877,12 @@ public class Activity extends ContextThemeWrapper
if (isChild() || !window.hasFeature(Window.FEATURE_ACTION_BAR) || mActionBar != null) {
return;
}
-
+
mActionBar = new ActionBarImpl(this);
mActionBar.setDefaultDisplayHomeAsUpEnabled(mEnableDefaultActionBarUp);
+
+ mWindow.setDefaultIcon(mActivityInfo.getIconResource());
+ mWindow.setDefaultLogo(mActivityInfo.getLogoResource());
}
/**
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index bb9e19f..63ac42e 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -31,9 +31,8 @@ import android.content.pm.UserInfo;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Point;
-import android.hardware.display.DisplayManager;
+import android.graphics.Rect;
import android.hardware.display.DisplayManagerGlobal;
-import android.os.Binder;
import android.os.Bundle;
import android.os.Debug;
import android.os.Handler;
@@ -453,14 +452,21 @@ public class ActivityManager {
* Description of the task's last state.
*/
public CharSequence description;
-
+
+ /**
+ * The id of the ActivityStack this Task was on most recently.
+ */
+ public int stackId;
+
public RecentTaskInfo() {
}
+ @Override
public int describeContents() {
return 0;
}
+ @Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(id);
dest.writeInt(persistentId);
@@ -473,6 +479,7 @@ public class ActivityManager {
ComponentName.writeToParcel(origActivity, dest);
TextUtils.writeToParcel(description, dest,
Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
+ dest.writeInt(stackId);
}
public void readFromParcel(Parcel source) {
@@ -485,8 +492,9 @@ public class ActivityManager {
}
origActivity = ComponentName.readFromParcel(source);
description = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
+ stackId = source.readInt();
}
-
+
public static final Creator<RecentTaskInfo> CREATOR
= new Creator<RecentTaskInfo>() {
public RecentTaskInfo createFromParcel(Parcel source) {
@@ -1229,7 +1237,169 @@ public class ActivityManager {
} catch (RemoteException e) {
}
}
-
+
+ /**
+ * Information you can retrieve about the WindowManager StackBox hierarchy.
+ * @hide
+ */
+ public static class StackBoxInfo implements Parcelable {
+ public int stackBoxId;
+ public float weight;
+ public boolean vertical;
+ public Rect bounds;
+ public StackBoxInfo[] children;
+ public int stackId;
+ public StackInfo stack;
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(stackBoxId);
+ dest.writeFloat(weight);
+ dest.writeInt(vertical ? 1 : 0);
+ bounds.writeToParcel(dest, flags);
+ dest.writeInt(stackId);
+ if (children != null) {
+ children[0].writeToParcel(dest, flags);
+ children[1].writeToParcel(dest, flags);
+ } else {
+ stack.writeToParcel(dest, flags);
+ }
+ }
+
+ public void readFromParcel(Parcel source) {
+ stackBoxId = source.readInt();
+ weight = source.readFloat();
+ vertical = source.readInt() == 1;
+ bounds = Rect.CREATOR.createFromParcel(source);
+ stackId = source.readInt();
+ if (stackId == -1) {
+ children = new StackBoxInfo[2];
+ children[0] = StackBoxInfo.CREATOR.createFromParcel(source);
+ children[1] = StackBoxInfo.CREATOR.createFromParcel(source);
+ } else {
+ stack = StackInfo.CREATOR.createFromParcel(source);
+ }
+ }
+
+ public static final Creator<StackBoxInfo> CREATOR =
+ new Creator<ActivityManager.StackBoxInfo>() {
+
+ @Override
+ public StackBoxInfo createFromParcel(Parcel source) {
+ return new StackBoxInfo(source);
+ }
+
+ @Override
+ public StackBoxInfo[] newArray(int size) {
+ return new StackBoxInfo[size];
+ }
+ };
+
+ public StackBoxInfo() {
+ }
+
+ public StackBoxInfo(Parcel source) {
+ readFromParcel(source);
+ }
+
+ public String toString(String prefix) {
+ StringBuilder sb = new StringBuilder(256);
+ sb.append(prefix); sb.append("Box id=" + stackBoxId); sb.append(" weight=" + weight);
+ sb.append(" vertical=" + vertical); sb.append(" bounds=" + bounds.toShortString());
+ sb.append("\n");
+ if (children != null) {
+ sb.append(prefix); sb.append("First child=\n");
+ sb.append(children[0].toString(prefix + " "));
+ sb.append(prefix); sb.append("Second child=\n");
+ sb.append(children[1].toString(prefix + " "));
+ } else {
+ sb.append(prefix); sb.append("Stack=\n");
+ sb.append(stack.toString(prefix + " "));
+ }
+ return sb.toString();
+ }
+
+ @Override
+ public String toString() {
+ return toString("");
+ }
+ }
+
+ /**
+ * Information you can retrieve about an ActivityStack in the system.
+ * @hide
+ */
+ public static class StackInfo implements Parcelable {
+ public int stackId;
+ public Rect bounds;
+ public int[] taskIds;
+ public String[] taskNames;
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(stackId);
+ dest.writeInt(bounds.left);
+ dest.writeInt(bounds.top);
+ dest.writeInt(bounds.right);
+ dest.writeInt(bounds.bottom);
+ dest.writeIntArray(taskIds);
+ dest.writeStringArray(taskNames);
+ }
+
+ public void readFromParcel(Parcel source) {
+ stackId = source.readInt();
+ bounds = new Rect(
+ source.readInt(), source.readInt(), source.readInt(), source.readInt());
+ taskIds = source.createIntArray();
+ taskNames = source.createStringArray();
+ }
+
+ public static final Creator<StackInfo> CREATOR = new Creator<StackInfo>() {
+ @Override
+ public StackInfo createFromParcel(Parcel source) {
+ return new StackInfo(source);
+ }
+ @Override
+ public StackInfo[] newArray(int size) {
+ return new StackInfo[size];
+ }
+ };
+
+ public StackInfo() {
+ }
+
+ private StackInfo(Parcel source) {
+ readFromParcel(source);
+ }
+
+ public String toString(String prefix) {
+ StringBuilder sb = new StringBuilder(256);
+ sb.append(prefix); sb.append("Stack id="); sb.append(stackId);
+ sb.append(" bounds="); sb.append(bounds.toShortString()); sb.append("\n");
+ prefix = prefix + " ";
+ for (int i = 0; i < taskIds.length; ++i) {
+ sb.append(prefix); sb.append("taskId="); sb.append(taskIds[i]);
+ sb.append(": "); sb.append(taskNames[i]); sb.append("\n");
+ }
+ return sb.toString();
+ }
+
+ @Override
+ public String toString() {
+ return toString("");
+ }
+ }
+
/**
* @hide
*/
@@ -1303,10 +1473,12 @@ public class ActivityManager {
public ProcessErrorStateInfo() {
}
+ @Override
public int describeContents() {
return 0;
}
+ @Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(condition);
dest.writeString(processName);
@@ -1317,7 +1489,7 @@ public class ActivityManager {
dest.writeString(longMsg);
dest.writeString(stackTrace);
}
-
+
public void readFromParcel(Parcel source) {
condition = source.readInt();
processName = source.readString();
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index d4478bf..27e20b9 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -16,6 +16,7 @@
package android.app;
+import android.app.ActivityManager.StackBoxInfo;
import android.content.ComponentName;
import android.content.IIntentReceiver;
import android.content.IIntentSender;
@@ -107,7 +108,8 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
public ActivityManagerNative() {
attachInterface(this, descriptor);
}
-
+
+ @Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
throws RemoteException {
switch (code) {
@@ -197,7 +199,7 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
Intent intent = Intent.CREATOR.createFromParcel(data);
String resolvedType = data.readString();
IBinder resultTo = data.readStrongBinder();
- String resultWho = data.readString();
+ String resultWho = data.readString();
int requestCode = data.readInt();
int startFlags = data.readInt();
Configuration config = Configuration.CREATOR.createFromParcel(data);
@@ -223,7 +225,7 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
}
String resolvedType = data.readString();
IBinder resultTo = data.readStrongBinder();
- String resultWho = data.readString();
+ String resultWho = data.readString();
int requestCode = data.readInt();
int flagsMask = data.readInt();
int flagsValues = data.readInt();
@@ -236,7 +238,7 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
reply.writeInt(result);
return true;
}
-
+
case START_NEXT_MATCHING_ACTIVITY_TRANSACTION:
{
data.enforceInterface(IActivityManager.descriptor);
@@ -267,7 +269,7 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
case FINISH_SUB_ACTIVITY_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
IBinder token = data.readStrongBinder();
- String resultWho = data.readString();
+ String resultWho = data.readString();
int requestCode = data.readInt();
finishSubActivity(token, resultWho, requestCode);
reply.writeNoException();
@@ -478,14 +480,13 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
IThumbnailReceiver receiver = receiverBinder != null
? IThumbnailReceiver.Stub.asInterface(receiverBinder)
: null;
- List list = getTasks(maxNum, fl, receiver);
+ List<ActivityManager.RunningTaskInfo> list = getTasks(maxNum, fl, receiver);
reply.writeNoException();
int N = list != null ? list.size() : -1;
reply.writeInt(N);
int i;
for (i=0; i<N; i++) {
- ActivityManager.RunningTaskInfo info =
- (ActivityManager.RunningTaskInfo)list.get(i);
+ ActivityManager.RunningTaskInfo info = list.get(i);
info.writeToParcel(reply, 0);
}
return true;
@@ -535,14 +536,13 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
data.enforceInterface(IActivityManager.descriptor);
int maxNum = data.readInt();
int fl = data.readInt();
- List list = getServices(maxNum, fl);
+ List<ActivityManager.RunningServiceInfo> list = getServices(maxNum, fl);
reply.writeNoException();
int N = list != null ? list.size() : -1;
reply.writeInt(N);
int i;
for (i=0; i<N; i++) {
- ActivityManager.RunningServiceInfo info =
- (ActivityManager.RunningServiceInfo)list.get(i);
+ ActivityManager.RunningServiceInfo info = list.get(i);
info.writeToParcel(reply, 0);
}
return true;
@@ -555,7 +555,7 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
reply.writeTypedList(list);
return true;
}
-
+
case GET_RUNNING_APP_PROCESSES_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
List<ActivityManager.RunningAppProcessInfo> list = getRunningAppProcesses();
@@ -609,6 +609,53 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
return true;
}
+ case CREATE_STACK_TRANSACTION: {
+ data.enforceInterface(IActivityManager.descriptor);
+ int taskId = data.readInt();
+ int relativeStackId = data.readInt();
+ int position = data.readInt();
+ float weight = data.readFloat();
+ int res = createStack(taskId, relativeStackId, position, weight);
+ reply.writeNoException();
+ reply.writeInt(res);
+ return true;
+ }
+
+ case MOVE_TASK_TO_STACK_TRANSACTION: {
+ data.enforceInterface(IActivityManager.descriptor);
+ int taskId = data.readInt();
+ int stackId = data.readInt();
+ boolean toTop = data.readInt() != 0;
+ moveTaskToStack(taskId, stackId, toTop);
+ reply.writeNoException();
+ return true;
+ }
+
+ case RESIZE_STACK_TRANSACTION: {
+ data.enforceInterface(IActivityManager.descriptor);
+ int stackBoxId = data.readInt();
+ float weight = data.readFloat();
+ resizeStackBox(stackBoxId, weight);
+ reply.writeNoException();
+ return true;
+ }
+
+ case GET_STACK_BOXES_TRANSACTION: {
+ data.enforceInterface(IActivityManager.descriptor);
+ List<StackBoxInfo> list = getStackBoxes();
+ reply.writeNoException();
+ reply.writeTypedList(list);
+ return true;
+ }
+
+ case SET_FOCUSED_STACK_TRANSACTION: {
+ data.enforceInterface(IActivityManager.descriptor);
+ int stackId = data.readInt();
+ setFocusedStack(stackId);
+ reply.writeNoException();
+ return true;
+ }
+
case GET_TASK_FOR_ACTIVITY_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
IBinder token = data.readStrongBinder();
@@ -1033,9 +1080,9 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
reply.writeInt(res);
return true;
}
-
+
case CLEAR_APP_DATA_TRANSACTION: {
- data.enforceInterface(IActivityManager.descriptor);
+ data.enforceInterface(IActivityManager.descriptor);
String packageName = data.readString();
IPackageDataObserver observer = IPackageDataObserver.Stub.asInterface(
data.readStrongBinder());
@@ -1045,7 +1092,7 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
reply.writeInt(res ? 1 : 0);
return true;
}
-
+
case GRANT_URI_PERMISSION_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
IBinder b = data.readStrongBinder();
@@ -1057,7 +1104,7 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
reply.writeNoException();
return true;
}
-
+
case REVOKE_URI_PERMISSION_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
IBinder b = data.readStrongBinder();
@@ -1068,7 +1115,7 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
reply.writeNoException();
return true;
}
-
+
case SHOW_WAITING_FOR_DEBUGGER_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
IBinder b = data.readStrongBinder();
@@ -1257,7 +1304,7 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
reply.writeNoException();
return true;
}
-
+
case FORCE_STOP_PACKAGE_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
String packageName = data.readString();
@@ -1363,7 +1410,8 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
data.enforceInterface(IActivityManager.descriptor);
String pkg = data.readString();
int appid = data.readInt();
- killApplicationWithAppId(pkg, appid);
+ String reason = data.readString();
+ killApplicationWithAppId(pkg, appid, reason);
reply.writeNoException();
return true;
}
@@ -2565,6 +2613,76 @@ class ActivityManagerProxy implements IActivityManager
data.recycle();
reply.recycle();
}
+ @Override
+ public int createStack(int taskId, int relativeStackBoxId, int position, float weight)
+ throws RemoteException
+ {
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ data.writeInterfaceToken(IActivityManager.descriptor);
+ data.writeInt(taskId);
+ data.writeInt(relativeStackBoxId);
+ data.writeInt(position);
+ data.writeFloat(weight);
+ mRemote.transact(CREATE_STACK_TRANSACTION, data, reply, 0);
+ reply.readException();
+ int res = reply.readInt();
+ data.recycle();
+ reply.recycle();
+ return res;
+ }
+ @Override
+ public void moveTaskToStack(int taskId, int stackId, boolean toTop) throws RemoteException
+ {
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ data.writeInterfaceToken(IActivityManager.descriptor);
+ data.writeInt(taskId);
+ data.writeInt(stackId);
+ data.writeInt(toTop ? 1 : 0);
+ mRemote.transact(MOVE_TASK_TO_STACK_TRANSACTION, data, reply, 0);
+ reply.readException();
+ data.recycle();
+ reply.recycle();
+ }
+ @Override
+ public void resizeStackBox(int stackBoxId, float weight) throws RemoteException
+ {
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ data.writeInterfaceToken(IActivityManager.descriptor);
+ data.writeInt(stackBoxId);
+ data.writeFloat(weight);
+ mRemote.transact(RESIZE_STACK_TRANSACTION, data, reply, IBinder.FLAG_ONEWAY);
+ reply.readException();
+ data.recycle();
+ reply.recycle();
+ }
+ @Override
+ public List<StackBoxInfo> getStackBoxes() throws RemoteException
+ {
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ data.writeInterfaceToken(IActivityManager.descriptor);
+ mRemote.transact(GET_STACK_BOXES_TRANSACTION, data, reply, 0);
+ reply.readException();
+ ArrayList<StackBoxInfo> list = reply.createTypedArrayList(StackBoxInfo.CREATOR);
+ data.recycle();
+ reply.recycle();
+ return list;
+ }
+ @Override
+ public void setFocusedStack(int stackId) throws RemoteException
+ {
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ data.writeInterfaceToken(IActivityManager.descriptor);
+ data.writeInt(stackId);
+ mRemote.transact(SET_FOCUSED_STACK_TRANSACTION, data, reply, IBinder.FLAG_ONEWAY);
+ reply.readException();
+ data.recycle();
+ reply.recycle();
+ }
public int getTaskForActivity(IBinder token, boolean onlyRoot) throws RemoteException
{
Parcel data = Parcel.obtain();
@@ -3575,12 +3693,14 @@ class ActivityManagerProxy implements IActivityManager
data.recycle();
}
- public void killApplicationWithAppId(String pkg, int appid) throws RemoteException {
+ public void killApplicationWithAppId(String pkg, int appid, String reason)
+ throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
data.writeString(pkg);
data.writeInt(appid);
+ data.writeString(reason);
mRemote.transact(KILL_APPLICATION_WITH_APPID_TRANSACTION, data, reply, 0);
reply.readException();
data.recycle();
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 4268fa6..4a41896 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -539,17 +539,17 @@ public final class ActivityThread {
IBinder requestToken;
int requestType;
}
-
+
private native void dumpGraphicsInfo(FileDescriptor fd);
private class ApplicationThread extends ApplicationThreadNative {
- private static final String HEAP_COLUMN = "%13s %8s %8s %8s %8s %8s %8s";
+ private static final String HEAP_COLUMN = "%13s %8s %8s %8s %8s %8s %8s %8s %8s %8s";
private static final String ONE_COUNT_COLUMN = "%21s %8d";
private static final String TWO_COUNT_COLUMNS = "%21s %8d %21s %8d";
private static final String DB_INFO_FORMAT = " %8s %8s %14s %14s %s";
// Formatting for checkin service - update version if row format changes
- private static final int ACTIVITY_THREAD_CHECKIN_VERSION = 1;
+ private static final int ACTIVITY_THREAD_CHECKIN_VERSION = 2;
private void updatePendingConfiguration(Configuration config) {
synchronized (mPackages) {
@@ -895,17 +895,18 @@ public final class ActivityThread {
@Override
public Debug.MemoryInfo dumpMemInfo(FileDescriptor fd, boolean checkin,
- boolean all, String[] args) {
+ boolean dumpInfo, boolean dumpDalvik, String[] args) {
FileOutputStream fout = new FileOutputStream(fd);
PrintWriter pw = new PrintWriter(fout);
try {
- return dumpMemInfo(pw, checkin, all);
+ return dumpMemInfo(pw, checkin, dumpInfo, dumpDalvik);
} finally {
pw.flush();
}
}
- private Debug.MemoryInfo dumpMemInfo(PrintWriter pw, boolean checkin, boolean all) {
+ private Debug.MemoryInfo dumpMemInfo(PrintWriter pw, boolean checkin, boolean dumpInfo,
+ boolean dumpDalvik) {
long nativeMax = Debug.getNativeHeapSize() / 1024;
long nativeAllocated = Debug.getNativeHeapAllocatedSize() / 1024;
long nativeFree = Debug.getNativeHeapFreeSize() / 1024;
@@ -913,7 +914,7 @@ public final class ActivityThread {
Debug.MemoryInfo memInfo = new Debug.MemoryInfo();
Debug.getMemoryInfo(memInfo);
- if (!all) {
+ if (!dumpInfo) {
return memInfo;
}
@@ -970,20 +971,42 @@ public final class ActivityThread {
pw.print(memInfo.otherPss); pw.print(',');
pw.print(memInfo.nativePss + memInfo.dalvikPss + memInfo.otherPss); pw.print(',');
- // Heap info - shared
+ // Heap info - proportional set size
+ pw.print(memInfo.nativeSwappablePss); pw.print(',');
+ pw.print(memInfo.dalvikSwappablePss); pw.print(',');
+ pw.print(memInfo.otherSwappablePss); pw.print(',');
+ pw.print(memInfo.nativeSwappablePss + memInfo.dalvikSwappablePss + memInfo.otherSwappablePss); pw.print(',');
+
+ // Heap info - shared dirty
pw.print(memInfo.nativeSharedDirty); pw.print(',');
pw.print(memInfo.dalvikSharedDirty); pw.print(',');
pw.print(memInfo.otherSharedDirty); pw.print(',');
pw.print(memInfo.nativeSharedDirty + memInfo.dalvikSharedDirty
+ memInfo.otherSharedDirty); pw.print(',');
- // Heap info - private
+ // Heap info - shared clean
+ pw.print(memInfo.nativeSharedClean); pw.print(',');
+ pw.print(memInfo.dalvikSharedClean); pw.print(',');
+ pw.print(memInfo.otherSharedClean); pw.print(',');
+ pw.print(memInfo.nativeSharedClean + memInfo.dalvikSharedClean
+ + memInfo.otherSharedClean); pw.print(',');
+
+ // Heap info - private Dirty
pw.print(memInfo.nativePrivateDirty); pw.print(',');
pw.print(memInfo.dalvikPrivateDirty); pw.print(',');
pw.print(memInfo.otherPrivateDirty); pw.print(',');
pw.print(memInfo.nativePrivateDirty + memInfo.dalvikPrivateDirty
+ memInfo.otherPrivateDirty); pw.print(',');
+
+ // Heap info - private Clean
+ pw.print(memInfo.nativePrivateClean); pw.print(',');
+ pw.print(memInfo.dalvikPrivateClean); pw.print(',');
+ pw.print(memInfo.otherPrivateClean); pw.print(',');
+ pw.print(memInfo.nativePrivateClean + memInfo.dalvikPrivateClean
+ + memInfo.otherPrivateClean); pw.print(',');
+
+
// Object counts
pw.print(viewInstanceCount); pw.print(',');
pw.print(viewRootInstanceCount); pw.print(',');
@@ -1018,34 +1041,80 @@ public final class ActivityThread {
}
// otherwise, show human-readable format
- printRow(pw, HEAP_COLUMN, "", "", "Shared", "Private", "Heap", "Heap", "Heap");
- printRow(pw, HEAP_COLUMN, "", "Pss", "Dirty", "Dirty", "Size", "Alloc", "Free");
+ printRow(pw, HEAP_COLUMN, "", "Pss", "Pss","Shared", "Private", "Shared", "Private",
+ "Heap", "Heap", "Heap");
+ printRow(pw, HEAP_COLUMN, "", "Total", "Clean", "Dirty", "Dirty", "Clean", "Clean",
+ "Size", "Alloc", "Free");
printRow(pw, HEAP_COLUMN, "", "------", "------", "------", "------", "------",
- "------");
- printRow(pw, HEAP_COLUMN, "Native", memInfo.nativePss, memInfo.nativeSharedDirty,
- memInfo.nativePrivateDirty, nativeMax, nativeAllocated, nativeFree);
- printRow(pw, HEAP_COLUMN, "Dalvik", memInfo.dalvikPss, memInfo.dalvikSharedDirty,
- memInfo.dalvikPrivateDirty, dalvikMax, dalvikAllocated, dalvikFree);
+ "------", "------", "------", "------");
+ printRow(pw, HEAP_COLUMN, "Native Heap", memInfo.nativePss, memInfo.nativeSwappablePss,
+ memInfo.nativeSharedDirty,
+ memInfo.nativePrivateDirty, memInfo.nativeSharedClean,
+ memInfo.nativePrivateClean, nativeMax, nativeAllocated, nativeFree);
+ printRow(pw, HEAP_COLUMN, "Dalvik Heap", memInfo.dalvikPss, memInfo.dalvikSwappablePss,
+ memInfo.dalvikSharedDirty,
+ memInfo.dalvikPrivateDirty, memInfo.dalvikSharedClean,
+ memInfo.dalvikPrivateClean, dalvikMax, dalvikAllocated, dalvikFree);
int otherPss = memInfo.otherPss;
+ int otherSwappablePss = memInfo.otherSwappablePss;
int otherSharedDirty = memInfo.otherSharedDirty;
int otherPrivateDirty = memInfo.otherPrivateDirty;
+ int otherSharedClean = memInfo.otherSharedClean;
+ int otherPrivateClean = memInfo.otherPrivateClean;
for (int i=0; i<Debug.MemoryInfo.NUM_OTHER_STATS; i++) {
- printRow(pw, HEAP_COLUMN, Debug.MemoryInfo.getOtherLabel(i),
- memInfo.getOtherPss(i), memInfo.getOtherSharedDirty(i),
- memInfo.getOtherPrivateDirty(i), "", "", "");
- otherPss -= memInfo.getOtherPss(i);
- otherSharedDirty -= memInfo.getOtherSharedDirty(i);
- otherPrivateDirty -= memInfo.getOtherPrivateDirty(i);
+ final int myPss = memInfo.getOtherPss(i);
+ final int mySwappablePss = memInfo.getOtherSwappablePss(i);
+ final int mySharedDirty = memInfo.getOtherSharedDirty(i);
+ final int myPrivateDirty = memInfo.getOtherPrivateDirty(i);
+ final int mySharedClean = memInfo.getOtherSharedClean(i);
+ final int myPrivateClean = memInfo.getOtherPrivateClean(i);
+ if (myPss != 0 || mySharedDirty != 0 || myPrivateDirty != 0
+ || mySharedClean != 0 || myPrivateClean != 0) {
+ printRow(pw, HEAP_COLUMN, Debug.MemoryInfo.getOtherLabel(i),
+ myPss, mySwappablePss, mySharedDirty, myPrivateDirty,
+ mySharedClean, myPrivateClean, "", "", "");
+ otherPss -= myPss;
+ otherSwappablePss -= mySwappablePss;
+ otherSharedDirty -= mySharedDirty;
+ otherPrivateDirty -= myPrivateDirty;
+ otherSharedClean -= mySharedClean;
+ otherPrivateClean -= myPrivateClean;
+ }
}
- printRow(pw, HEAP_COLUMN, "Unknown", otherPss, otherSharedDirty,
- otherPrivateDirty, "", "", "");
+
+
+ printRow(pw, HEAP_COLUMN, "Unknown", otherPss, otherSwappablePss, otherSharedDirty,
+ otherPrivateDirty, otherSharedClean, otherPrivateClean,"", "", "");
printRow(pw, HEAP_COLUMN, "TOTAL", memInfo.getTotalPss(),
+ memInfo.getTotalSwappablePss(),
memInfo.getTotalSharedDirty(), memInfo.getTotalPrivateDirty(),
- nativeMax+dalvikMax, nativeAllocated+dalvikAllocated,
- nativeFree+dalvikFree);
+ memInfo.getTotalSharedClean(), memInfo.getTotalPrivateClean(),
+ nativeMax+dalvikMax,
+ nativeAllocated+dalvikAllocated, nativeFree+dalvikFree);
+
+ if (dumpDalvik) {
+ pw.println(" ");
+ pw.println(" Dalvik Details");
+
+ for (int i=Debug.MemoryInfo.NUM_OTHER_STATS;
+ i<Debug.MemoryInfo.NUM_OTHER_STATS + Debug.MemoryInfo.NUM_DVK_STATS; i++) {
+ final int myPss = memInfo.getOtherPss(i);
+ final int mySwappablePss = memInfo.getOtherSwappablePss(i);
+ final int mySharedDirty = memInfo.getOtherSharedDirty(i);
+ final int myPrivateDirty = memInfo.getOtherPrivateDirty(i);
+ final int mySharedClean = memInfo.getOtherSharedClean(i);
+ final int myPrivateClean = memInfo.getOtherPrivateClean(i);
+ if (myPss != 0 || mySharedDirty != 0 || myPrivateDirty != 0
+ || mySharedClean != 0 || myPrivateClean != 0) {
+ printRow(pw, HEAP_COLUMN, Debug.MemoryInfo.getOtherLabel(i),
+ myPss, mySwappablePss, mySharedDirty, myPrivateDirty,
+ mySharedClean, myPrivateClean, "", "", "");
+ }
+ }
+ }
pw.println(" ");
pw.println(" Objects");
@@ -1748,7 +1817,7 @@ public final class ActivityThread {
r.getAssets().close();
return existing;
}
-
+
// XXX need to remove entries when weak references go away
mActiveResources.put(key, new WeakReference<Resources>(r));
return r;
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index c9776f1..32bb71e 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -95,8 +95,18 @@ public class AppOpsManager {
public static final int OP_PLAY_AUDIO = 28;
public static final int OP_READ_CLIPBOARD = 29;
public static final int OP_WRITE_CLIPBOARD = 30;
+ public static final int OP_TAKE_MEDIA_BUTTONS = 31;
+ public static final int OP_TAKE_AUDIO_FOCUS = 32;
+ public static final int OP_AUDIO_MASTER_VOLUME = 33;
+ public static final int OP_AUDIO_VOICE_VOLUME = 34;
+ public static final int OP_AUDIO_RING_VOLUME = 35;
+ public static final int OP_AUDIO_MEDIA_VOLUME = 36;
+ public static final int OP_AUDIO_ALARM_VOLUME = 37;
+ public static final int OP_AUDIO_NOTIFICATION_VOLUME = 38;
+ public static final int OP_AUDIO_BLUETOOTH_VOLUME = 39;
+ public static final int OP_WAKE_LOCK = 40;
/** @hide */
- public static final int _NUM_OP = 31;
+ public static final int _NUM_OP = 41;
/**
* This maps each operation to the operation that serves as the
@@ -138,6 +148,16 @@ public class AppOpsManager {
OP_PLAY_AUDIO,
OP_READ_CLIPBOARD,
OP_WRITE_CLIPBOARD,
+ OP_TAKE_MEDIA_BUTTONS,
+ OP_TAKE_AUDIO_FOCUS,
+ OP_AUDIO_MASTER_VOLUME,
+ OP_AUDIO_VOICE_VOLUME,
+ OP_AUDIO_RING_VOLUME,
+ OP_AUDIO_MEDIA_VOLUME,
+ OP_AUDIO_ALARM_VOLUME,
+ OP_AUDIO_NOTIFICATION_VOLUME,
+ OP_AUDIO_BLUETOOTH_VOLUME,
+ OP_WAKE_LOCK,
};
/**
@@ -176,6 +196,16 @@ public class AppOpsManager {
"PLAY_AUDIO",
"READ_CLIPBOARD",
"WRITE_CLIPBOARD",
+ "TAKE_MEDIA_BUTTONS",
+ "TAKE_AUDIO_FOCUS",
+ "AUDIO_MASTER_VOLUME",
+ "AUDIO_VOICE_VOLUME",
+ "AUDIO_RING_VOLUME",
+ "AUDIO_MEDIA_VOLUME",
+ "AUDIO_ALARM_VOLUME",
+ "AUDIO_NOTIFICATION_VOLUME",
+ "AUDIO_BLUETOOTH_VOLUME",
+ "WAKE_LOCK",
};
/**
@@ -214,6 +244,16 @@ public class AppOpsManager {
null, // no permission for playing audio
null, // no permission for reading clipboard
null, // no permission for writing clipboard
+ null, // no permission for taking media buttons
+ null, // no permission for taking audio focus
+ null, // no permission for changing master volume
+ null, // no permission for changing voice volume
+ null, // no permission for changing ring volume
+ null, // no permission for changing media volume
+ null, // no permission for changing alarm volume
+ null, // no permission for changing notification volume
+ null, // no permission for changing bluetooth volume
+ android.Manifest.permission.WAKE_LOCK,
};
/**
diff --git a/core/java/android/app/ApplicationThreadNative.java b/core/java/android/app/ApplicationThreadNative.java
index b1c58f2..e903447 100644
--- a/core/java/android/app/ApplicationThreadNative.java
+++ b/core/java/android/app/ApplicationThreadNative.java
@@ -524,12 +524,13 @@ public abstract class ApplicationThreadNative extends Binder
data.enforceInterface(IApplicationThread.descriptor);
ParcelFileDescriptor fd = data.readFileDescriptor();
boolean checkin = data.readInt() != 0;
- boolean all = data.readInt() != 0;
+ boolean dumpInfo = data.readInt() != 0;
+ boolean dumpDalvik = data.readInt() != 0;
String[] args = data.readStringArray();
Debug.MemoryInfo mi = null;
if (fd != null) {
try {
- mi = dumpMemInfo(fd.getFileDescriptor(), checkin, all, args);
+ mi = dumpMemInfo(fd.getFileDescriptor(), checkin, dumpInfo, dumpDalvik, args);
} finally {
try {
fd.close();
@@ -1159,14 +1160,15 @@ class ApplicationThreadProxy implements IApplicationThread {
IBinder.FLAG_ONEWAY);
}
- public Debug.MemoryInfo dumpMemInfo(FileDescriptor fd, boolean checkin, boolean all,
- String[] args) throws RemoteException {
+ public Debug.MemoryInfo dumpMemInfo(FileDescriptor fd, boolean checkin, boolean dumpInfo,
+ boolean dumpDalvik, String[] args) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IApplicationThread.descriptor);
data.writeFileDescriptor(fd);
data.writeInt(checkin ? 1 : 0);
- data.writeInt(all ? 1 : 0);
+ data.writeInt(dumpInfo ? 1 : 0);
+ data.writeInt(dumpDalvik ? 1 : 0);
data.writeStringArray(args);
mRemote.transact(DUMP_MEM_INFO_TRANSACTION, data, reply, 0);
reply.readException();
diff --git a/core/java/android/app/Dialog.java b/core/java/android/app/Dialog.java
index b3d99c5..634fa30 100644
--- a/core/java/android/app/Dialog.java
+++ b/core/java/android/app/Dialog.java
@@ -16,6 +16,8 @@
package android.app;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
import com.android.internal.app.ActionBarImpl;
import com.android.internal.policy.PolicyManager;
@@ -264,6 +266,9 @@ public class Dialog implements DialogInterface, Window.Callback,
mDecor = mWindow.getDecorView();
if (mActionBar == null && mWindow.hasFeature(Window.FEATURE_ACTION_BAR)) {
+ final ApplicationInfo info = mContext.getApplicationInfo();
+ mWindow.setDefaultIcon(info.icon);
+ mWindow.setDefaultLogo(info.logo);
mActionBar = new ActionBarImpl(this);
}
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index a21caee..b48eed2 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -16,6 +16,9 @@
package android.app;
+import android.app.ActivityManager.RunningTaskInfo;
+import android.app.ActivityManager.RunningServiceInfo;
+import android.app.ActivityManager.StackBoxInfo;
import android.content.ComponentName;
import android.content.ContentProviderNative;
import android.content.IContentProvider;
@@ -99,19 +102,25 @@ public interface IActivityManager extends IInterface {
public void activityDestroyed(IBinder token) throws RemoteException;
public String getCallingPackage(IBinder token) throws RemoteException;
public ComponentName getCallingActivity(IBinder token) throws RemoteException;
- public List getTasks(int maxNum, int flags,
+ public List<RunningTaskInfo> getTasks(int maxNum, int flags,
IThumbnailReceiver receiver) throws RemoteException;
public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
int flags, int userId) throws RemoteException;
public ActivityManager.TaskThumbnails getTaskThumbnails(int taskId) throws RemoteException;
public Bitmap getTaskTopThumbnail(int taskId) throws RemoteException;
- public List getServices(int maxNum, int flags) throws RemoteException;
+ public List<RunningServiceInfo> getServices(int maxNum, int flags) throws RemoteException;
public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState()
throws RemoteException;
public void moveTaskToFront(int task, int flags, Bundle options) throws RemoteException;
public void moveTaskToBack(int task) throws RemoteException;
public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) throws RemoteException;
public void moveTaskBackwards(int task) throws RemoteException;
+ public int createStack(int taskId, int relativeStackBoxId, int position, float weight)
+ throws RemoteException;
+ public void moveTaskToStack(int taskId, int stackId, boolean toTop) throws RemoteException;
+ public void resizeStackBox(int stackBoxId, float weight) throws RemoteException;
+ public List<StackBoxInfo> getStackBoxes() throws RemoteException;
+ public void setFocusedStack(int stackId) throws RemoteException;
public int getTaskForActivity(IBinder token, boolean onlyRoot) throws RemoteException;
/* oneway */
public void reportThumbnail(IBinder token,
@@ -149,14 +158,14 @@ public interface IActivityManager extends IInterface {
public void serviceDoneExecuting(IBinder token, int type, int startId,
int res) throws RemoteException;
public IBinder peekService(Intent service, String resolvedType) throws RemoteException;
-
+
public boolean bindBackupAgent(ApplicationInfo appInfo, int backupRestoreMode)
throws RemoteException;
public void clearPendingBackup() throws RemoteException;
public void backupAgentCreated(String packageName, IBinder agent) throws RemoteException;
public void unbindBackupAgent(ApplicationInfo appInfo) throws RemoteException;
public void killApplicationProcess(String processName, int uid) throws RemoteException;
-
+
public boolean startInstrumentation(ComponentName className, String profileFile,
int flags, Bundle arguments, IInstrumentationWatcher watcher,
IUiAutomationConnection connection, int userId) throws RemoteException;
@@ -168,7 +177,7 @@ public interface IActivityManager extends IInterface {
public void setRequestedOrientation(IBinder token,
int requestedOrientation) throws RemoteException;
public int getRequestedOrientation(IBinder token) throws RemoteException;
-
+
public ComponentName getActivityClassForToken(IBinder token) throws RemoteException;
public String getPackageForToken(IBinder token) throws RemoteException;
@@ -181,16 +190,16 @@ public interface IActivityManager extends IInterface {
final IPackageDataObserver observer, int userId) throws RemoteException;
public String getPackageForIntentSender(IIntentSender sender) throws RemoteException;
public int getUidForIntentSender(IIntentSender sender) throws RemoteException;
-
+
public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
boolean requireFull, String name, String callerPackage) throws RemoteException;
public void setProcessLimit(int max) throws RemoteException;
public int getProcessLimit() throws RemoteException;
-
+
public void setProcessForeground(IBinder token, int pid,
boolean isForeground) throws RemoteException;
-
+
public int checkPermission(String permission, int pid, int uid)
throws RemoteException;
@@ -274,7 +283,8 @@ public interface IActivityManager extends IInterface {
public void stopAppSwitches() throws RemoteException;
public void resumeAppSwitches() throws RemoteException;
- public void killApplicationWithAppId(String pkg, int appid) throws RemoteException;
+ public void killApplicationWithAppId(String pkg, int appid, String reason)
+ throws RemoteException;
public void closeSystemDialogs(String reason) throws RemoteException;
@@ -395,10 +405,12 @@ public interface IActivityManager extends IInterface {
info = _info;
}
+ @Override
public int describeContents() {
return 0;
}
+ @Override
public void writeToParcel(Parcel dest, int flags) {
info.writeToParcel(dest, 0);
if (provider != null) {
@@ -412,10 +424,12 @@ public interface IActivityManager extends IInterface {
public static final Parcelable.Creator<ContentProviderHolder> CREATOR
= new Parcelable.Creator<ContentProviderHolder>() {
+ @Override
public ContentProviderHolder createFromParcel(Parcel source) {
return new ContentProviderHolder(source);
}
+ @Override
public ContentProviderHolder[] newArray(int size) {
return new ContentProviderHolder[size];
}
@@ -441,10 +455,12 @@ public interface IActivityManager extends IInterface {
public WaitResult() {
}
+ @Override
public int describeContents() {
return 0;
}
+ @Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(result);
dest.writeInt(timeout ? 1 : 0);
@@ -455,10 +471,12 @@ public interface IActivityManager extends IInterface {
public static final Parcelable.Creator<WaitResult> CREATOR
= new Parcelable.Creator<WaitResult>() {
+ @Override
public WaitResult createFromParcel(Parcel source) {
return new WaitResult(source);
}
+ @Override
public WaitResult[] newArray(int size) {
return new WaitResult[size];
}
@@ -641,4 +659,9 @@ public interface IActivityManager extends IInterface {
int KILL_UID_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+164;
int SET_USER_IS_MONKEY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+165;
int HANG_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+166;
+ int CREATE_STACK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+167;
+ int MOVE_TASK_TO_STACK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+168;
+ int RESIZE_STACK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+169;
+ int GET_STACK_BOXES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+170;
+ int SET_FOCUSED_STACK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+171;
}
diff --git a/core/java/android/app/IApplicationThread.java b/core/java/android/app/IApplicationThread.java
index 3189b31..a009bd3 100644
--- a/core/java/android/app/IApplicationThread.java
+++ b/core/java/android/app/IApplicationThread.java
@@ -126,8 +126,8 @@ public interface IApplicationThread extends IInterface {
void setCoreSettings(Bundle coreSettings) throws RemoteException;
void updatePackageCompatibilityInfo(String pkg, CompatibilityInfo info) throws RemoteException;
void scheduleTrimMemory(int level) throws RemoteException;
- Debug.MemoryInfo dumpMemInfo(FileDescriptor fd, boolean checkin, boolean all,
- String[] args) throws RemoteException;
+ Debug.MemoryInfo dumpMemInfo(FileDescriptor fd, boolean checkin, boolean dumpInfo,
+ boolean dumpDalvik, String[] args) throws RemoteException;
void dumpGfxInfo(FileDescriptor fd, String[] args) throws RemoteException;
void dumpDbInfo(FileDescriptor fd, String[] args) throws RemoteException;
void unstableProviderDied(IBinder provider) throws RemoteException;
diff --git a/core/java/android/app/LoaderManager.java b/core/java/android/app/LoaderManager.java
index 267555a..b13b24a 100644
--- a/core/java/android/app/LoaderManager.java
+++ b/core/java/android/app/LoaderManager.java
@@ -204,13 +204,13 @@ class LoaderManagerImpl extends LoaderManager {
// These are the currently active loaders. A loader is here
// from the time its load is started until it has been explicitly
// stopped or restarted by the application.
- final SparseArray<LoaderInfo> mLoaders = new SparseArray<LoaderInfo>();
+ final SparseArray<LoaderInfo> mLoaders = new SparseArray<LoaderInfo>(0);
// These are previously run loaders. This list is maintained internally
// to avoid destroying a loader while an application is still using it.
// It allows an application to restart a loader, but continue using its
// previously run loader until the new loader's data is available.
- final SparseArray<LoaderInfo> mInactiveLoaders = new SparseArray<LoaderInfo>();
+ final SparseArray<LoaderInfo> mInactiveLoaders = new SparseArray<LoaderInfo>(0);
final String mWho;
diff --git a/core/java/android/appwidget/AppWidgetHost.java b/core/java/android/appwidget/AppWidgetHost.java
index c62bf32..3a355f9 100644
--- a/core/java/android/appwidget/AppWidgetHost.java
+++ b/core/java/android/appwidget/AppWidgetHost.java
@@ -198,7 +198,6 @@ public class AppWidgetHost {
* @return a appWidgetId
*/
public int allocateAppWidgetId() {
-
try {
if (mPackageName == null) {
mPackageName = mContext.getPackageName();
@@ -211,20 +210,17 @@ public class AppWidgetHost {
}
/**
- * Get a appWidgetId for a host in the calling process.
+ * Get a appWidgetId for a host in the given package.
*
* @return a appWidgetId
* @hide
*/
- public static int allocateAppWidgetIdForSystem(int hostId, int userId) {
+ public static int allocateAppWidgetIdForPackage(int hostId, int userId, String packageName) {
checkCallerIsSystem();
try {
if (sService == null) {
bindService();
}
- Context systemContext =
- (Context) ActivityThread.currentActivityThread().getSystemContext();
- String packageName = systemContext.getPackageName();
return sService.allocateAppWidgetId(packageName, hostId, userId);
} catch (RemoteException e) {
throw new RuntimeException("system server dead?", e);
diff --git a/core/java/android/bluetooth/BluetoothGatt.java b/core/java/android/bluetooth/BluetoothGatt.java
index 0752df8..df3ec1a 100644
--- a/core/java/android/bluetooth/BluetoothGatt.java
+++ b/core/java/android/bluetooth/BluetoothGatt.java
@@ -167,7 +167,7 @@ public final class BluetoothGatt implements BluetoothProfile {
try {
mCallback.onConnectionStateChange(BluetoothGatt.this, status, profileState);
} catch (Exception ex) {
- Log.w(TAG, "Unhandled exception: " + ex);
+ Log.w(TAG, "Unhandled exception in callback", ex);
}
synchronized(mStateLock) {
@@ -294,7 +294,7 @@ public final class BluetoothGatt implements BluetoothProfile {
try {
mCallback.onServicesDiscovered(BluetoothGatt.this, status);
} catch (Exception ex) {
- Log.w(TAG, "Unhandled exception: " + ex);
+ Log.w(TAG, "Unhandled exception in callback", ex);
}
}
@@ -341,7 +341,7 @@ public final class BluetoothGatt implements BluetoothProfile {
try {
mCallback.onCharacteristicRead(BluetoothGatt.this, characteristic, status);
} catch (Exception ex) {
- Log.w(TAG, "Unhandled exception: " + ex);
+ Log.w(TAG, "Unhandled exception in callback", ex);
}
}
@@ -387,7 +387,7 @@ public final class BluetoothGatt implements BluetoothProfile {
try {
mCallback.onCharacteristicWrite(BluetoothGatt.this, characteristic, status);
} catch (Exception ex) {
- Log.w(TAG, "Unhandled exception: " + ex);
+ Log.w(TAG, "Unhandled exception in callback", ex);
}
}
@@ -418,7 +418,7 @@ public final class BluetoothGatt implements BluetoothProfile {
try {
mCallback.onCharacteristicChanged(BluetoothGatt.this, characteristic);
} catch (Exception ex) {
- Log.w(TAG, "Unhandled exception: " + ex);
+ Log.w(TAG, "Unhandled exception in callback", ex);
}
}
@@ -467,7 +467,7 @@ public final class BluetoothGatt implements BluetoothProfile {
try {
mCallback.onDescriptorRead(BluetoothGatt.this, descriptor, status);
} catch (Exception ex) {
- Log.w(TAG, "Unhandled exception: " + ex);
+ Log.w(TAG, "Unhandled exception in callback", ex);
}
}
@@ -515,7 +515,7 @@ public final class BluetoothGatt implements BluetoothProfile {
try {
mCallback.onDescriptorWrite(BluetoothGatt.this, descriptor, status);
} catch (Exception ex) {
- Log.w(TAG, "Unhandled exception: " + ex);
+ Log.w(TAG, "Unhandled exception in callback", ex);
}
}
@@ -532,7 +532,7 @@ public final class BluetoothGatt implements BluetoothProfile {
try {
mCallback.onReliableWriteCompleted(BluetoothGatt.this, status);
} catch (Exception ex) {
- Log.w(TAG, "Unhandled exception: " + ex);
+ Log.w(TAG, "Unhandled exception in callback", ex);
}
}
@@ -549,7 +549,7 @@ public final class BluetoothGatt implements BluetoothProfile {
try {
mCallback.onReadRemoteRssi(BluetoothGatt.this, rssi, status);
} catch (Exception ex) {
- Log.w(TAG, "Unhandled exception: " + ex);
+ Log.w(TAG, "Unhandled exception in callback", ex);
}
}
};
diff --git a/core/java/android/bluetooth/BluetoothGattServer.java b/core/java/android/bluetooth/BluetoothGattServer.java
index 78d536b..58ee54f 100644
--- a/core/java/android/bluetooth/BluetoothGattServer.java
+++ b/core/java/android/bluetooth/BluetoothGattServer.java
@@ -108,7 +108,7 @@ public final class BluetoothGattServer implements BluetoothProfile {
connected ? BluetoothProfile.STATE_CONNECTED :
BluetoothProfile.STATE_DISCONNECTED);
} catch (Exception ex) {
- Log.w(TAG, "Unhandled exception: " + ex);
+ Log.w(TAG, "Unhandled exception in callback", ex);
}
}
@@ -128,7 +128,7 @@ public final class BluetoothGattServer implements BluetoothProfile {
try {
mCallback.onServiceAdded((int)status, service);
} catch (Exception ex) {
- Log.w(TAG, "Unhandled exception: " + ex);
+ Log.w(TAG, "Unhandled exception in callback", ex);
}
}
@@ -154,7 +154,7 @@ public final class BluetoothGattServer implements BluetoothProfile {
try {
mCallback.onCharacteristicReadRequest(device, transId, offset, characteristic);
} catch (Exception ex) {
- Log.w(TAG, "Unhandled exception: " + ex);
+ Log.w(TAG, "Unhandled exception in callback", ex);
}
}
@@ -186,7 +186,7 @@ public final class BluetoothGattServer implements BluetoothProfile {
try {
mCallback.onDescriptorReadRequest(device, transId, offset, descriptor);
} catch (Exception ex) {
- Log.w(TAG, "Unhandled exception: " + ex);
+ Log.w(TAG, "Unhandled exception in callback", ex);
}
}
@@ -214,7 +214,7 @@ public final class BluetoothGattServer implements BluetoothProfile {
mCallback.onCharacteristicWriteRequest(device, transId, characteristic,
isPrep, needRsp, offset, value);
} catch (Exception ex) {
- Log.w(TAG, "Unhandled exception: " + ex);
+ Log.w(TAG, "Unhandled exception in callback", ex);
}
}
@@ -250,7 +250,7 @@ public final class BluetoothGattServer implements BluetoothProfile {
mCallback.onDescriptorWriteRequest(device, transId, descriptor,
isPrep, needRsp, offset, value);
} catch (Exception ex) {
- Log.w(TAG, "Unhandled exception: " + ex);
+ Log.w(TAG, "Unhandled exception in callback", ex);
}
}
@@ -270,7 +270,7 @@ public final class BluetoothGattServer implements BluetoothProfile {
try {
mCallback.onExecuteWrite(device, transId, execWrite);
} catch (Exception ex) {
- Log.w(TAG, "Unhandled exception: " + ex);
+ Log.w(TAG, "Unhandled exception in callback", ex);
}
}
};
diff --git a/core/java/android/bluetooth/BluetoothHeadset.java b/core/java/android/bluetooth/BluetoothHeadset.java
index 793d798..963e9fc 100644
--- a/core/java/android/bluetooth/BluetoothHeadset.java
+++ b/core/java/android/bluetooth/BluetoothHeadset.java
@@ -815,27 +815,6 @@ public final class BluetoothHeadset implements BluetoothProfile {
}
/**
- * Notify Headset of phone roam state change.
- * This is a backdoor for phone app to call BluetoothHeadset since
- * there is currently not a good way to get roaming state change outside
- * of phone app.
- *
- * @hide
- */
- public void roamChanged(boolean roaming) {
- if (mService != null && isEnabled()) {
- try {
- mService.roamChanged(roaming);
- } catch (RemoteException e) {
- Log.e(TAG, e.toString());
- }
- } else {
- Log.w(TAG, "Proxy not attached to service");
- if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
- }
- }
-
- /**
* Send Headset of CLCC response
*
* @hide
diff --git a/core/java/android/bluetooth/IBluetoothHeadset.aidl b/core/java/android/bluetooth/IBluetoothHeadset.aidl
index fc7627a..285eea7 100644..100755
--- a/core/java/android/bluetooth/IBluetoothHeadset.aidl
+++ b/core/java/android/bluetooth/IBluetoothHeadset.aidl
@@ -50,7 +50,6 @@ interface IBluetoothHeadset {
boolean startScoUsingVirtualVoiceCall(in BluetoothDevice device);
boolean stopScoUsingVirtualVoiceCall(in BluetoothDevice device);
void phoneStateChanged(int numActive, int numHeld, int callState, String number, int type);
- void roamChanged(boolean roam);
void clccResponse(int index, int direction, int status, int mode, boolean mpty,
String number, int type);
}
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index fefd343..b3f0d96 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -220,6 +220,7 @@ public abstract class ContentResolver {
// Always log queries which take 500ms+; shorter queries are
// sampled accordingly.
+ private static final boolean ENABLE_CONTENT_SAMPLE = false;
private static final int SLOW_THRESHOLD_MILLIS = 500;
private final Random mRandom = new Random(); // guarded by itself
@@ -1832,6 +1833,7 @@ public abstract class ContentResolver {
private void maybeLogQueryToEventLog(long durationMillis,
Uri uri, String[] projection,
String selection, String sortOrder) {
+ if (!ENABLE_CONTENT_SAMPLE) return;
int samplePercent = samplePercentForDuration(durationMillis);
if (samplePercent < 100) {
synchronized (mRandom) {
@@ -1871,6 +1873,7 @@ public abstract class ContentResolver {
private void maybeLogUpdateToEventLog(
long durationMillis, Uri uri, String operation, String selection) {
+ if (!ENABLE_CONTENT_SAMPLE) return;
int samplePercent = samplePercentForDuration(durationMillis);
if (samplePercent < 100) {
synchronized (mRandom) {
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 5bd28b9..81d6f0b 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -2434,7 +2434,7 @@ public abstract class Context {
* Remove all permissions to access a particular content provider Uri
* that were previously added with {@link #grantUriPermission}. The given
* Uri will match all previously granted Uris that are the same or a
- * sub-path of the given Uri. That is, revoking "content://foo/one" will
+ * sub-path of the given Uri. That is, revoking "content://foo/target" will
* revoke both "content://foo/target" and "content://foo/target/sub", but not
* "content://foo".
*
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index fc95728..897e6fe 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -1165,13 +1165,12 @@ public class Intent implements Parcelable, Cloneable {
* additional optional contextual information about where the user was when they requested
* the voice assist.
* Output: nothing.
- * @hide
*/
@SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
public static final String ACTION_VOICE_ASSIST = "android.intent.action.VOICE_ASSIST";
/**
- * An optional field on {@link #ACTION_ASSIST}
+ * An optional field on {@link #ACTION_ASSIST} and {@link #ACTION_VOICE_ASSIST}
* containing the name of the current foreground application package at the time
* the assist was invoked.
*/
@@ -1179,7 +1178,7 @@ public class Intent implements Parcelable, Cloneable {
= "android.intent.extra.ASSIST_PACKAGE";
/**
- * An optional field on {@link #ACTION_ASSIST}
+ * An optional field on {@link #ACTION_ASSIST} and {@link #ACTION_VOICE_ASSIST}
* containing additional contextual information supplied by the current
* foreground app at the time of the assist request. This is a {@link Bundle} of
* additional data.
@@ -2599,6 +2598,46 @@ public class Intent implements Parcelable, Cloneable {
*/
public static final String ACTION_GLOBAL_BUTTON = "android.intent.action.GLOBAL_BUTTON";
+ /**
+ * Activity Action: Allow the user to select and open one or more existing
+ * documents. Both read and write access to the documents will be granted
+ * until explicitly revoked by the user.
+ * <p>
+ * Callers can restrict selection to a specific kind of data, such as
+ * photos, by setting one or more MIME types in {@link #EXTRA_MIME_TYPES}.
+ * <p>
+ * If the caller can handle multiple returned items (the user performing
+ * multiple selection), then it can specify {@link #EXTRA_ALLOW_MULTIPLE} to
+ * indicate this.
+ * <p>
+ * All returned URIs can be opened as a stream with
+ * {@link ContentResolver#openInputStream(Uri)}.
+ * <p>
+ * Output: The URI of the item that was picked. This must be a content: URI
+ * so that any receiver can access it.
+ */
+ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+ public static final String ACTION_OPEN_DOCUMENT = "android.intent.action.OPEN_DOCUMENT";
+
+ /**
+ * Activity Action: Allow the user to create a new document. Both read and
+ * write access to the document will be granted until explicitly revoked by
+ * the user.
+ * <p>
+ * Callers can provide a hint document name by setting {@link #EXTRA_TITLE},
+ * but the user may change this value before creating the file. Callers can
+ * optionally hint at the MIME type being created by setting
+ * {@link #setType(String)}.
+ * <p>
+ * All returned URIs can be opened as a stream with
+ * {@link ContentResolver#openOutputStream(Uri)}.
+ * <p>
+ * Output: The URI of the item that was created. This must be a content: URI
+ * so that any receiver can access it.
+ */
+ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+ public static final String ACTION_CREATE_DOCUMENT = "android.intent.action.CREATE_DOCUMENT";
+
// ---------------------------------------------------------------------
// ---------------------------------------------------------------------
// Standard intent categories (see addCategory()).
@@ -3202,6 +3241,13 @@ public class Intent implements Parcelable, Cloneable {
public static final String EXTRA_RESTRICTIONS_INTENT =
"android.intent.extra.restrictions_intent";
+ /**
+ * Extra used to communicate set of acceptable MIME types for
+ * {@link #ACTION_GET_CONTENT} or {@link #ACTION_OPEN_DOCUMENT}. The type of the
+ * extra is <code>ArrayList&lt;String&gt;</code>.
+ */
+ public static final String EXTRA_MIME_TYPES = "android.intent.extra.MIME_TYPES";
+
// ---------------------------------------------------------------------
// ---------------------------------------------------------------------
// Intent flags (see mFlags variable).
@@ -3251,6 +3297,15 @@ public class Intent implements Parcelable, Cloneable {
public static final int FLAG_INCLUDE_STOPPED_PACKAGES = 0x00000020;
/**
+ * When combined with {@link #FLAG_GRANT_READ_URI_PERMISSION} and/or
+ * {@link #FLAG_GRANT_WRITE_URI_PERMISSION}, the grant will be remembered
+ * until explicitly revoked with
+ * {@link Context#revokeUriPermission(Uri, int)}. These grants persist
+ * across device reboots.
+ */
+ public static final int FLAG_PERSIST_GRANT_URI_PERMISSION = 0x00000040;
+
+ /**
* If set, the new activity is not kept in the history stack. As soon as
* the user navigates away from it, the activity is finished. This may also
* be set with the {@link android.R.styleable#AndroidManifestActivity_noHistory
@@ -7039,7 +7094,8 @@ public class Intent implements Parcelable, Cloneable {
// and flags to ourselves to grant.
setClipData(target.getClipData());
addFlags(target.getFlags()
- & (FLAG_GRANT_READ_URI_PERMISSION | FLAG_GRANT_WRITE_URI_PERMISSION));
+ & (FLAG_GRANT_READ_URI_PERMISSION | FLAG_GRANT_WRITE_URI_PERMISSION
+ | FLAG_PERSIST_GRANT_URI_PERMISSION));
return true;
} else {
return false;
diff --git a/core/java/android/content/UndoManager.java b/core/java/android/content/UndoManager.java
new file mode 100644
index 0000000..1c2db47
--- /dev/null
+++ b/core/java/android/content/UndoManager.java
@@ -0,0 +1,932 @@
+/*
+ * 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 android.content;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.ParcelableParcel;
+import android.text.TextUtils;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+/**
+ * Top-level class for managing and interacting with the global undo state for
+ * a document or application. This class supports both undo and redo and has
+ * helpers for merging undoable operations together as they are performed.
+ *
+ * <p>A single undoable operation is represented by {@link UndoOperation} which
+ * apps implement to define their undo/redo behavior. The UndoManager keeps
+ * a stack of undo states; each state can have one or more undo operations
+ * inside of it.</p>
+ *
+ * <p>Updates to the stack must be done inside of a {@link #beginUpdate}/{@link #endUpdate()}
+ * pair. During this time you can add new operations to the stack with
+ * {@link #addOperation}, retrieve and modify existing operations with
+ * {@link #getLastOperation}, control the label shown to the user for this operation
+ * with {@link #setUndoLabel} and {@link #suggestUndoLabel}, etc.</p>
+ *
+ * <p>Every {link UndoOperation} is associated with an {@link UndoOwner}, which identifies
+ * the data it belongs to. The owner is used to indicate how operations are dependent
+ * on each other -- operations with the same owner are dependent on others with the
+ * same owner. For example, you may have a document with multiple embedded objects. If the
+ * document itself and each embedded object use different owners, then you
+ * can provide undo semantics appropriate to the user's context: while within
+ * an embedded object, only edits to that object are seen and the user can
+ * undo/redo them without needing to impact edits in other objects; while
+ * within the larger document, all edits can be seen and the user must
+ * undo/redo them as a single stream.</p>
+ */
+public class UndoManager {
+ private final HashMap<String, UndoOwner> mOwners = new HashMap<String, UndoOwner>();
+ private final ArrayList<UndoState> mUndos = new ArrayList<UndoState>();
+ private final ArrayList<UndoState> mRedos = new ArrayList<UndoState>();
+ private int mUpdateCount;
+ private int mHistorySize = 20;
+ private UndoState mWorking;
+ private int mCommitId = 1;
+ private boolean mInUndo;
+ private boolean mMerged;
+
+ private int mStateSeq;
+ private int mNextSavedIdx;
+ private UndoOwner[] mStateOwners;
+
+ /**
+ * Never merge with the last undo state.
+ */
+ public static final int MERGE_MODE_NONE = 0;
+
+ /**
+ * Allow merge with the last undo state only if it contains
+ * operations with the caller's owner.
+ */
+ public static final int MERGE_MODE_UNIQUE = 1;
+
+ /**
+ * Always allow merge with the last undo state, if possible.
+ */
+ public static final int MERGE_MODE_ANY = 2;
+
+ public UndoOwner getOwner(String tag, Object data) {
+ if (tag == null) {
+ throw new NullPointerException("tag can't be null");
+ }
+ if (data == null) {
+ throw new NullPointerException("data can't be null");
+ }
+ UndoOwner owner = mOwners.get(tag);
+ if (owner != null) {
+ if (owner.mData != data) {
+ if (owner.mData != null) {
+ throw new IllegalStateException("Owner " + owner + " already exists with data "
+ + owner.mData + " but giving different data " + data);
+ }
+ owner.mData = data;
+ }
+ return owner;
+ }
+
+ owner = new UndoOwner(tag);
+ owner.mManager = this;
+ owner.mData = data;
+ mOwners.put(tag, owner);
+ return owner;
+ }
+
+ void removeOwner(UndoOwner owner) {
+ // XXX need to figure out how to prune.
+ if (false) {
+ mOwners.remove(owner.mTag);
+ owner.mManager = null;
+ }
+ }
+
+ /**
+ * Flatten the current undo state into a Parcelable object, which can later be restored
+ * with {@link #restoreInstanceState(android.os.Parcelable)}.
+ */
+ public Parcelable saveInstanceState() {
+ if (mUpdateCount > 0) {
+ throw new IllegalStateException("Can't save state while updating");
+ }
+ ParcelableParcel pp = new ParcelableParcel(getClass().getClassLoader());
+ Parcel p = pp.getParcel();
+ mStateSeq++;
+ if (mStateSeq <= 0) {
+ mStateSeq = 0;
+ }
+ mNextSavedIdx = 0;
+ p.writeInt(mHistorySize);
+ p.writeInt(mOwners.size());
+ // XXX eventually we need to be smart here about limiting the
+ // number of undo states we write to not exceed X bytes.
+ int i = mUndos.size();
+ while (i > 0) {
+ p.writeInt(1);
+ i--;
+ mUndos.get(i).writeToParcel(p);
+ }
+ i = mRedos.size();
+ p.writeInt(i);
+ while (i > 0) {
+ p.writeInt(2);
+ i--;
+ mRedos.get(i).writeToParcel(p);
+ }
+ p.writeInt(0);
+ return pp;
+ }
+
+ void saveOwner(UndoOwner owner, Parcel out) {
+ if (owner.mStateSeq == mStateSeq) {
+ out.writeInt(owner.mSavedIdx);
+ } else {
+ owner.mStateSeq = mStateSeq;
+ owner.mSavedIdx = mNextSavedIdx;
+ out.writeInt(owner.mSavedIdx);
+ out.writeString(owner.mTag);
+ mNextSavedIdx++;
+ }
+ }
+
+ /**
+ * Restore an undo state previously created with {@link #saveInstanceState()}. This will
+ * restore the UndoManager's state to almost exactly what it was at the point it had
+ * been previously saved; the only information not restored is the data object
+ * associated with each {@link UndoOwner}, which requires separate calls to
+ * {@link #getOwner(String, Object)} to re-associate the owner with its data.
+ */
+ public void restoreInstanceState(Parcelable state) {
+ if (mUpdateCount > 0) {
+ throw new IllegalStateException("Can't save state while updating");
+ }
+ forgetUndos(null, -1);
+ forgetRedos(null, -1);
+ ParcelableParcel pp = (ParcelableParcel)state;
+ Parcel p = pp.getParcel();
+ mHistorySize = p.readInt();
+ mStateOwners = new UndoOwner[p.readInt()];
+
+ int stype;
+ while ((stype=p.readInt()) != 0) {
+ UndoState ustate = new UndoState(this, p, pp.getClassLoader());
+ if (stype == 1) {
+ mUndos.add(0, ustate);
+ } else {
+ mRedos.add(0, ustate);
+ }
+ }
+ }
+
+ UndoOwner restoreOwner(Parcel in) {
+ int idx = in.readInt();
+ UndoOwner owner = mStateOwners[idx];
+ if (owner == null) {
+ String tag = in.readString();
+ owner = new UndoOwner(tag);
+ mStateOwners[idx] = owner;
+ mOwners.put(tag, owner);
+ }
+ return owner;
+ }
+
+ /**
+ * Set the maximum number of undo states that will be retained.
+ */
+ public void setHistorySize(int size) {
+ mHistorySize = size;
+ if (mHistorySize >= 0 && countUndos(null) > mHistorySize) {
+ forgetUndos(null, countUndos(null) - mHistorySize);
+ }
+ }
+
+ /**
+ * Return the current maximum number of undo states.
+ */
+ public int getHistorySize() {
+ return mHistorySize;
+ }
+
+ /**
+ * Perform undo of last/top <var>count</var> undo states. The states impacted
+ * by this can be limited through <var>owners</var>.
+ * @param owners Optional set of owners that should be impacted. If null, all
+ * undo states will be visible and available for undo. If non-null, only those
+ * states that contain one of the owners specified here will be visible.
+ * @param count Number of undo states to pop.
+ * @return Returns the number of undo states that were actually popped.
+ */
+ public int undo(UndoOwner[] owners, int count) {
+ if (mWorking != null) {
+ throw new IllegalStateException("Can't be called during an update");
+ }
+
+ int num = 0;
+ int i = -1;
+
+ mInUndo = true;
+
+ UndoState us = getTopUndo(null);
+ if (us != null) {
+ us.makeExecuted();
+ }
+
+ while (count > 0 && (i=findPrevState(mUndos, owners, i)) >= 0) {
+ UndoState state = mUndos.remove(i);
+ state.undo();
+ mRedos.add(state);
+ count--;
+ num++;
+ }
+
+ mInUndo = false;
+
+ return num;
+ }
+
+ /**
+ * Perform redo of last/top <var>count</var> undo states in the transient redo stack.
+ * The states impacted by this can be limited through <var>owners</var>.
+ * @param owners Optional set of owners that should be impacted. If null, all
+ * undo states will be visible and available for undo. If non-null, only those
+ * states that contain one of the owners specified here will be visible.
+ * @param count Number of undo states to pop.
+ * @return Returns the number of undo states that were actually redone.
+ */
+ public int redo(UndoOwner[] owners, int count) {
+ if (mWorking != null) {
+ throw new IllegalStateException("Can't be called during an update");
+ }
+
+ int num = 0;
+ int i = -1;
+
+ mInUndo = true;
+
+ while (count > 0 && (i=findPrevState(mRedos, owners, i)) >= 0) {
+ UndoState state = mRedos.remove(i);
+ state.redo();
+ mUndos.add(state);
+ count--;
+ num++;
+ }
+
+ mInUndo = false;
+
+ return num;
+ }
+
+ /**
+ * Returns true if we are currently inside of an undo/redo operation. This is
+ * useful for editors to know whether they should be generating new undo state
+ * when they see edit operations happening.
+ */
+ public boolean isInUndo() {
+ return mInUndo;
+ }
+
+ public int forgetUndos(UndoOwner[] owners, int count) {
+ if (count < 0) {
+ count = mUndos.size();
+ }
+
+ int removed = 0;
+ for (int i=0; i<mUndos.size() && removed < count; i++) {
+ UndoState state = mUndos.get(i);
+ if (count > 0 && matchOwners(state, owners)) {
+ state.destroy();
+ mUndos.remove(i);
+ removed++;
+ }
+ }
+
+ return removed;
+ }
+
+ public int forgetRedos(UndoOwner[] owners, int count) {
+ if (count < 0) {
+ count = mRedos.size();
+ }
+
+ int removed = 0;
+ for (int i=0; i<mRedos.size() && removed < count; i++) {
+ UndoState state = mRedos.get(i);
+ if (count > 0 && matchOwners(state, owners)) {
+ state.destroy();
+ mRedos.remove(i);
+ removed++;
+ }
+ }
+
+ return removed;
+ }
+
+ /**
+ * Return the number of undo states on the undo stack.
+ * @param owners If non-null, only those states containing an operation with one of
+ * the owners supplied here will be counted.
+ */
+ public int countUndos(UndoOwner[] owners) {
+ if (owners == null) {
+ return mUndos.size();
+ }
+
+ int count=0;
+ int i=0;
+ while ((i=findNextState(mUndos, owners, i)) >= 0) {
+ count++;
+ i++;
+ }
+ return count;
+ }
+
+ /**
+ * Return the number of redo states on the undo stack.
+ * @param owners If non-null, only those states containing an operation with one of
+ * the owners supplied here will be counted.
+ */
+ public int countRedos(UndoOwner[] owners) {
+ if (owners == null) {
+ return mRedos.size();
+ }
+
+ int count=0;
+ int i=0;
+ while ((i=findNextState(mRedos, owners, i)) >= 0) {
+ count++;
+ i++;
+ }
+ return count;
+ }
+
+ /**
+ * Return the user-visible label for the top undo state on the stack.
+ * @param owners If non-null, will select the top-most undo state containing an
+ * operation with one of the owners supplied here.
+ */
+ public CharSequence getUndoLabel(UndoOwner[] owners) {
+ UndoState state = getTopUndo(owners);
+ return state != null ? state.getLabel() : null;
+ }
+
+ /**
+ * Return the user-visible label for the top redo state on the stack.
+ * @param owners If non-null, will select the top-most undo state containing an
+ * operation with one of the owners supplied here.
+ */
+ public CharSequence getRedoLabel(UndoOwner[] owners) {
+ UndoState state = getTopRedo(owners);
+ return state != null ? state.getLabel() : null;
+ }
+
+ /**
+ * Start creating a new undo state. Multiple calls to this function will nest until
+ * they are all matched by a later call to {@link #endUpdate}.
+ * @param label Optional user-visible label for this new undo state.
+ */
+ public void beginUpdate(CharSequence label) {
+ if (mInUndo) {
+ throw new IllegalStateException("Can't being update while performing undo/redo");
+ }
+ if (mUpdateCount <= 0) {
+ createWorkingState();
+ mMerged = false;
+ mUpdateCount = 0;
+ }
+
+ mWorking.updateLabel(label);
+ mUpdateCount++;
+ }
+
+ private void createWorkingState() {
+ mWorking = new UndoState(this, mCommitId++);
+ if (mCommitId < 0) {
+ mCommitId = 1;
+ }
+ }
+
+ /**
+ * Returns true if currently inside of a {@link #beginUpdate}.
+ */
+ public boolean isInUpdate() {
+ return mUpdateCount > 0;
+ }
+
+ /**
+ * Forcibly set a new for the new undo state being built within a {@link #beginUpdate}.
+ * Any existing label will be replaced with this one.
+ */
+ public void setUndoLabel(CharSequence label) {
+ if (mWorking == null) {
+ throw new IllegalStateException("Must be called during an update");
+ }
+ mWorking.setLabel(label);
+ }
+
+ /**
+ * Set a new for the new undo state being built within a {@link #beginUpdate}, but
+ * only if there is not a label currently set for it.
+ */
+ public void suggestUndoLabel(CharSequence label) {
+ if (mWorking == null) {
+ throw new IllegalStateException("Must be called during an update");
+ }
+ mWorking.updateLabel(label);
+ }
+
+ /**
+ * Return the number of times {@link #beginUpdate} has been called without a matching
+ * {@link #endUpdate} call.
+ */
+ public int getUpdateNestingLevel() {
+ return mUpdateCount;
+ }
+
+ /**
+ * Check whether there is an {@link UndoOperation} in the current {@link #beginUpdate}
+ * undo state.
+ * @param owner Optional owner of the operation to look for. If null, will succeed
+ * if there is any operation; if non-null, will only succeed if there is an operation
+ * with the given owner.
+ * @return Returns true if there is a matching operation in the current undo state.
+ */
+ public boolean hasOperation(UndoOwner owner) {
+ if (mWorking == null) {
+ throw new IllegalStateException("Must be called during an update");
+ }
+ return mWorking.hasOperation(owner);
+ }
+
+ /**
+ * Return the most recent {@link UndoOperation} that was added to the update.
+ * @param mergeMode May be either {@link #MERGE_MODE_NONE} or {@link #MERGE_MODE_ANY}.
+ */
+ public UndoOperation<?> getLastOperation(int mergeMode) {
+ return getLastOperation(null, null, mergeMode);
+ }
+
+ /**
+ * Return the most recent {@link UndoOperation} that was added to the update and
+ * has the given owner.
+ * @param owner Optional owner of last operation to retrieve. If null, the last
+ * operation regardless of owner will be retrieved; if non-null, the last operation
+ * matching the given owner will be retrieved.
+ * @param mergeMode May be either {@link #MERGE_MODE_NONE}, {@link #MERGE_MODE_UNIQUE},
+ * or {@link #MERGE_MODE_ANY}.
+ */
+ public UndoOperation<?> getLastOperation(UndoOwner owner, int mergeMode) {
+ return getLastOperation(null, owner, mergeMode);
+ }
+
+ /**
+ * Return the most recent {@link UndoOperation} that was added to the update and
+ * has the given owner.
+ * @param clazz Optional class of the last operation to retrieve. If null, the
+ * last operation regardless of class will be retrieved; if non-null, the last
+ * operation whose class is the same as the given class will be retrieved.
+ * @param owner Optional owner of last operation to retrieve. If null, the last
+ * operation regardless of owner will be retrieved; if non-null, the last operation
+ * matching the given owner will be retrieved.
+ * @param mergeMode May be either {@link #MERGE_MODE_NONE}, {@link #MERGE_MODE_UNIQUE},
+ * or {@link #MERGE_MODE_ANY}.
+ */
+ public <T extends UndoOperation> T getLastOperation(Class<T> clazz, UndoOwner owner,
+ int mergeMode) {
+ if (mWorking == null) {
+ throw new IllegalStateException("Must be called during an update");
+ }
+ if (mergeMode != MERGE_MODE_NONE && !mMerged && !mWorking.hasData()) {
+ UndoState state = getTopUndo(null);
+ UndoOperation<?> last;
+ if (state != null && (mergeMode == MERGE_MODE_ANY || !state.hasMultipleOwners())
+ && state.canMerge() && (last=state.getLastOperation(clazz, owner)) != null) {
+ if (last.allowMerge()) {
+ mWorking.destroy();
+ mWorking = state;
+ mUndos.remove(state);
+ mMerged = true;
+ return (T)last;
+ }
+ }
+ }
+
+ return mWorking.getLastOperation(clazz, owner);
+ }
+
+ /**
+ * Add a new UndoOperation to the current update.
+ * @param op The new operation to add.
+ * @param mergeMode May be either {@link #MERGE_MODE_NONE}, {@link #MERGE_MODE_UNIQUE},
+ * or {@link #MERGE_MODE_ANY}.
+ */
+ public void addOperation(UndoOperation<?> op, int mergeMode) {
+ if (mWorking == null) {
+ throw new IllegalStateException("Must be called during an update");
+ }
+ UndoOwner owner = op.getOwner();
+ if (owner.mManager != this) {
+ throw new IllegalArgumentException(
+ "Given operation's owner is not in this undo manager.");
+ }
+ if (mergeMode != MERGE_MODE_NONE && !mMerged && !mWorking.hasData()) {
+ UndoState state = getTopUndo(null);
+ if (state != null && (mergeMode == MERGE_MODE_ANY || !state.hasMultipleOwners())
+ && state.canMerge() && state.hasOperation(op.getOwner())) {
+ mWorking.destroy();
+ mWorking = state;
+ mUndos.remove(state);
+ mMerged = true;
+ }
+ }
+ mWorking.addOperation(op);
+ }
+
+ /**
+ * Finish the creation of an undo state, matching a previous call to
+ * {@link #beginUpdate}.
+ */
+ public void endUpdate() {
+ if (mWorking == null) {
+ throw new IllegalStateException("Must be called during an update");
+ }
+ mUpdateCount--;
+
+ if (mUpdateCount == 0) {
+ pushWorkingState();
+ }
+ }
+
+ private void pushWorkingState() {
+ int N = mUndos.size() + 1;
+
+ if (mWorking.hasData()) {
+ mUndos.add(mWorking);
+ forgetRedos(null, -1);
+ mWorking.commit();
+ if (N >= 2) {
+ // The state before this one can no longer be merged, ever.
+ // The only way to get back to it is for the user to perform
+ // an undo.
+ mUndos.get(N-2).makeExecuted();
+ }
+ } else {
+ mWorking.destroy();
+ }
+ mWorking = null;
+
+ if (mHistorySize >= 0 && N > mHistorySize) {
+ forgetUndos(null, N - mHistorySize);
+ }
+ }
+
+ /**
+ * Commit the last finished undo state. This undo state can no longer be
+ * modified with further {@link #MERGE_MODE_UNIQUE} or
+ * {@link #MERGE_MODE_ANY} merge modes. If called while inside of an update,
+ * this will push any changes in the current update on to the undo stack
+ * and result with a fresh undo state, behaving as if {@link #endUpdate()}
+ * had been called enough to unwind the current update, then the last state
+ * committed, and {@link #beginUpdate} called to restore the update nesting.
+ * @param owner The optional owner to determine whether to perform the commit.
+ * If this is non-null, the commit will only execute if the current top undo
+ * state contains an operation with the given owner.
+ * @return Returns an integer identifier for the committed undo state, which
+ * can later be used to try to uncommit the state to perform further edits on it.
+ */
+ public int commitState(UndoOwner owner) {
+ if (mWorking != null && mWorking.hasData()) {
+ if (owner == null || mWorking.hasOperation(owner)) {
+ mWorking.setCanMerge(false);
+ int commitId = mWorking.getCommitId();
+ pushWorkingState();
+ createWorkingState();
+ mMerged = true;
+ return commitId;
+ }
+ } else {
+ UndoState state = getTopUndo(null);
+ if (state != null && (owner == null || state.hasOperation(owner))) {
+ state.setCanMerge(false);
+ return state.getCommitId();
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * Attempt to undo a previous call to {@link #commitState}. This will work
+ * if the undo state at the top of the stack has the given id, and has not been
+ * involved in an undo operation. Otherwise false is returned.
+ * @param commitId The identifier for the state to be uncommitted, as returned
+ * by {@link #commitState}.
+ * @param owner Optional owner that must appear in the committed state.
+ * @return Returns true if the uncommit is successful, else false.
+ */
+ public boolean uncommitState(int commitId, UndoOwner owner) {
+ if (mWorking != null && mWorking.getCommitId() == commitId) {
+ if (owner == null || mWorking.hasOperation(owner)) {
+ return mWorking.setCanMerge(true);
+ }
+ } else {
+ UndoState state = getTopUndo(null);
+ if (state != null && (owner == null || state.hasOperation(owner))) {
+ if (state.getCommitId() == commitId) {
+ return state.setCanMerge(true);
+ }
+ }
+ }
+ return false;
+ }
+
+ UndoState getTopUndo(UndoOwner[] owners) {
+ if (mUndos.size() <= 0) {
+ return null;
+ }
+ int i = findPrevState(mUndos, owners, -1);
+ return i >= 0 ? mUndos.get(i) : null;
+ }
+
+ UndoState getTopRedo(UndoOwner[] owners) {
+ if (mRedos.size() <= 0) {
+ return null;
+ }
+ int i = findPrevState(mRedos, owners, -1);
+ return i >= 0 ? mRedos.get(i) : null;
+ }
+
+ boolean matchOwners(UndoState state, UndoOwner[] owners) {
+ if (owners == null) {
+ return true;
+ }
+ for (int i=0; i<owners.length; i++) {
+ if (state.matchOwner(owners[i])) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ int findPrevState(ArrayList<UndoState> states, UndoOwner[] owners, int from) {
+ final int N = states.size();
+
+ if (from == -1) {
+ from = N-1;
+ }
+ if (from >= N) {
+ return -1;
+ }
+ if (owners == null) {
+ return from;
+ }
+
+ while (from >= 0) {
+ UndoState state = states.get(from);
+ if (matchOwners(state, owners)) {
+ return from;
+ }
+ from--;
+ }
+
+ return -1;
+ }
+
+ int findNextState(ArrayList<UndoState> states, UndoOwner[] owners, int from) {
+ final int N = states.size();
+
+ if (from < 0) {
+ from = 0;
+ }
+ if (from >= N) {
+ return -1;
+ }
+ if (owners == null) {
+ return from;
+ }
+
+ while (from < N) {
+ UndoState state = states.get(from);
+ if (matchOwners(state, owners)) {
+ return from;
+ }
+ from++;
+ }
+
+ return -1;
+ }
+
+ final static class UndoState {
+ private final UndoManager mManager;
+ private final int mCommitId;
+ private final ArrayList<UndoOperation<?>> mOperations = new ArrayList<UndoOperation<?>>();
+ private ArrayList<UndoOperation<?>> mRecent;
+ private CharSequence mLabel;
+ private boolean mCanMerge = true;
+ private boolean mExecuted;
+
+ UndoState(UndoManager manager, int commitId) {
+ mManager = manager;
+ mCommitId = commitId;
+ }
+
+ UndoState(UndoManager manager, Parcel p, ClassLoader loader) {
+ mManager = manager;
+ mCommitId = p.readInt();
+ mCanMerge = p.readInt() != 0;
+ mExecuted = p.readInt() != 0;
+ mLabel = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(p);
+ final int N = p.readInt();
+ for (int i=0; i<N; i++) {
+ UndoOwner owner = mManager.restoreOwner(p);
+ UndoOperation op = (UndoOperation)p.readParcelable(loader);
+ op.mOwner = owner;
+ mOperations.add(op);
+ }
+ }
+
+ void writeToParcel(Parcel p) {
+ if (mRecent != null) {
+ throw new IllegalStateException("Can't save state before committing");
+ }
+ p.writeInt(mCommitId);
+ p.writeInt(mCanMerge ? 1 : 0);
+ p.writeInt(mExecuted ? 1 : 0);
+ TextUtils.writeToParcel(mLabel, p, 0);
+ final int N = mOperations.size();
+ p.writeInt(N);
+ for (int i=0; i<N; i++) {
+ UndoOperation op = mOperations.get(i);
+ mManager.saveOwner(op.mOwner, p);
+ p.writeParcelable(op, 0);
+ }
+ }
+
+ int getCommitId() {
+ return mCommitId;
+ }
+
+ void setLabel(CharSequence label) {
+ mLabel = label;
+ }
+
+ void updateLabel(CharSequence label) {
+ if (mLabel != null) {
+ mLabel = label;
+ }
+ }
+
+ CharSequence getLabel() {
+ return mLabel;
+ }
+
+ boolean setCanMerge(boolean state) {
+ // Don't allow re-enabling of merging if state has been executed.
+ if (state && mExecuted) {
+ return false;
+ }
+ mCanMerge = state;
+ return true;
+ }
+
+ void makeExecuted() {
+ mExecuted = true;
+ }
+
+ boolean canMerge() {
+ return mCanMerge && !mExecuted;
+ }
+
+ int countOperations() {
+ return mOperations.size();
+ }
+
+ boolean hasOperation(UndoOwner owner) {
+ final int N = mOperations.size();
+ if (owner == null) {
+ return N != 0;
+ }
+ for (int i=0; i<N; i++) {
+ if (mOperations.get(i).getOwner() == owner) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ boolean hasMultipleOwners() {
+ final int N = mOperations.size();
+ if (N <= 1) {
+ return false;
+ }
+ UndoOwner owner = mOperations.get(0).getOwner();
+ for (int i=1; i<N; i++) {
+ if (mOperations.get(i).getOwner() != owner) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ void addOperation(UndoOperation<?> op) {
+ if (mOperations.contains(op)) {
+ throw new IllegalStateException("Already holds " + op);
+ }
+ mOperations.add(op);
+ if (mRecent == null) {
+ mRecent = new ArrayList<UndoOperation<?>>();
+ mRecent.add(op);
+ }
+ op.mOwner.mOpCount++;
+ }
+
+ <T extends UndoOperation> T getLastOperation(Class<T> clazz, UndoOwner owner) {
+ final int N = mOperations.size();
+ if (clazz == null && owner == null) {
+ return N > 0 ? (T)mOperations.get(N-1) : null;
+ }
+ // First look for the top-most operation with the same owner.
+ for (int i=N-1; i>=0; i--) {
+ UndoOperation<?> op = mOperations.get(i);
+ if (owner != null && op.getOwner() != owner) {
+ continue;
+ }
+ // Return this operation if it has the same class that the caller wants.
+ // Note that we don't search deeper for the class, because we don't want
+ // to end up with a different order of operations for the same owner.
+ if (clazz != null && op.getClass() != clazz) {
+ return null;
+ }
+ return (T)op;
+ }
+
+ return null;
+ }
+
+ boolean matchOwner(UndoOwner owner) {
+ for (int i=mOperations.size()-1; i>=0; i--) {
+ if (mOperations.get(i).matchOwner(owner)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ boolean hasData() {
+ for (int i=mOperations.size()-1; i>=0; i--) {
+ if (mOperations.get(i).hasData()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ void commit() {
+ final int N = mRecent != null ? mRecent.size() : 0;
+ for (int i=0; i<N; i++) {
+ mRecent.get(i).commit();
+ }
+ mRecent = null;
+ }
+
+ void undo() {
+ for (int i=mOperations.size()-1; i>=0; i--) {
+ mOperations.get(i).undo();
+ }
+ }
+
+ void redo() {
+ final int N = mOperations.size();
+ for (int i=0; i<N; i++) {
+ mOperations.get(i).redo();
+ }
+ }
+
+ void destroy() {
+ for (int i=mOperations.size()-1; i>=0; i--) {
+ UndoOwner owner = mOperations.get(i).mOwner;
+ owner.mOpCount--;
+ if (owner.mOpCount <= 0) {
+ if (owner.mOpCount < 0) {
+ throw new IllegalStateException("Underflow of op count on owner " + owner
+ + " in op " + mOperations.get(i));
+ }
+ mManager.removeOwner(owner);
+ }
+ }
+ }
+ }
+}
diff --git a/core/java/android/content/UndoOperation.java b/core/java/android/content/UndoOperation.java
new file mode 100644
index 0000000..8084b1f
--- /dev/null
+++ b/core/java/android/content/UndoOperation.java
@@ -0,0 +1,110 @@
+/*
+ * 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 android.content;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * A single undoable operation. You must subclass this to implement the state
+ * and behavior for your operation. Instances of this class are placed and
+ * managed in an {@link UndoManager}.
+ */
+public abstract class UndoOperation<DATA> implements Parcelable {
+ UndoOwner mOwner;
+
+ /**
+ * Create a new instance of the operation.
+ * @param owner Who owns the data being modified by this undo state; must be
+ * returned by {@link UndoManager#getOwner(String, Object) UndoManager.getOwner}.
+ */
+ public UndoOperation(UndoOwner owner) {
+ mOwner = owner;
+ }
+
+ /**
+ * Construct from a Parcel.
+ */
+ protected UndoOperation(Parcel src, ClassLoader loader) {
+ }
+
+ /**
+ * Owning object as given to {@link #UndoOperation(UndoOwner)}.
+ */
+ public UndoOwner getOwner() {
+ return mOwner;
+ }
+
+ /**
+ * Synonym for {@link #getOwner()}.{@link android.content.UndoOwner#getData()}.
+ */
+ public DATA getOwnerData() {
+ return (DATA)mOwner.getData();
+ }
+
+ /**
+ * Return true if this undo operation is a member of the given owner.
+ * The default implementation is <code>owner == getOwner()</code>. You
+ * can override this to provide more sophisticated dependencies between
+ * owners.
+ */
+ public boolean matchOwner(UndoOwner owner) {
+ return owner == getOwner();
+ }
+
+ /**
+ * Return true if this operation actually contains modification data. The
+ * default implementation always returns true. If you return false, the
+ * operation will be dropped when the final undo state is being built.
+ */
+ public boolean hasData() {
+ return true;
+ }
+
+ /**
+ * Return true if this operation can be merged with a later operation.
+ * The default implementation always returns true.
+ */
+ public boolean allowMerge() {
+ return true;
+ }
+
+ /**
+ * Called when this undo state is being committed to the undo stack.
+ * The implementation should perform the initial edits and save any state that
+ * may be needed to undo them.
+ */
+ public abstract void commit();
+
+ /**
+ * Called when this undo state is being popped off the undo stack (in to
+ * the temporary redo stack). The implementation should remove the original
+ * edits and thus restore the target object to its prior value.
+ */
+ public abstract void undo();
+
+ /**
+ * Called when this undo state is being pushed back from the transient
+ * redo stack to the main undo stack. The implementation should re-apply
+ * the edits that were previously removed by {@link #undo}.
+ */
+ public abstract void redo();
+
+ public int describeContents() {
+ return 0;
+ }
+}
diff --git a/core/java/android/content/UndoOwner.java b/core/java/android/content/UndoOwner.java
new file mode 100644
index 0000000..a279de6
--- /dev/null
+++ b/core/java/android/content/UndoOwner.java
@@ -0,0 +1,55 @@
+/*
+ * 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 android.content;
+
+/**
+ * Representation of an owner of {@link UndoOperation} objects in an {@link UndoManager}.
+ */
+public class UndoOwner {
+ final String mTag;
+
+ UndoManager mManager;
+ Object mData;
+ int mOpCount;
+
+ // For saving/restoring state.
+ int mStateSeq;
+ int mSavedIdx;
+
+ UndoOwner(String tag) {
+ mTag = tag;
+ }
+
+ /**
+ * Return the unique tag name identifying this owner. This is the tag
+ * supplied to {@link UndoManager#getOwner(String, Object) UndoManager.getOwner}
+ * and is immutable.
+ */
+ public String getTag() {
+ return mTag;
+ }
+
+ /**
+ * Return the actual data object of the owner. This is the data object
+ * supplied to {@link UndoManager#getOwner(String, Object) UndoManager.getOwner}. An
+ * owner may have a null data if it was restored from a previously saved state with
+ * no getOwner call to associate it with its data.
+ */
+ public Object getData() {
+ return mData;
+ }
+}
diff --git a/core/java/android/content/pm/ComponentInfo.java b/core/java/android/content/pm/ComponentInfo.java
index 2812477..4dbcf23 100644
--- a/core/java/android/content/pm/ComponentInfo.java
+++ b/core/java/android/content/pm/ComponentInfo.java
@@ -116,6 +116,17 @@ public class ComponentInfo extends PackageItemInfo {
public final int getIconResource() {
return icon != 0 ? icon : applicationInfo.icon;
}
+
+ /**
+ * Return the logo resource identifier to use for this component. If
+ * the component defines a logo, that is used; else, the application
+ * logo is used.
+ *
+ * @return The logo associated with this component.
+ */
+ public final int getLogoResource() {
+ return logo != 0 ? logo : applicationInfo.logo;
+ }
protected void dumpFront(Printer pw, String prefix) {
super.dumpFront(pw, prefix);
diff --git a/core/java/android/content/pm/KeySet.java b/core/java/android/content/pm/KeySet.java
new file mode 100644
index 0000000..0ef09a4
--- /dev/null
+++ b/core/java/android/content/pm/KeySet.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.content.pm;
+
+import android.os.Binder;
+
+/** @hide */
+public class KeySet {
+
+ private Binder token;
+
+ /** @hide */
+ public KeySet(Binder token) {
+ this.token = token;
+ }
+
+ Binder getToken() {
+ return token;
+ }
+} \ No newline at end of file
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 34e0c12..1b997f0 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -45,14 +45,20 @@ import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.security.cert.Certificate;
import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.CertPath;
+import java.security.cert.X509Certificate;
import java.security.spec.EncodedKeySpec;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.X509EncodedKeySpec;
import java.util.ArrayList;
import java.util.Enumeration;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
+import java.util.Map;
+import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.zip.ZipEntry;
@@ -714,6 +720,13 @@ public class PackageParser {
mParseError = PackageManager.INSTALL_PARSE_FAILED_NO_CERTIFICATES;
return false;
}
+
+ // Add the signing KeySet to the system
+ pkg.mSigningKeys = new HashSet<PublicKey>();
+ for (int i=0; i < certs.length; i++) {
+ pkg.mSigningKeys.add(certs[i].getPublicKey());
+ }
+
} catch (CertificateEncodingException e) {
Slog.w(TAG, "Exception reading " + mArchiveSourcePath, e);
mParseError = PackageManager.INSTALL_PARSE_FAILED_CERTIFICATE_ENCODING;
@@ -1027,6 +1040,10 @@ public class PackageParser {
if (!parseApplication(pkg, res, parser, attrs, flags, outError)) {
return null;
}
+ } else if (tagName.equals("keys")) {
+ if (!parseKeys(pkg, res, parser, attrs, outError)) {
+ return null;
+ }
} else if (tagName.equals("permission-group")) {
if (parsePermissionGroup(pkg, flags, res, parser, attrs, outError) == null) {
return null;
@@ -1519,7 +1536,71 @@ public class PackageParser {
}
return buildCompoundName(pkg, procSeq, "taskAffinity", outError);
}
-
+
+ private boolean parseKeys(Package owner, Resources res,
+ XmlPullParser parser, AttributeSet attrs, String[] outError)
+ throws XmlPullParserException, IOException {
+ // we've encountered the 'keys' tag
+ // all the keys and keysets that we want must be defined here
+ // so we're going to iterate over the parser and pull out the things we want
+ int outerDepth = parser.getDepth();
+
+ int type;
+ PublicKey currentKey = null;
+ Map<PublicKey, Set<String>> definedKeySets = new HashMap<PublicKey, Set<String>>();
+ while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
+ && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
+ if (type == XmlPullParser.END_TAG) {
+ continue;
+ }
+ String tagname = parser.getName();
+ if (tagname.equals("publicKey")) {
+ final TypedArray sa = res.obtainAttributes(attrs,
+ com.android.internal.R.styleable.PublicKey);
+ final String encodedKey = sa.getNonResourceString(
+ com.android.internal.R.styleable.PublicKey_value);
+ currentKey = parsePublicKey(encodedKey);
+ definedKeySets.put(currentKey, new HashSet<String>());
+ sa.recycle();
+ } else if (tagname.equals("keyset")) {
+ final TypedArray sa = res.obtainAttributes(attrs,
+ com.android.internal.R.styleable.KeySet);
+ final String name = sa.getNonResourceString(
+ com.android.internal.R.styleable.KeySet_name);
+ definedKeySets.get(currentKey).add(name);
+ sa.recycle();
+ } else if (RIGID_PARSER) {
+ Slog.w(TAG, "Bad element under <keys>: " + parser.getName()
+ + " at " + mArchiveSourcePath + " "
+ + parser.getPositionDescription());
+ return false;
+ } else {
+ Slog.w(TAG, "Unknown element under <keys>: " + parser.getName()
+ + " at " + mArchiveSourcePath + " "
+ + parser.getPositionDescription());
+ XmlUtils.skipCurrentTag(parser);
+ continue;
+ }
+ }
+
+ owner.mKeySetMapping = new HashMap<String, Set<PublicKey>>();
+ for (Map.Entry<PublicKey, Set<String>> e : definedKeySets.entrySet()) {
+ PublicKey key = e.getKey();
+ Set<String> keySetNames = e.getValue();
+ for (String alias : keySetNames) {
+ if (owner.mKeySetMapping.containsKey(alias)) {
+ owner.mKeySetMapping.get(alias).add(key);
+ } else {
+ Set<PublicKey> keys = new HashSet<PublicKey>();
+ keys.add(key);
+ owner.mKeySetMapping.put(alias, keys);
+ }
+ }
+ }
+
+ return true;
+ }
+
private PermissionGroup parsePermissionGroup(Package owner, int flags, Resources res,
XmlPullParser parser, AttributeSet attrs, String[] outError)
throws XmlPullParserException, IOException {
@@ -3083,20 +3164,28 @@ public class PackageParser {
Slog.i(TAG, "verifier " + packageName + " public key was null; skipping");
}
+ PublicKey publicKey = parsePublicKey(encodedPublicKey);
+ if (publicKey != null) {
+ return new VerifierInfo(packageName, publicKey);
+ }
+
+ return null;
+ }
+
+ public static final PublicKey parsePublicKey(String encodedPublicKey) {
EncodedKeySpec keySpec;
try {
final byte[] encoded = Base64.decode(encodedPublicKey, Base64.DEFAULT);
keySpec = new X509EncodedKeySpec(encoded);
} catch (IllegalArgumentException e) {
- Slog.i(TAG, "Could not parse verifier " + packageName + " public key; invalid Base64");
+ Slog.i(TAG, "Could not parse verifier public key; invalid Base64");
return null;
}
/* First try the key as an RSA key. */
try {
final KeyFactory keyFactory = KeyFactory.getInstance("RSA");
- final PublicKey publicKey = keyFactory.generatePublic(keySpec);
- return new VerifierInfo(packageName, publicKey);
+ return keyFactory.generatePublic(keySpec);
} catch (NoSuchAlgorithmException e) {
Log.wtf(TAG, "Could not parse public key because RSA isn't included in build");
return null;
@@ -3107,8 +3196,7 @@ public class PackageParser {
/* Now try it as a DSA key. */
try {
final KeyFactory keyFactory = KeyFactory.getInstance("DSA");
- final PublicKey publicKey = keyFactory.generatePublic(keySpec);
- return new VerifierInfo(packageName, publicKey);
+ return keyFactory.generatePublic(keySpec);
} catch (NoSuchAlgorithmException e) {
Log.wtf(TAG, "Could not parse public key because DSA isn't included in build");
return null;
@@ -3360,6 +3448,12 @@ public class PackageParser {
*/
public ManifestDigest manifestDigest;
+ /**
+ * Data used to feed the KeySetManager
+ */
+ public Set<PublicKey> mSigningKeys;
+ public Map<String, Set<PublicKey>> mKeySetMapping;
+
public Package(String _name) {
packageName = _name;
applicationInfo.packageName = _name;
diff --git a/core/java/android/content/pm/RegisteredServicesCache.java b/core/java/android/content/pm/RegisteredServicesCache.java
index 288d55f..875e8de 100644
--- a/core/java/android/content/pm/RegisteredServicesCache.java
+++ b/core/java/android/content/pm/RegisteredServicesCache.java
@@ -82,7 +82,7 @@ public abstract class RegisteredServicesCache<V> {
@GuardedBy("mServicesLock")
private boolean mPersistentServicesFileDidNotExist;
@GuardedBy("mServicesLock")
- private final SparseArray<UserServices<V>> mUserServices = new SparseArray<UserServices<V>>();
+ private final SparseArray<UserServices<V>> mUserServices = new SparseArray<UserServices<V>>(2);
private static class UserServices<V> {
@GuardedBy("mServicesLock")
diff --git a/core/java/android/content/pm/ResolveInfo.java b/core/java/android/content/pm/ResolveInfo.java
index 07117fe..de8e256 100644
--- a/core/java/android/content/pm/ResolveInfo.java
+++ b/core/java/android/content/pm/ResolveInfo.java
@@ -328,6 +328,7 @@ public class ResolveInfo implements Parcelable {
implements Comparator<ResolveInfo> {
public DisplayNameComparator(PackageManager pm) {
mPM = pm;
+ mCollator.setStrength(Collator.PRIMARY);
}
public final int compare(ResolveInfo a, ResolveInfo b) {
@@ -336,10 +337,10 @@ public class ResolveInfo implements Parcelable {
CharSequence sb = b.loadLabel(mPM);
if (sb == null) sb = b.activityInfo.name;
- return sCollator.compare(sa.toString(), sb.toString());
+ return mCollator.compare(sa.toString(), sb.toString());
}
- private final Collator sCollator = Collator.getInstance();
+ private final Collator mCollator = Collator.getInstance();
private PackageManager mPM;
}
}
diff --git a/core/java/android/content/res/AssetFileDescriptor.java b/core/java/android/content/res/AssetFileDescriptor.java
index 7d46710..e4cc77f 100644
--- a/core/java/android/content/res/AssetFileDescriptor.java
+++ b/core/java/android/content/res/AssetFileDescriptor.java
@@ -20,6 +20,7 @@ import android.os.Parcel;
import android.os.ParcelFileDescriptor;
import android.os.Parcelable;
+import java.io.Closeable;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileOutputStream;
@@ -30,7 +31,7 @@ import java.io.IOException;
* opened FileDescriptor that can be used to read the data, as well as the
* offset and length of that entry's data in the file.
*/
-public class AssetFileDescriptor implements Parcelable {
+public class AssetFileDescriptor implements Parcelable, Closeable {
/**
* Length used with {@link #AssetFileDescriptor(ParcelFileDescriptor, long, long)}
* and {@link #getDeclaredLength} when a length has not been declared. This means
@@ -122,6 +123,7 @@ public class AssetFileDescriptor implements Parcelable {
/**
* Convenience for calling <code>getParcelFileDescriptor().close()</code>.
*/
+ @Override
public void close() throws IOException {
mFd.close();
}
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
index 42f4faf..cff974d 100644
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -16,8 +16,6 @@
package android.content.res;
-import android.os.Trace;
-import android.view.View;
import com.android.internal.util.XmlUtils;
import org.xmlpull.v1.XmlPullParser;
@@ -30,6 +28,7 @@ import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable.ConstantState;
import android.os.Build;
import android.os.Bundle;
+import android.os.Trace;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
@@ -100,11 +99,11 @@ public class Resources {
/*package*/ final Configuration mTmpConfig = new Configuration();
/*package*/ TypedValue mTmpValue = new TypedValue();
/*package*/ final LongSparseArray<WeakReference<Drawable.ConstantState> > mDrawableCache
- = new LongSparseArray<WeakReference<Drawable.ConstantState> >();
+ = new LongSparseArray<WeakReference<Drawable.ConstantState> >(0);
/*package*/ final LongSparseArray<WeakReference<ColorStateList> > mColorStateListCache
- = new LongSparseArray<WeakReference<ColorStateList> >();
+ = new LongSparseArray<WeakReference<ColorStateList> >(0);
/*package*/ final LongSparseArray<WeakReference<Drawable.ConstantState> > mColorDrawableCache
- = new LongSparseArray<WeakReference<Drawable.ConstantState> >();
+ = new LongSparseArray<WeakReference<Drawable.ConstantState> >(0);
/*package*/ boolean mPreloading;
/*package*/ TypedArray mCachedStyledAttributes = null;
@@ -1985,6 +1984,13 @@ public class Resources {
}
}
+ /**
+ * @hide
+ */
+ public LongSparseArray<Drawable.ConstantState> getPreloadedDrawables() {
+ return sPreloadedDrawables[0];
+ }
+
private boolean verifyPreloadConfig(int changingConfigurations, int allowVarying,
int resourceId, String name) {
// We allow preloading of resources even if they vary by font scale (which
diff --git a/core/java/android/database/AbstractCursor.java b/core/java/android/database/AbstractCursor.java
index 300b4d1..b5b89dd 100644
--- a/core/java/android/database/AbstractCursor.java
+++ b/core/java/android/database/AbstractCursor.java
@@ -369,7 +369,9 @@ public abstract class AbstractCursor implements CrossProcessCursor {
}
public Uri getNotificationUri() {
- return mNotifyUri;
+ synchronized (mSelfObserverLock) {
+ return mNotifyUri;
+ }
}
public boolean getWantsAllOnMoveCalls() {
diff --git a/core/java/android/database/Cursor.java b/core/java/android/database/Cursor.java
index 907833d..7381e2c 100644
--- a/core/java/android/database/Cursor.java
+++ b/core/java/android/database/Cursor.java
@@ -425,6 +425,16 @@ public interface Cursor extends Closeable {
void setNotificationUri(ContentResolver cr, Uri uri);
/**
+ * Return the URI at which notifications of changes in this Cursor's data
+ * will be delivered, as previously set by {@link #setNotificationUri}.
+ * @return Returns a URI that can be used with
+ * {@link ContentResolver#registerContentObserver(android.net.Uri, boolean, ContentObserver)
+ * ContentResolver.registerContentObserver} to find out about changes to this Cursor's
+ * data. May be null if no notification URI has been set.
+ */
+ Uri getNotificationUri();
+
+ /**
* onMove() will only be called across processes if this method returns true.
* @return whether all cursor movement should result in a call to onMove().
*/
diff --git a/core/java/android/database/CursorWrapper.java b/core/java/android/database/CursorWrapper.java
index 7baeb8c..d8fcb17 100644
--- a/core/java/android/database/CursorWrapper.java
+++ b/core/java/android/database/CursorWrapper.java
@@ -194,6 +194,10 @@ public class CursorWrapper implements Cursor {
mCursor.setNotificationUri(cr, uri);
}
+ public Uri getNotificationUri() {
+ return mCursor.getNotificationUri();
+ }
+
public void unregisterContentObserver(ContentObserver observer) {
mCursor.unregisterContentObserver(observer);
}
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index 4e51080..ac42b76 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -31,6 +31,11 @@ import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.renderscript.Allocation;
+import android.renderscript.Element;
+import android.renderscript.RenderScript;
+import android.renderscript.RSIllegalArgumentException;
+import android.renderscript.Type;
import android.util.Log;
import android.text.TextUtils;
import android.view.Surface;
@@ -152,6 +157,7 @@ public class Camera {
private PictureCallback mRawImageCallback;
private PictureCallback mJpegCallback;
private PreviewCallback mPreviewCallback;
+ private boolean mUsingPreviewAllocation;
private PictureCallback mPostviewCallback;
private AutoFocusCallback mAutoFocusCallback;
private AutoFocusMoveCallback mAutoFocusMoveCallback;
@@ -327,6 +333,7 @@ public class Camera {
mJpegCallback = null;
mPreviewCallback = null;
mPostviewCallback = null;
+ mUsingPreviewAllocation = false;
mZoomListener = null;
Looper looper;
@@ -587,6 +594,9 @@ public class Camera {
mPreviewCallback = cb;
mOneShot = false;
mWithBuffer = false;
+ if (cb != null) {
+ mUsingPreviewAllocation = false;
+ }
// Always use one-shot mode. We fake camera preview mode by
// doing one-shot preview continuously.
setHasPreviewCallback(cb != null, false);
@@ -610,6 +620,9 @@ public class Camera {
mPreviewCallback = cb;
mOneShot = true;
mWithBuffer = false;
+ if (cb != null) {
+ mUsingPreviewAllocation = false;
+ }
setHasPreviewCallback(cb != null, false);
}
@@ -645,6 +658,9 @@ public class Camera {
mPreviewCallback = cb;
mOneShot = false;
mWithBuffer = true;
+ if (cb != null) {
+ mUsingPreviewAllocation = false;
+ }
setHasPreviewCallback(cb != null, true);
}
@@ -744,6 +760,134 @@ public class Camera {
private native final void _addCallbackBuffer(
byte[] callbackBuffer, int msgType);
+ /**
+ * <p>Create a {@link android.renderscript RenderScript}
+ * {@link android.renderscript.Allocation Allocation} to use as a
+ * destination of preview callback frames. Use
+ * {@link #setPreviewCallbackAllocation setPreviewCallbackAllocation} to use
+ * the created Allocation as a destination for camera preview frames.</p>
+ *
+ * <p>The Allocation will be created with a YUV type, and its contents must
+ * be accessed within Renderscript with the {@code rsGetElementAtYuv_*}
+ * accessor methods. Its size will be based on the current
+ * {@link Parameters#getPreviewSize preview size} configured for this
+ * camera.</p>
+ *
+ * @param rs the RenderScript context for this Allocation.
+ * @param usage additional usage flags to set for the Allocation. The usage
+ * flag {@link android.renderscript.Allocation#USAGE_IO_INPUT} will always
+ * be set on the created Allocation, but additional flags may be provided
+ * here.
+ * @return a new YUV-type Allocation with dimensions equal to the current
+ * preview size.
+ * @throws RSIllegalArgumentException if the usage flags are not compatible
+ * with an YUV Allocation.
+ * @see #setPreviewCallbackAllocation
+ * @hide
+ */
+ public final Allocation createPreviewAllocation(RenderScript rs, int usage)
+ throws RSIllegalArgumentException {
+ Parameters p = getParameters();
+ Size previewSize = p.getPreviewSize();
+ Type.Builder yuvBuilder = new Type.Builder(rs,
+ Element.createPixel(rs,
+ Element.DataType.UNSIGNED_8,
+ Element.DataKind.PIXEL_YUV));
+ // Use YV12 for wide compatibility. Changing this requires also
+ // adjusting camera service's format selection.
+ yuvBuilder.setYuvFormat(ImageFormat.YV12);
+ yuvBuilder.setX(previewSize.width);
+ yuvBuilder.setY(previewSize.height);
+
+ Allocation a = Allocation.createTyped(rs, yuvBuilder.create(),
+ usage | Allocation.USAGE_IO_INPUT);
+
+ return a;
+ }
+
+ /**
+ * <p>Set an {@link android.renderscript.Allocation Allocation} as the
+ * target of preview callback data. Use this method for efficient processing
+ * of camera preview data with RenderScript. The Allocation must be created
+ * with the {@link #createPreviewAllocation createPreviewAllocation }
+ * method.</p>
+ *
+ * <p>Setting a preview allocation will disable any active preview callbacks
+ * set by {@link #setPreviewCallback setPreviewCallback} or
+ * {@link #setPreviewCallbackWithBuffer setPreviewCallbackWithBuffer}, and
+ * vice versa. Using a preview allocation still requires an active standard
+ * preview target to be set, either with
+ * {@link #setPreviewTexture setPreviewTexture} or
+ * {@link #setPreviewDisplay setPreviewDisplay}.</p>
+ *
+ * <p>To be notified when new frames are available to the Allocation, use
+ * {@link android.renderscript.Allocation#setIoInputNotificationHandler Allocation.setIoInputNotificationHandler}. To
+ * update the frame currently accessible from the Allocation to the latest
+ * preview frame, call
+ * {@link android.renderscript.Allocation#ioReceive Allocation.ioReceive}.</p>
+ *
+ * <p>To disable preview into the Allocation, call this method with a
+ * {@code null} parameter.</p>
+ *
+ * <p>Once a preview allocation is set, the preview size set by
+ * {@link Parameters#setPreviewSize setPreviewSize} cannot be changed. If
+ * you wish to change the preview size, first remove the preview allocation
+ * by calling {@code setPreviewCallbackAllocation(null)}, then change the
+ * preview size, create a new preview Allocation with
+ * {@link #createPreviewAllocation createPreviewAllocation}, and set it as
+ * the new preview callback allocation target.</p>
+ *
+ * <p>If you are using the preview data to create video or still images,
+ * strongly consider using {@link android.media.MediaActionSound} to
+ * properly indicate image capture or recording start/stop to the user.</p>
+ *
+ * @param previewAllocation the allocation to use as destination for preview
+ * @throws IOException if configuring the camera to use the Allocation for
+ * preview fails.
+ * @throws IllegalArgumentException if the Allocation's dimensions or other
+ * parameters don't meet the requirements.
+ * @see #createPreviewAllocation
+ * @see #setPreviewCallback
+ * @see #setPreviewCallbackWithBuffer
+ * @hide
+ */
+ public final void setPreviewCallbackAllocation(Allocation previewAllocation)
+ throws IOException {
+ Surface previewSurface = null;
+ if (previewAllocation != null) {
+ Parameters p = getParameters();
+ Size previewSize = p.getPreviewSize();
+ if (previewSize.width != previewAllocation.getType().getX() ||
+ previewSize.height != previewAllocation.getType().getY()) {
+ throw new IllegalArgumentException(
+ "Allocation dimensions don't match preview dimensions: " +
+ "Allocation is " +
+ previewAllocation.getType().getX() +
+ ", " +
+ previewAllocation.getType().getY() +
+ ". Preview is " + previewSize.width + ", " +
+ previewSize.height);
+ }
+ if ((previewAllocation.getUsage() &
+ Allocation.USAGE_IO_INPUT) == 0) {
+ throw new IllegalArgumentException(
+ "Allocation usage does not include USAGE_IO_INPUT");
+ }
+ if (previewAllocation.getType().getElement().getDataKind() !=
+ Element.DataKind.PIXEL_YUV) {
+ throw new IllegalArgumentException(
+ "Allocation is not of a YUV type");
+ }
+ previewSurface = previewAllocation.getSurface();
+ mUsingPreviewAllocation = true;
+ } else {
+ mUsingPreviewAllocation = false;
+ }
+ setPreviewCallbackSurface(previewSurface);
+ }
+
+ private native final void setPreviewCallbackSurface(Surface s);
+
private class EventHandler extends Handler
{
private Camera mCamera;
@@ -1492,6 +1636,17 @@ public class Camera {
* @see #getParameters()
*/
public void setParameters(Parameters params) {
+ // If using preview allocations, don't allow preview size changes
+ if (mUsingPreviewAllocation) {
+ Size newPreviewSize = params.getPreviewSize();
+ Size currentPreviewSize = getParameters().getPreviewSize();
+ if (newPreviewSize.width != currentPreviewSize.width ||
+ newPreviewSize.height != currentPreviewSize.height) {
+ throw new IllegalStateException("Cannot change preview size" +
+ " while a preview allocation is configured.");
+ }
+ }
+
native_setParameters(params.flatten());
}
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index 4881d14..7f82ce3 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -381,7 +381,6 @@ public class InputMethodService extends AbstractInputMethodService {
if (DEBUG) Log.v(TAG, "unbindInput(): binding=" + mInputBinding
+ " ic=" + mInputConnection);
onUnbindInput();
- mInputStarted = false;
mInputBinding = null;
mInputConnection = null;
}
@@ -719,7 +718,7 @@ public class InputMethodService extends AbstractInputMethodService {
super.onDestroy();
mRootView.getViewTreeObserver().removeOnComputeInternalInsetsListener(
mInsetsComputer);
- finishViews();
+ doFinishInput();
if (mWindowAdded) {
// Disable exit animation for the current IME window
// to avoid the race condition between the exit and enter animations
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index 499ec77..d0f7511 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -98,6 +98,11 @@ public abstract class BatteryStats implements Parcelable {
public static final int VIBRATOR_ON = 9;
/**
+ * A constant indicating a foreground activity timer
+ */
+ public static final int FOREGROUND_ACTIVITY = 10;
+
+ /**
* Include all of the data in the stats, including previously saved data.
*/
public static final int STATS_SINCE_CHARGED = 0;
@@ -125,7 +130,7 @@ public abstract class BatteryStats implements Parcelable {
/**
* Bump the version on this if the checkin format changes.
*/
- private static final int BATTERY_STATS_CHECKIN_VERSION = 5;
+ private static final int BATTERY_STATS_CHECKIN_VERSION = 6;
private static final long BYTES_PER_KB = 1024;
private static final long BYTES_PER_MB = 1048576; // 1024^2
@@ -137,6 +142,7 @@ public abstract class BatteryStats implements Parcelable {
private static final String PROCESS_DATA = "pr";
private static final String SENSOR_DATA = "sr";
private static final String VIBRATOR_DATA = "vib";
+ private static final String FOREGROUND_DATA = "fg";
private static final String WAKELOCK_DATA = "wl";
private static final String KERNEL_WAKELOCK_DATA = "kwl";
private static final String NETWORK_DATA = "nt";
@@ -276,6 +282,8 @@ public abstract class BatteryStats implements Parcelable {
public abstract void noteAudioTurnedOffLocked();
public abstract void noteVideoTurnedOnLocked();
public abstract void noteVideoTurnedOffLocked();
+ public abstract void noteActivityResumedLocked();
+ public abstract void noteActivityPausedLocked();
public abstract long getWifiRunningTime(long batteryRealtime, int which);
public abstract long getFullWifiLockTime(long batteryRealtime, int which);
public abstract long getWifiScanTime(long batteryRealtime, int which);
@@ -283,6 +291,7 @@ public abstract class BatteryStats implements Parcelable {
int which);
public abstract long getAudioTurnedOnTime(long batteryRealtime, int which);
public abstract long getVideoTurnedOnTime(long batteryRealtime, int which);
+ public abstract Timer getForegroundActivityTimer();
public abstract Timer getVibratorOnTimer();
/**
@@ -1229,7 +1238,7 @@ public abstract class BatteryStats implements Parcelable {
final int NU = uidStats.size();
String category = STAT_NAMES[which];
-
+
// Dump "battery" stat
dumpLine(pw, 0 /* uid */, category, BATTERY_DATA,
which == STATS_SINCE_CHARGED ? getStartCount() : "N/A",
@@ -1417,22 +1426,31 @@ public abstract class BatteryStats implements Parcelable {
}
}
+ Timer fgTimer = u.getForegroundActivityTimer();
+ if (fgTimer != null) {
+ // Convert from microseconds to milliseconds with rounding
+ long totalTime = (fgTimer.getTotalTimeLocked(batteryRealtime, which) + 500) / 1000;
+ int count = fgTimer.getCountLocked(which);
+ if (totalTime != 0) {
+ dumpLine(pw, uid, category, FOREGROUND_DATA, totalTime, count);
+ }
+ }
+
Map<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats();
if (processStats.size() > 0) {
for (Map.Entry<String, ? extends BatteryStats.Uid.Proc> ent
: processStats.entrySet()) {
Uid.Proc ps = ent.getValue();
-
- long userTime = ps.getUserTime(which);
- long systemTime = ps.getSystemTime(which);
- int starts = ps.getStarts(which);
-
- if (userTime != 0 || systemTime != 0 || starts != 0) {
- dumpLine(pw, uid, category, PROCESS_DATA,
- ent.getKey(), // proc
- userTime * 10, // cpu time in ms
- systemTime * 10, // user time in ms
- starts); // process starts
+
+ final long userMillis = ps.getUserTime(which) * 10;
+ final long systemMillis = ps.getSystemTime(which) * 10;
+ final long foregroundMillis = ps.getForegroundTime(which) * 10;
+ final long starts = ps.getStarts(which);
+
+ if (userMillis != 0 || systemMillis != 0 || foregroundMillis != 0
+ || starts != 0) {
+ dumpLine(pw, uid, category, PROCESS_DATA, ent.getKey(), userMillis,
+ systemMillis, foregroundMillis, starts);
}
}
}
@@ -1961,6 +1979,24 @@ public abstract class BatteryStats implements Parcelable {
}
}
+ Timer fgTimer = u.getForegroundActivityTimer();
+ if (fgTimer != null) {
+ // Convert from microseconds to milliseconds with rounding
+ long totalTime = (fgTimer.getTotalTimeLocked(batteryRealtime, which) + 500) / 1000;
+ int count = fgTimer.getCountLocked(which);
+ if (totalTime != 0) {
+ sb.setLength(0);
+ sb.append(prefix);
+ sb.append(" Foreground activities: ");
+ formatTimeMs(sb, totalTime);
+ sb.append("realtime (");
+ sb.append(count);
+ sb.append(" times)");
+ pw.println(sb.toString());
+ uidActivity = true;
+ }
+ }
+
Map<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats();
if (processStats.size() > 0) {
for (Map.Entry<String, ? extends BatteryStats.Uid.Proc> ent
@@ -1968,23 +2004,26 @@ public abstract class BatteryStats implements Parcelable {
Uid.Proc ps = ent.getValue();
long userTime;
long systemTime;
+ long foregroundTime;
int starts;
int numExcessive;
userTime = ps.getUserTime(which);
systemTime = ps.getSystemTime(which);
+ foregroundTime = ps.getForegroundTime(which);
starts = ps.getStarts(which);
numExcessive = which == STATS_SINCE_CHARGED
? ps.countExcessivePowers() : 0;
- if (userTime != 0 || systemTime != 0 || starts != 0
+ if (userTime != 0 || systemTime != 0 || foregroundTime != 0 || starts != 0
|| numExcessive != 0) {
sb.setLength(0);
sb.append(prefix); sb.append(" Proc ");
sb.append(ent.getKey()); sb.append(":\n");
sb.append(prefix); sb.append(" CPU: ");
formatTime(sb, userTime); sb.append("usr + ");
- formatTime(sb, systemTime); sb.append("krn");
+ formatTime(sb, systemTime); sb.append("krn ; ");
+ formatTime(sb, foregroundTime); sb.append("fg");
if (starts != 0) {
sb.append("\n"); sb.append(prefix); sb.append(" ");
sb.append(starts); sb.append(" proc starts");
@@ -2042,7 +2081,7 @@ public abstract class BatteryStats implements Parcelable {
sb.append(sent.getKey()); sb.append(":\n");
sb.append(prefix); sb.append(" Created for: ");
formatTimeMs(sb, startTime / 1000);
- sb.append(" uptime\n");
+ sb.append("uptime\n");
sb.append(prefix); sb.append(" Starts: ");
sb.append(starts);
sb.append(", launches: "); sb.append(launches);
@@ -2215,7 +2254,7 @@ public abstract class BatteryStats implements Parcelable {
* @param pw a Printer to receive the dump output.
*/
@SuppressWarnings("unused")
- public void dumpLocked(PrintWriter pw) {
+ public void dumpLocked(PrintWriter pw, boolean isUnpluggedOnly) {
prepareForDumpLocked();
long now = getHistoryBaseTime() + SystemClock.elapsedRealtime();
@@ -2267,28 +2306,22 @@ public abstract class BatteryStats implements Parcelable {
if (didPid) {
pw.println("");
}
-
- pw.println("Statistics since last charge:");
- pw.println(" System starts: " + getStartCount()
- + ", currently on battery: " + getIsOnBattery());
- dumpLocked(pw, "", STATS_SINCE_CHARGED, -1);
- pw.println("");
+
+ if (!isUnpluggedOnly) {
+ pw.println("Statistics since last charge:");
+ pw.println(" System starts: " + getStartCount()
+ + ", currently on battery: " + getIsOnBattery());
+ dumpLocked(pw, "", STATS_SINCE_CHARGED, -1);
+ pw.println("");
+ }
pw.println("Statistics since last unplugged:");
dumpLocked(pw, "", STATS_SINCE_UNPLUGGED, -1);
}
@SuppressWarnings("unused")
- public void dumpCheckinLocked(PrintWriter pw, String[] args, List<ApplicationInfo> apps) {
+ public void dumpCheckinLocked(
+ PrintWriter pw, List<ApplicationInfo> apps, boolean isUnpluggedOnly) {
prepareForDumpLocked();
-
- boolean isUnpluggedOnly = false;
-
- for (String arg : args) {
- if ("-u".equals(arg)) {
- if (LOCAL_LOGV) Log.v("BatteryStats", "Dumping unplugged data");
- isUnpluggedOnly = true;
- }
- }
if (apps != null) {
SparseArray<ArrayList<String>> uids = new SparseArray<ArrayList<String>>();
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index 6c9f2d1..71c3e4a 100644
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -436,6 +436,11 @@ public class Build {
* Android 4.3: Jelly Bean MR2, the revenge of the beans.
*/
public static final int JELLY_BEAN_MR2 = 18;
+
+ /**
+ * Android X.X: Key Lime Pie, another tasty treat.
+ */
+ public static final int KEY_LIME_PIE = CUR_DEVELOPMENT;
}
/** The type of build, like "user" or "eng". */
diff --git a/core/java/android/os/Debug.java b/core/java/android/os/Debug.java
index fd01da9..362ae29 100644
--- a/core/java/android/os/Debug.java
+++ b/core/java/android/os/Debug.java
@@ -108,31 +108,78 @@ public final class Debug
* process. The returns info broken down by dalvik, native, and other. All results are in kB.
*/
public static class MemoryInfo implements Parcelable {
- /** The proportional set size for dalvik. */
+ /** The proportional set size for dalvik heap. (Doesn't include other Dalvik overhead.) */
public int dalvikPss;
- /** The private dirty pages used by dalvik. */
+ /** The proportional set size that is swappable for dalvik heap. */
+ /** @hide We may want to expose this, eventually. */
+ public int dalvikSwappablePss;
+ /** The private dirty pages used by dalvik heap. */
public int dalvikPrivateDirty;
- /** The shared dirty pages used by dalvik. */
+ /** The shared dirty pages used by dalvik heap. */
public int dalvikSharedDirty;
+ /** The private clean pages used by dalvik heap. */
+ /** @hide We may want to expose this, eventually. */
+ public int dalvikPrivateClean;
+ /** The shared clean pages used by dalvik heap. */
+ /** @hide We may want to expose this, eventually. */
+ public int dalvikSharedClean;
/** The proportional set size for the native heap. */
public int nativePss;
+ /** The proportional set size that is swappable for the native heap. */
+ /** @hide We may want to expose this, eventually. */
+ public int nativeSwappablePss;
/** The private dirty pages used by the native heap. */
public int nativePrivateDirty;
/** The shared dirty pages used by the native heap. */
public int nativeSharedDirty;
+ /** The private clean pages used by the native heap. */
+ /** @hide We may want to expose this, eventually. */
+ public int nativePrivateClean;
+ /** The shared clean pages used by the native heap. */
+ /** @hide We may want to expose this, eventually. */
+ public int nativeSharedClean;
/** The proportional set size for everything else. */
public int otherPss;
+ /** The proportional set size that is swappable for everything else. */
+ /** @hide We may want to expose this, eventually. */
+ public int otherSwappablePss;
/** The private dirty pages used by everything else. */
public int otherPrivateDirty;
/** The shared dirty pages used by everything else. */
public int otherSharedDirty;
+ /** The private clean pages used by everything else. */
+ /** @hide We may want to expose this, eventually. */
+ public int otherPrivateClean;
+ /** The shared clean pages used by everything else. */
+ /** @hide We may want to expose this, eventually. */
+ public int otherSharedClean;
/** @hide */
- public static final int NUM_OTHER_STATS = 10;
+ public static final int NUM_OTHER_STATS = 13;
- private int[] otherStats = new int[NUM_OTHER_STATS*3];
+ /** @hide */
+ public static final int NUM_DVK_STATS = 5;
+
+ /** @hide */
+ public static final int NUM_CATEGORIES = 6;
+
+ /** @hide */
+ public static final int offsetPss = 0;
+ /** @hide */
+ public static final int offsetSwappablePss = 1;
+ /** @hide */
+ public static final int offsetPrivateDirty = 2;
+ /** @hide */
+ public static final int offsetSharedDirty = 3;
+ /** @hide */
+ public static final int offsetPrivateClean = 4;
+ /** @hide */
+ public static final int offsetSharedClean = 5;
+
+
+ private int[] otherStats = new int[(NUM_OTHER_STATS+NUM_DVK_STATS)*NUM_CATEGORIES];
public MemoryInfo() {
}
@@ -144,6 +191,14 @@ public final class Debug
return dalvikPss + nativePss + otherPss;
}
+
+ /**
+ * Return total PSS memory usage in kB.
+ */
+ public int getTotalSwappablePss() {
+ return dalvikSwappablePss + nativeSwappablePss + otherSwappablePss;
+ }
+
/**
* Return total private dirty memory usage in kB.
*/
@@ -158,35 +213,74 @@ public final class Debug
return dalvikSharedDirty + nativeSharedDirty + otherSharedDirty;
}
+ /**
+ * Return total shared clean memory usage in kB.
+ */
+ public int getTotalPrivateClean() {
+ return dalvikPrivateClean + nativePrivateClean + otherPrivateClean;
+ }
+
+ /**
+ * Return total shared clean memory usage in kB.
+ */
+ public int getTotalSharedClean() {
+ return dalvikSharedClean + nativeSharedClean + otherSharedClean;
+ }
+
/* @hide */
public int getOtherPss(int which) {
- return otherStats[which*3];
+ return otherStats[which*NUM_CATEGORIES + offsetPss];
+ }
+
+
+ /* @hide */
+ public int getOtherSwappablePss(int which) {
+ return otherStats[which*NUM_CATEGORIES + offsetSwappablePss];
}
+
/* @hide */
public int getOtherPrivateDirty(int which) {
- return otherStats[which*3 + 1];
+ return otherStats[which*NUM_CATEGORIES + offsetPrivateDirty];
}
/* @hide */
public int getOtherSharedDirty(int which) {
- return otherStats[which*3 + 2];
+ return otherStats[which*NUM_CATEGORIES + offsetSharedDirty];
}
+ /* @hide */
+ public int getOtherPrivateClean(int which) {
+ return otherStats[which*NUM_CATEGORIES + offsetPrivateClean];
+ }
+
+
+ /* @hide */
+ public int getOtherSharedClean(int which) {
+ return otherStats[which*NUM_CATEGORIES + offsetSharedClean];
+ }
/* @hide */
public static String getOtherLabel(int which) {
switch (which) {
- case 0: return "Stack";
- case 1: return "Cursor";
- case 2: return "Ashmem";
- case 3: return "Other dev";
- case 4: return ".so mmap";
- case 5: return ".jar mmap";
- case 6: return ".apk mmap";
- case 7: return ".ttf mmap";
- case 8: return ".dex mmap";
- case 9: return "Other mmap";
+ case 0: return "Dalvik Other";
+ case 1: return "Stack";
+ case 2: return "Cursor";
+ case 3: return "Ashmem";
+ case 4: return "Other dev";
+ case 5: return ".so mmap";
+ case 6: return ".jar mmap";
+ case 7: return ".apk mmap";
+ case 8: return ".ttf mmap";
+ case 9: return ".dex mmap";
+ case 10: return "code mmap";
+ case 11: return "image mmap";
+ case 12: return "Other mmap";
+ case 13: return ".Heap";
+ case 14: return ".LOS";
+ case 15: return ".LinearAlloc";
+ case 16: return ".GC";
+ case 17: return ".JITCache";
default: return "????";
}
}
@@ -197,27 +291,45 @@ public final class Debug
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(dalvikPss);
+ dest.writeInt(dalvikSwappablePss);
dest.writeInt(dalvikPrivateDirty);
dest.writeInt(dalvikSharedDirty);
+ dest.writeInt(dalvikPrivateClean);
+ dest.writeInt(dalvikSharedClean);
dest.writeInt(nativePss);
+ dest.writeInt(nativeSwappablePss);
dest.writeInt(nativePrivateDirty);
dest.writeInt(nativeSharedDirty);
+ dest.writeInt(nativePrivateClean);
+ dest.writeInt(nativeSharedClean);
dest.writeInt(otherPss);
+ dest.writeInt(otherSwappablePss);
dest.writeInt(otherPrivateDirty);
dest.writeInt(otherSharedDirty);
+ dest.writeInt(otherPrivateClean);
+ dest.writeInt(otherSharedClean);
dest.writeIntArray(otherStats);
}
public void readFromParcel(Parcel source) {
dalvikPss = source.readInt();
+ dalvikSwappablePss = source.readInt();
dalvikPrivateDirty = source.readInt();
dalvikSharedDirty = source.readInt();
+ dalvikPrivateClean = source.readInt();
+ dalvikSharedClean = source.readInt();
nativePss = source.readInt();
+ nativeSwappablePss = source.readInt();
nativePrivateDirty = source.readInt();
nativeSharedDirty = source.readInt();
+ nativePrivateClean = source.readInt();
+ nativeSharedClean = source.readInt();
otherPss = source.readInt();
+ otherSwappablePss = source.readInt();
otherPrivateDirty = source.readInt();
otherSharedDirty = source.readInt();
+ otherPrivateClean = source.readInt();
+ otherSharedClean = source.readInt();
otherStats = source.createIntArray();
}
@@ -1397,7 +1509,7 @@ href="{@docRoot}guide/developing/tools/traceview.html">Traceview: A Graphical Lo
/**
* Return a String describing the calling method and location at a particular stack depth.
- * @param callStack the Thread stack
+ * @param callStack the Thread stack
* @param depth the depth of stack to return information for.
* @return the String describing the caller at that depth.
*/
diff --git a/core/java/android/os/Environment.java b/core/java/android/os/Environment.java
index 61eef1f..70a1edc 100644
--- a/core/java/android/os/Environment.java
+++ b/core/java/android/os/Environment.java
@@ -19,6 +19,7 @@ package android.os;
import android.os.storage.IMountService;
import android.os.storage.StorageManager;
import android.os.storage.StorageVolume;
+import android.os.SystemProperties;
import android.text.TextUtils;
import android.util.Log;
@@ -59,6 +60,10 @@ public class Environment {
private static volatile StorageVolume sPrimaryVolume;
private static StorageVolume getPrimaryVolume() {
+ if (SystemProperties.getBoolean("config.disable_storage", false)) {
+ return null;
+ }
+
if (sPrimaryVolume == null) {
synchronized (sLock) {
if (sPrimaryVolume == null) {
diff --git a/core/java/android/os/IPowerManager.aidl b/core/java/android/os/IPowerManager.aidl
index 6d6d147..23492ff 100644
--- a/core/java/android/os/IPowerManager.aidl
+++ b/core/java/android/os/IPowerManager.aidl
@@ -25,7 +25,7 @@ interface IPowerManager
{
// WARNING: The first two methods must remain the first two methods because their
// transaction numbers must not change unless IPowerManager.cpp is also updated.
- void acquireWakeLock(IBinder lock, int flags, String tag, in WorkSource ws);
+ void acquireWakeLock(IBinder lock, int flags, String tag, String packageName, in WorkSource ws);
void releaseWakeLock(IBinder lock, int flags);
void updateWakeLockWorkSource(IBinder lock, in WorkSource ws);
diff --git a/core/java/android/os/Looper.java b/core/java/android/os/Looper.java
index d5cf771..78c859e 100644
--- a/core/java/android/os/Looper.java
+++ b/core/java/android/os/Looper.java
@@ -289,6 +289,16 @@ public final class Looper {
return mQueue;
}
+ /**
+ * Return whether this looper's thread is currently idle, waiting for new work
+ * to do. This is intrinsically racy, since its state can change before you get
+ * the result back.
+ * @hide
+ */
+ public boolean isIdling() {
+ return mQueue.isIdling();
+ }
+
public void dump(Printer pw, String prefix) {
pw = PrefixPrinter.create(pw, prefix);
pw.println(this.toString());
diff --git a/core/java/android/os/MessageQueue.java b/core/java/android/os/MessageQueue.java
index bf7e5ca..1e8983e 100644
--- a/core/java/android/os/MessageQueue.java
+++ b/core/java/android/os/MessageQueue.java
@@ -52,6 +52,7 @@ public final class MessageQueue {
private native static void nativeDestroy(int ptr);
private native static void nativePollOnce(int ptr, int timeoutMillis);
private native static void nativeWake(int ptr);
+ private native static boolean nativeIsIdling(int ptr);
/**
* Callback interface for discovering when a thread is going to block
@@ -379,6 +380,10 @@ public final class MessageQueue {
}
}
+ boolean isIdling() {
+ return nativeIsIdling(mPtr);
+ }
+
void removeMessages(Handler h, int what, Object object) {
if (h == null) {
return;
diff --git a/core/java/android/os/ParcelableParcel.java b/core/java/android/os/ParcelableParcel.java
new file mode 100644
index 0000000..11785f1
--- /dev/null
+++ b/core/java/android/os/ParcelableParcel.java
@@ -0,0 +1,75 @@
+/*
+ * 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 android.os;
+
+/**
+ * Parcelable containing a raw Parcel of data.
+ * @hide
+ */
+public class ParcelableParcel implements Parcelable {
+ final Parcel mParcel;
+ final ClassLoader mClassLoader;
+
+ public ParcelableParcel(ClassLoader loader) {
+ mParcel = Parcel.obtain();
+ mClassLoader = loader;
+ }
+
+ public ParcelableParcel(Parcel src, ClassLoader loader) {
+ mParcel = Parcel.obtain();
+ mClassLoader = loader;
+ int size = src.readInt();
+ int pos = src.dataPosition();
+ mParcel.appendFrom(src, src.dataPosition(), size);
+ src.setDataPosition(pos + size);
+ }
+
+ public Parcel getParcel() {
+ mParcel.setDataPosition(0);
+ return mParcel;
+ }
+
+ public ClassLoader getClassLoader() {
+ return mClassLoader;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(mParcel.dataSize());
+ dest.appendFrom(mParcel, 0, mParcel.dataSize());
+ }
+
+ public static final Parcelable.ClassLoaderCreator<ParcelableParcel> CREATOR
+ = new Parcelable.ClassLoaderCreator<ParcelableParcel>() {
+ public ParcelableParcel createFromParcel(Parcel in) {
+ return new ParcelableParcel(in, null);
+ }
+
+ public ParcelableParcel createFromParcel(Parcel in, ClassLoader loader) {
+ return new ParcelableParcel(in, loader);
+ }
+
+ public ParcelableParcel[] newArray(int size) {
+ return new ParcelableParcel[size];
+ }
+ };
+}
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index 736762f..52e5f38 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -224,7 +224,7 @@ public final class PowerManager {
/**
* Flag for {@link WakeLock#release release(int)} to defer releasing a
- * {@link #WAKE_BIT_PROXIMITY_SCREEN_OFF} wake lock until the proximity sensor returns
+ * {@link #PROXIMITY_SCREEN_OFF_WAKE_LOCK} wake lock until the proximity sensor returns
* a negative value.
*
* {@hide}
@@ -407,7 +407,7 @@ public final class PowerManager {
*/
public WakeLock newWakeLock(int levelAndFlags, String tag) {
validateWakeLockParameters(levelAndFlags, tag);
- return new WakeLock(levelAndFlags, tag);
+ return new WakeLock(levelAndFlags, tag, mContext.getBasePackageName());
}
/** @hide */
@@ -624,6 +624,7 @@ public final class PowerManager {
public final class WakeLock {
private final int mFlags;
private final String mTag;
+ private final String mPackageName;
private final IBinder mToken;
private int mCount;
private boolean mRefCounted = true;
@@ -636,9 +637,10 @@ public final class PowerManager {
}
};
- WakeLock(int flags, String tag) {
+ WakeLock(int flags, String tag, String packageName) {
mFlags = flags;
mTag = tag;
+ mPackageName = packageName;
mToken = new Binder();
}
@@ -714,7 +716,7 @@ public final class PowerManager {
// been explicitly released by the keyguard.
mHandler.removeCallbacks(mReleaser);
try {
- mService.acquireWakeLock(mToken, mFlags, mTag, mWorkSource);
+ mService.acquireWakeLock(mToken, mFlags, mTag, mPackageName, mWorkSource);
} catch (RemoteException e) {
}
mHeld = true;
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java
index 476b4ea..93b1255 100644
--- a/core/java/android/os/Process.java
+++ b/core/java/android/os/Process.java
@@ -650,6 +650,12 @@ public class Process {
public static final native int myPid();
/**
+ * Returns the identifier of this process' parent.
+ * @hide
+ */
+ public static native int myPpid();
+
+ /**
* Returns the identifier of the calling thread, which be used with
* {@link #setThreadPriority(int, int)}.
*/
diff --git a/core/java/android/os/RecoverySystem.java b/core/java/android/os/RecoverySystem.java
index 480fe7d..5e20dec 100644
--- a/core/java/android/os/RecoverySystem.java
+++ b/core/java/android/os/RecoverySystem.java
@@ -244,12 +244,17 @@ public class RecoverySystem {
// The signature cert matches a trusted key. Now verify that
// the digest in the cert matches the actual file data.
- // The verifier in recovery *only* handles SHA1withRSA
- // signatures. SignApk.java always uses SHA1withRSA, no
- // matter what the cert says to use. Ignore
- // cert.getSigAlgName(), and instead use whatever
- // algorithm is used by the signature (which should be
- // SHA1withRSA).
+ // The verifier in recovery only handles SHA1withRSA and
+ // SHA256withRSA signatures. SignApk chooses which to use
+ // based on the signature algorithm of the cert:
+ //
+ // "SHA256withRSA" cert -> "SHA256withRSA" signature
+ // "SHA1withRSA" cert -> "SHA1withRSA" signature
+ // "MD5withRSA" cert -> "SHA1withRSA" signature (for backwards compatibility)
+ // any other cert -> SignApk fails
+ //
+ // Here we ignore whatever the cert says, and instead use
+ // whatever algorithm is used by the signature.
String da = sigInfo.getDigestAlgorithm();
String dea = sigInfo.getDigestEncryptionAlgorithm();
diff --git a/core/java/android/os/RemoteCallbackList.java b/core/java/android/os/RemoteCallbackList.java
index d02a320..c1d4ae9 100644
--- a/core/java/android/os/RemoteCallbackList.java
+++ b/core/java/android/os/RemoteCallbackList.java
@@ -16,6 +16,8 @@
package android.os;
+import android.util.ArrayMap;
+
import java.util.HashMap;
/**
@@ -47,8 +49,8 @@ import java.util.HashMap;
* implements the {@link #onCallbackDied} method.
*/
public class RemoteCallbackList<E extends IInterface> {
- /*package*/ HashMap<IBinder, Callback> mCallbacks
- = new HashMap<IBinder, Callback>();
+ /*package*/ ArrayMap<IBinder, Callback> mCallbacks
+ = new ArrayMap<IBinder, Callback>();
private Object[] mActiveBroadcast;
private int mBroadcastCount = -1;
private boolean mKilled = false;
@@ -159,7 +161,8 @@ public class RemoteCallbackList<E extends IInterface> {
*/
public void kill() {
synchronized (mCallbacks) {
- for (Callback cb : mCallbacks.values()) {
+ for (int cbi=mCallbacks.size()-1; cbi>=0; cbi--) {
+ Callback cb = mCallbacks.valueAt(cbi);
cb.mCallback.asBinder().unlinkToDeath(cb, 0);
}
mCallbacks.clear();
@@ -238,11 +241,10 @@ public class RemoteCallbackList<E extends IInterface> {
if (active == null || active.length < N) {
mActiveBroadcast = active = new Object[N];
}
- int i=0;
- for (Callback cb : mCallbacks.values()) {
- active[i++] = cb;
+ for (int i=0; i<N; i++) {
+ active[i] = mCallbacks.valueAt(i);
}
- return i;
+ return N;
}
}
diff --git a/core/java/android/os/StrictMode.java b/core/java/android/os/StrictMode.java
index 3267939..31da091 100644
--- a/core/java/android/os/StrictMode.java
+++ b/core/java/android/os/StrictMode.java
@@ -24,6 +24,7 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
+import android.util.ArrayMap;
import android.util.Log;
import android.util.Printer;
import android.util.Singleton;
@@ -1069,7 +1070,7 @@ public final class StrictMode {
// Map from violation stacktrace hashcode -> uptimeMillis of
// last violation. No locking needed, as this is only
// accessed by the same thread.
- private final HashMap<Integer, Long> mLastViolationTime = new HashMap<Integer, Long>();
+ private ArrayMap<Integer, Long> mLastViolationTime;
public AndroidBlockGuardPolicy(final int policyMask) {
mPolicyMask = policyMask;
@@ -1279,8 +1280,13 @@ public final class StrictMode {
// Not perfect, but fast and good enough for dup suppression.
Integer crashFingerprint = info.hashCode();
long lastViolationTime = 0;
- if (mLastViolationTime.containsKey(crashFingerprint)) {
- lastViolationTime = mLastViolationTime.get(crashFingerprint);
+ if (mLastViolationTime != null) {
+ Long vtime = mLastViolationTime.get(crashFingerprint);
+ if (vtime != null) {
+ lastViolationTime = vtime;
+ }
+ } else {
+ mLastViolationTime = new ArrayMap<Integer, Long>(1);
}
long now = SystemClock.uptimeMillis();
mLastViolationTime.put(crashFingerprint, now);
diff --git a/core/java/android/os/Trace.java b/core/java/android/os/Trace.java
index e53cb5e..bb3d296 100644
--- a/core/java/android/os/Trace.java
+++ b/core/java/android/os/Trace.java
@@ -67,6 +67,8 @@ public final class Trace {
public static final long TRACE_TAG_RESOURCES = 1L << 13;
/** @hide */
public static final long TRACE_TAG_DALVIK = 1L << 14;
+ /** @hide */
+ public static final long TRACE_TAG_RS = 1L << 15;
private static final long TRACE_TAG_NOT_READY = 1L << 63;
private static final int MAX_SECTION_NAME_LEN = 127;
diff --git a/core/java/android/provider/DocumentsContract.java b/core/java/android/provider/DocumentsContract.java
new file mode 100644
index 0000000..c26f6d4
--- /dev/null
+++ b/core/java/android/provider/DocumentsContract.java
@@ -0,0 +1,209 @@
+/*
+ * 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 android.provider;
+
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.content.Intent;
+import android.content.res.AssetFileDescriptor;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Point;
+import android.net.Uri;
+import android.os.Bundle;
+import android.util.Log;
+
+import libcore.io.IoUtils;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * The contract between a storage backend and the platform. Contains definitions
+ * for the supported URIs and columns.
+ */
+public final class DocumentsContract {
+ private static final String TAG = "Documents";
+
+ // content://com.example/docs/0/
+ // content://com.example/docs/0/contents/
+ // content://com.example/search/?query=pony
+
+ /**
+ * MIME type of a document which is a directory that may contain additional
+ * documents.
+ *
+ * @see #buildContentsUri(Uri)
+ */
+ public static final String MIME_TYPE_DIRECTORY = "vnd.android.cursor.dir/doc";
+
+ /** {@hide} */
+ public static final String META_DATA_DOCUMENT_PROVIDER = "android.content.DOCUMENT_PROVIDER";
+
+ /**
+ * {@link DocumentColumns#GUID} value representing the root directory of a
+ * storage backend.
+ */
+ public static final String ROOT_GUID = "0";
+
+ /**
+ * Flag indicating that a document is a directory that supports creation of
+ * new files within it.
+ *
+ * @see DocumentColumns#FLAGS
+ * @see #buildContentsUri(Uri)
+ */
+ public static final int FLAG_SUPPORTS_CREATE = 1;
+
+ /**
+ * Flag indicating that a document is renamable.
+ *
+ * @see DocumentColumns#FLAGS
+ * @see #renameDocument(ContentResolver, Uri, String)
+ */
+ public static final int FLAG_SUPPORTS_RENAME = 1 << 1;
+
+ /**
+ * Flag indicating that a document can be represented as a thumbnail.
+ *
+ * @see DocumentColumns#FLAGS
+ * @see #getThumbnail(ContentResolver, Uri, Point)
+ */
+ public static final int FLAG_SUPPORTS_THUMBNAIL = 1 << 2;
+
+ /**
+ * Optimal dimensions for a document thumbnail request, stored as a
+ * {@link Point} object. This is only a hint, and the returned thumbnail may
+ * have different dimensions.
+ */
+ public static final String EXTRA_THUMBNAIL_SIZE = "thumbnail_size";
+
+ private static final String PATH_DOCS = "docs";
+ private static final String PATH_CONTENTS = "contents";
+ private static final String PATH_SEARCH = "search";
+
+ private static final String PARAM_QUERY = "query";
+
+ /**
+ * Build URI representing the given {@link DocumentColumns#GUID} in a
+ * storage backend.
+ */
+ public static Uri buildDocumentUri(String authority, String guid) {
+ return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
+ .authority(authority).appendPath(PATH_DOCS).appendPath(guid).build();
+ }
+
+ /**
+ * Build URI representing a search for matching documents in a storage
+ * backend.
+ */
+ public static Uri buildSearchUri(String authority, String query) {
+ return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT).authority(authority)
+ .appendPath(PATH_SEARCH).appendQueryParameter(PARAM_QUERY, query).build();
+ }
+
+ /**
+ * Build URI representing the contents of the given directory in a storage
+ * backend. The given document must be {@link #MIME_TYPE_DIRECTORY}.
+ */
+ public static Uri buildContentsUri(Uri documentUri) {
+ return documentUri.buildUpon().appendPath(PATH_CONTENTS).build();
+ }
+
+ /**
+ * These are standard columns for document URIs. Storage backend providers
+ * <em>must</em> support at least these columns when queried.
+ *
+ * @see Intent#ACTION_OPEN_DOCUMENT
+ * @see Intent#ACTION_CREATE_DOCUMENT
+ */
+ public interface DocumentColumns extends OpenableColumns {
+ /**
+ * The globally unique ID for a document within a storage backend.
+ * Values <em>must</em> never change once returned.
+ * <p>
+ * Type: STRING
+ *
+ * @see DocumentsContract#ROOT_GUID
+ */
+ public static final String GUID = "guid";
+
+ /**
+ * MIME type of a document, matching the value returned by
+ * {@link ContentResolver#getType(android.net.Uri)}.
+ * <p>
+ * Type: STRING
+ *
+ * @see DocumentsContract#MIME_TYPE_DIRECTORY
+ */
+ public static final String MIME_TYPE = "mime_type";
+
+ /**
+ * Timestamp when a document was last modified, in milliseconds since
+ * January 1, 1970 00:00:00.0 UTC.
+ * <p>
+ * Type: INTEGER (long)
+ *
+ * @see System#currentTimeMillis()
+ */
+ public static final String LAST_MODIFIED = "last_modified";
+
+ /**
+ * Flags that apply to a specific document.
+ * <p>
+ * Type: INTEGER (int)
+ */
+ public static final String FLAGS = "flags";
+ }
+
+ /**
+ * Return thumbnail representing the document at the given URI. Callers are
+ * responsible for their own caching. Given document must have
+ * {@link #FLAG_SUPPORTS_THUMBNAIL} set.
+ *
+ * @return decoded thumbnail, or {@code null} if problem was encountered.
+ */
+ public static Bitmap getThumbnail(ContentResolver resolver, Uri documentUri, Point size) {
+ final Bundle opts = new Bundle();
+ opts.putParcelable(EXTRA_THUMBNAIL_SIZE, size);
+
+ InputStream is = null;
+ try {
+ is = new AssetFileDescriptor.AutoCloseInputStream(
+ resolver.openTypedAssetFileDescriptor(documentUri, "image/*", opts));
+ return BitmapFactory.decodeStream(is);
+ } catch (IOException e) {
+ Log.w(TAG, "Failed to load thumbnail for " + documentUri + ": " + e);
+ return null;
+ } finally {
+ IoUtils.closeQuietly(is);
+ }
+ }
+
+ /**
+ * Rename the document at the given URI. Given document must have
+ * {@link #FLAG_SUPPORTS_RENAME} set.
+ *
+ * @return if rename was successful.
+ */
+ public static boolean renameDocument(
+ ContentResolver resolver, Uri documentUri, String displayName) {
+ final ContentValues values = new ContentValues();
+ values.put(DocumentColumns.DISPLAY_NAME, displayName);
+ return (resolver.update(documentUri, values, null, null) == 1);
+ }
+}
diff --git a/core/java/android/provider/DrmStore.java b/core/java/android/provider/DrmStore.java
deleted file mode 100644
index 34f2f0d..0000000
--- a/core/java/android/provider/DrmStore.java
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.provider;
-
-import android.content.ContentResolver;
-import android.content.ContentValues;
-import android.content.Context;
-import android.drm.mobile1.DrmRawContent;
-import android.drm.mobile1.DrmRights;
-import android.drm.mobile1.DrmRightsManager;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.net.Uri;
-import android.util.Log;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.InputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-
-/**
- * The DRM provider contains forward locked DRM content.
- *
- * @hide
- */
-public final class DrmStore
-{
- private static final String TAG = "DrmStore";
-
- public static final String AUTHORITY = "drm";
-
- /**
- * This is in the Manifest class of the drm provider, but that isn't visible
- * in the framework.
- */
- private static final String ACCESS_DRM_PERMISSION = "android.permission.ACCESS_DRM";
-
- /**
- * Fields for DRM database
- */
-
- public interface Columns extends BaseColumns {
- /**
- * The data stream for the file
- * <P>Type: DATA STREAM</P>
- */
- public static final String DATA = "_data";
-
- /**
- * The size of the file in bytes
- * <P>Type: INTEGER (long)</P>
- */
- public static final String SIZE = "_size";
-
- /**
- * The title of the file content
- * <P>Type: TEXT</P>
- */
- public static final String TITLE = "title";
-
- /**
- * The MIME type of the file
- * <P>Type: TEXT</P>
- */
- public static final String MIME_TYPE = "mime_type";
-
- }
-
- public interface Images extends Columns {
-
- public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/images");
- }
-
- public interface Audio extends Columns {
-
- public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/audio");
- }
-
- /**
- * Utility function for inserting a file into the DRM content provider.
- *
- * @param cr The content resolver to use
- * @param file The file to insert
- * @param title The title for the content (or null)
- * @return uri to the DRM record or null
- */
- public static final Intent addDrmFile(ContentResolver cr, File file, String title) {
- FileInputStream fis = null;
- Intent result = null;
-
- try {
- fis = new FileInputStream(file);
- if (title == null) {
- title = file.getName();
- int lastDot = title.lastIndexOf('.');
- if (lastDot > 0) {
- title = title.substring(0, lastDot);
- }
- }
- result = addDrmFile(cr, fis, title);
- } catch (Exception e) {
- Log.e(TAG, "pushing file failed", e);
- } finally {
- try {
- if (fis != null)
- fis.close();
- } catch (IOException e) {
- Log.e(TAG, "IOException in DrmStore.addDrmFile()", e);
- }
- }
-
- return result;
- }
-
- /**
- * Utility function for inserting a file stream into the DRM content provider.
- *
- * @param cr The content resolver to use
- * @param fis The FileInputStream to insert
- * @param title The title for the content (or null)
- * @return uri to the DRM record or null
- */
- public static final Intent addDrmFile(ContentResolver cr, FileInputStream fis, String title) {
- OutputStream os = null;
- Intent result = null;
-
- try {
- DrmRawContent content = new DrmRawContent(fis, (int) fis.available(),
- DrmRawContent.DRM_MIMETYPE_MESSAGE_STRING);
- String mimeType = content.getContentType();
- long size = fis.getChannel().size();
-
- DrmRightsManager manager = manager = DrmRightsManager.getInstance();
- DrmRights rights = manager.queryRights(content);
- InputStream stream = content.getContentInputStream(rights);
-
- Uri contentUri = null;
- if (mimeType.startsWith("audio/")) {
- contentUri = DrmStore.Audio.CONTENT_URI;
- } else if (mimeType.startsWith("image/")) {
- contentUri = DrmStore.Images.CONTENT_URI;
- } else {
- Log.w(TAG, "unsupported mime type " + mimeType);
- }
-
- if (contentUri != null) {
- ContentValues values = new ContentValues(3);
- values.put(DrmStore.Columns.TITLE, title);
- values.put(DrmStore.Columns.SIZE, size);
- values.put(DrmStore.Columns.MIME_TYPE, mimeType);
-
- Uri uri = cr.insert(contentUri, values);
- if (uri != null) {
- os = cr.openOutputStream(uri);
-
- byte[] buffer = new byte[1000];
- int count;
-
- while ((count = stream.read(buffer)) != -1) {
- os.write(buffer, 0, count);
- }
- result = new Intent();
- result.setDataAndType(uri, mimeType);
-
- }
- }
- } catch (Exception e) {
- Log.e(TAG, "pushing file failed", e);
- } finally {
- try {
- if (fis != null)
- fis.close();
- if (os != null)
- os.close();
- } catch (IOException e) {
- Log.e(TAG, "IOException in DrmStore.addDrmFile()", e);
- }
- }
-
- return result;
- }
-
- /**
- * Utility function to enforce any permissions required to access DRM
- * content.
- *
- * @param context A context used for checking calling permission.
- */
- public static void enforceAccessDrmPermission(Context context) {
- if (context.checkCallingOrSelfPermission(ACCESS_DRM_PERMISSION) !=
- PackageManager.PERMISSION_GRANTED) {
- throw new SecurityException("Requires DRM permission");
- }
- }
-
-}
diff --git a/core/java/android/provider/OpenableColumns.java b/core/java/android/provider/OpenableColumns.java
index f548bae..faf96b7 100644
--- a/core/java/android/provider/OpenableColumns.java
+++ b/core/java/android/provider/OpenableColumns.java
@@ -16,11 +16,17 @@
package android.provider;
+import android.content.ContentResolver;
+import android.content.Intent;
+
/**
- * These are standard columns for openable URIs. (See
- * {@link android.content.Intent#CATEGORY_OPENABLE}.) If possible providers that have openable URIs
- * should support these columns. To find the content type of a URI use
- * {@link android.content.ContentResolver#getType(android.net.Uri)} as normal.
+ * These are standard columns for openable URIs. Providers that serve openable
+ * URIs <em>must</em> support at least these columns when queried.
+ * <p>
+ * To find the content type of a URI, use
+ * {@link ContentResolver#getType(android.net.Uri)}.
+ *
+ * @see Intent#CATEGORY_OPENABLE
*/
public interface OpenableColumns {
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 3c8187e..c1a296d 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -1010,6 +1010,14 @@ public final class Settings {
MOVED_TO_GLOBAL.add(Settings.Global.WAIT_FOR_DEBUGGER);
MOVED_TO_GLOBAL.add(Settings.Global.SHOW_PROCESSES);
MOVED_TO_GLOBAL.add(Settings.Global.ALWAYS_FINISH_ACTIVITIES);
+ MOVED_TO_GLOBAL.add(Settings.Global.TZINFO_UPDATE_CONTENT_URL);
+ MOVED_TO_GLOBAL.add(Settings.Global.TZINFO_UPDATE_METADATA_URL);
+ MOVED_TO_GLOBAL.add(Settings.Global.SELINUX_UPDATE_CONTENT_URL);
+ MOVED_TO_GLOBAL.add(Settings.Global.SELINUX_UPDATE_METADATA_URL);
+ MOVED_TO_GLOBAL.add(Settings.Global.SMS_SHORT_CODES_UPDATE_CONTENT_URL);
+ MOVED_TO_GLOBAL.add(Settings.Global.SMS_SHORT_CODES_UPDATE_METADATA_URL);
+ MOVED_TO_GLOBAL.add(Settings.Global.CERT_PIN_UPDATE_CONTENT_URL);
+ MOVED_TO_GLOBAL.add(Settings.Global.CERT_PIN_UPDATE_METADATA_URL);
}
/** @hide */
diff --git a/core/java/android/speech/tts/TtsEngines.java b/core/java/android/speech/tts/TtsEngines.java
index 2706bc7..5fbd22e 100644
--- a/core/java/android/speech/tts/TtsEngines.java
+++ b/core/java/android/speech/tts/TtsEngines.java
@@ -355,7 +355,18 @@ public class TtsEngines {
return v1Locale;
}
- private String getDefaultLocale() {
+ /**
+ * Return the default device locale in form of 3 letter codes delimited by
+ * {@link #LOCALE_DELIMITER}:
+ * <ul>
+ * <li> "ISO 639-2/T language code" if locale have no country entry</li>
+ * <li> "ISO 639-2/T language code{@link #LOCALE_DELIMITER}ISO 3166 country code "
+ * if locale have no variant entry</li>
+ * <li> "ISO 639-2/T language code{@link #LOCALE_DELIMITER}ISO 3166 country code
+ * {@link #LOCALE_DELIMITER} variant" if locale have variant entry</li>
+ * </ul>
+ */
+ public String getDefaultLocale() {
final Locale locale = Locale.getDefault();
// Note that the default locale might have an empty variant
diff --git a/core/java/android/text/method/ArrowKeyMovementMethod.java b/core/java/android/text/method/ArrowKeyMovementMethod.java
index 30bb447..ba6f1d4 100644
--- a/core/java/android/text/method/ArrowKeyMovementMethod.java
+++ b/core/java/android/text/method/ArrowKeyMovementMethod.java
@@ -56,7 +56,7 @@ public class ArrowKeyMovementMethod extends BaseMovementMethod implements Moveme
if (event.getAction() == KeyEvent.ACTION_DOWN
&& event.getRepeatCount() == 0
&& MetaKeyKeyListener.getMetaState(buffer,
- MetaKeyKeyListener.META_SELECTING) != 0) {
+ MetaKeyKeyListener.META_SELECTING, event) != 0) {
return widget.showContextMenu();
}
}
diff --git a/core/java/android/text/method/BaseKeyListener.java b/core/java/android/text/method/BaseKeyListener.java
index 4fede32..63607fa 100644
--- a/core/java/android/text/method/BaseKeyListener.java
+++ b/core/java/android/text/method/BaseKeyListener.java
@@ -75,7 +75,7 @@ public abstract class BaseKeyListener extends MetaKeyKeyListener
}
// Alt+Backspace or Alt+ForwardDelete deletes the current line, if possible.
- if (event.isAltPressed() || getMetaState(content, META_ALT_ON) == 1) {
+ if (getMetaState(content, META_ALT_ON, event) == 1) {
if (deleteLine(view, content)) {
return true;
}
diff --git a/core/java/android/text/method/BaseMovementMethod.java b/core/java/android/text/method/BaseMovementMethod.java
index 113a4be..155a2c4 100644
--- a/core/java/android/text/method/BaseMovementMethod.java
+++ b/core/java/android/text/method/BaseMovementMethod.java
@@ -135,7 +135,7 @@ public class BaseMovementMethod implements MovementMethod {
*/
protected int getMovementMetaState(Spannable buffer, KeyEvent event) {
// We ignore locked modifiers and SHIFT.
- int metaState = (event.getMetaState() | MetaKeyKeyListener.getMetaState(buffer))
+ int metaState = MetaKeyKeyListener.getMetaState(buffer, event)
& ~(MetaKeyKeyListener.META_ALT_LOCKED | MetaKeyKeyListener.META_SYM_LOCKED);
return KeyEvent.normalizeMetaState(metaState) & ~KeyEvent.META_SHIFT_MASK;
}
diff --git a/core/java/android/text/method/DialerKeyListener.java b/core/java/android/text/method/DialerKeyListener.java
index ce51fae..bb8b0de 100644
--- a/core/java/android/text/method/DialerKeyListener.java
+++ b/core/java/android/text/method/DialerKeyListener.java
@@ -53,7 +53,7 @@ public class DialerKeyListener extends NumberKeyListener
* from the KeyEvent.
*/
protected int lookup(KeyEvent event, Spannable content) {
- int meta = event.getMetaState() | getMetaState(content);
+ int meta = getMetaState(content, event);
int number = event.getNumber();
/*
diff --git a/core/java/android/text/method/LinkMovementMethod.java b/core/java/android/text/method/LinkMovementMethod.java
index aff233d..3855ff3 100644
--- a/core/java/android/text/method/LinkMovementMethod.java
+++ b/core/java/android/text/method/LinkMovementMethod.java
@@ -36,6 +36,11 @@ public class LinkMovementMethod extends ScrollingMovementMethod {
private static final int DOWN = 3;
@Override
+ public boolean canSelectArbitrarily() {
+ return true;
+ }
+
+ @Override
protected boolean handleMovementKey(TextView widget, Spannable buffer, int keyCode,
int movementMetaState, KeyEvent event) {
switch (keyCode) {
diff --git a/core/java/android/text/method/MetaKeyKeyListener.java b/core/java/android/text/method/MetaKeyKeyListener.java
index 0a097f9..e9db5fd 100644
--- a/core/java/android/text/method/MetaKeyKeyListener.java
+++ b/core/java/android/text/method/MetaKeyKeyListener.java
@@ -135,6 +135,9 @@ public abstract class MetaKeyKeyListener {
private static final Object SYM = new NoCopySpan.Concrete();
private static final Object SELECTING = new NoCopySpan.Concrete();
+ private static final int PRESSED_RETURN_VALUE = 1;
+ private static final int LOCKED_RETURN_VALUE = 2;
+
/**
* Resets all meta state to inactive.
*/
@@ -161,9 +164,34 @@ public abstract class MetaKeyKeyListener {
}
/**
+ * Gets the state of the meta keys for a specific key event.
+ *
+ * For input devices that use toggled key modifiers, the `toggled' state
+ * is stored into the text buffer. This method retrieves the meta state
+ * for this event, accounting for the stored state. If the event has been
+ * created by a device that does not support toggled key modifiers, like
+ * a virtual device for example, the stored state is ignored.
+ *
+ * @param text the buffer in which the meta key would have been pressed.
+ * @param event the event for which to evaluate the meta state.
+ * @return an integer in which each bit set to one represents a pressed
+ * or locked meta key.
+ */
+ public static final int getMetaState(final CharSequence text, final KeyEvent event) {
+ int metaState = event.getMetaState();
+ if (event.getKeyCharacterMap().getModifierBehavior()
+ == KeyCharacterMap.MODIFIER_BEHAVIOR_CHORDED_OR_TOGGLED) {
+ metaState |= getMetaState(text);
+ }
+ return metaState;
+ }
+
+ // As META_SELECTING is @hide we should not mention it in public comments, hence the
+ // omission in @param meta
+ /**
* Gets the state of a particular meta key.
*
- * @param meta META_SHIFT_ON, META_ALT_ON, META_SYM_ON, or META_SELECTING
+ * @param meta META_SHIFT_ON, META_ALT_ON, META_SYM_ON
* @param text the buffer in which the meta key would have been pressed.
*
* @return 0 if inactive, 1 if active, 2 if locked.
@@ -171,22 +199,53 @@ public abstract class MetaKeyKeyListener {
public static final int getMetaState(CharSequence text, int meta) {
switch (meta) {
case META_SHIFT_ON:
- return getActive(text, CAP, 1, 2);
+ return getActive(text, CAP, PRESSED_RETURN_VALUE, LOCKED_RETURN_VALUE);
case META_ALT_ON:
- return getActive(text, ALT, 1, 2);
+ return getActive(text, ALT, PRESSED_RETURN_VALUE, LOCKED_RETURN_VALUE);
case META_SYM_ON:
- return getActive(text, SYM, 1, 2);
+ return getActive(text, SYM, PRESSED_RETURN_VALUE, LOCKED_RETURN_VALUE);
case META_SELECTING:
- return getActive(text, SELECTING, 1, 2);
+ return getActive(text, SELECTING, PRESSED_RETURN_VALUE, LOCKED_RETURN_VALUE);
default:
return 0;
}
}
+ /**
+ * Gets the state of a particular meta key to use with a particular key event.
+ *
+ * If the key event has been created by a device that does not support toggled
+ * key modifiers, like a virtual keyboard for example, only the meta state in
+ * the key event is considered.
+ *
+ * @param meta META_SHIFT_ON, META_ALT_ON, META_SYM_ON
+ * @param text the buffer in which the meta key would have been pressed.
+ * @param event the event for which to evaluate the meta state.
+ * @return 0 if inactive, 1 if active, 2 if locked.
+ */
+ public static final int getMetaState(final CharSequence text, final int meta,
+ final KeyEvent event) {
+ int metaState = event.getMetaState();
+ if (event.getKeyCharacterMap().getModifierBehavior()
+ == KeyCharacterMap.MODIFIER_BEHAVIOR_CHORDED_OR_TOGGLED) {
+ metaState |= getMetaState(text);
+ }
+ if (META_SELECTING == meta) {
+ // #getMetaState(long, int) does not support META_SELECTING, but we want the same
+ // behavior as #getMetaState(CharSequence, int) so we need to do it here
+ if ((metaState & META_SELECTING) != 0) {
+ // META_SELECTING is only ever set to PRESSED and can't be LOCKED, so return 1
+ return 1;
+ }
+ return 0;
+ }
+ return getMetaState(metaState, meta);
+ }
+
private static int getActive(CharSequence text, Object meta,
int on, int lock) {
if (!(text instanceof Spanned)) {
@@ -430,18 +489,18 @@ public abstract class MetaKeyKeyListener {
public static final int getMetaState(long state, int meta) {
switch (meta) {
case META_SHIFT_ON:
- if ((state & META_CAP_LOCKED) != 0) return 2;
- if ((state & META_SHIFT_ON) != 0) return 1;
+ if ((state & META_CAP_LOCKED) != 0) return LOCKED_RETURN_VALUE;
+ if ((state & META_SHIFT_ON) != 0) return PRESSED_RETURN_VALUE;
return 0;
case META_ALT_ON:
- if ((state & META_ALT_LOCKED) != 0) return 2;
- if ((state & META_ALT_ON) != 0) return 1;
+ if ((state & META_ALT_LOCKED) != 0) return LOCKED_RETURN_VALUE;
+ if ((state & META_ALT_ON) != 0) return PRESSED_RETURN_VALUE;
return 0;
case META_SYM_ON:
- if ((state & META_SYM_LOCKED) != 0) return 2;
- if ((state & META_SYM_ON) != 0) return 1;
+ if ((state & META_SYM_LOCKED) != 0) return LOCKED_RETURN_VALUE;
+ if ((state & META_SYM_ON) != 0) return PRESSED_RETURN_VALUE;
return 0;
default:
@@ -599,4 +658,3 @@ public abstract class MetaKeyKeyListener {
private static final int LOCKED =
Spannable.SPAN_MARK_MARK | (4 << Spannable.SPAN_USER_SHIFT);
}
-
diff --git a/core/java/android/text/method/NumberKeyListener.java b/core/java/android/text/method/NumberKeyListener.java
index 5d4c732..988d566 100644
--- a/core/java/android/text/method/NumberKeyListener.java
+++ b/core/java/android/text/method/NumberKeyListener.java
@@ -41,7 +41,7 @@ public abstract class NumberKeyListener extends BaseKeyListener
protected abstract char[] getAcceptedChars();
protected int lookup(KeyEvent event, Spannable content) {
- return event.getMatch(getAcceptedChars(), event.getMetaState() | getMetaState(content));
+ return event.getMatch(getAcceptedChars(), getMetaState(content, event));
}
public CharSequence filter(CharSequence source, int start, int end,
diff --git a/core/java/android/text/method/QwertyKeyListener.java b/core/java/android/text/method/QwertyKeyListener.java
index 98316ae..0bd46bc 100644
--- a/core/java/android/text/method/QwertyKeyListener.java
+++ b/core/java/android/text/method/QwertyKeyListener.java
@@ -108,7 +108,7 @@ public class QwertyKeyListener extends BaseKeyListener {
// QWERTY keyboard normal case
- int i = event.getUnicodeChar(event.getMetaState() | getMetaState(content));
+ int i = event.getUnicodeChar(getMetaState(content, event));
if (!mFullKeyboard) {
int count = event.getRepeatCount();
diff --git a/core/java/android/util/ArrayMap.java b/core/java/android/util/ArrayMap.java
new file mode 100644
index 0000000..6da7546
--- /dev/null
+++ b/core/java/android/util/ArrayMap.java
@@ -0,0 +1,617 @@
+/*
+ * 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 android.util;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * ArrayMap is a generic key->value mapping data structure that is
+ * designed to be more memory efficient than a traditional {@link java.util.HashMap}.
+ * It keeps its mappings in an array data structure -- an integer array of hash
+ * codes for each item, and an Object array of the key/value pairs. This allows it to
+ * avoid having to create an extra object for every entry put in to the map, and it
+ * also tries to control the growth of the size of these arrays more aggressively
+ * (since growing them only requires copying the entries in the array, not rebuilding
+ * a hash map).
+ *
+ * <p>Note that this implementation is not intended to be appropriate for data structures
+ * that may contain large numbers of items. It is generally slower than a traditional
+ * HashMap, since lookups require a binary search and adds and removes require inserting
+ * and deleting entries in the array. For containers holding up to hundreds of items,
+ * the performance difference is not significant, less than 50%. For larger numbers of items
+ * this data structure should be avoided.</p>
+ *
+ * <p><b>Note:</b> unlike {@link java.util.HashMap}, this container does not support
+ * null keys.</p>
+ *
+ * <p>Because this container is intended to better balance memory use, unlike most other
+ * standard Java containers it will shrink its array as items are removed from it. Currently
+ * you have no control over this shrinking -- if you set a capacity and then remove an
+ * item, it may reduce the capacity to better match the current size. In the future an
+ * explicitly call to set the capacity should turn off this aggressive shrinking behavior.</p>
+ *
+ * @hide
+ */
+public final class ArrayMap<K, V> implements Map<K, V> {
+ private static final boolean DEBUG = false;
+ private static final String TAG = "ArrayMap";
+
+ /**
+ * The minimum amount by which the capacity of a ArrayMap will increase.
+ * This is tuned to be relatively space-efficient.
+ */
+ private static final int BASE_SIZE = 4;
+
+ /**
+ * Maximum number of entries to have in array caches.
+ */
+ private static final int CACHE_SIZE = 10;
+
+ /**
+ * Caches of small array objects to avoid spamming garbage. The cache
+ * Object[] variable is a pointer to a linked list of array objects.
+ * The first entry in the array is a pointer to the next array in the
+ * list; the second entry is a pointer to the int[] hash code array for it.
+ */
+ static Object[] mBaseCache;
+ static int mBaseCacheSize;
+ static Object[] mTwiceBaseCache;
+ static int mTwiceBaseCacheSize;
+
+ int[] mHashes;
+ Object[] mArray;
+ int mSize;
+ MapCollections<K, V> mCollections;
+
+ private int indexOf(Object key, int hash) {
+ final int N = mSize;
+
+ // Important fast case: if nothing is in here, nothing to look for.
+ if (N == 0) {
+ return ~0;
+ }
+
+ int index = SparseArray.binarySearch(mHashes, N, hash);
+
+ // If the hash code wasn't found, then we have no entry for this key.
+ if (index < 0) {
+ return index;
+ }
+
+ // If the key at the returned index matches, that's what we want.
+ if (mArray[index<<1].equals(key)) {
+ return index;
+ }
+
+ // Search for a matching key after the index.
+ int end;
+ for (end = index + 1; end < N && mHashes[end] == hash; end++) {
+ if (mArray[end << 1].equals(key)) return end;
+ }
+
+ // Search for a matching key before the index.
+ for (int i = index - 1; i >= 0 && mHashes[i] == hash; i--) {
+ if (mArray[i << 1].equals(key)) return i;
+ }
+
+ // Key not found -- return negative value indicating where a
+ // new entry for this key should go. We use the end of the
+ // hash chain to reduce the number of array entries that will
+ // need to be copied when inserting.
+ return ~end;
+ }
+
+ private void allocArrays(final int size) {
+ if (size == (BASE_SIZE*2)) {
+ synchronized (ArrayMap.class) {
+ if (mTwiceBaseCache != null) {
+ final Object[] array = mTwiceBaseCache;
+ mArray = array;
+ mTwiceBaseCache = (Object[])array[0];
+ mHashes = (int[])array[1];
+ array[0] = array[1] = null;
+ mTwiceBaseCacheSize--;
+ if (DEBUG) Log.d(TAG, "Retrieving 2x cache " + mHashes
+ + " now have " + mTwiceBaseCacheSize + " entries");
+ return;
+ }
+ }
+ } else if (size == BASE_SIZE) {
+ synchronized (ArrayMap.class) {
+ if (mBaseCache != null) {
+ final Object[] array = mBaseCache;
+ mArray = array;
+ mBaseCache = (Object[])array[0];
+ mHashes = (int[])array[1];
+ array[0] = array[1] = null;
+ mBaseCacheSize--;
+ if (DEBUG) Log.d(TAG, "Retrieving 1x cache " + mHashes
+ + " now have " + mBaseCacheSize + " entries");
+ return;
+ }
+ }
+ }
+
+ mHashes = new int[size];
+ mArray = new Object[size<<1];
+ }
+
+ private static void freeArrays(final int[] hashes, final Object[] array, final int size) {
+ if (hashes.length == (BASE_SIZE*2)) {
+ synchronized (ArrayMap.class) {
+ if (mTwiceBaseCacheSize < CACHE_SIZE) {
+ array[0] = mTwiceBaseCache;
+ array[1] = hashes;
+ for (int i=(size<<1)-1; i>=2; i--) {
+ array[i] = null;
+ }
+ mTwiceBaseCache = array;
+ mTwiceBaseCacheSize++;
+ if (DEBUG) Log.d(TAG, "Storing 2x cache " + array
+ + " now have " + mTwiceBaseCacheSize + " entries");
+ }
+ }
+ } else if (hashes.length == BASE_SIZE) {
+ synchronized (ArrayMap.class) {
+ if (mBaseCacheSize < CACHE_SIZE) {
+ array[0] = mBaseCache;
+ array[1] = hashes;
+ for (int i=(size<<1)-1; i>=2; i--) {
+ array[i] = null;
+ }
+ mBaseCache = array;
+ mBaseCacheSize++;
+ if (DEBUG) Log.d(TAG, "Storing 1x cache " + array
+ + " now have " + mBaseCacheSize + " entries");
+ }
+ }
+ }
+ }
+
+ /**
+ * Create a new empty ArrayMap. The default capacity of an array map is 0, and
+ * will grow once items are added to it.
+ */
+ public ArrayMap() {
+ mHashes = SparseArray.EMPTY_INTS;
+ mArray = SparseArray.EMPTY_OBJECTS;
+ mSize = 0;
+ }
+
+ /**
+ * Create a new ArrayMap with a given initial capacity.
+ */
+ public ArrayMap(int capacity) {
+ if (capacity == 0) {
+ mHashes = SparseArray.EMPTY_INTS;
+ mArray = SparseArray.EMPTY_OBJECTS;
+ } else {
+ allocArrays(capacity);
+ }
+ mSize = 0;
+ }
+
+ /**
+ * Make the array map empty. All storage is released.
+ */
+ @Override
+ public void clear() {
+ if (mSize != 0) {
+ freeArrays(mHashes, mArray, mSize);
+ mHashes = SparseArray.EMPTY_INTS;
+ mArray = SparseArray.EMPTY_OBJECTS;
+ mSize = 0;
+ }
+ }
+
+ /**
+ * Ensure the array map can hold at least <var>minimumCapacity</var>
+ * items.
+ */
+ public void ensureCapacity(int minimumCapacity) {
+ if (mHashes.length < minimumCapacity) {
+ int[] ohashes = mHashes;
+ Object[] oarray = mArray;
+ allocArrays(minimumCapacity);
+ if (mSize > 0) {
+ System.arraycopy(ohashes, 0, mHashes, 0, mSize);
+ System.arraycopy(oarray, 0, mArray, 0, mSize<<1);
+ }
+ freeArrays(ohashes, oarray, mSize);
+ }
+ }
+
+ /**
+ * Check whether a key exists in the array.
+ *
+ * @param key The key to search for.
+ * @return Returns true if the key exists, else false.
+ */
+ @Override
+ public boolean containsKey(Object key) {
+ return indexOf(key, key.hashCode()) >= 0;
+ }
+
+ private int indexOfValue(Object value) {
+ final int N = mSize*2;
+ final Object[] array = mArray;
+ if (value == null) {
+ for (int i=1; i<N; i+=2) {
+ if (array[i] == null) {
+ return i>>1;
+ }
+ }
+ } else {
+ for (int i=1; i<N; i+=2) {
+ if (value.equals(array[i])) {
+ return i>>1;
+ }
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * Check whether a value exists in the array. This requires a linear search
+ * through the entire array.
+ *
+ * @param value The value to search for.
+ * @return Returns true if the value exists, else false.
+ */
+ @Override
+ public boolean containsValue(Object value) {
+ return indexOfValue(value) >= 0;
+ }
+
+ /**
+ * Retrieve a value from the array.
+ * @param key The key of the value to retrieve.
+ * @return Returns the value associated with the given key,
+ * or null if there is no such key.
+ */
+ @Override
+ public V get(Object key) {
+ final int index = indexOf(key, key.hashCode());
+ return index >= 0 ? (V)mArray[(index<<1)+1] : null;
+ }
+
+ /**
+ * Return the key at the given index in the array.
+ * @param index The desired index, must be between 0 and {@link #size()}-1.
+ * @return Returns the key stored at the given index.
+ */
+ public K keyAt(int index) {
+ return (K)mArray[index << 1];
+ }
+
+ /**
+ * Return the value at the given index in the array.
+ * @param index The desired index, must be between 0 and {@link #size()}-1.
+ * @return Returns the value stored at the given index.
+ */
+ public V valueAt(int index) {
+ return (V)mArray[(index << 1) + 1];
+ }
+
+ /**
+ * Set the value at a given index in the array.
+ * @param index The desired index, must be between 0 and {@link #size()}-1.
+ * @param value The new value to store at this index.
+ * @return Returns the previous value at the given index.
+ */
+ public V setValueAt(int index, V value) {
+ index = (index << 1) + 1;
+ V old = (V)mArray[index];
+ mArray[index] = value;
+ return old;
+ }
+
+ /**
+ * Return true if the array map contains no items.
+ */
+ @Override
+ public boolean isEmpty() {
+ return mSize <= 0;
+ }
+
+ /**
+ * Add a new value to the array map.
+ * @param key The key under which to store the value. <b>Must not be null.</b> If
+ * this key already exists in the array, its value will be replaced.
+ * @param value The value to store for the given key.
+ * @return Returns the old value that was stored for the given key, or null if there
+ * was no such key.
+ */
+ @Override
+ public V put(K key, V value) {
+ final int hash = key.hashCode();
+ int index = indexOf(key, hash);
+ if (index >= 0) {
+ index = (index<<1) + 1;
+ final V old = (V)mArray[index];
+ mArray[index] = value;
+ return old;
+ }
+
+ index = ~index;
+ if (mSize >= mHashes.length) {
+ final int n = mSize >= (BASE_SIZE*2) ? (mSize+(mSize>>1))
+ : (mSize >= BASE_SIZE ? (BASE_SIZE*2) : BASE_SIZE);
+
+ if (DEBUG) Log.d(TAG, "put: grow from " + mHashes.length + " to " + n);
+
+ final int[] ohashes = mHashes;
+ final Object[] oarray = mArray;
+ allocArrays(n);
+
+ if (mHashes.length > 0) {
+ if (DEBUG) Log.d(TAG, "put: copy 0-" + mSize + " to 0");
+ System.arraycopy(ohashes, 0, mHashes, 0, ohashes.length);
+ System.arraycopy(oarray, 0, mArray, 0, oarray.length);
+ }
+
+ freeArrays(ohashes, oarray, mSize);
+ }
+
+ if (index < mSize) {
+ if (DEBUG) Log.d(TAG, "put: move " + index + "-" + (mSize-index)
+ + " to " + (index+1));
+ System.arraycopy(mHashes, index, mHashes, index + 1, mSize - index);
+ System.arraycopy(mArray, index << 1, mArray, (index + 1) << 1, (mSize - index) << 1);
+ }
+
+ mHashes[index] = hash;
+ mArray[index<<1] = key;
+ mArray[(index<<1)+1] = value;
+ mSize++;
+ return null;
+ }
+
+ /**
+ * Perform a {@link #put(Object, Object)} of all key/value pairs in <var>array</var>
+ * @param array The array whose contents are to be retrieved.
+ */
+ public void putAll(ArrayMap<? extends K, ? extends V> array) {
+ final int N = array.mSize;
+ ensureCapacity(mSize + N);
+ for (int i=0; i<N; i++) {
+ put(array.keyAt(i), array.valueAt(i));
+ }
+ }
+
+ /**
+ * Remove an existing key from the array map.
+ * @param key The key of the mapping to remove.
+ * @return Returns the value that was stored under the key, or null if there
+ * was no such key.
+ */
+ @Override
+ public V remove(Object key) {
+ int index = indexOf(key, key.hashCode());
+ if (index >= 0) {
+ return removeAt(index);
+ }
+
+ return null;
+ }
+
+ /**
+ * Remove the key/value mapping at the given index.
+ * @param index The desired index, must be between 0 and {@link #size()}-1.
+ * @return Returns the value that was stored at this index.
+ */
+ public V removeAt(int index) {
+ final V old = (V)mArray[(index << 1) + 1];
+ if (mSize <= 1) {
+ // Now empty.
+ if (DEBUG) Log.d(TAG, "remove: shrink from " + mHashes.length + " to 0");
+ freeArrays(mHashes, mArray, mSize);
+ mHashes = SparseArray.EMPTY_INTS;
+ mArray = SparseArray.EMPTY_OBJECTS;
+ mSize = 0;
+ } else {
+ if (mHashes.length > (BASE_SIZE*2) && mSize < mHashes.length/3) {
+ // Shrunk enough to reduce size of arrays. We don't allow it to
+ // shrink smaller than (BASE_SIZE*2) to avoid flapping between
+ // that and BASE_SIZE.
+ final int n = mSize > (BASE_SIZE*2) ? (mSize + (mSize>>1)) : (BASE_SIZE*2);
+
+ if (DEBUG) Log.d(TAG, "remove: shrink from " + mHashes.length + " to " + n);
+
+ final int[] ohashes = mHashes;
+ final Object[] oarray = mArray;
+ allocArrays(n);
+
+ mSize--;
+ if (index > 0) {
+ if (DEBUG) Log.d(TAG, "remove: copy from 0-" + index + " to 0");
+ System.arraycopy(ohashes, 0, mHashes, 0, index);
+ System.arraycopy(oarray, 0, mArray, 0, index << 1);
+ }
+ if (index < mSize) {
+ if (DEBUG) Log.d(TAG, "remove: copy from " + (index+1) + "-" + mSize
+ + " to " + index);
+ System.arraycopy(ohashes, index + 1, mHashes, index, mSize - index);
+ System.arraycopy(oarray, (index + 1) << 1, mArray, index << 1,
+ (mSize - index) << 1);
+ }
+ } else {
+ mSize--;
+ if (index < mSize) {
+ if (DEBUG) Log.d(TAG, "remove: move " + (index+1) + "-" + mSize
+ + " to " + index);
+ System.arraycopy(mHashes, index + 1, mHashes, index, mSize - index);
+ System.arraycopy(mArray, (index + 1) << 1, mArray, index << 1,
+ (mSize - index) << 1);
+ }
+ mArray[mSize << 1] = null;
+ mArray[(mSize << 1) + 1] = null;
+ }
+ }
+ return old;
+ }
+
+ /**
+ * Return the number of items in this array map.
+ */
+ @Override
+ public int size() {
+ return mSize;
+ }
+
+ // ------------------------------------------------------------------------
+ // Interop with traditional Java containers. Not as efficient as using
+ // specialized collection APIs.
+ // ------------------------------------------------------------------------
+
+ private MapCollections<K, V> getCollection() {
+ if (mCollections == null) {
+ mCollections = new MapCollections<K, V>() {
+ @Override
+ protected int colGetSize() {
+ return mSize;
+ }
+
+ @Override
+ protected Object colGetEntry(int index, int offset) {
+ return mArray[(index<<1) + offset];
+ }
+
+ @Override
+ protected int colIndexOfKey(Object key) {
+ return indexOf(key, key.hashCode());
+ }
+
+ @Override
+ protected int colIndexOfValue(Object value) {
+ return indexOfValue(value);
+ }
+
+ @Override
+ protected Map<K, V> colGetMap() {
+ return ArrayMap.this;
+ }
+
+ @Override
+ protected void colPut(K key, V value) {
+ put(key, value);
+ }
+
+ @Override
+ protected V colSetValue(int index, V value) {
+ return setValueAt(index, value);
+ }
+
+ @Override
+ protected void colRemoveAt(int index) {
+ removeAt(index);
+ }
+
+ @Override
+ protected void colClear() {
+ clear();
+ }
+ };
+ }
+ return mCollections;
+ }
+
+ /**
+ * Determine if the array map contains all of the keys in the given collection.
+ * @param collection The collection whose contents are to be checked against.
+ * @return Returns true if this array map contains a key for every entry
+ * in <var>collection</var>, else returns false.
+ */
+ public boolean containsAll(Collection<?> collection) {
+ return MapCollections.containsAllHelper(this, collection);
+ }
+
+ /**
+ * Perform a {@link #put(Object, Object)} of all key/value pairs in <var>map</var>
+ * @param map The map whose contents are to be retrieved.
+ */
+ @Override
+ public void putAll(Map<? extends K, ? extends V> map) {
+ ensureCapacity(mSize + map.size());
+ for (Map.Entry<? extends K, ? extends V> entry : map.entrySet()) {
+ put(entry.getKey(), entry.getValue());
+ }
+ }
+
+ /**
+ * Remove all keys in the array map that exist in the given collection.
+ * @param collection The collection whose contents are to be used to remove keys.
+ * @return Returns true if any keys were removed from the array map, else false.
+ */
+ public boolean removeAll(Collection<?> collection) {
+ return MapCollections.removeAllHelper(this, collection);
+ }
+
+ /**
+ * Remove all keys in the array map that do <b>not</b> exist in the given collection.
+ * @param collection The collection whose contents are to be used to determine which
+ * keys to keep.
+ * @return Returns true if any keys were removed from the array map, else false.
+ */
+ public boolean retainAll(Collection<?> collection) {
+ return MapCollections.retainAllHelper(this, collection);
+ }
+
+ /**
+ * Return a {@link java.util.Set} for iterating over and interacting with all mappings
+ * in the array map.
+ *
+ * <p><b>Note:</b> this is a very inefficient way to access the array contents, it
+ * requires generating a number of temporary objects.</p>
+ *
+ * <p><b>Note:</b></p> the semantics of this
+ * Set are subtly different than that of a {@link java.util.HashMap}: most important,
+ * the {@link java.util.Map.Entry Map.Entry} object returned by its iterator is a single
+ * object that exists for the entire iterator, so you can <b>not</b> hold on to it
+ * after calling {@link java.util.Iterator#next() Iterator.next}.</p>
+ */
+ @Override
+ public Set<Map.Entry<K, V>> entrySet() {
+ return getCollection().getEntrySet();
+ }
+
+ /**
+ * Return a {@link java.util.Set} for iterating over and interacting with all keys
+ * in the array map.
+ *
+ * <p><b>Note:</b> this is a fair inefficient way to access the array contents, it
+ * requires generating a number of temporary objects.</p>
+ */
+ @Override
+ public Set<K> keySet() {
+ return getCollection().getKeySet();
+ }
+
+ /**
+ * Return a {@link java.util.Collection} for iterating over and interacting with all values
+ * in the array map.
+ *
+ * <p><b>Note:</b> this is a fair inefficient way to access the array contents, it
+ * requires generating a number of temporary objects.</p>
+ */
+ @Override
+ public Collection<V> values() {
+ return getCollection().getValues();
+ }
+}
diff --git a/core/java/android/util/LongSparseArray.java b/core/java/android/util/LongSparseArray.java
index 630e5f3..660b743 100644
--- a/core/java/android/util/LongSparseArray.java
+++ b/core/java/android/util/LongSparseArray.java
@@ -41,13 +41,19 @@ public class LongSparseArray<E> implements Cloneable {
/**
* Creates a new LongSparseArray containing no mappings that will not
* require any additional memory allocation to store the specified
- * number of mappings.
+ * number of mappings. If you supply an initial capacity of 0, the
+ * sparse array will be initialized with a light-weight representation
+ * not requiring any additional array allocations.
*/
public LongSparseArray(int initialCapacity) {
- initialCapacity = ArrayUtils.idealLongArraySize(initialCapacity);
-
- mKeys = new long[initialCapacity];
- mValues = new Object[initialCapacity];
+ if (initialCapacity == 0) {
+ mKeys = SparseLongArray.EMPTY_LONGS;
+ mValues = SparseArray.EMPTY_OBJECTS;
+ } else {
+ initialCapacity = ArrayUtils.idealLongArraySize(initialCapacity);
+ mKeys = new long[initialCapacity];
+ mValues = new Object[initialCapacity];
+ }
mSize = 0;
}
diff --git a/core/java/android/util/LongSparseLongArray.java b/core/java/android/util/LongSparseLongArray.java
index 34b6126..503295c 100644
--- a/core/java/android/util/LongSparseLongArray.java
+++ b/core/java/android/util/LongSparseLongArray.java
@@ -42,13 +42,19 @@ public class LongSparseLongArray implements Cloneable {
/**
* Creates a new SparseLongArray containing no mappings that will not
* require any additional memory allocation to store the specified
- * number of mappings.
+ * number of mappings. If you supply an initial capacity of 0, the
+ * sparse array will be initialized with a light-weight representation
+ * not requiring any additional array allocations.
*/
public LongSparseLongArray(int initialCapacity) {
- initialCapacity = ArrayUtils.idealLongArraySize(initialCapacity);
-
- mKeys = new long[initialCapacity];
- mValues = new long[initialCapacity];
+ if (initialCapacity == 0) {
+ mKeys = SparseLongArray.EMPTY_LONGS;
+ mValues = SparseLongArray.EMPTY_LONGS;
+ } else {
+ initialCapacity = ArrayUtils.idealLongArraySize(initialCapacity);
+ mKeys = new long[initialCapacity];
+ mValues = new long[initialCapacity];
+ }
mSize = 0;
}
diff --git a/core/java/android/util/MapCollections.java b/core/java/android/util/MapCollections.java
new file mode 100644
index 0000000..f29fb65
--- /dev/null
+++ b/core/java/android/util/MapCollections.java
@@ -0,0 +1,496 @@
+/*
+ * 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 android.util;
+
+import libcore.util.Objects;
+
+import java.lang.reflect.Array;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Helper for writing standard Java collection interfaces to a data
+ * structure like {@link ArrayMap}.
+ * @hide
+ */
+abstract class MapCollections<K, V> {
+ EntrySet mEntrySet;
+ KeySet mKeySet;
+ ValuesCollection mValues;
+
+ final class ArrayIterator<T> implements Iterator<T> {
+ final int mOffset;
+ int mSize;
+ int mIndex;
+ boolean mCanRemove = false;
+
+ ArrayIterator(int offset) {
+ mOffset = offset;
+ mSize = colGetSize();
+ }
+
+ @Override
+ public boolean hasNext() {
+ return mIndex < mSize;
+ }
+
+ @Override
+ public T next() {
+ Object res = colGetEntry(mIndex, mOffset);
+ mIndex++;
+ mCanRemove = true;
+ return (T)res;
+ }
+
+ @Override
+ public void remove() {
+ if (!mCanRemove) {
+ throw new IllegalStateException();
+ }
+ mIndex--;
+ mSize--;
+ mCanRemove = false;
+ colRemoveAt(mIndex);
+ }
+ }
+
+ final class MapIterator implements Iterator<Map.Entry<K, V>>, Map.Entry<K, V> {
+ int mEnd;
+ int mIndex;
+ boolean mEntryValid = false;
+
+ MapIterator() {
+ mEnd = colGetSize() - 1;
+ mIndex = -1;
+ }
+
+ @Override
+ public boolean hasNext() {
+ return mIndex < mEnd;
+ }
+
+ @Override
+ public Map.Entry<K, V> next() {
+ mIndex++;
+ mEntryValid = true;
+ return this;
+ }
+
+ @Override
+ public void remove() {
+ if (!mEntryValid) {
+ throw new IllegalStateException();
+ }
+ mIndex--;
+ mEnd--;
+ mEntryValid = false;
+ colRemoveAt(mIndex);
+ }
+
+ @Override
+ public K getKey() {
+ if (!mEntryValid) {
+ throw new IllegalStateException(
+ "This container does not support retaining Map.Entry objects");
+ }
+ return (K)colGetEntry(mIndex, 0);
+ }
+
+ @Override
+ public V getValue() {
+ if (!mEntryValid) {
+ throw new IllegalStateException(
+ "This container does not support retaining Map.Entry objects");
+ }
+ return (V)colGetEntry(mIndex, 1);
+ }
+
+ @Override
+ public V setValue(V object) {
+ if (!mEntryValid) {
+ throw new IllegalStateException(
+ "This container does not support retaining Map.Entry objects");
+ }
+ return colSetValue(mIndex, object);
+ }
+
+ @Override
+ public final boolean equals(Object o) {
+ if (!mEntryValid) {
+ throw new IllegalStateException(
+ "This container does not support retaining Map.Entry objects");
+ }
+ if (!(o instanceof Map.Entry)) {
+ return false;
+ }
+ Map.Entry<?, ?> e = (Map.Entry<?, ?>) o;
+ return Objects.equal(e.getKey(), colGetEntry(mIndex, 0))
+ && Objects.equal(e.getValue(), colGetEntry(mIndex, 1));
+ }
+
+ @Override
+ public final int hashCode() {
+ if (!mEntryValid) {
+ throw new IllegalStateException(
+ "This container does not support retaining Map.Entry objects");
+ }
+ final Object key = colGetEntry(mIndex, 0);
+ final Object value = colGetEntry(mIndex, 1);
+ return (key == null ? 0 : key.hashCode()) ^
+ (value == null ? 0 : value.hashCode());
+ }
+
+ @Override
+ public final String toString() {
+ return getKey() + "=" + getValue();
+ }
+ }
+
+ final class EntrySet implements Set<Map.Entry<K, V>> {
+ @Override
+ public boolean add(Map.Entry<K, V> object) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean addAll(Collection<? extends Map.Entry<K, V>> collection) {
+ int oldSize = colGetSize();
+ for (Map.Entry<K, V> entry : collection) {
+ colPut(entry.getKey(), entry.getValue());
+ }
+ return oldSize != colGetSize();
+ }
+
+ @Override
+ public void clear() {
+ colClear();
+ }
+
+ @Override
+ public boolean contains(Object object) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean containsAll(Collection<?> collection) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return colGetSize() == 0;
+ }
+
+ @Override
+ public Iterator<Map.Entry<K, V>> iterator() {
+ return new MapIterator();
+ }
+
+ @Override
+ public boolean remove(Object object) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean removeAll(Collection<?> collection) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean retainAll(Collection<?> collection) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int size() {
+ return colGetSize();
+ }
+
+ @Override
+ public Object[] toArray() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public <T> T[] toArray(T[] array) {
+ throw new UnsupportedOperationException();
+ }
+ };
+
+ final class KeySet implements Set<K> {
+
+ @Override
+ public boolean add(K object) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean addAll(Collection<? extends K> collection) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void clear() {
+ colClear();
+ }
+
+ @Override
+ public boolean contains(Object object) {
+ return colIndexOfKey(object) >= 0;
+ }
+
+ @Override
+ public boolean containsAll(Collection<?> collection) {
+ return removeAllHelper(colGetMap(), collection);
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return colGetSize() == 0;
+ }
+
+ @Override
+ public Iterator<K> iterator() {
+ return new ArrayIterator<K>(0);
+ }
+
+ @Override
+ public boolean remove(Object object) {
+ int index = colIndexOfKey(object);
+ if (index >= 0) {
+ colRemoveAt(index);
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public boolean removeAll(Collection<?> collection) {
+ return removeAllHelper(colGetMap(), collection);
+ }
+
+ @Override
+ public boolean retainAll(Collection<?> collection) {
+ return retainAllHelper(colGetMap(), collection);
+ }
+
+ @Override
+ public int size() {
+ return colGetSize();
+ }
+
+ @Override
+ public Object[] toArray() {
+ return toArrayHelper(1);
+ }
+
+ @Override
+ public <T> T[] toArray(T[] array) {
+ return toArrayHelper(array, 1);
+ }
+ };
+
+ final class ValuesCollection implements Collection<V> {
+
+ @Override
+ public boolean add(V object) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean addAll(Collection<? extends V> collection) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void clear() {
+ colClear();
+ }
+
+ @Override
+ public boolean contains(Object object) {
+ return colIndexOfValue(object) >= 0;
+ }
+
+ @Override
+ public boolean containsAll(Collection<?> collection) {
+ Iterator<?> it = collection.iterator();
+ while (it.hasNext()) {
+ if (!contains(it.next())) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return colGetSize() == 0;
+ }
+
+ @Override
+ public Iterator<V> iterator() {
+ return new ArrayIterator<V>(1);
+ }
+
+ @Override
+ public boolean remove(Object object) {
+ int index = colIndexOfValue(object);
+ if (index >= 0) {
+ colRemoveAt(index);
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public boolean removeAll(Collection<?> collection) {
+ int N = colGetSize();
+ boolean changed = false;
+ for (int i=0; i<N; i++) {
+ Object cur = colGetEntry(i, 1);
+ if (collection.contains(cur)) {
+ colRemoveAt(i);
+ i--;
+ N--;
+ changed = true;
+ }
+ }
+ return changed;
+ }
+
+ @Override
+ public boolean retainAll(Collection<?> collection) {
+ int N = colGetSize();
+ boolean changed = false;
+ for (int i=0; i<N; i++) {
+ Object cur = colGetEntry(i, 1);
+ if (!collection.contains(cur)) {
+ colRemoveAt(i);
+ i--;
+ N--;
+ changed = true;
+ }
+ }
+ return changed;
+ }
+
+ @Override
+ public int size() {
+ return colGetSize();
+ }
+
+ @Override
+ public Object[] toArray() {
+ return toArrayHelper(1);
+ }
+
+ @Override
+ public <T> T[] toArray(T[] array) {
+ return toArrayHelper(array, 1);
+ }
+ };
+
+ public static <K, V> boolean containsAllHelper(Map<K, V> map, Collection<?> collection) {
+ Iterator<?> it = collection.iterator();
+ while (it.hasNext()) {
+ if (!map.containsKey(it.next())) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public static <K, V> boolean removeAllHelper(Map<K, V> map, Collection<?> collection) {
+ int oldSize = map.size();
+ Iterator<?> it = collection.iterator();
+ while (it.hasNext()) {
+ map.remove(it.next());
+ }
+ return oldSize != map.size();
+ }
+
+ public static <K, V> boolean retainAllHelper(Map<K, V> map, Collection<?> collection) {
+ int oldSize = map.size();
+ Iterator<K> it = map.keySet().iterator();
+ while (it.hasNext()) {
+ if (!collection.contains(it.next())) {
+ it.remove();
+ }
+ }
+ return oldSize != map.size();
+ }
+
+
+ public Object[] toArrayHelper(int offset) {
+ final int N = colGetSize();
+ Object[] result = new Object[N];
+ for (int i=0; i<N; i++) {
+ result[i] = colGetEntry(i, offset);
+ }
+ return result;
+ }
+
+ public <T> T[] toArrayHelper(T[] array, int offset) {
+ final int N = colGetSize();
+ if (array.length < N) {
+ @SuppressWarnings("unchecked") T[] newArray
+ = (T[]) Array.newInstance(array.getClass().getComponentType(), N);
+ array = newArray;
+ }
+ for (int i=0; i<N; i++) {
+ array[i] = (T)colGetEntry(i, offset);
+ }
+ if (array.length > N) {
+ array[N] = null;
+ }
+ return array;
+ }
+
+ public Set<Map.Entry<K, V>> getEntrySet() {
+ if (mEntrySet == null) {
+ mEntrySet = new EntrySet();
+ }
+ return mEntrySet;
+ }
+
+ public Set<K> getKeySet() {
+ if (mKeySet == null) {
+ mKeySet = new KeySet();
+ }
+ return mKeySet;
+ }
+
+ public Collection<V> getValues() {
+ if (mValues == null) {
+ mValues = new ValuesCollection();
+ }
+ return mValues;
+ }
+
+ protected abstract int colGetSize();
+ protected abstract Object colGetEntry(int index, int offset);
+ protected abstract int colIndexOfKey(Object key);
+ protected abstract int colIndexOfValue(Object key);
+ protected abstract Map<K, V> colGetMap();
+ protected abstract void colPut(K key, V value);
+ protected abstract V colSetValue(int index, V value);
+ protected abstract void colRemoveAt(int index);
+ protected abstract void colClear();
+}
diff --git a/core/java/android/util/SparseArray.java b/core/java/android/util/SparseArray.java
index 7e8fee5..001fc5b 100644
--- a/core/java/android/util/SparseArray.java
+++ b/core/java/android/util/SparseArray.java
@@ -25,6 +25,8 @@ import com.android.internal.util.ArrayUtils;
*/
public class SparseArray<E> implements Cloneable {
private static final Object DELETED = new Object();
+ static final int[] EMPTY_INTS = new int[0];
+ static final Object[] EMPTY_OBJECTS = new Object[0];
private boolean mGarbage = false;
private int[] mKeys;
@@ -41,13 +43,19 @@ public class SparseArray<E> implements Cloneable {
/**
* Creates a new SparseArray containing no mappings that will not
* require any additional memory allocation to store the specified
- * number of mappings.
+ * number of mappings. If you supply an initial capacity of 0, the
+ * sparse array will be initialized with a light-weight representation
+ * not requiring any additional array allocations.
*/
public SparseArray(int initialCapacity) {
- initialCapacity = ArrayUtils.idealIntArraySize(initialCapacity);
-
- mKeys = new int[initialCapacity];
- mValues = new Object[initialCapacity];
+ if (initialCapacity == 0) {
+ mKeys = EMPTY_INTS;
+ mValues = EMPTY_OBJECTS;
+ } else {
+ initialCapacity = ArrayUtils.idealIntArraySize(initialCapacity);
+ mKeys = new int[initialCapacity];
+ mValues = new Object[initialCapacity];
+ }
mSize = 0;
}
@@ -79,7 +87,7 @@ public class SparseArray<E> implements Cloneable {
*/
@SuppressWarnings("unchecked")
public E get(int key, E valueIfKeyNotFound) {
- int i = binarySearch(mKeys, 0, mSize, key);
+ int i = binarySearch(mKeys, mSize, key);
if (i < 0 || mValues[i] == DELETED) {
return valueIfKeyNotFound;
@@ -92,7 +100,7 @@ public class SparseArray<E> implements Cloneable {
* Removes the mapping from the specified key, if there was any.
*/
public void delete(int key) {
- int i = binarySearch(mKeys, 0, mSize, key);
+ int i = binarySearch(mKeys, mSize, key);
if (i >= 0) {
if (mValues[i] != DELETED) {
@@ -153,7 +161,7 @@ public class SparseArray<E> implements Cloneable {
* was one.
*/
public void put(int key, E value) {
- int i = binarySearch(mKeys, 0, mSize, key);
+ int i = binarySearch(mKeys, mSize, key);
if (i >= 0) {
mValues[i] = value;
@@ -170,7 +178,7 @@ public class SparseArray<E> implements Cloneable {
gc();
// Search again because indices may have changed.
- i = ~binarySearch(mKeys, 0, mSize, key);
+ i = ~binarySearch(mKeys, mSize, key);
}
if (mSize >= mKeys.length) {
@@ -261,7 +269,7 @@ public class SparseArray<E> implements Cloneable {
gc();
}
- return binarySearch(mKeys, 0, mSize, key);
+ return binarySearch(mKeys, mSize, key);
}
/**
@@ -335,23 +343,23 @@ public class SparseArray<E> implements Cloneable {
mSize = pos + 1;
}
- private static int binarySearch(int[] a, int start, int len, int key) {
- int high = start + len, low = start - 1, guess;
-
- while (high - low > 1) {
- guess = (high + low) / 2;
-
- if (a[guess] < key)
- low = guess;
- else
- high = guess;
+ // This is Arrays.binarySearch(), but doesn't do any argument validation.
+ static int binarySearch(int[] array, int size, int value) {
+ int lo = 0;
+ int hi = size - 1;
+
+ while (lo <= hi) {
+ int mid = (lo + hi) >>> 1;
+ int midVal = array[mid];
+
+ if (midVal < value) {
+ lo = mid + 1;
+ } else if (midVal > value) {
+ hi = mid - 1;
+ } else {
+ return mid; // value found
+ }
}
-
- if (high == start + len)
- return ~(start + len);
- else if (a[high] == key)
- return high;
- else
- return ~high;
+ return ~lo; // value not present
}
}
diff --git a/core/java/android/util/SparseBooleanArray.java b/core/java/android/util/SparseBooleanArray.java
index 76c47c6..73e3629 100644
--- a/core/java/android/util/SparseBooleanArray.java
+++ b/core/java/android/util/SparseBooleanArray.java
@@ -25,6 +25,8 @@ import com.android.internal.util.ArrayUtils;
* than using a HashMap to map Integers to Booleans.
*/
public class SparseBooleanArray implements Cloneable {
+ static final boolean[] EMPTY_BOOLEANS = new boolean[0];
+
/**
* Creates a new SparseBooleanArray containing no mappings.
*/
@@ -35,13 +37,19 @@ public class SparseBooleanArray implements Cloneable {
/**
* Creates a new SparseBooleanArray containing no mappings that will not
* require any additional memory allocation to store the specified
- * number of mappings.
+ * number of mappings. If you supply an initial capacity of 0, the
+ * sparse array will be initialized with a light-weight representation
+ * not requiring any additional array allocations.
*/
public SparseBooleanArray(int initialCapacity) {
- initialCapacity = ArrayUtils.idealIntArraySize(initialCapacity);
-
- mKeys = new int[initialCapacity];
- mValues = new boolean[initialCapacity];
+ if (initialCapacity == 0) {
+ mKeys = SparseArray.EMPTY_INTS;
+ mValues = EMPTY_BOOLEANS;
+ } else {
+ initialCapacity = ArrayUtils.idealIntArraySize(initialCapacity);
+ mKeys = new int[initialCapacity];
+ mValues = new boolean[initialCapacity];
+ }
mSize = 0;
}
@@ -71,7 +79,7 @@ public class SparseBooleanArray implements Cloneable {
* if no such mapping has been made.
*/
public boolean get(int key, boolean valueIfKeyNotFound) {
- int i = binarySearch(mKeys, 0, mSize, key);
+ int i = SparseArray.binarySearch(mKeys, mSize, key);
if (i < 0) {
return valueIfKeyNotFound;
@@ -84,7 +92,7 @@ public class SparseBooleanArray implements Cloneable {
* Removes the mapping from the specified key, if there was any.
*/
public void delete(int key) {
- int i = binarySearch(mKeys, 0, mSize, key);
+ int i = SparseArray.binarySearch(mKeys, mSize, key);
if (i >= 0) {
System.arraycopy(mKeys, i + 1, mKeys, i, mSize - (i + 1));
@@ -99,7 +107,7 @@ public class SparseBooleanArray implements Cloneable {
* was one.
*/
public void put(int key, boolean value) {
- int i = binarySearch(mKeys, 0, mSize, key);
+ int i = SparseArray.binarySearch(mKeys, mSize, key);
if (i >= 0) {
mValues[i] = value;
@@ -164,7 +172,7 @@ public class SparseBooleanArray implements Cloneable {
* key is not mapped.
*/
public int indexOfKey(int key) {
- return binarySearch(mKeys, 0, mSize, key);
+ return SparseArray.binarySearch(mKeys, mSize, key);
}
/**
@@ -220,26 +228,6 @@ public class SparseBooleanArray implements Cloneable {
mSize = pos + 1;
}
- private static int binarySearch(int[] a, int start, int len, int key) {
- int high = start + len, low = start - 1, guess;
-
- while (high - low > 1) {
- guess = (high + low) / 2;
-
- if (a[guess] < key)
- low = guess;
- else
- high = guess;
- }
-
- if (high == start + len)
- return ~(start + len);
- else if (a[high] == key)
- return high;
- else
- return ~high;
- }
-
private int[] mKeys;
private boolean[] mValues;
private int mSize;
diff --git a/core/java/android/util/SparseIntArray.java b/core/java/android/util/SparseIntArray.java
index 8d11177..122f7f5 100644
--- a/core/java/android/util/SparseIntArray.java
+++ b/core/java/android/util/SparseIntArray.java
@@ -24,7 +24,6 @@ import com.android.internal.util.ArrayUtils;
* than using a HashMap to map Integers to Integers.
*/
public class SparseIntArray implements Cloneable {
-
private int[] mKeys;
private int[] mValues;
private int mSize;
@@ -39,13 +38,19 @@ public class SparseIntArray implements Cloneable {
/**
* Creates a new SparseIntArray containing no mappings that will not
* require any additional memory allocation to store the specified
- * number of mappings.
+ * number of mappings. If you supply an initial capacity of 0, the
+ * sparse array will be initialized with a light-weight representation
+ * not requiring any additional array allocations.
*/
public SparseIntArray(int initialCapacity) {
- initialCapacity = ArrayUtils.idealIntArraySize(initialCapacity);
-
- mKeys = new int[initialCapacity];
- mValues = new int[initialCapacity];
+ if (initialCapacity == 0) {
+ mKeys = SparseArray.EMPTY_INTS;
+ mValues = SparseArray.EMPTY_INTS;
+ } else {
+ initialCapacity = ArrayUtils.idealIntArraySize(initialCapacity);
+ mKeys = new int[initialCapacity];
+ mValues = new int[initialCapacity];
+ }
mSize = 0;
}
@@ -75,7 +80,7 @@ public class SparseIntArray implements Cloneable {
* if no such mapping has been made.
*/
public int get(int key, int valueIfKeyNotFound) {
- int i = binarySearch(mKeys, 0, mSize, key);
+ int i = SparseArray.binarySearch(mKeys, mSize, key);
if (i < 0) {
return valueIfKeyNotFound;
@@ -88,7 +93,7 @@ public class SparseIntArray implements Cloneable {
* Removes the mapping from the specified key, if there was any.
*/
public void delete(int key) {
- int i = binarySearch(mKeys, 0, mSize, key);
+ int i = SparseArray.binarySearch(mKeys, mSize, key);
if (i >= 0) {
removeAt(i);
@@ -110,7 +115,7 @@ public class SparseIntArray implements Cloneable {
* was one.
*/
public void put(int key, int value) {
- int i = binarySearch(mKeys, 0, mSize, key);
+ int i = SparseArray.binarySearch(mKeys, mSize, key);
if (i >= 0) {
mValues[i] = value;
@@ -175,7 +180,7 @@ public class SparseIntArray implements Cloneable {
* key is not mapped.
*/
public int indexOfKey(int key) {
- return binarySearch(mKeys, 0, mSize, key);
+ return SparseArray.binarySearch(mKeys, mSize, key);
}
/**
@@ -230,24 +235,4 @@ public class SparseIntArray implements Cloneable {
mValues[pos] = value;
mSize = pos + 1;
}
-
- private static int binarySearch(int[] a, int start, int len, int key) {
- int high = start + len, low = start - 1, guess;
-
- while (high - low > 1) {
- guess = (high + low) / 2;
-
- if (a[guess] < key)
- low = guess;
- else
- high = guess;
- }
-
- if (high == start + len)
- return ~(start + len);
- else if (a[high] == key)
- return high;
- else
- return ~high;
- }
}
diff --git a/core/java/android/util/SparseLongArray.java b/core/java/android/util/SparseLongArray.java
index 2f7a6fe..c608996 100644
--- a/core/java/android/util/SparseLongArray.java
+++ b/core/java/android/util/SparseLongArray.java
@@ -24,6 +24,7 @@ import com.android.internal.util.ArrayUtils;
* than using a HashMap to map Integers to Longs.
*/
public class SparseLongArray implements Cloneable {
+ static final long[] EMPTY_LONGS = new long[0];
private int[] mKeys;
private long[] mValues;
@@ -39,13 +40,19 @@ public class SparseLongArray implements Cloneable {
/**
* Creates a new SparseLongArray containing no mappings that will not
* require any additional memory allocation to store the specified
- * number of mappings.
+ * number of mappings. If you supply an initial capacity of 0, the
+ * sparse array will be initialized with a light-weight representation
+ * not requiring any additional array allocations.
*/
public SparseLongArray(int initialCapacity) {
- initialCapacity = ArrayUtils.idealLongArraySize(initialCapacity);
-
- mKeys = new int[initialCapacity];
- mValues = new long[initialCapacity];
+ if (initialCapacity == 0) {
+ mKeys = SparseArray.EMPTY_INTS;
+ mValues = EMPTY_LONGS;
+ } else {
+ initialCapacity = ArrayUtils.idealLongArraySize(initialCapacity);
+ mKeys = new int[initialCapacity];
+ mValues = new long[initialCapacity];
+ }
mSize = 0;
}
@@ -75,7 +82,7 @@ public class SparseLongArray implements Cloneable {
* if no such mapping has been made.
*/
public long get(int key, long valueIfKeyNotFound) {
- int i = binarySearch(mKeys, 0, mSize, key);
+ int i = SparseArray.binarySearch(mKeys, mSize, key);
if (i < 0) {
return valueIfKeyNotFound;
@@ -88,7 +95,7 @@ public class SparseLongArray implements Cloneable {
* Removes the mapping from the specified key, if there was any.
*/
public void delete(int key) {
- int i = binarySearch(mKeys, 0, mSize, key);
+ int i = SparseArray.binarySearch(mKeys, mSize, key);
if (i >= 0) {
removeAt(i);
@@ -110,7 +117,7 @@ public class SparseLongArray implements Cloneable {
* was one.
*/
public void put(int key, long value) {
- int i = binarySearch(mKeys, 0, mSize, key);
+ int i = SparseArray.binarySearch(mKeys, mSize, key);
if (i >= 0) {
mValues[i] = value;
@@ -164,7 +171,7 @@ public class SparseLongArray implements Cloneable {
* key is not mapped.
*/
public int indexOfKey(int key) {
- return binarySearch(mKeys, 0, mSize, key);
+ return SparseArray.binarySearch(mKeys, mSize, key);
}
/**
@@ -222,24 +229,4 @@ public class SparseLongArray implements Cloneable {
mKeys = nkeys;
mValues = nvalues;
}
-
- private static int binarySearch(int[] a, int start, int len, long key) {
- int high = start + len, low = start - 1, guess;
-
- while (high - low > 1) {
- guess = (high + low) / 2;
-
- if (a[guess] < key)
- low = guess;
- else
- high = guess;
- }
-
- if (high == start + len)
- return ~(start + len);
- else if (a[high] == key)
- return high;
- else
- return ~high;
- }
}
diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java
index 2ec9a7d..cc7d948 100644
--- a/core/java/android/view/GLES20Canvas.java
+++ b/core/java/android/view/GLES20Canvas.java
@@ -21,6 +21,7 @@ import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.DrawFilter;
import android.graphics.Matrix;
+import android.graphics.NinePatch;
import android.graphics.Paint;
import android.graphics.PaintFlagsDrawFilter;
import android.graphics.Path;
@@ -273,6 +274,18 @@ class GLES20Canvas extends HardwareCanvas {
private static native int nGetStencilSize();
+ void setCountOverdrawEnabled(boolean enabled) {
+ nSetCountOverdrawEnabled(mRenderer, enabled);
+ }
+
+ static native void nSetCountOverdrawEnabled(int renderer, boolean enabled);
+
+ float getOverdraw() {
+ return nGetOverdraw(mRenderer);
+ }
+
+ static native float nGetOverdraw(int renderer);
+
///////////////////////////////////////////////////////////////////////////
// Functor
///////////////////////////////////////////////////////////////////////////
@@ -314,21 +327,21 @@ class GLES20Canvas extends HardwareCanvas {
*
* @see #flushCaches(int)
*/
- public static final int FLUSH_CACHES_LAYERS = 0;
+ static final int FLUSH_CACHES_LAYERS = 0;
/**
* Must match Caches::FlushMode values
*
* @see #flushCaches(int)
*/
- public static final int FLUSH_CACHES_MODERATE = 1;
+ static final int FLUSH_CACHES_MODERATE = 1;
/**
* Must match Caches::FlushMode values
*
* @see #flushCaches(int)
*/
- public static final int FLUSH_CACHES_FULL = 2;
+ static final int FLUSH_CACHES_FULL = 2;
/**
* Flush caches to reclaim as much memory as possible. The amount of memory
@@ -338,10 +351,8 @@ class GLES20Canvas extends HardwareCanvas {
* {@link #FLUSH_CACHES_FULL}.
*
* @param level Hint about the amount of memory to reclaim
- *
- * @hide
*/
- public static void flushCaches(int level) {
+ static void flushCaches(int level) {
nFlushCaches(level);
}
@@ -353,21 +364,28 @@ class GLES20Canvas extends HardwareCanvas {
*
* @hide
*/
- public static void terminateCaches() {
+ static void terminateCaches() {
nTerminateCaches();
}
private static native void nTerminateCaches();
- /**
- * @hide
- */
- public static void initCaches() {
- nInitCaches();
+ static boolean initCaches() {
+ return nInitCaches();
}
- private static native void nInitCaches();
-
+ private static native boolean nInitCaches();
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Atlas
+ ///////////////////////////////////////////////////////////////////////////
+
+ static void initAtlas(GraphicBuffer buffer, int[] map) {
+ nInitAtlas(buffer, map, map.length);
+ }
+
+ private static native void nInitAtlas(GraphicBuffer buffer, int[] map, int count);
+
///////////////////////////////////////////////////////////////////////////
// Display list
///////////////////////////////////////////////////////////////////////////
@@ -718,20 +736,21 @@ class GLES20Canvas extends HardwareCanvas {
}
@Override
- public void drawPatch(Bitmap bitmap, byte[] chunks, RectF dst, Paint paint) {
+ public void drawPatch(NinePatch patch, RectF dst, Paint paint) {
+ Bitmap bitmap = patch.getBitmap();
if (bitmap.isRecycled()) throw new IllegalArgumentException("Cannot draw recycled bitmaps");
// Shaders are ignored when drawing patches
int modifier = paint != null ? setupColorFilter(paint) : MODIFIER_NONE;
try {
final int nativePaint = paint == null ? 0 : paint.mNativePaint;
- nDrawPatch(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, chunks,
+ nDrawPatch(mRenderer, bitmap.mNativeBitmap, patch.mChunk,
dst.left, dst.top, dst.right, dst.bottom, nativePaint);
} finally {
if (modifier != MODIFIER_NONE) nResetModifiers(mRenderer, modifier);
}
}
- private static native void nDrawPatch(int renderer, int bitmap, byte[] buffer, byte[] chunks,
+ private static native void nDrawPatch(int renderer, int bitmap, byte[] chunks,
float left, float top, float right, float bottom, int paint);
@Override
@@ -741,14 +760,14 @@ class GLES20Canvas extends HardwareCanvas {
int modifiers = paint != null ? setupModifiers(bitmap, paint) : MODIFIER_NONE;
try {
final int nativePaint = paint == null ? 0 : paint.mNativePaint;
- nDrawBitmap(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, left, top, nativePaint);
+ nDrawBitmap(mRenderer, bitmap.mNativeBitmap, left, top, nativePaint);
} finally {
if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
}
}
- private static native void nDrawBitmap(
- int renderer, int bitmap, byte[] buffer, float left, float top, int paint);
+ private static native void nDrawBitmap(int renderer, int bitmap,
+ float left, float top, int paint);
@Override
public void drawBitmap(Bitmap bitmap, Matrix matrix, Paint paint) {
@@ -757,15 +776,13 @@ class GLES20Canvas extends HardwareCanvas {
int modifiers = paint != null ? setupModifiers(bitmap, paint) : MODIFIER_NONE;
try {
final int nativePaint = paint == null ? 0 : paint.mNativePaint;
- nDrawBitmap(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer,
- matrix.native_instance, nativePaint);
+ nDrawBitmap(mRenderer, bitmap.mNativeBitmap, matrix.native_instance, nativePaint);
} finally {
if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
}
}
- private static native void nDrawBitmap(int renderer, int bitmap, byte[] buff,
- int matrix, int paint);
+ private static native void nDrawBitmap(int renderer, int bitmap, int matrix, int paint);
@Override
public void drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint) {
@@ -787,7 +804,7 @@ class GLES20Canvas extends HardwareCanvas {
bottom = src.bottom;
}
- nDrawBitmap(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, left, top, right, bottom,
+ nDrawBitmap(mRenderer, bitmap.mNativeBitmap, left, top, right, bottom,
dst.left, dst.top, dst.right, dst.bottom, nativePaint);
} finally {
if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
@@ -814,14 +831,14 @@ class GLES20Canvas extends HardwareCanvas {
bottom = src.bottom;
}
- nDrawBitmap(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, left, top, right, bottom,
+ nDrawBitmap(mRenderer, bitmap.mNativeBitmap, left, top, right, bottom,
dst.left, dst.top, dst.right, dst.bottom, nativePaint);
} finally {
if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
}
}
- private static native void nDrawBitmap(int renderer, int bitmap, byte[] buffer,
+ private static native void nDrawBitmap(int renderer, int bitmap,
float srcLeft, float srcTop, float srcRight, float srcBottom,
float left, float top, float right, float bottom, int paint);
@@ -891,14 +908,14 @@ class GLES20Canvas extends HardwareCanvas {
int modifiers = paint != null ? setupModifiers(bitmap, paint) : MODIFIER_NONE;
try {
final int nativePaint = paint == null ? 0 : paint.mNativePaint;
- nDrawBitmapMesh(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, meshWidth, meshHeight,
+ nDrawBitmapMesh(mRenderer, bitmap.mNativeBitmap, meshWidth, meshHeight,
verts, vertOffset, colors, colorOffset, nativePaint);
} finally {
if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
}
}
- private static native void nDrawBitmapMesh(int renderer, int bitmap, byte[] buffer,
+ private static native void nDrawBitmapMesh(int renderer, int bitmap,
int meshWidth, int meshHeight, float[] verts, int vertOffset,
int[] colors, int colorOffset, int paint);
diff --git a/core/java/android/view/GLES20DisplayList.java b/core/java/android/view/GLES20DisplayList.java
index 3272504..d367267 100644
--- a/core/java/android/view/GLES20DisplayList.java
+++ b/core/java/android/view/GLES20DisplayList.java
@@ -18,6 +18,7 @@ package android.view;
import android.graphics.Bitmap;
import android.graphics.Matrix;
+import android.graphics.NinePatch;
import java.util.ArrayList;
@@ -29,7 +30,8 @@ class GLES20DisplayList extends DisplayList {
// alive as long as the DisplayList is alive. The Bitmap and DisplayList lists
// are populated by the GLES20RecordingCanvas during appropriate drawing calls and are
// cleared at the start of a new drawing frame or when the view is detached from the window.
- final ArrayList<Bitmap> mBitmaps = new ArrayList<Bitmap>(5);
+ final ArrayList<Bitmap> mBitmaps = new ArrayList<Bitmap>(10);
+ final ArrayList<NinePatch> mNinePatches = new ArrayList<NinePatch>(10);
final ArrayList<DisplayList> mChildDisplayLists = new ArrayList<DisplayList>();
private GLES20RecordingCanvas mCanvas;
@@ -83,7 +85,12 @@ class GLES20DisplayList extends DisplayList {
}
mValid = false;
+ clearReferences();
+ }
+
+ void clearReferences() {
mBitmaps.clear();
+ mNinePatches.clear();
mChildDisplayLists.clear();
}
diff --git a/core/java/android/view/GLES20RecordingCanvas.java b/core/java/android/view/GLES20RecordingCanvas.java
index 7da2451..ec059d5 100644
--- a/core/java/android/view/GLES20RecordingCanvas.java
+++ b/core/java/android/view/GLES20RecordingCanvas.java
@@ -19,6 +19,7 @@ package android.view;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Matrix;
+import android.graphics.NinePatch;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
@@ -62,8 +63,7 @@ class GLES20RecordingCanvas extends GLES20Canvas {
}
void start() {
- mDisplayList.mBitmaps.clear();
- mDisplayList.mChildDisplayLists.clear();
+ mDisplayList.clearReferences();
}
int end(int nativeDisplayList) {
@@ -80,9 +80,10 @@ class GLES20RecordingCanvas extends GLES20Canvas {
}
@Override
- public void drawPatch(Bitmap bitmap, byte[] chunks, RectF dst, Paint paint) {
- super.drawPatch(bitmap, chunks, dst, paint);
- mDisplayList.mBitmaps.add(bitmap);
+ public void drawPatch(NinePatch patch, RectF dst, Paint paint) {
+ super.drawPatch(patch, dst, paint);
+ mDisplayList.mBitmaps.add(patch.getBitmap());
+ mDisplayList.mNinePatches.add(patch);
// Shaders in the Paint are ignored when drawing a Bitmap
}
diff --git a/core/java/android/view/GLES20RenderLayer.java b/core/java/android/view/GLES20RenderLayer.java
index 685dc70..68ba77c 100644
--- a/core/java/android/view/GLES20RenderLayer.java
+++ b/core/java/android/view/GLES20RenderLayer.java
@@ -100,12 +100,17 @@ class GLES20RenderLayer extends GLES20Layer {
@Override
HardwareCanvas start(Canvas currentCanvas) {
+ return start(currentCanvas, null);
+ }
+
+ @Override
+ HardwareCanvas start(Canvas currentCanvas, Rect dirty) {
if (currentCanvas instanceof GLES20Canvas) {
((GLES20Canvas) currentCanvas).interrupt();
}
HardwareCanvas canvas = getCanvas();
canvas.setViewport(mWidth, mHeight);
- canvas.onPreDraw(null);
+ canvas.onPreDraw(dirty);
return canvas;
}
diff --git a/core/java/android/view/GLES20TextureLayer.java b/core/java/android/view/GLES20TextureLayer.java
index e863e49..a4cc630 100644
--- a/core/java/android/view/GLES20TextureLayer.java
+++ b/core/java/android/view/GLES20TextureLayer.java
@@ -63,6 +63,11 @@ class GLES20TextureLayer extends GLES20Layer {
}
@Override
+ HardwareCanvas start(Canvas currentCanvas, Rect dirty) {
+ return null;
+ }
+
+ @Override
void end(Canvas currentCanvas) {
}
diff --git a/core/java/android/view/GraphicBuffer.aidl b/core/java/android/view/GraphicBuffer.aidl
new file mode 100644
index 0000000..6dc6bed
--- /dev/null
+++ b/core/java/android/view/GraphicBuffer.aidl
@@ -0,0 +1,19 @@
+/*
+ * 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 android.view;
+
+parcelable GraphicBuffer;
diff --git a/core/java/android/view/GraphicBuffer.java b/core/java/android/view/GraphicBuffer.java
new file mode 100644
index 0000000..b4576f3
--- /dev/null
+++ b/core/java/android/view/GraphicBuffer.java
@@ -0,0 +1,229 @@
+/*
+ * 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 android.view;
+
+import android.graphics.Canvas;
+import android.graphics.PixelFormat;
+import android.graphics.Rect;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Simple wrapper for the native GraphicBuffer class.
+ *
+ * @hide
+ */
+@SuppressWarnings("UnusedDeclaration")
+public class GraphicBuffer implements Parcelable {
+ // Note: keep usage flags in sync with GraphicBuffer.h and gralloc.h
+ public static final int USAGE_SW_READ_NEVER = 0x0;
+ public static final int USAGE_SW_READ_RARELY = 0x2;
+ public static final int USAGE_SW_READ_OFTEN = 0x3;
+ public static final int USAGE_SW_READ_MASK = 0xF;
+
+ public static final int USAGE_SW_WRITE_NEVER = 0x0;
+ public static final int USAGE_SW_WRITE_RARELY = 0x20;
+ public static final int USAGE_SW_WRITE_OFTEN = 0x30;
+ public static final int USAGE_SW_WRITE_MASK = 0xF0;
+
+ public static final int USAGE_SOFTWARE_MASK = USAGE_SW_READ_MASK | USAGE_SW_WRITE_MASK;
+
+ public static final int USAGE_PROTECTED = 0x4000;
+
+ public static final int USAGE_HW_TEXTURE = 0x100;
+ public static final int USAGE_HW_RENDER = 0x200;
+ public static final int USAGE_HW_2D = 0x400;
+ public static final int USAGE_HW_COMPOSER = 0x800;
+ public static final int USAGE_HW_VIDEO_ENCODER = 0x10000;
+ public static final int USAGE_HW_MASK = 0x71F00;
+
+ private final int mWidth;
+ private final int mHeight;
+ private final int mFormat;
+ private final int mUsage;
+ // Note: do not rename, this field is used by native code
+ private final int mNativeObject;
+
+ // These two fields are only used by lock/unlockCanvas()
+ private Canvas mCanvas;
+ private int mSaveCount;
+
+ /**
+ * Creates new <code>GraphicBuffer</code> instance. This method will return null
+ * if the buffer cannot be created.
+ *
+ * @param width The width in pixels of the buffer
+ * @param height The height in pixels of the buffer
+ * @param format The format of each pixel as specified in {@link PixelFormat}
+ * @param usage Hint indicating how the buffer will be used
+ *
+ * @return A <code>GraphicBuffer</code> instance or null
+ */
+ public static GraphicBuffer create(int width, int height, int format, int usage) {
+ int nativeObject = nCreateGraphicBuffer(width, height, format, usage);
+ if (nativeObject != 0) {
+ return new GraphicBuffer(width, height, format, usage, nativeObject);
+ }
+ return null;
+ }
+
+ /**
+ * Private use only. See {@link #create(int, int, int, int)}.
+ */
+ private GraphicBuffer(int width, int height, int format, int usage, int nativeObject) {
+ mWidth = width;
+ mHeight = height;
+ mFormat = format;
+ mUsage = usage;
+ mNativeObject = nativeObject;
+ }
+
+ /**
+ * Returns the width of this buffer in pixels.
+ */
+ public int getWidth() {
+ return mWidth;
+ }
+
+ /**
+ * Returns the height of this buffer in pixels.
+ */
+ public int getHeight() {
+ return mHeight;
+ }
+
+ /**
+ * Returns the pixel format of this buffer. The pixel format must be one of
+ * the formats defined in {@link PixelFormat}.
+ */
+ public int getFormat() {
+ return mFormat;
+ }
+
+ /**
+ * Returns the usage hint set on this buffer.
+ */
+ public int getUsage() {
+ return mUsage;
+ }
+
+ /**
+ * <p>Start editing the pixels in the buffer. A null is returned if the buffer
+ * cannot be locked for editing.</p>
+ *
+ * <p>The content of the buffer is preserved between unlockCanvas()
+ * and lockCanvas().</p>
+ *
+ * @return A Canvas used to draw into the buffer, or null.
+ *
+ * @see #lockCanvas(android.graphics.Rect)
+ * @see #unlockCanvasAndPost(android.graphics.Canvas)
+ */
+ public Canvas lockCanvas() {
+ return lockCanvas(null);
+ }
+
+ /**
+ * Just like {@link #lockCanvas()} but allows specification of a dirty
+ * rectangle.
+ *
+ * @param dirty Area of the buffer that may be modified.
+
+ * @return A Canvas used to draw into the surface or null
+ *
+ * @see #lockCanvas()
+ * @see #unlockCanvasAndPost(android.graphics.Canvas)
+ */
+ public Canvas lockCanvas(Rect dirty) {
+ if (mCanvas == null) {
+ mCanvas = new Canvas();
+ }
+
+ if (nLockCanvas(mNativeObject, mCanvas, dirty)) {
+ mSaveCount = mCanvas.save();
+ return mCanvas;
+ }
+
+ return null;
+ }
+
+ /**
+ * Finish editing pixels in the buffer.
+ *
+ * @param canvas The Canvas previously returned by lockCanvas()
+ *
+ * @see #lockCanvas()
+ * @see #lockCanvas(android.graphics.Rect)
+ */
+ public void unlockCanvasAndPost(Canvas canvas) {
+ if (mCanvas != null && canvas == mCanvas) {
+ canvas.restoreToCount(mSaveCount);
+ mSaveCount = 0;
+
+ nUnlockCanvasAndPost(mNativeObject, mCanvas);
+ }
+ }
+
+ @Override
+ protected void finalize() throws Throwable {
+ try {
+ nDestroyGraphicBuffer(mNativeObject);
+ } finally {
+ super.finalize();
+ }
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(mWidth);
+ dest.writeInt(mHeight);
+ dest.writeInt(mFormat);
+ dest.writeInt(mUsage);
+ nWriteGraphicBufferToParcel(mNativeObject, dest);
+ }
+
+ public static final Parcelable.Creator<GraphicBuffer> CREATOR =
+ new Parcelable.Creator<GraphicBuffer>() {
+ public GraphicBuffer createFromParcel(Parcel in) {
+ int width = in.readInt();
+ int height = in.readInt();
+ int format = in.readInt();
+ int usage = in.readInt();
+ int nativeObject = nReadGraphicBufferFromParcel(in);
+ if (nativeObject != 0) {
+ return new GraphicBuffer(width, height, format, usage, nativeObject);
+ }
+ return null;
+ }
+
+ public GraphicBuffer[] newArray(int size) {
+ return new GraphicBuffer[size];
+ }
+ };
+
+ private static native int nCreateGraphicBuffer(int width, int height, int format, int usage);
+ private static native void nDestroyGraphicBuffer(int nativeObject);
+ private static native void nWriteGraphicBufferToParcel(int nativeObject, Parcel dest);
+ private static native int nReadGraphicBufferFromParcel(Parcel in);
+ private static native boolean nLockCanvas(int nativeObject, Canvas canvas, Rect dirty);
+ private static native boolean nUnlockCanvasAndPost(int nativeObject, Canvas canvas);
+}
diff --git a/core/java/android/view/HardwareLayer.java b/core/java/android/view/HardwareLayer.java
index 18b838b..23383d9 100644
--- a/core/java/android/view/HardwareLayer.java
+++ b/core/java/android/view/HardwareLayer.java
@@ -158,14 +158,22 @@ abstract class HardwareLayer {
/**
* This must be invoked before drawing onto this layer.
*
- * @param currentCanvas
+ * @param currentCanvas The canvas whose rendering needs to be interrupted
*/
abstract HardwareCanvas start(Canvas currentCanvas);
/**
+ * This must be invoked before drawing onto this layer.
+ *
+ * @param dirty The dirty area to repaint
+ * @param currentCanvas The canvas whose rendering needs to be interrupted
+ */
+ abstract HardwareCanvas start(Canvas currentCanvas, Rect dirty);
+
+ /**
* This must be invoked after drawing onto this layer.
*
- * @param currentCanvas
+ * @param currentCanvas The canvas whose rendering needs to be resumed
*/
abstract void end(Canvas currentCanvas);
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index 8308459..c07b187 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -17,6 +17,7 @@
package android.view;
import android.content.ComponentCallbacks2;
+import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.SurfaceTexture;
@@ -24,7 +25,10 @@ import android.opengl.EGL14;
import android.opengl.GLUtils;
import android.opengl.ManagedEGLContext;
import android.os.Handler;
+import android.os.IBinder;
import android.os.Looper;
+import android.os.RemoteException;
+import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.SystemProperties;
import android.os.Trace;
@@ -42,7 +46,6 @@ import javax.microedition.khronos.opengles.GL;
import java.io.File;
import java.io.PrintWriter;
-import java.util.Arrays;
import java.util.concurrent.locks.ReentrantLock;
import static javax.microedition.khronos.egl.EGL10.*;
@@ -162,15 +165,32 @@ public abstract class HardwareRenderer {
"debug.hwui.show_layers_updates";
/**
- * Turn on to show overdraw level.
+ * Controls overdraw debugging.
*
* Possible values:
- * "true", to enable overdraw debugging
* "false", to disable overdraw debugging
+ * "show", to show overdraw areas on screen
+ * "count", to display an overdraw counter
*
* @hide
*/
- public static final String DEBUG_SHOW_OVERDRAW_PROPERTY = "debug.hwui.show_overdraw";
+ public static final String DEBUG_OVERDRAW_PROPERTY = "debug.hwui.overdraw";
+
+ /**
+ * Value for {@link #DEBUG_OVERDRAW_PROPERTY}. When the property is set to this
+ * value, overdraw will be shown on screen by coloring pixels.
+ *
+ * @hide
+ */
+ public static final String OVERDRAW_PROPERTY_SHOW = "show";
+
+ /**
+ * Value for {@link #DEBUG_OVERDRAW_PROPERTY}. When the property is set to this
+ * value, an overdraw counter will be shown on screen.
+ *
+ * @hide
+ */
+ public static final String OVERDRAW_PROPERTY_COUNT = "count";
/**
* Turn on to debug non-rectangular clip operations.
@@ -386,6 +406,17 @@ public abstract class HardwareRenderer {
private static native void nBeginFrame(int[] size);
/**
+ * Returns the current system time according to the renderer.
+ * This method is used for debugging only and should not be used
+ * as a clock.
+ */
+ static long getSystemTime() {
+ return nGetSystemTime();
+ }
+
+ private static native long nGetSystemTime();
+
+ /**
* Preserves the back buffer of the current surface after a buffer swap.
* Calling this method sets the EGL_SWAP_BEHAVIOR attribute of the current
* surface to EGL_BUFFER_PRESERVED. Calling this method requires an EGL
@@ -762,6 +793,17 @@ public abstract class HardwareRenderer {
private static final int PROFILE_DRAW_THRESHOLD_STROKE_WIDTH = 2;
private static final int PROFILE_DRAW_DP_PER_MS = 7;
+ private static final String[] VISUALIZERS = {
+ PROFILE_PROPERTY_VISUALIZE_BARS,
+ PROFILE_PROPERTY_VISUALIZE_LINES
+ };
+
+ private static final String[] OVERDRAW = {
+ OVERDRAW_PROPERTY_SHOW,
+ OVERDRAW_PROPERTY_COUNT
+ };
+ private static final int OVERDRAW_TYPE_COUNT = 1;
+
static EGL10 sEgl;
static EGLDisplay sEglDisplay;
static EGLConfig sEglConfig;
@@ -807,7 +849,9 @@ public abstract class HardwareRenderer {
Paint mProfilePaint;
boolean mDebugDirtyRegions;
- boolean mShowOverdraw;
+ int mDebugOverdraw = -1;
+ HardwareLayer mDebugOverdrawLayer;
+ Paint mDebugOverdrawPaint;
final int mGlVersion;
final boolean mTranslucent;
@@ -819,6 +863,8 @@ public abstract class HardwareRenderer {
private final int[] mSurfaceSize = new int[2];
private final FunctorsRunnable mFunctorsRunnable = new FunctorsRunnable();
+ private long mDrawDelta = Long.MAX_VALUE;
+
GlRenderer(int glVersion, boolean translucent) {
mGlVersion = glVersion;
mTranslucent = translucent;
@@ -826,18 +872,13 @@ public abstract class HardwareRenderer {
loadSystemProperties(null);
}
- private static final String[] VISUALIZERS = {
- PROFILE_PROPERTY_VISUALIZE_BARS,
- PROFILE_PROPERTY_VISUALIZE_LINES
- };
-
@Override
boolean loadSystemProperties(Surface surface) {
boolean value;
boolean changed = false;
String profiling = SystemProperties.get(PROFILE_PROPERTY);
- int graphType = Arrays.binarySearch(VISUALIZERS, profiling);
+ int graphType = search(VISUALIZERS, profiling);
value = graphType >= 0;
if (graphType != mProfileVisualizerType) {
@@ -894,11 +935,19 @@ public abstract class HardwareRenderer {
}
}
- value = SystemProperties.getBoolean(
- HardwareRenderer.DEBUG_SHOW_OVERDRAW_PROPERTY, false);
- if (value != mShowOverdraw) {
+ String overdraw = SystemProperties.get(HardwareRenderer.DEBUG_OVERDRAW_PROPERTY);
+ int debugOverdraw = search(OVERDRAW, overdraw);
+ if (debugOverdraw != mDebugOverdraw) {
changed = true;
- mShowOverdraw = value;
+ mDebugOverdraw = debugOverdraw;
+
+ if (mDebugOverdraw != OVERDRAW_TYPE_COUNT) {
+ if (mDebugOverdrawLayer != null) {
+ mDebugOverdrawLayer.destroy();
+ mDebugOverdrawLayer = null;
+ mDebugOverdrawPaint = null;
+ }
+ }
}
if (nLoadProperties()) {
@@ -908,6 +957,13 @@ public abstract class HardwareRenderer {
return changed;
}
+ private static int search(String[] values, String value) {
+ for (int i = 0; i < values.length; i++) {
+ if (values[i].equals(value)) return i;
+ }
+ return -1;
+ }
+
@Override
void dumpGfxInfo(PrintWriter pw) {
if (mProfileEnabled) {
@@ -968,7 +1024,7 @@ public abstract class HardwareRenderer {
if (fallback) {
// we'll try again if it was context lost
setRequested(false);
- Log.w(LOG_TAG, "Mountain View, we've had a problem here. "
+ Log.w(LOG_TAG, "Mountain View, we've had a problem here. "
+ "Switching back to software rendering.");
}
}
@@ -976,7 +1032,7 @@ public abstract class HardwareRenderer {
@Override
boolean initialize(Surface surface) throws Surface.OutOfResourcesException {
if (isRequested() && !isEnabled()) {
- initializeEgl();
+ boolean contextCreated = initializeEgl();
mGl = createEglSurface(surface);
mDestroyed = false;
@@ -991,6 +1047,10 @@ public abstract class HardwareRenderer {
mCanvas.setName(mName);
}
setEnabled(true);
+
+ if (contextCreated) {
+ initAtlas();
+ }
}
return mCanvas != null;
@@ -1010,7 +1070,7 @@ public abstract class HardwareRenderer {
abstract int[] getConfig(boolean dirtyRegions);
- void initializeEgl() {
+ boolean initializeEgl() {
synchronized (sEglLock) {
if (sEgl == null && sEglConfig == null) {
sEgl = (EGL10) EGLContext.getEGL();
@@ -1043,7 +1103,10 @@ public abstract class HardwareRenderer {
if (mEglContext == null) {
mEglContext = createContext(sEgl, sEglDisplay, sEglConfig);
sEglContextStorage.set(createManagedContext(mEglContext));
+ return true;
}
+
+ return false;
}
private EGLConfig loadEglConfig() {
@@ -1181,6 +1244,7 @@ public abstract class HardwareRenderer {
}
abstract void initCaches();
+ abstract void initAtlas();
EGLContext createContext(EGL10 egl, EGLDisplay eglDisplay, EGLConfig eglConfig) {
int[] attribs = { EGL14.EGL_CONTEXT_CLIENT_VERSION, mGlVersion, EGL_NONE };
@@ -1193,6 +1257,7 @@ public abstract class HardwareRenderer {
"Could not create an EGL context. eglCreateContext failed with error: " +
GLUtils.getEGLErrorString(sEgl.eglGetError()));
}
+
return context;
}
@@ -1361,6 +1426,7 @@ public abstract class HardwareRenderer {
int saveCount = 0;
int status = DisplayList.STATUS_DONE;
+ long start = getSystemTime();
try {
status = prepareFrame(dirty);
@@ -1380,10 +1446,15 @@ public abstract class HardwareRenderer {
canvas.restoreToCount(saveCount);
view.mRecreateDisplayList = false;
- mFrameCount++;
+ mDrawDelta = getSystemTime() - start;
+
+ if (mDrawDelta > 0) {
+ mFrameCount++;
- debugDirtyRegions(dirty, canvas);
- drawProfileData(attachInfo);
+ debugOverdraw(attachInfo, dirty, canvas, displayList);
+ debugDirtyRegions(dirty, canvas);
+ drawProfileData(attachInfo);
+ }
}
onPostDraw();
@@ -1399,7 +1470,66 @@ public abstract class HardwareRenderer {
}
}
+ abstract void countOverdraw(HardwareCanvas canvas);
+ abstract float getOverdraw(HardwareCanvas canvas);
+
+ private void debugOverdraw(View.AttachInfo attachInfo, Rect dirty,
+ HardwareCanvas canvas, DisplayList displayList) {
+
+ if (mDebugOverdraw == OVERDRAW_TYPE_COUNT) {
+ // TODO: Use an alpha layer allocated from a GraphicBuffer
+ // The alpha format will help with rendering performance and
+ // the GraphicBuffer will let us skip the read pixels step
+ if (mDebugOverdrawLayer == null) {
+ mDebugOverdrawLayer = createHardwareLayer(mWidth, mHeight, true);
+ } else if (mDebugOverdrawLayer.getWidth() != mWidth ||
+ mDebugOverdrawLayer.getHeight() != mHeight) {
+ mDebugOverdrawLayer.resize(mWidth, mHeight);
+ }
+
+ if (!mDebugOverdrawLayer.isValid()) {
+ mDebugOverdraw = -1;
+ return;
+ }
+
+ HardwareCanvas layerCanvas = mDebugOverdrawLayer.start(canvas, dirty);
+ countOverdraw(layerCanvas);
+ final int restoreCount = layerCanvas.save();
+ layerCanvas.drawDisplayList(displayList, null, DisplayList.FLAG_CLIP_CHILDREN);
+ layerCanvas.restoreToCount(restoreCount);
+ mDebugOverdrawLayer.end(canvas);
+
+ float overdraw = getOverdraw(layerCanvas);
+ DisplayMetrics metrics = attachInfo.mRootView.getResources().getDisplayMetrics();
+
+ drawOverdrawCounter(canvas, overdraw, metrics.density);
+ }
+ }
+
+ private void drawOverdrawCounter(HardwareCanvas canvas, float overdraw, float density) {
+ final String text = String.format("%.2fx", overdraw);
+ final Paint paint = setupPaint(density);
+ // HSBtoColor will clamp the values in the 0..1 range
+ paint.setColor(Color.HSBtoColor(0.28f - 0.28f * overdraw / 3.5f, 0.8f, 1.0f));
+
+ canvas.drawText(text, density * 4.0f, mHeight - paint.getFontMetrics().bottom, paint);
+ }
+
+ private Paint setupPaint(float density) {
+ if (mDebugOverdrawPaint == null) {
+ mDebugOverdrawPaint = new Paint();
+ mDebugOverdrawPaint.setAntiAlias(true);
+ mDebugOverdrawPaint.setShadowLayer(density * 3.0f, 0.0f, 0.0f, 0xff000000);
+ mDebugOverdrawPaint.setTextSize(density * 20.0f);
+ }
+ return mDebugOverdrawPaint;
+ }
+
private DisplayList buildDisplayList(View view, HardwareCanvas canvas) {
+ if (mDrawDelta <= 0) {
+ return view.mDisplayList;
+ }
+
view.mRecreateDisplayList = (view.mPrivateFlags & View.PFLAG_INVALIDATED)
== View.PFLAG_INVALIDATED;
view.mPrivateFlags &= ~View.PFLAG_INVALIDATED;
@@ -1788,7 +1918,31 @@ public abstract class HardwareRenderer {
@Override
void initCaches() {
- GLES20Canvas.initCaches();
+ if (GLES20Canvas.initCaches()) {
+ // Caches were (re)initialized, rebind atlas
+ initAtlas();
+ }
+ }
+
+ @Override
+ void initAtlas() {
+ IBinder binder = ServiceManager.getService("assetatlas");
+ if (binder == null) return;
+
+ IAssetAtlas atlas = IAssetAtlas.Stub.asInterface(binder);
+ try {
+ if (atlas.isCompatible(android.os.Process.myPpid())) {
+ GraphicBuffer buffer = atlas.getBuffer();
+ if (buffer != null) {
+ int[] map = atlas.getMap();
+ if (map != null) {
+ GLES20Canvas.initAtlas(buffer, map);
+ }
+ }
+ }
+ } catch (RemoteException e) {
+ Log.w(LOG_TAG, "Could not acquire atlas", e);
+ }
}
@Override
@@ -1985,6 +2139,16 @@ public abstract class HardwareRenderer {
}
@Override
+ void countOverdraw(HardwareCanvas canvas) {
+ ((GLES20Canvas) canvas).setCountOverdrawEnabled(true);
+ }
+
+ @Override
+ float getOverdraw(HardwareCanvas canvas) {
+ return ((GLES20Canvas) canvas).getOverdraw();
+ }
+
+ @Override
public SurfaceTexture createSurfaceTexture(HardwareLayer layer) {
return ((GLES20TextureLayer) layer).getSurfaceTexture();
}
diff --git a/core/java/android/view/IAssetAtlas.aidl b/core/java/android/view/IAssetAtlas.aidl
new file mode 100644
index 0000000..5f1e238
--- /dev/null
+++ b/core/java/android/view/IAssetAtlas.aidl
@@ -0,0 +1,54 @@
+/**
+ * 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 android.view;
+
+import android.view.GraphicBuffer;
+
+/**
+ * Programming interface to the system assets atlas. This atlas, when
+ * present, holds preloaded drawable in a single, shareable graphics
+ * buffer. This allows multiple processes to share the same data to
+ * save up on memory.
+ *
+ * @hide
+ */
+interface IAssetAtlas {
+ /**
+ * Indicates whether the atlas is compatible with the specified
+ * parent process id. If the atlas' ppid does not match, this
+ * method will return false.
+ */
+ boolean isCompatible(int ppid);
+
+ /**
+ * Returns the atlas buffer (texture) or null if the atlas is
+ * not available yet.
+ */
+ GraphicBuffer getBuffer();
+
+ /**
+ * Returns the map of the bitmaps stored in the atlas or null
+ * if the atlas is not available yet.
+ *
+ * Each bitmap is represented by several entries in the array:
+ * int0: SkBitmap*, the native bitmap object
+ * int1: x position
+ * int2: y position
+ * int3: rotated, 1 if the bitmap must be rotated, 0 otherwise
+ */
+ int[] getMap();
+}
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index 8ed4a86..ad3082e 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -80,8 +80,8 @@ interface IWindowManager
void setEventDispatching(boolean enabled);
void addWindowToken(IBinder token, int type);
void removeWindowToken(IBinder token);
- void addAppToken(int addPos, IApplicationToken token,
- int groupId, int requestedOrientation, boolean fullscreen, boolean showWhenLocked);
+ void addAppToken(int addPos, IApplicationToken token, int groupId, int stackId,
+ int requestedOrientation, boolean fullscreen, boolean showWhenLocked);
void setAppGroupId(IBinder token, int groupId);
void setAppOrientation(IApplicationToken token, int requestedOrientation);
int getAppOrientation(IApplicationToken token);
@@ -97,15 +97,12 @@ interface IWindowManager
void executeAppTransition();
void setAppStartingWindow(IBinder token, String pkg, int theme,
in CompatibilityInfo compatInfo, CharSequence nonLocalizedLabel, int labelRes,
- int icon, int windowFlags, IBinder transferFrom, boolean createIfNeeded);
+ int icon, int logo, int windowFlags, IBinder transferFrom, boolean createIfNeeded);
void setAppWillBeHidden(IBinder token);
void setAppVisibility(IBinder token, boolean visible);
void startAppFreezingScreen(IBinder token, int configChanges);
void stopAppFreezingScreen(IBinder token, boolean force);
void removeAppToken(IBinder token);
- void moveAppToken(int index, IBinder token);
- void moveAppTokensToTop(in List<IBinder> tokens);
- void moveAppTokensToBottom(in List<IBinder> tokens);
// Re-evaluate the current orientation from the caller's state.
// If there is a change, the new Configuration is returned and the
diff --git a/core/java/android/view/InputEvent.java b/core/java/android/view/InputEvent.java
index 07a937c..1ecdf30 100644
--- a/core/java/android/view/InputEvent.java
+++ b/core/java/android/view/InputEvent.java
@@ -70,6 +70,7 @@ public abstract class InputEvent implements Parcelable {
* Gets the source of the event.
*
* @return The event source or {@link InputDevice#SOURCE_UNKNOWN} if unknown.
+ * @see InputDevice#getSources
*/
public abstract int getSource();
diff --git a/core/java/android/view/InputFilter.java b/core/java/android/view/InputFilter.java
index c25b87b..4aba30c 100644
--- a/core/java/android/view/InputFilter.java
+++ b/core/java/android/view/InputFilter.java
@@ -40,7 +40,7 @@ import android.view.WindowManagerPolicy;
* <li>Input events are then asynchronously delivered to the input filter's
* {@link #onInputEvent(InputEvent)} method instead of being enqueued for dispatch to
* applications as usual. The input filter only receives input events that were
- * generated by input device; the input filter will not receive input events that were
+ * generated by an input device; the input filter will not receive input events that were
* injected into the system by other means, such as by instrumentation.</li>
* <li>The input filter processes and optionally transforms the stream of events. For example,
* it may transform a sequence of motion events representing an accessibility gesture into
@@ -68,7 +68,7 @@ import android.view.WindowManagerPolicy;
* The input filter must take into account the fact that the input events coming from different
* devices or even different sources all consist of distinct streams of input.
* Use {@link InputEvent#getDeviceId()} and {@link InputEvent#getSource()} to identify
- * the source of the event and its semantics. There are be multiple sources of keys,
+ * the source of the event and its semantics. There may be multiple sources of keys,
* touches and other input: they must be kept separate.
* </p>
* <h3>Policy flags</h3>
@@ -88,7 +88,7 @@ import android.view.WindowManagerPolicy;
* The input filter should clear its internal state about the gesture and then send key or
* motion events to the dispatcher to cancel any keys or pointers that are down.
* </p><p>
- * Corollary: Events that set sent to the dispatcher should usually include the
+ * Corollary: Events that get sent to the dispatcher should usually include the
* {@link WindowManagerPolicy#FLAG_PASS_TO_USER} flag. Otherwise, they will be dropped!
* </p><p>
* It may be prudent to disable automatic key repeating for synthetic key events
diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java
index ae4005b..e0786f7 100644
--- a/core/java/android/view/Surface.java
+++ b/core/java/android/view/Surface.java
@@ -71,8 +71,8 @@ public class Surface implements Parcelable {
// Guarded state.
final Object mLock = new Object(); // protects the native state
private String mName;
- int mNativeSurface; // package scope only for SurfaceControl access
- private int mGenerationId; // incremented each time mNativeSurface changes
+ int mNativeObject; // package scope only for SurfaceControl access
+ private int mGenerationId; // incremented each time mNativeObject changes
private final Canvas mCanvas = new CompatibleCanvas();
// A matrix to scale the matrix set by application. This is set to null for
@@ -158,8 +158,8 @@ public class Surface implements Parcelable {
*/
public void release() {
synchronized (mLock) {
- if (mNativeSurface != 0) {
- nativeRelease(mNativeSurface);
+ if (mNativeObject != 0) {
+ nativeRelease(mNativeObject);
setNativeObjectLocked(0);
}
}
@@ -183,8 +183,8 @@ public class Surface implements Parcelable {
*/
public boolean isValid() {
synchronized (mLock) {
- if (mNativeSurface == 0) return false;
- return nativeIsValid(mNativeSurface);
+ if (mNativeObject == 0) return false;
+ return nativeIsValid(mNativeObject);
}
}
@@ -210,7 +210,7 @@ public class Surface implements Parcelable {
public boolean isConsumerRunningBehind() {
synchronized (mLock) {
checkNotReleasedLocked();
- return nativeIsConsumerRunningBehind(mNativeSurface);
+ return nativeIsConsumerRunningBehind(mNativeObject);
}
}
@@ -233,7 +233,7 @@ public class Surface implements Parcelable {
throws OutOfResourcesException, IllegalArgumentException {
synchronized (mLock) {
checkNotReleasedLocked();
- nativeLockCanvas(mNativeSurface, mCanvas, inOutDirty);
+ nativeLockCanvas(mNativeObject, mCanvas, inOutDirty);
return mCanvas;
}
}
@@ -252,7 +252,7 @@ public class Surface implements Parcelable {
synchronized (mLock) {
checkNotReleasedLocked();
- nativeUnlockCanvasAndPost(mNativeSurface, canvas);
+ nativeUnlockCanvasAndPost(mNativeObject, canvas);
}
}
@@ -298,8 +298,8 @@ public class Surface implements Parcelable {
int newNativeObject = nativeCreateFromSurfaceControl(surfaceControlPtr);
synchronized (mLock) {
- if (mNativeSurface != 0) {
- nativeRelease(mNativeSurface);
+ if (mNativeObject != 0) {
+ nativeRelease(mNativeObject);
}
setNativeObjectLocked(newNativeObject);
}
@@ -319,13 +319,13 @@ public class Surface implements Parcelable {
if (other != this) {
final int newPtr;
synchronized (other.mLock) {
- newPtr = other.mNativeSurface;
+ newPtr = other.mNativeObject;
other.setNativeObjectLocked(0);
}
synchronized (mLock) {
- if (mNativeSurface != 0) {
- nativeRelease(mNativeSurface);
+ if (mNativeObject != 0) {
+ nativeRelease(mNativeObject);
}
setNativeObjectLocked(newPtr);
}
@@ -344,7 +344,7 @@ public class Surface implements Parcelable {
synchronized (mLock) {
mName = source.readString();
- setNativeObjectLocked(nativeReadFromParcel(mNativeSurface, source));
+ setNativeObjectLocked(nativeReadFromParcel(mNativeObject, source));
}
}
@@ -355,7 +355,7 @@ public class Surface implements Parcelable {
}
synchronized (mLock) {
dest.writeString(mName);
- nativeWriteToParcel(mNativeSurface, dest);
+ nativeWriteToParcel(mNativeObject, dest);
}
if ((flags & Parcelable.PARCELABLE_WRITE_RETURN_VALUE) != 0) {
release();
@@ -370,19 +370,19 @@ public class Surface implements Parcelable {
}
private void setNativeObjectLocked(int ptr) {
- if (mNativeSurface != ptr) {
- if (mNativeSurface == 0 && ptr != 0) {
+ if (mNativeObject != ptr) {
+ if (mNativeObject == 0 && ptr != 0) {
mCloseGuard.open("release");
- } else if (mNativeSurface != 0 && ptr == 0) {
+ } else if (mNativeObject != 0 && ptr == 0) {
mCloseGuard.close();
}
- mNativeSurface = ptr;
+ mNativeObject = ptr;
mGenerationId += 1;
}
}
private void checkNotReleasedLocked() {
- if (mNativeSurface == 0) {
+ if (mNativeObject == 0) {
throw new IllegalStateException("Surface has already been released.");
}
}
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index c6da84f..6b530ef 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -499,7 +499,7 @@ public class SurfaceControl {
if (surface != null) {
synchronized (surface.mLock) {
- nativeSetDisplaySurface(displayToken, surface.mNativeSurface);
+ nativeSetDisplaySurface(displayToken, surface.mNativeObject);
}
} else {
nativeSetDisplaySurface(displayToken, 0);
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index 793fb5e..8b2b556 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -160,7 +160,6 @@ public class SurfaceView extends View {
int mHeight = -1;
int mFormat = -1;
final Rect mSurfaceFrame = new Rect();
- Rect mTmpDirty;
int mLastSurfaceWidth = -1, mLastSurfaceHeight = -1;
boolean mUpdateWindowNeeded;
boolean mReportDrawNeeded;
@@ -795,14 +794,6 @@ public class SurfaceView extends View {
Canvas c = null;
if (!mDrawingStopped && mWindow != null) {
- if (dirty == null) {
- if (mTmpDirty == null) {
- mTmpDirty = new Rect();
- }
- mTmpDirty.set(mSurfaceFrame);
- dirty = mTmpDirty;
- }
-
try {
c = mSurface.lockCanvas(dirty);
} catch (Exception e) {
diff --git a/core/java/android/view/TextureView.java b/core/java/android/view/TextureView.java
index 5c3934d..f0acba1 100644
--- a/core/java/android/view/TextureView.java
+++ b/core/java/android/view/TextureView.java
@@ -648,13 +648,19 @@ public class TextureView extends View {
* rectangle. Every pixel within that rectangle must be written; however
* pixels outside the dirty rectangle will be preserved by the next call
* to lockCanvas().
+ *
+ * This method can return null if the underlying surface texture is not
+ * available (see {@link #isAvailable()} or if the surface texture is
+ * already connected to an image producer (for instance: the camera,
+ * OpenGL, a media player, etc.)
*
* @param dirty Area of the surface that will be modified.
* @return A Canvas used to draw into the surface.
*
* @see #lockCanvas()
- * @see #unlockCanvasAndPost(android.graphics.Canvas)
+ * @see #unlockCanvasAndPost(android.graphics.Canvas)
+ * @see #isAvailable()
*/
public Canvas lockCanvas(Rect dirty) {
if (!isAvailable()) return null;
@@ -664,7 +670,9 @@ public class TextureView extends View {
}
synchronized (mNativeWindowLock) {
- nLockCanvas(mNativeWindow, mCanvas, dirty);
+ if (!nLockCanvas(mNativeWindow, mCanvas, dirty)) {
+ return null;
+ }
}
mSaveCount = mCanvas.save();
@@ -803,6 +811,6 @@ public class TextureView extends View {
private static native void nSetDefaultBufferSize(SurfaceTexture surfaceTexture,
int width, int height);
- private static native void nLockCanvas(int nativeWindow, Canvas canvas, Rect dirty);
+ private static native boolean nLockCanvas(int nativeWindow, Canvas canvas, Rect dirty);
private static native void nUnlockCanvasAndPost(int nativeWindow, Canvas canvas);
}
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 50638aa..6f88bb2 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -73,6 +73,7 @@ import android.view.animation.Transformation;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputMethodManager;
+import android.view.transition.Scene;
import android.widget.ScrollBarDrawable;
import static android.os.Build.VERSION_CODES.*;
@@ -1572,6 +1573,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
*/
protected Object mTag;
+ private Scene mCurrentScene = null;
+
// for mPrivateFlags:
/** {@hide} */
static final int PFLAG_WANTS_FOCUS = 0x00000001;
@@ -2341,7 +2344,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* allows it to avoid artifacts when switching in and out of that mode, at
* the expense that some of its user interface may be covered by screen
* decorations when they are shown. You can perform layout of your inner
- * UI elements to account for the navagation system UI through the
+ * UI elements to account for the navigation system UI through the
* {@link #fitSystemWindows(Rect)} method.
*/
public static final int SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION = 0x00000200;
@@ -2359,6 +2362,15 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
public static final int SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN = 0x00000400;
/**
+ * Flag for {@link #setSystemUiVisibility(int)}: View would like to receive touch events
+ * when hiding the status bar with {@link #SYSTEM_UI_FLAG_FULLSCREEN} and/or hiding the
+ * navigation bar with {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION} instead of having the system
+ * clear these flags upon interaction. The system may compensate by temporarily overlaying
+ * transparent system ui while also delivering the event.
+ */
+ public static final int SYSTEM_UI_FLAG_ALLOW_OVERLAY = 0x00000800;
+
+ /**
* @deprecated Use {@link #SYSTEM_UI_FLAG_LOW_PROFILE} instead.
*/
public static final int STATUS_BAR_HIDDEN = SYSTEM_UI_FLAG_LOW_PROFILE;
@@ -2479,6 +2491,30 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
/**
* @hide
+ *
+ * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
+ * out of the public fields to keep the undefined bits out of the developer's way.
+ *
+ * Flag to specify that the status bar should temporarily overlay underlying content
+ * that is otherwise assuming the status bar is hidden. The status bar may
+ * have some degree of transparency while in this temporary overlay mode.
+ */
+ public static final int STATUS_BAR_OVERLAY = 0x04000000;
+
+ /**
+ * @hide
+ *
+ * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
+ * out of the public fields to keep the undefined bits out of the developer's way.
+ *
+ * Flag to specify that the navigation bar should temporarily overlay underlying content
+ * that is otherwise assuming the navigation bar is hidden. The navigation bar mayu
+ * have some degree of transparency while in this temporary overlay mode.
+ */
+ public static final int NAVIGATION_BAR_OVERLAY = 0x08000000;
+
+ /**
+ * @hide
*/
public static final int PUBLIC_STATUS_BAR_VISIBILITY_MASK = 0x0000FFFF;
@@ -8556,7 +8592,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
}
}
- if ((flags & VISIBILITY_MASK) == VISIBLE) {
+ final int newVisibility = flags & VISIBILITY_MASK;
+ if (newVisibility == VISIBLE) {
if ((changed & VISIBILITY_MASK) != 0) {
/*
* If this view is becoming visible, invalidate it in case it changed while
@@ -8622,14 +8659,19 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
}
if ((changed & VISIBILITY_MASK) != 0) {
+ // If the view is invisible, cleanup its display list to free up resources
+ if (newVisibility != VISIBLE) {
+ cleanupDraw();
+ }
+
if (mParent instanceof ViewGroup) {
((ViewGroup) mParent).onChildVisibilityChanged(this,
- (changed & VISIBILITY_MASK), (flags & VISIBILITY_MASK));
+ (changed & VISIBILITY_MASK), newVisibility);
((View) mParent).invalidate(true);
} else if (mParent != null) {
mParent.invalidateChild(this, null);
}
- dispatchVisibilityChanged(this, (flags & VISIBILITY_MASK));
+ dispatchVisibilityChanged(this, newVisibility);
}
if ((changed & WILL_NOT_CACHE_DRAWING) != 0) {
@@ -12009,6 +12051,15 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
destroyLayer(false);
+ cleanupDraw();
+
+ mCurrentAnimation = null;
+ mCurrentScene = null;
+
+ resetAccessibilityStateChanged();
+ }
+
+ private void cleanupDraw() {
if (mAttachInfo != null) {
if (mDisplayList != null) {
mDisplayList.markDirty();
@@ -12019,10 +12070,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
// Should never happen
clearDisplayList();
}
+ }
- mCurrentAnimation = null;
-
- resetAccessibilityStateChanged();
+ void invalidateInheritedLayoutMode(int layoutModeOfRoot) {
}
/**
@@ -12640,6 +12690,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* @hide
*/
protected void destroyHardwareResources() {
+ clearDisplayList();
destroyLayer(true);
}
@@ -15637,7 +15688,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
private void setKeyedTag(int key, Object tag) {
if (mKeyedTags == null) {
- mKeyedTags = new SparseArray<Object>();
+ mKeyedTags = new SparseArray<Object>(2);
}
mKeyedTags.put(key, tag);
@@ -17742,6 +17793,31 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
}
/**
+ * Set the current Scene that this view is in. The current scene is set only
+ * on the root view of a scene, not for every view in that hierarchy. This
+ * information is used by Scene to determine whether there is a previous
+ * scene which should be exited before the new scene is entered.
+ *
+ * @param scene The new scene being set on the view
+ *
+ * @hide
+ */
+ public void setCurrentScene(Scene scene) {
+ mCurrentScene = scene;
+ }
+
+ /**
+ * Gets the current {@link Scene} set on this view. A scene is set on a view
+ * only if that view is the scene root.
+ *
+ * @return The current Scene set on this view. A value of null indicates that
+ * no Scene is current set.
+ */
+ public Scene getCurrentScene() {
+ return mCurrentScene;
+ }
+
+ /**
* Interface definition for a callback to be invoked when a hardware key event is
* dispatched to this view. The callback will be invoked before the key event is
* given to the view. This is only useful for hardware keyboards; a software input
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 426c9d4..b0fbe84 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -204,7 +204,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
/**
* Either {@link #LAYOUT_MODE_CLIP_BOUNDS} or {@link #LAYOUT_MODE_OPTICAL_BOUNDS}.
*/
- private int mLayoutMode = DEFAULT_LAYOUT_MODE;
+ private int mLayoutMode = LAYOUT_MODE_UNDEFINED;
/**
* NOTE: If you change the flags below make sure to reflect the changes
@@ -345,6 +345,14 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
private static final int FLAG_PREVENT_DISPATCH_ATTACHED_TO_WINDOW = 0x400000;
/**
+ * When true, indicates that a layoutMode has been explicitly set, either with
+ * an explicit call to {@link #setLayoutMode(int)} in code or from an XML resource.
+ * This distinguishes the situation in which a layout mode was inherited from
+ * one of the ViewGroup's ancestors and cached locally.
+ */
+ private static final int FLAG_LAYOUT_MODE_WAS_EXPLICITLY_SET = 0x800000;
+
+ /**
* Indicates which types of drawing caches are to be kept in memory.
* This field should be made private, so it is hidden from the SDK.
* {@hide}
@@ -373,6 +381,8 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
// Layout Modes
+ private static final int LAYOUT_MODE_UNDEFINED = -1;
+
/**
* This constant is a {@link #setLayoutMode(int) layoutMode}.
* Clip bounds are the raw values of {@link #getLeft() left}, {@link #getTop() top},
@@ -389,7 +399,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
public static final int LAYOUT_MODE_OPTICAL_BOUNDS = 1;
/** @hide */
- public static int DEFAULT_LAYOUT_MODE = LAYOUT_MODE_CLIP_BOUNDS;
+ public static int LAYOUT_MODE_DEFAULT = LAYOUT_MODE_CLIP_BOUNDS;
/**
* We clip to padding when FLAG_CLIP_TO_PADDING and FLAG_PADDING_NOT_NULL
@@ -531,7 +541,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
}
break;
case R.styleable.ViewGroup_layoutMode:
- setLayoutMode(a.getInt(attr, DEFAULT_LAYOUT_MODE));
+ setLayoutMode(a.getInt(attr, LAYOUT_MODE_UNDEFINED));
break;
}
}
@@ -3448,6 +3458,24 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
}
}
+ private void clearCachedLayoutMode() {
+ if (!getBooleanFlag(FLAG_LAYOUT_MODE_WAS_EXPLICITLY_SET)) {
+ mLayoutMode = LAYOUT_MODE_UNDEFINED;
+ }
+ }
+
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ clearCachedLayoutMode();
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ clearCachedLayoutMode();
+ }
+
/**
* Adds a view during layout. This is useful if in your onLayout() method,
* you need to add more views (as does the list view for example).
@@ -4751,6 +4779,10 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
setBooleanFlag(FLAG_USE_CHILD_DRAWING_ORDER, enabled);
}
+ private boolean getBooleanFlag(int flag) {
+ return (mGroupFlags & flag) == flag;
+ }
+
private void setBooleanFlag(int flag, boolean value) {
if (value) {
mGroupFlags |= flag;
@@ -4794,24 +4826,63 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
mPersistentDrawingCache = drawingCacheToKeep & PERSISTENT_ALL_CACHES;
}
+ private void setLayoutMode(int layoutMode, boolean explicitly) {
+ mLayoutMode = layoutMode;
+ setBooleanFlag(FLAG_LAYOUT_MODE_WAS_EXPLICITLY_SET, explicitly);
+ }
+
/**
- * Returns the basis of alignment during layout operations on this view group:
+ * Recursively traverse the view hierarchy, resetting the layoutMode of any
+ * descendants that had inherited a different layoutMode from a previous parent.
+ * Recursion terminates when a descendant's mode is:
+ * <ul>
+ * <li>Undefined</li>
+ * <li>The same as the root node's</li>
+ * <li>A mode that had been explicitly set</li>
+ * <ul/>
+ * The first two clauses are optimizations.
+ * @param layoutModeOfRoot
+ */
+ @Override
+ void invalidateInheritedLayoutMode(int layoutModeOfRoot) {
+ if (mLayoutMode == LAYOUT_MODE_UNDEFINED ||
+ mLayoutMode == layoutModeOfRoot ||
+ getBooleanFlag(FLAG_LAYOUT_MODE_WAS_EXPLICITLY_SET)) {
+ return;
+ }
+ setLayoutMode(LAYOUT_MODE_UNDEFINED, false);
+
+ // apply recursively
+ for (int i = 0, N = getChildCount(); i < N; i++) {
+ getChildAt(i).invalidateInheritedLayoutMode(layoutModeOfRoot);
+ }
+ }
+
+ /**
+ * Returns the basis of alignment during layout operations on this ViewGroup:
* either {@link #LAYOUT_MODE_CLIP_BOUNDS} or {@link #LAYOUT_MODE_OPTICAL_BOUNDS}.
+ * <p>
+ * If no layoutMode was explicitly set, either programmatically or in an XML resource,
+ * the method returns the layoutMode of the view's parent ViewGroup if such a parent exists,
+ * otherwise the method returns a default value of {@link #LAYOUT_MODE_CLIP_BOUNDS}.
*
* @return the layout mode to use during layout operations
*
* @see #setLayoutMode(int)
*/
public int getLayoutMode() {
+ if (mLayoutMode == LAYOUT_MODE_UNDEFINED) {
+ int inheritedLayoutMode = (mParent instanceof ViewGroup) ?
+ ((ViewGroup) mParent).getLayoutMode() : LAYOUT_MODE_DEFAULT;
+ setLayoutMode(inheritedLayoutMode, false);
+ }
return mLayoutMode;
}
/**
- * Sets the basis of alignment during the layout of this view group.
+ * Sets the basis of alignment during the layout of this ViewGroup.
* Valid values are either {@link #LAYOUT_MODE_CLIP_BOUNDS} or
* {@link #LAYOUT_MODE_OPTICAL_BOUNDS}.
- * <p>
- * The default is {@link #LAYOUT_MODE_CLIP_BOUNDS}.
*
* @param layoutMode the layout mode to use during layout operations
*
@@ -4819,7 +4890,8 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
*/
public void setLayoutMode(int layoutMode) {
if (mLayoutMode != layoutMode) {
- mLayoutMode = layoutMode;
+ invalidateInheritedLayoutMode(layoutMode);
+ setLayoutMode(layoutMode, layoutMode != LAYOUT_MODE_UNDEFINED);
requestLayout();
}
}
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index bbf5ae9..bcc58a2 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -23,7 +23,6 @@ import android.content.ClipDescription;
import android.content.ComponentCallbacks;
import android.content.ComponentCallbacks2;
import android.content.Context;
-import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.res.CompatibilityInfo;
import android.content.res.Configuration;
@@ -108,13 +107,12 @@ public final class ViewRootImpl implements ViewParent,
private static final boolean DEBUG_FPS = false;
private static final boolean DEBUG_INPUT_PROCESSING = false || LOCAL_LOGV;
- private static final boolean USE_RENDER_THREAD = false;
-
/**
* Set this system property to true to force the view hierarchy to render
* at 60 Hz. This can be used to measure the potential framerate.
*/
- private static final String PROPERTY_PROFILE_RENDERING = "viewancestor.profile_rendering";
+ private static final String PROPERTY_PROFILE_RENDERING = "viewroot.profile_rendering";
+ private static final String PROPERTY_MEDIA_DISABLED = "config.disable_media";
/**
* Maximum time we allow the user to roll the trackball enough to generate
@@ -130,10 +128,6 @@ public final class ViewRootImpl implements ViewParent,
static final ArrayList<ComponentCallbacks> sConfigCallbacks
= new ArrayList<ComponentCallbacks>();
- private static boolean sUseRenderThread = false;
- private static boolean sRenderThreadQueried = false;
- private static final Object[] sRenderThreadQueryLock = new Object[0];
-
final Context mContext;
final IWindowSession mWindowSession;
final Display mDisplay;
@@ -286,6 +280,8 @@ public final class ViewRootImpl implements ViewParent,
private Choreographer.FrameCallback mRenderProfiler;
private boolean mRenderProfilingEnabled;
+ private boolean mMediaDisabled;
+
// Variables to track frames per second, enabled via DEBUG_FPS flag
private long mFpsStartTime = -1;
private long mFpsPrevTime = -1;
@@ -373,35 +369,6 @@ public final class ViewRootImpl implements ViewParent,
loadSystemProperties();
}
- /**
- * @return True if the application requests the use of a separate render thread,
- * false otherwise
- */
- private static boolean isRenderThreadRequested(Context context) {
- if (USE_RENDER_THREAD) {
- synchronized (sRenderThreadQueryLock) {
- if (!sRenderThreadQueried) {
- final PackageManager packageManager = context.getPackageManager();
- final String packageName = context.getApplicationInfo().packageName;
- try {
- ApplicationInfo applicationInfo = packageManager.getApplicationInfo(packageName,
- PackageManager.GET_META_DATA);
- if (applicationInfo.metaData != null) {
- sUseRenderThread = applicationInfo.metaData.getBoolean(
- "android.graphics.renderThread", false);
- }
- } catch (PackageManager.NameNotFoundException e) {
- } finally {
- sRenderThreadQueried = true;
- }
- }
- return sUseRenderThread;
- }
- } else {
- return false;
- }
- }
-
public static void addFirstDrawHandler(Runnable callback) {
synchronized (sFirstDrawHandlers) {
if (!sFirstDrawComplete) {
@@ -479,7 +446,7 @@ public final class ViewRootImpl implements ViewParent,
// If the application owns the surface, don't enable hardware acceleration
if (mSurfaceHolder == null) {
- enableHardwareAcceleration(mView.getContext(), attrs);
+ enableHardwareAcceleration(attrs);
}
boolean restore = false;
@@ -687,7 +654,7 @@ public final class ViewRootImpl implements ViewParent,
}
}
- private void enableHardwareAcceleration(Context context, WindowManager.LayoutParams attrs) {
+ private void enableHardwareAcceleration(WindowManager.LayoutParams attrs) {
mAttachInfo.mHardwareAccelerated = false;
mAttachInfo.mHardwareAccelerationRequested = false;
@@ -727,11 +694,6 @@ public final class ViewRootImpl implements ViewParent,
return;
}
- final boolean renderThread = isRenderThreadRequested(context);
- if (renderThread) {
- Log.i(HardwareRenderer.LOG_TAG, "Render threat initiated");
- }
-
if (mAttachInfo.mHardwareRenderer != null) {
mAttachInfo.mHardwareRenderer.destroy(true);
}
@@ -5057,6 +5019,10 @@ public final class ViewRootImpl implements ViewParent,
public void playSoundEffect(int effectId) {
checkThread();
+ if (mMediaDisabled) {
+ return;
+ }
+
try {
final AudioManager audioManager = getAudioManager();
@@ -5202,6 +5168,9 @@ public final class ViewRootImpl implements ViewParent,
mProfileRendering = SystemProperties.getBoolean(PROPERTY_PROFILE_RENDERING, false);
profileRendering(mAttachInfo.mHasWindowFocus);
+ // Media (used by sound effects)
+ mMediaDisabled = SystemProperties.getBoolean(PROPERTY_MEDIA_DISABLED, false);
+
// Hardware rendering
if (mAttachInfo.mHardwareRenderer != null) {
if (mAttachInfo.mHardwareRenderer.loadSystemProperties(mHolder.getSurface())) {
diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java
index 06974d3..39d48a7 100644
--- a/core/java/android/view/Window.java
+++ b/core/java/android/view/Window.java
@@ -1256,4 +1256,38 @@ public abstract class Window {
* @param mask Flags specifying which options should be modified. Others will remain unchanged.
*/
public void setUiOptions(int uiOptions, int mask) { }
+
+ /**
+ * Set the primary icon for this window.
+ *
+ * @param resId resource ID of a drawable to set
+ */
+ public void setIcon(int resId) { }
+
+ /**
+ * Set the default icon for this window.
+ * This will be overridden by any other icon set operation which could come from the
+ * theme or another explicit set.
+ *
+ * @hide
+ */
+ public void setDefaultIcon(int resId) { }
+
+ /**
+ * Set the logo for this window. A logo is often shown in place of an
+ * {@link #setIcon(int) icon} but is generally wider and communicates window title information
+ * as well.
+ *
+ * @param resId resource ID of a drawable to set
+ */
+ public void setLogo(int resId) { }
+
+ /**
+ * Set the default logo for this window.
+ * This will be overridden by any other logo set operation which could come from the
+ * theme or another explicit set.
+ *
+ * @hide
+ */
+ public void setDefaultLogo(int resId) { }
}
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 541c503..5144889 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -527,6 +527,14 @@ public interface WindowManager extends ViewManager {
*/
public static final int TYPE_RECENTS_OVERLAY = FIRST_SYSTEM_WINDOW+28;
+
+ /**
+ * Window type: keyguard scrim window. Shows if keyguard needs to be restarted.
+ * In multiuser systems shows on all users' windows.
+ * @hide
+ */
+ public static final int TYPE_KEYGUARD_SCRIM = FIRST_SYSTEM_WINDOW+29;
+
/**
* End of types of system windows.
*/
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index c0044b6..6291e62 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -420,6 +420,11 @@ public interface WindowManagerPolicy {
public void shutdown(boolean confirm);
public void rebootSafeMode(boolean confirm);
+
+ /**
+ * Return the window manager lock needed to correctly call "Lw" methods.
+ */
+ public Object getWindowManagerLock();
}
/** Window has been added to the screen. */
@@ -637,7 +642,7 @@ public interface WindowManagerPolicy {
*/
public View addStartingWindow(IBinder appToken, String packageName,
int theme, CompatibilityInfo compatInfo, CharSequence nonLocalizedLabel,
- int labelRes, int icon, int windowFlags);
+ int labelRes, int icon, int logo, int windowFlags);
/**
* Called when the first window of an application has been displayed, while
@@ -816,6 +821,14 @@ public interface WindowManagerPolicy {
public int getSystemDecorRectLw(Rect systemRect);
/**
+ * Return the rectangle of the screen that is available for applications to run in.
+ * This will be called immediately after {@link #beginLayoutLw}.
+ *
+ * @param r The rectangle to be filled with the boundaries available to applications.
+ */
+ public void getContentRectLw(Rect r);
+
+ /**
* Called for each window attached to the window manager as layout is
* proceeding. The implementation of this function must take care of
* setting the window's frame, either here or in finishLayout().
diff --git a/core/java/android/view/accessibility/AccessibilityManager.java b/core/java/android/view/accessibility/AccessibilityManager.java
index 732699b..04ce7e2 100644
--- a/core/java/android/view/accessibility/AccessibilityManager.java
+++ b/core/java/android/view/accessibility/AccessibilityManager.java
@@ -16,14 +16,17 @@
package android.view.accessibility;
+import android.Manifest;
import android.accessibilityservice.AccessibilityServiceInfo;
import android.content.Context;
+import android.content.pm.PackageManager;
import android.content.pm.ServiceInfo;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
+import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
@@ -132,29 +135,6 @@ public final class AccessibilityManager {
}
/**
- * Creates the singleton AccessibilityManager to be shared across users. This
- * has to be called before the local AccessibilityManager is created to ensure
- * it registers itself in the system correctly.
- * <p>
- * Note: Calling this method requires INTERACT_ACROSS_USERS_FULL or
- * INTERACT_ACROSS_USERS permission.
- * </p>
- * @param context Context in which this manager operates.
- * @throws IllegalStateException if not called before the local
- * AccessibilityManager is instantiated.
- *
- * @hide
- */
- public static void createAsSharedAcrossUsers(Context context) {
- synchronized (sInstanceSync) {
- if (sInstance != null) {
- throw new IllegalStateException("AccessibilityManager already created.");
- }
- createSingletonInstance(context, UserHandle.USER_CURRENT);
- }
- }
-
- /**
* Get an AccessibilityManager instance (create one if necessary).
*
* @param context Context in which this manager operates.
@@ -164,25 +144,27 @@ public final class AccessibilityManager {
public static AccessibilityManager getInstance(Context context) {
synchronized (sInstanceSync) {
if (sInstance == null) {
- createSingletonInstance(context, UserHandle.myUserId());
+ final int userId;
+ if (Binder.getCallingUid() == Process.SYSTEM_UID
+ || context.checkCallingOrSelfPermission(
+ Manifest.permission.INTERACT_ACROSS_USERS)
+ == PackageManager.PERMISSION_GRANTED
+ || context.checkCallingOrSelfPermission(
+ Manifest.permission.INTERACT_ACROSS_USERS_FULL)
+ == PackageManager.PERMISSION_GRANTED) {
+ userId = UserHandle.USER_CURRENT;
+ } else {
+ userId = UserHandle.myUserId();
+ }
+ IBinder iBinder = ServiceManager.getService(Context.ACCESSIBILITY_SERVICE);
+ IAccessibilityManager service = IAccessibilityManager.Stub.asInterface(iBinder);
+ sInstance = new AccessibilityManager(context, service, userId);
}
}
return sInstance;
}
/**
- * Creates the singleton instance.
- *
- * @param context Context in which this manager operates.
- * @param userId The user id under which to operate.
- */
- private static void createSingletonInstance(Context context, int userId) {
- IBinder iBinder = ServiceManager.getService(Context.ACCESSIBILITY_SERVICE);
- IAccessibilityManager service = IAccessibilityManager.Stub.asInterface(iBinder);
- sInstance = new AccessibilityManager(context, service, userId);
- }
-
- /**
* Create an instance.
*
* @param context A {@link Context}.
diff --git a/core/java/android/view/inputmethod/BaseInputConnection.java b/core/java/android/view/inputmethod/BaseInputConnection.java
index d6b973e..f730cf7 100644
--- a/core/java/android/view/inputmethod/BaseInputConnection.java
+++ b/core/java/android/view/inputmethod/BaseInputConnection.java
@@ -269,8 +269,9 @@ public class BaseInputConnection implements InputConnection {
if (content != null) {
beginBatchEdit();
removeComposingSpans(content);
- endBatchEdit();
+ // Note: sendCurrentText does nothing unless mDummyMode is set
sendCurrentText();
+ endBatchEdit();
}
return true;
}
@@ -467,8 +468,9 @@ public class BaseInputConnection implements InputConnection {
content.setSpan(COMPOSING, a, b,
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE | Spanned.SPAN_COMPOSING);
- endBatchEdit();
+ // Note: sendCurrentText does nothing unless mDummyMode is set
sendCurrentText();
+ endBatchEdit();
}
return true;
}
diff --git a/core/java/android/view/transition/AutoTransition.java b/core/java/android/view/transition/AutoTransition.java
new file mode 100644
index 0000000..d94cf2c
--- /dev/null
+++ b/core/java/android/view/transition/AutoTransition.java
@@ -0,0 +1,34 @@
+/*
+ * 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 android.view.transition;
+
+/**
+ * Utility class for creating a default transition that automatically fades,
+ * moves, and resizes views during a scene change.
+ */
+public class AutoTransition extends TransitionGroup {
+
+ /**
+ * Constructs an AutoTransition object, which is a TransitionGroup which
+ * first fades out disappearing targets, then moves and resizes existing
+ * targets, and finally fades in appearing targets.
+ *
+ */
+ public AutoTransition() {
+ setOrdering(SEQUENTIALLY);
+ addTransitions(new Fade(Fade.OUT), new Move(), new Fade(Fade.IN));
+ }
+}
diff --git a/core/java/android/view/transition/Crossfade.java b/core/java/android/view/transition/Crossfade.java
new file mode 100644
index 0000000..babf58f
--- /dev/null
+++ b/core/java/android/view/transition/Crossfade.java
@@ -0,0 +1,163 @@
+/*
+ * 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 android.view.transition;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
+import android.animation.RectEvaluator;
+import android.animation.ValueAnimator;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Rect;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.util.Log;
+import android.view.SurfaceView;
+import android.view.TextureView;
+import android.view.View;
+import android.view.ViewGroup;
+
+import java.util.HashMap;
+
+/**
+ * This transition captures bitmap representations of target views before and
+ * after the scene change and fades between them.
+ *
+ * <p>Note: This transition is not compatible with {@link TextureView}
+ * or {@link SurfaceView}.</p>
+ */
+public class Crossfade extends Transition {
+ // TODO: Add a hook that lets a Transition call user code to query whether it should run on
+ // a given target view. This would save bitmap comparisons in this transition, for example.
+
+ private static final String LOG_TAG = "Crossfade";
+
+ private static final String PROPNAME_BITMAP = "android:crossfade:bitmap";
+ private static final String PROPNAME_DRAWABLE = "android:crossfade:drawable";
+ private static final String PROPNAME_BOUNDS = "android:crossfade:bounds";
+
+ private static RectEvaluator sRectEvaluator = new RectEvaluator();
+
+ @Override
+ protected boolean prePlay(ViewGroup sceneRoot, TransitionValues startValues,
+ TransitionValues endValues) {
+ if (startValues == null || endValues == null) {
+ return false;
+ }
+ final View view = startValues.view;
+ HashMap<String, Object> startVals = startValues.values;
+ HashMap<String, Object> endVals = endValues.values;
+ Bitmap startBitmap = (Bitmap) startVals.get(PROPNAME_BITMAP);
+ Bitmap endBitmap = (Bitmap) endVals.get(PROPNAME_BITMAP);
+ Drawable startDrawable = (Drawable) startVals.get(PROPNAME_DRAWABLE);
+ Drawable endDrawable = (Drawable) endVals.get(PROPNAME_DRAWABLE);
+ if (Transition.DBG) {
+ Log.d(LOG_TAG, "StartBitmap.sameAs(endBitmap) = " + startBitmap.sameAs(endBitmap) +
+ " for start, end: " + startBitmap + ", " + endBitmap);
+ }
+ if (startDrawable != null && endDrawable != null && !startBitmap.sameAs(endBitmap)) {
+ view.getOverlay().add(endDrawable);
+ view.getOverlay().add(startDrawable);
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ @Override
+ protected Animator play(ViewGroup sceneRoot, TransitionValues startValues,
+ TransitionValues endValues) {
+ if (startValues == null || endValues == null) {
+ return null;
+ }
+ HashMap<String, Object> startVals = startValues.values;
+ HashMap<String, Object> endVals = endValues.values;
+
+ final View view = endValues.view;
+ Rect startBounds = (Rect) startVals.get(PROPNAME_BOUNDS);
+ Rect endBounds = (Rect) endVals.get(PROPNAME_BOUNDS);
+ final BitmapDrawable startDrawable = (BitmapDrawable) startVals.get(PROPNAME_DRAWABLE);
+ final BitmapDrawable endDrawable = (BitmapDrawable) endVals.get(PROPNAME_DRAWABLE);
+
+ // The transition works by placing the end drawable under the start drawable and
+ // gradually fading out the start drawable. So it's not really a cross-fade, but rather
+ // a reveal of the end scene over time. Also, animate the bounds of both drawables
+ // to mimic the change in the size of the view itself between scenes.
+ ObjectAnimator anim = ObjectAnimator.ofInt(startDrawable, "alpha", 0);
+ anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ // TODO: some way to auto-invalidate views based on drawable changes? callbacks?
+ view.invalidate(startDrawable.getBounds());
+ }
+ });
+ if (Transition.DBG) {
+ Log.d(LOG_TAG, "Crossfade: created anim " + anim + " for start, end values " +
+ startValues + ", " + endValues);
+ }
+ anim.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ view.getOverlay().remove(startDrawable);
+ view.getOverlay().remove(endDrawable);
+ }
+ });
+ AnimatorSet set = new AnimatorSet();
+ set.playTogether(anim);
+ if (!startBounds.equals(endBounds)) {
+ if (Transition.DBG) {
+ Log.d(LOG_TAG, "animating from startBounds to endBounds: " +
+ startBounds + ", " + endBounds);
+ }
+ Animator anim2 = ObjectAnimator.ofObject(startDrawable, "bounds",
+ sRectEvaluator, startBounds, endBounds);
+ Animator anim3 = ObjectAnimator.ofObject(endDrawable, "bounds",
+ sRectEvaluator, startBounds, endBounds);
+ set.playTogether(anim2);
+ set.playTogether(anim3);
+ }
+ return set;
+ }
+
+ @Override
+ protected void captureValues(TransitionValues values, boolean start) {
+ View view = values.view;
+ values.values.put(PROPNAME_BOUNDS, new Rect(0, 0,
+ view.getWidth(), view.getHeight()));
+
+ if (Transition.DBG) {
+ Log.d(LOG_TAG, "Captured bounds " + values.values.get(PROPNAME_BOUNDS) + ": start = " +
+ start);
+ }
+ Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(),
+ Bitmap.Config.ARGB_8888);
+ if (view instanceof TextureView) {
+ bitmap = ((TextureView) view).getBitmap();
+ } else {
+ Canvas c = new Canvas(bitmap);
+ view.draw(c);
+ }
+ values.values.put(PROPNAME_BITMAP, bitmap);
+ // TODO: I don't have resources, can't call the non-deprecated method?
+ BitmapDrawable drawable = new BitmapDrawable(bitmap);
+ // TODO: lrtb will be wrong if the view has transXY set
+ drawable.setBounds(view.getLeft(), view.getTop(), view.getRight(), view.getBottom());
+ values.values.put(PROPNAME_DRAWABLE, drawable);
+ }
+
+}
diff --git a/core/java/android/view/transition/Fade.java b/core/java/android/view/transition/Fade.java
new file mode 100644
index 0000000..8e4909d
--- /dev/null
+++ b/core/java/android/view/transition/Fade.java
@@ -0,0 +1,209 @@
+/*
+ * 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 android.view.transition;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ObjectAnimator;
+import android.util.Log;
+import android.view.View;
+import android.view.ViewGroup;
+
+/**
+ * This transition tracks changes to the visibility of target views in the
+ * start and end scenes and fades views in or out when they become visible
+ * or non-visible. Visibility is determined by both the
+ * {@link View#setVisibility(int)} state of the view as well as whether it
+ * is parented in the current view hierarchy.
+ */
+public class Fade extends Visibility {
+
+ private static final String LOG_TAG = "Fade";
+
+ /**
+ * Fading mode used in {@link #Fade(int)} to make the transition
+ * operate on targets that are appearing. Maybe be combined with
+ * {@link #OUT} to fade both in and out.
+ */
+ public static final int IN = 0x1;
+ /**
+ * Fading mode used in {@link #Fade(int)} to make the transition
+ * operate on targets that are disappearing. Maybe be combined with
+ * {@link #IN} to fade both in and out.
+ */
+ public static final int OUT = 0x2;
+
+ private int mFadingMode;
+
+ /**
+ * Constructs a Fade transition that will fade targets in and out.
+ */
+ public Fade() {
+ this(IN | OUT);
+ }
+
+ /**
+ * Constructs a Fade transition that will fade targets in
+ * and/or out, according to the value of fadingMode.
+ *
+ * @param fadingMode The behavior of this transition, a combination of
+ * {@link #IN} and {@link #OUT}.
+ */
+ public Fade(int fadingMode) {
+ mFadingMode = fadingMode;
+ }
+
+ /**
+ * Utility method to handle creating and running the Animator.
+ */
+ private Animator runAnimation(View view, float startAlpha, float endAlpha,
+ Animator.AnimatorListener listener) {
+ final ObjectAnimator anim = ObjectAnimator.ofFloat(view, "alpha", startAlpha, endAlpha);
+ if (listener != null) {
+ anim.addListener(listener);
+ }
+ // TODO: Maybe extract a method into Transition to run an animation that handles the
+ // duration/startDelay stuff for all subclasses.
+ return anim;
+ }
+
+ @Override
+ protected boolean preAppear(ViewGroup sceneRoot, View startView, int startVisibility,
+ View endView, int endVisibility) {
+ if ((mFadingMode & IN) != IN) {
+ return false;
+ }
+ endView.setAlpha(0);
+ return true;
+ }
+
+ @Override
+ protected Animator appear(ViewGroup sceneRoot, View startView, int startVisibility,
+ View endView, int endVisibility) {
+ if ((mFadingMode & IN) != IN) {
+ return null;
+ }
+ // TODO: hack - retain original value from before preAppear
+ return runAnimation(endView, 0, 1, null);
+ // TODO: end listener to make sure we end at 1 no matter what
+ }
+
+ @Override
+ protected boolean preDisappear(ViewGroup sceneRoot, View startView, int startVisibility,
+ View endView, int endVisibility) {
+ if ((mFadingMode & OUT) != OUT) {
+ return false;
+ }
+ if (Transition.DBG) {
+ Log.d(LOG_TAG, "Fade.predisappear: startView, startVis, endView, endVis = " +
+ startView + ", " + startVisibility + ", " + endView + ", " + endVisibility);
+ }
+ View view;
+ View overlayView = null;
+ View viewToKeep = null;
+ if (endView == null) {
+ // view was removed: add the start view to the Overlay
+ view = startView;
+ overlayView = view;
+ } else {
+ // visibility change
+ if (endVisibility == View.INVISIBLE) {
+ view = endView;
+ viewToKeep = view;
+ } else {
+ // Becoming GONE
+ if (startView == endView) {
+ view = endView;
+ viewToKeep = view;
+ } else {
+ view = startView;
+ overlayView = view;
+ }
+ }
+ }
+ // TODO: add automatic facility to Visibility superclass for keeping views around
+ if (overlayView != null) {
+ // TODO: Need to do this for general case of adding to overlay
+ sceneRoot.getOverlay().add(overlayView);
+ return true;
+ }
+ if (viewToKeep != null) {
+ // TODO: find a different way to do this, like just changing the view to be
+ // VISIBLE for the duration of the transition
+ viewToKeep.setVisibility((View.VISIBLE));
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ protected Animator disappear(ViewGroup sceneRoot, View startView, int startVisibility,
+ View endView, int endVisibility) {
+ if ((mFadingMode & OUT) != OUT) {
+ return null;
+ }
+ if (Transition.DBG) {
+ Log.d(LOG_TAG, "Fade.disappear: startView, startVis, endView, endVis = " +
+ startView + ", " + startVisibility + ", " + endView + ", " + endVisibility);
+ }
+ View view;
+ View overlayView = null;
+ View viewToKeep = null;
+ final int finalVisibility = endVisibility;
+ if (endView == null) {
+ // view was removed: add the start view to the Overlay
+ view = startView;
+ overlayView = view;
+ } else {
+ // visibility change
+ if (endVisibility == View.INVISIBLE) {
+ view = endView;
+ viewToKeep = view;
+ } else {
+ // Becoming GONE
+ if (startView == endView) {
+ view = endView;
+ viewToKeep = view;
+ } else {
+ view = startView;
+ overlayView = view;
+ }
+ }
+ }
+ // TODO: add automatic facility to Visibility superclass for keeping views around
+ final float startAlpha = view.getAlpha();
+ float endAlpha = 0;
+ final View finalView = view;
+ final View finalOverlayView = overlayView;
+ final View finalViewToKeep = viewToKeep;
+ final ViewGroup finalSceneRoot = sceneRoot;
+ final Animator.AnimatorListener endListener = new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ finalView.setAlpha(startAlpha);
+ // TODO: restore view offset from overlay repositioning
+ if (finalViewToKeep != null) {
+ finalViewToKeep.setVisibility(finalVisibility);
+ }
+ if (finalOverlayView != null) {
+ finalSceneRoot.getOverlay().remove(finalOverlayView);
+ }
+ }
+ };
+ return runAnimation(view, startAlpha, endAlpha, endListener);
+ }
+
+} \ No newline at end of file
diff --git a/core/java/android/view/transition/Move.java b/core/java/android/view/transition/Move.java
new file mode 100644
index 0000000..3bd57bd
--- /dev/null
+++ b/core/java/android/view/transition/Move.java
@@ -0,0 +1,299 @@
+/*
+ * 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 android.view.transition;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ObjectAnimator;
+import android.animation.PropertyValuesHolder;
+import android.animation.RectEvaluator;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Rect;
+import android.graphics.drawable.BitmapDrawable;
+import android.view.View;
+import android.view.ViewGroup;
+
+import java.util.HashMap;
+
+/**
+ * This transition captures the layout bounds of target views before and after
+ * the scene change and animates those changes during the transition.
+ */
+public class Move extends Transition {
+
+ private static final String PROPNAME_BOUNDS = "android:move:bounds";
+ private static final String PROPNAME_PARENT = "android:move:parent";
+ private static final String PROPNAME_WINDOW_X = "android:move:windowX";
+ private static final String PROPNAME_WINDOW_Y = "android:move:windowY";
+ int[] tempLocation = new int[2];
+ boolean mResizeClip = false;
+ boolean mReparent = false;
+
+ private static RectEvaluator sRectEvaluator = new RectEvaluator();
+
+ public void setResizeClip(boolean resizeClip) {
+ mResizeClip = resizeClip;
+ }
+
+ /**
+ * Setting this flag tells Move to track the before/after parent
+ * of every view using this transition. The flag is not enabled by
+ * default because it requires the parent instances to be the same
+ * in the two scenes or else all parents must use ids to allow
+ * the transition to determine which parents are the same.
+ *
+ * @param reparent true if the transition should track the parent
+ * container of target views and animate parent changes.
+ */
+ public void setReparent(boolean reparent) {
+ mReparent = reparent;
+ }
+
+ @Override
+ protected void captureValues(TransitionValues values, boolean start) {
+ View view = values.view;
+ values.values.put(PROPNAME_BOUNDS, new Rect(view.getLeft(), view.getTop(),
+ view.getRight(), view.getBottom()));
+ values.values.put(PROPNAME_PARENT, values.view.getParent());
+ values.view.getLocationInWindow(tempLocation);
+ values.values.put(PROPNAME_WINDOW_X, tempLocation[0]);
+ values.values.put(PROPNAME_WINDOW_Y, tempLocation[1]);
+ }
+
+ @Override
+ protected Animator play(final ViewGroup sceneRoot, TransitionValues startValues,
+ TransitionValues endValues) {
+ if (startValues == null || endValues == null) {
+ return null;
+ }
+ final View view = endValues.view;
+ if (view.getParent() == null) {
+ // TODO: Might want to make it possible to Move an disappearing view.
+ // This workaround is here because if a parallel Fade is not running on the view
+ // Then it won't get added to the hierarchy and the animator below will not fire,
+ // causing the transition to not end
+ return null;
+ }
+ // TODO: need to handle non-VG case?
+ ViewGroup startParent = (ViewGroup) startValues.values.get(PROPNAME_PARENT);
+ ViewGroup endParent = (ViewGroup) endValues.values.get(PROPNAME_PARENT);
+ if (startParent == null || endParent == null) {
+ return null;
+ }
+ boolean parentsEqual = (startParent == endParent) ||
+ (startParent.getId() == endParent.getId());
+ if (!mReparent || parentsEqual) {
+ // Common case - view belongs to the same layout before/after. Just animate its bounds
+ Rect startBounds = (Rect) startValues.values.get(PROPNAME_BOUNDS);
+ Rect endBounds = (Rect) endValues.values.get(PROPNAME_BOUNDS);
+ int startLeft = startBounds.left;
+ int endLeft = endBounds.left;
+ int startTop = startBounds.top;
+ int endTop = endBounds.top;
+ int startRight = startBounds.right;
+ int endRight = endBounds.right;
+ int startBottom = startBounds.bottom;
+ int endBottom = endBounds.bottom;
+ int startWidth = startRight - startLeft;
+ int startHeight = startBottom - startTop;
+ int endWidth = endRight - endLeft;
+ int endHeight = endBottom - endTop;
+ int numChanges = 0;
+ if (startWidth != 0 && startHeight != 0 && endWidth != 0 && endHeight != 0) {
+ if (startLeft != endLeft) ++numChanges;
+ if (startTop != endTop) ++numChanges;
+ if (startRight != endRight) ++numChanges;
+ if (startBottom != endBottom) ++numChanges;
+ }
+ if (numChanges > 0) {
+ if (!mResizeClip) {
+ PropertyValuesHolder pvh[] = new PropertyValuesHolder[numChanges];
+ int pvhIndex = 0;
+ if (startLeft != endLeft) {
+ pvh[pvhIndex++] = PropertyValuesHolder.ofInt("left", startLeft, endLeft);
+ }
+ if (startTop != endTop) {
+ pvh[pvhIndex++] = PropertyValuesHolder.ofInt("top", startTop, endTop);
+ }
+ if (startRight != endRight) {
+ pvh[pvhIndex++] = PropertyValuesHolder.ofInt("right",
+ startRight, endRight);
+ }
+ if (startBottom != endBottom) {
+ pvh[pvhIndex++] = PropertyValuesHolder.ofInt("bottom",
+ startBottom, endBottom);
+ }
+ ObjectAnimator anim = ObjectAnimator.ofPropertyValuesHolder(view, pvh);
+ if (view.getParent() instanceof ViewGroup) {
+ final ViewGroup parent = (ViewGroup) view.getParent();
+ parent.suppressLayout(true);
+ anim.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ parent.suppressLayout(false);
+ }
+ });
+ }
+ return anim;
+ } else {
+ // Animate location with translationX/Y and size with clip bounds
+ float transXDelta = endLeft - startLeft;
+ float transYDelta = endTop - startTop;
+ int widthDelta = endWidth - startWidth;
+ int heightDelta = endHeight - startHeight;
+ numChanges = 0;
+ if (transXDelta != 0) numChanges++;
+ if (transYDelta != 0) numChanges++;
+ if (widthDelta != 0 || heightDelta != 0) numChanges++;
+ PropertyValuesHolder pvh[] = new PropertyValuesHolder[numChanges];
+ int pvhIndex = 0;
+ if (transXDelta != 0) {
+ pvh[pvhIndex++] = PropertyValuesHolder.ofFloat("translationX",
+ view.getTranslationX(), 0);
+ }
+ if (transYDelta != 0) {
+ pvh[pvhIndex++] = PropertyValuesHolder.ofFloat("translationY",
+ view.getTranslationY(), 0);
+ }
+ if (widthDelta != 0 || heightDelta != 0) {
+ Rect tempStartBounds = new Rect(0, 0, startWidth, startHeight);
+ Rect tempEndBounds = new Rect(0, 0, endWidth, endHeight);
+ pvh[pvhIndex++] = PropertyValuesHolder.ofObject("clipBounds",
+ sRectEvaluator, tempStartBounds, tempEndBounds);
+ }
+ ObjectAnimator anim = ObjectAnimator.ofPropertyValuesHolder(view, pvh);
+ if (view.getParent() instanceof ViewGroup) {
+ final ViewGroup parent = (ViewGroup) view.getParent();
+ parent.suppressLayout(true);
+ anim.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ parent.suppressLayout(false);
+ }
+ });
+ }
+ anim.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ view.setClipBounds(null);
+ }
+ });
+ return anim;
+ }
+ }
+ } else {
+ return (ObjectAnimator) endValues.values.get("drawableAnim");
+ }
+ return null;
+ }
+
+ @Override
+ protected boolean prePlay(final ViewGroup sceneRoot, TransitionValues startValues,
+ TransitionValues endValues) {
+ if (startValues == null || endValues == null) {
+ return false;
+ }
+ HashMap<String, Object> startParentVals = startValues.values;
+ HashMap<String, Object> endParentVals = endValues.values;
+ ViewGroup startParent = (ViewGroup) startParentVals.get(PROPNAME_PARENT);
+ ViewGroup endParent = (ViewGroup) endParentVals.get(PROPNAME_PARENT);
+ if (startParent == null || endParent == null) {
+ return false;
+ }
+ final View view = endValues.view;
+ boolean parentsEqual = (startParent == endParent) ||
+ (startParent.getId() == endParent.getId());
+ // TODO: Might want reparenting to be separate/subclass transition, or at least
+ // triggered by a property on Move. Otherwise, we're forcing the requirement that
+ // all parents in layouts have IDs to avoid layout-inflation resulting in a side-effect
+ // of reparenting the views.
+ if (!mReparent || parentsEqual) {
+ Rect startBounds = (Rect) startValues.values.get(PROPNAME_BOUNDS);
+ Rect endBounds = (Rect) endValues.values.get(PROPNAME_BOUNDS);
+ int startLeft = startBounds.left;
+ int endLeft = endBounds.left;
+ int startTop = startBounds.top;
+ int endTop = endBounds.top;
+ int startRight = startBounds.right;
+ int endRight = endBounds.right;
+ int startBottom = startBounds.bottom;
+ int endBottom = endBounds.bottom;
+ int startWidth = startRight - startLeft;
+ int startHeight = startBottom - startTop;
+ int endWidth = endRight - endLeft;
+ int endHeight = endBottom - endTop;
+ int numChanges = 0;
+ if (startWidth != 0 && startHeight != 0 && endWidth != 0 && endHeight != 0) {
+ if (startLeft != endLeft) ++numChanges;
+ if (startTop != endTop) ++numChanges;
+ if (startRight != endRight) ++numChanges;
+ if (startBottom != endBottom) ++numChanges;
+ }
+ if (numChanges > 0) {
+ if (!mResizeClip) {
+ if (startLeft != endLeft) view.setLeft(startLeft);
+ if (startTop != endTop) view.setTop(startTop);
+ if (startRight != endRight) view.setRight(startRight);
+ if (startBottom != endBottom) view.setBottom(startBottom);
+ } else {
+ if (startWidth != endWidth) view.setRight(endLeft +
+ Math.max(startWidth, endWidth));
+ if (startHeight != endHeight) view.setBottom(endTop +
+ Math.max(startHeight, endHeight));
+ // TODO: don't clobber TX/TY
+ if (startLeft != endLeft) view.setTranslationX(startLeft - endLeft);
+ if (startTop != endTop) view.setTranslationY(startTop - endTop);
+ }
+ return true;
+ }
+ } else {
+ int startX = (Integer) startValues.values.get(PROPNAME_WINDOW_X);
+ int startY = (Integer) startValues.values.get(PROPNAME_WINDOW_Y);
+ int endX = (Integer) endValues.values.get(PROPNAME_WINDOW_X);
+ int endY = (Integer) endValues.values.get(PROPNAME_WINDOW_Y);
+ // TODO: also handle size changes: check bounds and animate size changes
+ if (startX != endX || startY != endY) {
+ sceneRoot.getLocationInWindow(tempLocation);
+ Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(),
+ Bitmap.Config.ARGB_8888);
+ Canvas canvas = new Canvas(bitmap);
+ view.draw(canvas);
+ final BitmapDrawable drawable = new BitmapDrawable(bitmap);
+ view.setVisibility(View.INVISIBLE);
+ sceneRoot.getOverlay().add(drawable);
+ Rect startBounds = new Rect(startX - tempLocation[0], startY - tempLocation[1],
+ startX - tempLocation[0] + view.getWidth(),
+ startY - tempLocation[1] + view.getHeight());
+ Rect endBounds = new Rect(endX - tempLocation[0], endY - tempLocation[1],
+ endX - tempLocation[0] + view.getWidth(),
+ endY - tempLocation[1] + view.getHeight());
+ ObjectAnimator anim = ObjectAnimator.ofObject(drawable, "bounds",
+ sRectEvaluator, startBounds, endBounds);
+ anim.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ sceneRoot.getOverlay().remove(drawable);
+ view.setVisibility(View.VISIBLE);
+ }
+ });
+ endParentVals.put("drawableAnim", anim);
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/core/java/android/view/transition/Recolor.java b/core/java/android/view/transition/Recolor.java
new file mode 100644
index 0000000..7048be9
--- /dev/null
+++ b/core/java/android/view/transition/Recolor.java
@@ -0,0 +1,118 @@
+/*
+ * 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 android.view.transition;
+
+import android.animation.Animator;
+import android.animation.ArgbEvaluator;
+import android.animation.ObjectAnimator;
+import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.Drawable;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+import java.util.HashMap;
+
+/**
+ * This transition tracks changes during scene changes to the
+ * {@link View#setBackground(android.graphics.drawable.Drawable) background}
+ * property of its target views (when the background is a
+ * {@link ColorDrawable}, as well as the
+ * {@link TextView#setTextColor(android.content.res.ColorStateList)
+ * color} of the text for target TextViews. If the color changes between
+ * scenes, the color change is animated.
+ */
+public class Recolor extends Transition {
+
+ private static final String PROPNAME_BACKGROUND = "android:recolor:background";
+ private static final String PROPNAME_TEXT_COLOR = "android:recolor:textColor";
+
+ @Override
+ protected void captureValues(TransitionValues values, boolean start) {
+ values.values.put(PROPNAME_BACKGROUND, values.view.getBackground());
+ if (values.view instanceof TextView) {
+ values.values.put(PROPNAME_TEXT_COLOR, ((TextView)values.view).getCurrentTextColor());
+ }
+ }
+
+ @Override
+ protected boolean prePlay(ViewGroup sceneRoot, TransitionValues startValues,
+ TransitionValues endValues) {
+ if (startValues == null || endValues == null) {
+ return false;
+ }
+ final View view = endValues.view;
+ Drawable startBackground = (Drawable) startValues.values.get(PROPNAME_BACKGROUND);
+ Drawable endBackground = (Drawable) endValues.values.get(PROPNAME_BACKGROUND);
+ boolean changed = false;
+ if (startBackground instanceof ColorDrawable && endBackground instanceof ColorDrawable) {
+ ColorDrawable startColor = (ColorDrawable) startBackground;
+ ColorDrawable endColor = (ColorDrawable) endBackground;
+ if (startColor.getColor() != endColor.getColor()) {
+ endColor.setColor(startColor.getColor());
+ changed = true;
+ }
+ }
+ if (view instanceof TextView) {
+ TextView textView = (TextView) view;
+ int start = (Integer) startValues.values.get(PROPNAME_TEXT_COLOR);
+ int end = (Integer) endValues.values.get(PROPNAME_TEXT_COLOR);
+ if (start != end) {
+ textView.setTextColor(end);
+ changed = true;
+ }
+ }
+ return changed;
+ }
+
+ @Override
+ protected Animator play(ViewGroup sceneRoot, TransitionValues startValues,
+ TransitionValues endValues) {
+ if (startValues == null || endValues == null) {
+ return null;
+ }
+ ObjectAnimator anim = null;
+ final View view = endValues.view;
+ HashMap<String, Object> startVals = startValues.values;
+ HashMap<String, Object> endVals = endValues.values;
+ Drawable startBackground = (Drawable) startVals.get(PROPNAME_BACKGROUND);
+ Drawable endBackground = (Drawable) endVals.get(PROPNAME_BACKGROUND);
+ if (startBackground instanceof ColorDrawable && endBackground instanceof ColorDrawable) {
+ ColorDrawable startColor = (ColorDrawable) startBackground;
+ ColorDrawable endColor = (ColorDrawable) endBackground;
+ if (startColor.getColor() != endColor.getColor()) {
+ anim = ObjectAnimator.ofObject(endBackground, "color",
+ new ArgbEvaluator(), startColor.getColor(), endColor.getColor());
+ if (getStartDelay() > 0) {
+ endColor.setColor(startColor.getColor());
+ }
+ }
+ }
+ if (view instanceof TextView) {
+ TextView textView = (TextView) view;
+ int start = (Integer) startValues.values.get(PROPNAME_TEXT_COLOR);
+ int end = (Integer) endValues.values.get(PROPNAME_TEXT_COLOR);
+ if (start != end) {
+ anim = ObjectAnimator.ofObject(textView, "textColor",
+ new ArgbEvaluator(), start, end);
+ if (getStartDelay() > 0) {
+ textView.setTextColor(end);
+ }
+ }
+ }
+ return anim;
+ }
+}
diff --git a/core/java/android/view/transition/Rotate.java b/core/java/android/view/transition/Rotate.java
new file mode 100644
index 0000000..b42fbe5
--- /dev/null
+++ b/core/java/android/view/transition/Rotate.java
@@ -0,0 +1,67 @@
+/*
+ * 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 android.view.transition;
+
+import android.animation.Animator;
+import android.animation.ObjectAnimator;
+import android.view.View;
+import android.view.ViewGroup;
+
+/**
+ * This transition captures the rotation property of targets before and after
+ * the scene change and animates any changes.
+ */
+public class Rotate extends Transition {
+
+ private static final String PROPNAME_ROTATION = "android:rotate:rotation";
+
+ @Override
+ protected void captureValues(TransitionValues values, boolean start) {
+ values.values.put(PROPNAME_ROTATION, values.view.getRotation());
+ }
+
+ @Override
+ protected boolean prePlay(ViewGroup sceneRoot, TransitionValues startValues,
+ TransitionValues endValues) {
+ if (startValues == null || endValues == null) {
+ return false;
+ }
+ final View view = endValues.view;
+ float startRotation = (Float) startValues.values.get(PROPNAME_ROTATION);
+ float endRotation = (Float) endValues.values.get(PROPNAME_ROTATION);
+ if (startRotation != endRotation) {
+ view.setRotation(startRotation);
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ protected Animator play(ViewGroup sceneRoot, TransitionValues startValues,
+ TransitionValues endValues) {
+ if (startValues == null || endValues == null) {
+ return null;
+ }
+ final View view = endValues.view;
+ float startRotation = (Float) startValues.values.get(PROPNAME_ROTATION);
+ float endRotation = (Float) endValues.values.get(PROPNAME_ROTATION);
+ if (startRotation != endRotation) {
+ return ObjectAnimator.ofFloat(view, View.ROTATION,
+ startRotation, endRotation);
+ }
+ return null;
+ }
+}
diff --git a/core/java/android/view/transition/Scene.java b/core/java/android/view/transition/Scene.java
new file mode 100644
index 0000000..62cb9d3
--- /dev/null
+++ b/core/java/android/view/transition/Scene.java
@@ -0,0 +1,191 @@
+/*
+ * 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 android.view.transition;
+
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.ViewGroup;
+
+/**
+ * A scene represents the collection of values that various properties in the
+ * View hierarchy will have when the scene is applied. A Scene can be
+ * configured to automatically run a Transition when it is applied, which will
+ * animate the various property changes that take place during the
+ * scene change.
+ */
+public final class Scene {
+
+ private Context mContext;
+ private int mLayoutId = -1;
+ private ViewGroup mSceneRoot;
+ private ViewGroup mLayout; // alternative to layoutId
+ Runnable mEnterAction, mExitAction;
+
+ /**
+ * Constructs a Scene with no information about how values will change
+ * when this scene is applied. This constructor might be used when
+ * a Scene is created with the intention of being dynamically configured,
+ * through setting {@link #setEnterAction(Runnable)} and possibly
+ * {@link #setExitAction(Runnable)}.
+ *
+ * @param sceneRoot The root of the hierarchy in which scene changes
+ * and transitions will take place.
+ */
+ public Scene(ViewGroup sceneRoot) {
+ mSceneRoot = sceneRoot;
+ }
+
+ /**
+ * Constructs a Scene which, when entered, will remove any
+ * children from the sceneRoot container and will inflate and add
+ * the hierarchy specified by the layoutId resource file.
+ *
+ * @param sceneRoot The root of the hierarchy in which scene changes
+ * and transitions will take place.
+ * @param layoutId The id of a resource file that defines the view
+ * hierarchy of this scene.
+ * @param context The context used in the process of inflating
+ * the layout resource.
+ */
+ public Scene(ViewGroup sceneRoot, int layoutId, Context context) {
+ mContext = context;
+ mSceneRoot = sceneRoot;
+ mLayoutId = layoutId;
+ }
+
+ /**
+ * Constructs a Scene which, when entered, will remove any
+ * children from the sceneRoot container and add the layout
+ * object as a new child of that container.
+ *
+ * @param sceneRoot The root of the hierarchy in which scene changes
+ * and transitions will take place.
+ * @param layout The view hiearrchy of this scene, added as a child
+ * of sceneRoot when this scene is entered.
+ */
+ public Scene(ViewGroup sceneRoot, ViewGroup layout) {
+ mSceneRoot = sceneRoot;
+ mLayout = layout;
+ }
+
+ /**
+ * Gets the root of the scene, which is the root of the view hierarchy
+ * affected by changes due to this scene, and which will be animated
+ * when this scene is entered.
+ *
+ * @return The root of the view hierarchy affected by this scene.
+ */
+ public ViewGroup getSceneRoot() {
+ return mSceneRoot;
+ }
+
+ /**
+ * Exits this scene, if it is the {@link ViewGroup#getCurrentScene()
+ * currentScene} on the scene's {@link #getSceneRoot() scene root}.
+ * Exiting a scene involves removing the layout added if the scene
+ * has either a layoutId or layout view group (set at construction
+ * time) and running the {@link #setExitAction(Runnable) exit action}
+ * if there is one.
+ */
+ public void exit() {
+ if (mSceneRoot.getCurrentScene() == this) {
+ if (mLayoutId >= 0 || mLayout != null) {
+ // Undo layout change caused by entering this scene
+ getSceneRoot().removeAllViews();
+ }
+ if (mExitAction != null) {
+ mExitAction.run();
+ }
+ }
+ }
+
+ /**
+ * Enters this scene, which entails changing all values that
+ * are specified by this scene. These may be values associated
+ * with a layout view group or layout resource file which will
+ * now be added to the scene root, or it may be values changed by
+ * an {@link #setEnterAction(Runnable)} enter action}, or a
+ * combination of the these. No transition will be run when the
+ * scene is entered. To get transition behavior in scene changes,
+ * use one of the methods in {@link TransitionManager} instead.
+ */
+ public void enter() {
+
+ // Apply layout change, if any
+ if (mLayoutId >= 0 || mLayout != null) {
+ // redundant with exit() action of previous scene, but must
+ // empty out that parent container before adding to it
+ getSceneRoot().removeAllViews();
+
+ if (mLayoutId >= 0) {
+ LayoutInflater.from(mContext).inflate(mLayoutId, mSceneRoot);
+ } else {
+ mSceneRoot.addView(mLayout);
+ }
+ }
+
+ // Notify next scene that it is entering. Subclasses may override to configure scene.
+ if (mEnterAction != null) {
+ mEnterAction.run();
+ }
+
+ mSceneRoot.setCurrentScene(this );
+ }
+
+ /**
+ * Scenes that are not defined with layout resources or
+ * hierarchies, or which need to perform additional steps
+ * after those hierarchies are changed to, should set an enter
+ * action, and possibly an exit action as well. An enter action
+ * will cause Scene to call back into application code to do
+ * anything else the application needs after transitions have
+ * captured pre-change values and after any other scene changes
+ * have been applied, such as the layout (if any) being added to
+ * the view hierarchy. After this method is called, Transitions will
+ * be played.
+ *
+ * @param action The runnable whose {@link Runnable#run() run()} method will
+ * be called when this scene is entered
+ * @see #setExitAction(Runnable)
+ * @see Scene#Scene(ViewGroup, int, Context)
+ * @see Scene#Scene(ViewGroup, ViewGroup)
+ */
+ public void setEnterAction(Runnable action) {
+ mEnterAction = action;
+ }
+
+ /**
+ * Scenes that are not defined with layout resources or
+ * hierarchies, or which need to perform additional steps
+ * after those hierarchies are changed to, should set an enter
+ * action, and possibly an exit action as well. An exit action
+ * will cause Scene to call back into application code to do
+ * anything the application needs to do after applicable transitions have
+ * captured pre-change values, but before any other scene changes
+ * have been applied, such as the new layout (if any) being added to
+ * the view hierarchy. After this method is called, the next scene
+ * will be entered, including a call to {@link #setEnterAction(Runnable)}
+ * if an enter action is set.
+ *
+ * @see #setEnterAction(Runnable)
+ * @see Scene#Scene(ViewGroup, int, Context)
+ * @see Scene#Scene(ViewGroup, ViewGroup)
+ */
+ public void setExitAction(Runnable action) {
+ mExitAction = action;
+ }
+
+} \ No newline at end of file
diff --git a/core/java/android/view/transition/Slide.java b/core/java/android/view/transition/Slide.java
new file mode 100644
index 0000000..8630ee2
--- /dev/null
+++ b/core/java/android/view/transition/Slide.java
@@ -0,0 +1,70 @@
+/*
+ * 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 android.view.transition;
+
+import android.animation.Animator;
+import android.animation.ObjectAnimator;
+import android.animation.TimeInterpolator;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.animation.AccelerateInterpolator;
+import android.view.animation.DecelerateInterpolator;
+
+/**
+ * This transition captures the visibility of target objects before and
+ * after a scene change and animates any changes by sliding the target
+ * objects into or out of place.
+ */
+public class Slide extends Visibility {
+
+ // TODO: Add parameter for sliding factor - it's hard-coded below
+
+ private static final TimeInterpolator sAccelerator = new AccelerateInterpolator();
+ private static final TimeInterpolator sDecelerator = new DecelerateInterpolator();
+
+ @Override
+ protected Animator appear(ViewGroup sceneRoot, View startView, int startVisibility,
+ View endView, int endVisibility) {
+ ObjectAnimator anim = ObjectAnimator.ofFloat(endView, View.TRANSLATION_Y,
+ -2 * endView.getHeight(), 0);
+ anim.setInterpolator(sDecelerator);
+ return anim;
+ }
+
+ @Override
+ protected boolean preAppear(ViewGroup sceneRoot, View startView, int startVisibility,
+ View endView, int endVisibility) {
+ endView.setTranslationY(-2 * endView.getHeight());
+ return true;
+ }
+
+ @Override
+ protected boolean preDisappear(ViewGroup sceneRoot, View startView, int startVisibility,
+ View endView, int endVisibility) {
+ startView.setTranslationY(0);
+ return true;
+ }
+
+ @Override
+ protected Animator disappear(ViewGroup sceneRoot, View startView, int startVisibility,
+ View endView, int endVisibility) {
+ ObjectAnimator anim = ObjectAnimator.ofFloat(startView, View.TRANSLATION_Y, 0,
+ -2 * startView.getHeight());
+ anim.setInterpolator(sAccelerator);
+ return anim;
+ }
+
+}
diff --git a/core/java/android/view/transition/TextChange.java b/core/java/android/view/transition/TextChange.java
new file mode 100644
index 0000000..0ba2412
--- /dev/null
+++ b/core/java/android/view/transition/TextChange.java
@@ -0,0 +1,90 @@
+/*
+ * 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 android.view.transition;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ValueAnimator;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+import java.util.HashMap;
+
+/**
+ * This transition tracks changes to the text in TextView targets. If the text
+ * changes between the start and end scenes, the transition ensures that the
+ * starting text stays until the transition ends, at which point it changes
+ * to the end text. This is useful in situations where you want to resize a
+ * text view to its new size before displaying the text that goes there.
+ */
+public class TextChange extends Transition {
+ private static final String PROPNAME_TEXT = "android:textchange:text";
+
+ // TODO: think about other options we could have here, like cross-fading the text, or fading
+ // it out/in. These could be parameters to supply to the constructors (and xml attributes).
+
+ @Override
+ protected void captureValues(TransitionValues values, boolean start) {
+ if (values.view instanceof TextView) {
+ TextView textview = (TextView) values.view;
+ values.values.put(PROPNAME_TEXT, textview.getText());
+ }
+ }
+
+ @Override
+ protected boolean prePlay(ViewGroup sceneRoot, TransitionValues startValues,
+ TransitionValues endValues) {
+ if (startValues == null || endValues == null || !(endValues.view instanceof TextView)) {
+ return false;
+ }
+ final TextView view = (TextView) endValues.view;
+ HashMap<String, Object> startVals = startValues.values;
+ HashMap<String, Object> endVals = endValues.values;
+ String startText = (String) startVals.get(PROPNAME_TEXT);
+ String endText = (String) endVals.get(PROPNAME_TEXT);
+ if (!startText.equals(endText)) {
+ view.setText(startText);
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ protected Animator play(ViewGroup sceneRoot, TransitionValues startValues,
+ TransitionValues endValues) {
+ if (startValues == null || endValues == null || !(endValues.view instanceof TextView)) {
+ return null;
+ }
+ final TextView view = (TextView) endValues.view;
+ HashMap<String, Object> startVals = startValues.values;
+ HashMap<String, Object> endVals = endValues.values;
+ final String startText = (String) startVals.get(PROPNAME_TEXT);
+ final String endText = (String) endVals.get(PROPNAME_TEXT);
+ if (!startText.equals(endText)) {
+ // This noop animation is just used to keep the text in its start state
+ // until the transition ends
+ ValueAnimator anim = ValueAnimator.ofFloat(0, 1);
+ anim.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ view.setText(endText);
+ }
+ });
+ return anim;
+ }
+ return null;
+ }
+}
diff --git a/core/java/android/view/transition/Transition.java b/core/java/android/view/transition/Transition.java
new file mode 100644
index 0000000..150c218
--- /dev/null
+++ b/core/java/android/view/transition/Transition.java
@@ -0,0 +1,911 @@
+/*
+ * 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 android.view.transition;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.TimeInterpolator;
+import android.util.LongSparseArray;
+import android.util.SparseArray;
+import android.view.SurfaceView;
+import android.view.TextureView;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewOverlay;
+import android.widget.ListView;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+/**
+ * A Transition holds information about animations that will be run on its
+ * targets during a scene change. Subclasses of this abstract class may
+ * choreograph several child transitions ({@link TransitionGroup} or they may
+ * perform custom animations themselves. Any Transition has two main jobs:
+ * (1) capture property values, and (2) play animations based on changes to
+ * captured property values. A custom transition knows what property values
+ * on View objects are of interest to it, and also knows how to animate
+ * changes to those values. For example, the {@link Fade} transition tracks
+ * changes to visibility-related properties and is able to construct and run
+ * animations that fade items in or out based on changes to those properties.
+ *
+ * <p>Note: Transitions may not work correctly with either {@link SurfaceView}
+ * or {@link TextureView}, due to the way that these views are displayed
+ * on the screen. For SurfaceView, the problem is that the view is updated from
+ * a non-UI thread, so changes to the view due to transitions (such as moving
+ * and resizing the view) may be out of sync with the display inside those bounds.
+ * TextureView is more compatible with transitions in general, but some
+ * specific transitions (such as {@link Crossfade}) may not be compatible
+ * with TextureView because they rely on {@link ViewOverlay} functionality,
+ * which does not currently work with TextureView.</p>
+ */
+public abstract class Transition {
+
+ private static final String LOG_TAG = "Transition";
+ static final boolean DBG = false;
+
+ long mStartDelay = -1;
+ long mDuration = -1;
+ TimeInterpolator mInterpolator = null;
+ int[] mTargetIds;
+ View[] mTargets;
+ // TODO: sparse arrays instead of hashmaps?
+ private HashMap<View, TransitionValues> mStartValues =
+ new HashMap<View, TransitionValues>();
+ private SparseArray<TransitionValues> mStartIdValues = new SparseArray<TransitionValues>();
+ private LongSparseArray<TransitionValues> mStartItemIdValues =
+ new LongSparseArray<TransitionValues>();
+ private HashMap<View, TransitionValues> mEndValues =
+ new HashMap<View, TransitionValues>();
+ private SparseArray<TransitionValues> mEndIdValues = new SparseArray<TransitionValues>();
+ private LongSparseArray<TransitionValues> mEndItemIdValues =
+ new LongSparseArray<TransitionValues>();
+
+ // Used to carry data between preplay() and play(), cleared before every scene transition
+ private ArrayList<TransitionValues> mPlayStartValuesList = new ArrayList<TransitionValues>();
+ private ArrayList<TransitionValues> mPlayEndValuesList = new ArrayList<TransitionValues>();
+
+ // Number of per-target instances of this Transition currently running. This count is
+ // determined by calls to startTransition() and endTransition()
+ int mNumInstances = 0;
+
+
+ /**
+ * The set of listeners to be sent transition lifecycle events.
+ */
+ ArrayList<TransitionListener> mListeners = null;
+
+ /**
+ * Constructs a Transition object with no target objects. A transition with
+ * no targets defaults to running on all target objects in the scene hierarchy
+ * (if the transition is not contained in a TransitionGroup), or all target
+ * objects passed down from its parent (if it is in a TransitionGroup).
+ */
+ public Transition() {}
+
+ /**
+ * Sets the duration of this transition. By default, there is no duration
+ * (indicated by a negative number), which means that the Animator created by
+ * the transition will have its own specified duration. If the duration of a
+ * Transition is set, that duration will override the Animator duration.
+ *
+ * @param duration The length of the animation, in milliseconds.
+ * @return This transition object.
+ */
+ public Transition setDuration(long duration) {
+ mDuration = duration;
+ return this;
+ }
+
+ public long getDuration() {
+ return mDuration;
+ }
+
+ /**
+ * Sets the startDelay of this transition. By default, there is no delay
+ * (indicated by a negative number), which means that the Animator created by
+ * the transition will have its own specified startDelay. If the delay of a
+ * Transition is set, that delay will override the Animator delay.
+ *
+ * @param startDelay The length of the delay, in milliseconds.
+ */
+ public void setStartDelay(long startDelay) {
+ mStartDelay = startDelay;
+ }
+
+ public long getStartDelay() {
+ return mStartDelay;
+ }
+
+ /**
+ * Sets the interpolator of this transition. By default, the interpolator
+ * is null, which means that the Animator created by the transition
+ * will have its own specified interpolator. If the interpolator of a
+ * Transition is set, that interpolator will override the Animator interpolator.
+ *
+ * @param interpolator The time interpolator used by the transition
+ */
+ public void setInterpolator(TimeInterpolator interpolator) {
+ mInterpolator = interpolator;
+ }
+
+ public TimeInterpolator getInterpolator() {
+ return mInterpolator;
+ }
+
+ /**
+ * This method is called by the transition's parent (all the way up to the
+ * topmost Transition in the hierarchy) with the sceneRoot and start/end
+ * values that the transition may need to run animations on its target
+ * views. The method is called for every applicable target object, which
+ * is stored in the {@link TransitionValues#view} field. When the method
+ * results in an animation needing to be run, the transition will construct
+ * the appropriate {@link Animator} object and return it. The transition
+ * mechanism will apply any applicable duration, startDelay, and interpolator
+ * to that animation and start it. Returning null from the method tells the
+ * transition engine that there is no animation to be played (TransitionGroup
+ * will return null because any applicable animations were started on its child
+ * transitions already and there is no animation to be run on the group itself).
+ *
+ * @param sceneRoot
+ * @param startValues
+ * @param endValues
+ * @return Animator The animation to run.
+ */
+ protected abstract Animator play(ViewGroup sceneRoot, TransitionValues startValues,
+ TransitionValues endValues);
+
+ /**
+ * This method is called by the transition's parent (all the way up to the
+ * topmost Transition in the hierarchy) with the sceneRoot and start/end
+ * values that the transition may need to set things up at the start of a
+ * Transition. For example, if an overall Transition consists of several
+ * child transitions in sequence, then some of the child transitions may
+ * want to set initial values on target views prior to the overall
+ * Transition commencing, to put them in an appropriate scene for the
+ * delay between that start and the child Transition start time. For
+ * example, a transition that fades an item in may wish to set the starting
+ * alpha value to 0, to avoid it blinking in prior to the transition
+ * actually starting the animation. This is necessary because the scene
+ * change that triggers the Transition will automatically set the end-scene
+ * on all target views, so a Transition that wants to animate from a
+ * different value should set that value in the preplay() method.
+ *
+ * <p>Additionally, a Transition can perform logic to determine whether
+ * the transition needs to run on the given target and start/end values.
+ * For example, a transition that resizes objects on the screen may wish
+ * to avoid running for views which are not present in either the start
+ * or end scenes. A return value of <code>false</code> indicates that
+ * the transition should not run, and there will be no ensuing call to the
+ * {@link #play(ViewGroup, TransitionValues, TransitionValues)} method during
+ * this scene change. The default implementation returns true.</p>
+ *
+ * <p>The method is called for every applicable target object, which is
+ * stored in the {@link TransitionValues#view} field.</p>
+ *
+ * @param sceneRoot
+ * @param startValues
+ * @param endValues
+ * @return True if the Transition's {@link #play(ViewGroup,
+ * TransitionValues, TransitionValues) play()} method should be called
+ * during this scene change, false otherwise.
+ */
+ protected boolean prePlay(ViewGroup sceneRoot, TransitionValues startValues,
+ TransitionValues endValues) {
+ return true;
+ }
+
+ /**
+ * This version of prePlay() is called with the entire set of start/end
+ * values. The implementation in Transition iterates through these lists
+ * and calls {@link #prePlay(ViewGroup, TransitionValues, TransitionValues)}
+ * with each set of start/end values on this transition. The
+ * TransitionGroup subclass overrides this method and delegates it to
+ * each of its children in succession. The intention in splitting
+ * preplay() out from play() is to allow all Transitions in the tree to
+ * set up the appropriate start scene for their target objects prior to
+ * any calls to play(), which is necessary when there is a sequential
+ * Transition, where a child transition which is not the first may want to
+ * set up a target's scene prior to the overall Transition start.
+ *
+ * @hide
+ */
+ protected void prePlay(ViewGroup sceneRoot, HashMap<View, TransitionValues> startValues,
+ SparseArray<TransitionValues> startIdValues,
+ LongSparseArray<TransitionValues> startItemIdValues,
+ HashMap<View, TransitionValues> endValues,
+ SparseArray<TransitionValues> endIdValues,
+ LongSparseArray<TransitionValues> endItemIdValues) {
+ mPlayStartValuesList.clear();
+ mPlayEndValuesList.clear();
+ HashMap<View, TransitionValues> endCopy = new HashMap<View, TransitionValues>(endValues);
+ SparseArray<TransitionValues> endIdCopy =
+ new SparseArray<TransitionValues>(endIdValues.size());
+ for (int i = 0; i < endIdValues.size(); ++i) {
+ int id = endIdValues.keyAt(i);
+ endIdCopy.put(id, endIdValues.valueAt(i));
+ }
+ LongSparseArray<TransitionValues> endItemIdCopy =
+ new LongSparseArray<TransitionValues>(endItemIdValues.size());
+ for (int i = 0; i < endItemIdValues.size(); ++i) {
+ long id = endItemIdValues.keyAt(i);
+ endItemIdCopy.put(id, endItemIdValues.valueAt(i));
+ }
+ // Walk through the start values, playing everything we find
+ // Remove from the end set as we go
+ ArrayList<TransitionValues> startValuesList = new ArrayList<TransitionValues>();
+ ArrayList<TransitionValues> endValuesList = new ArrayList<TransitionValues>();
+ for (View view : startValues.keySet()) {
+ TransitionValues start = null;
+ TransitionValues end = null;
+ boolean isInListView = false;
+ if (view.getParent() instanceof ListView) {
+ isInListView = true;
+ }
+ if (!isInListView) {
+ int id = view.getId();
+ start = startValues.get(view) != null ?
+ startValues.get(view) : startIdValues.get(id);
+ if (endValues.get(view) != null) {
+ end = endValues.get(view);
+ endCopy.remove(view);
+ } else {
+ end = endIdValues.get(id);
+ View removeView = null;
+ for (View viewToRemove : endCopy.keySet()) {
+ if (viewToRemove.getId() == id) {
+ removeView = viewToRemove;
+ }
+ }
+ if (removeView != null) {
+ endCopy.remove(removeView);
+ }
+ }
+ endIdCopy.remove(id);
+ if (isValidTarget(view, id)) {
+ startValuesList.add(start);
+ endValuesList.add(end);
+ }
+ } else {
+ ListView parent = (ListView) view.getParent();
+ if (parent.getAdapter().hasStableIds()) {
+ int position = parent.getPositionForView(view);
+ long itemId = parent.getItemIdAtPosition(position);
+ start = startItemIdValues.get(itemId);
+ endItemIdCopy.remove(itemId);
+ // TODO: deal with targetIDs for itemIDs for ListView items
+ startValuesList.add(start);
+ endValuesList.add(end);
+ }
+ }
+ }
+ int startItemIdCopySize = startItemIdValues.size();
+ for (int i = 0; i < startItemIdCopySize; ++i) {
+ long id = startItemIdValues.keyAt(i);
+ if (isValidTarget(null, id)) {
+ TransitionValues start = startItemIdValues.get(id);
+ TransitionValues end = endItemIdValues.get(id);
+ endItemIdCopy.remove(id);
+ startValuesList.add(start);
+ endValuesList.add(end);
+ }
+ }
+ // Now walk through the remains of the end set
+ for (View view : endCopy.keySet()) {
+ int id = view.getId();
+ if (isValidTarget(view, id)) {
+ TransitionValues start = startValues.get(view) != null ?
+ startValues.get(view) : startIdValues.get(id);
+ TransitionValues end = endCopy.get(view);
+ endIdCopy.remove(id);
+ startValuesList.add(start);
+ endValuesList.add(end);
+ }
+ }
+ int endIdCopySize = endIdCopy.size();
+ for (int i = 0; i < endIdCopySize; ++i) {
+ int id = endIdCopy.keyAt(i);
+ if (isValidTarget(null, id)) {
+ TransitionValues start = startIdValues.get(id);
+ TransitionValues end = endIdCopy.get(id);
+ startValuesList.add(start);
+ endValuesList.add(end);
+ }
+ }
+ int endItemIdCopySize = endItemIdCopy.size();
+ for (int i = 0; i < endItemIdCopySize; ++i) {
+ long id = endItemIdCopy.keyAt(i);
+ // TODO: Deal with targetIDs and itemIDs
+ TransitionValues start = startItemIdValues.get(id);
+ TransitionValues end = endItemIdCopy.get(id);
+ startValuesList.add(start);
+ endValuesList.add(end);
+ }
+ for (int i = 0; i < startValuesList.size(); ++i) {
+ TransitionValues start = startValuesList.get(i);
+ TransitionValues end = endValuesList.get(i);
+ // TODO: what to do about targetIds and itemIds?
+ if (prePlay(sceneRoot, start, end)) {
+ // Note: we've already done the check against targetIDs in these lists
+ mPlayStartValuesList.add(start);
+ mPlayEndValuesList.add(end);
+ }
+ }
+ }
+
+ /**
+ * Internal utility method for checking whether a given view/id
+ * is valid for this transition, where "valid" means that either
+ * the Transition has no target/targetId list (the default, in which
+ * cause the transition should act on all views in the hiearchy), or
+ * the given view is in the target list or the view id is in the
+ * targetId list. If the target parameter is null, then the target list
+ * is not checked (this is in the case of ListView items, where the
+ * views are ignored and only the ids are used).
+ */
+ boolean isValidTarget(View target, long targetId) {
+ if (mTargetIds == null && mTargets == null) {
+ return true;
+ }
+ if (mTargetIds != null) {
+ for (int i = 0; i < mTargetIds.length; ++i) {
+ if (mTargetIds[i] == targetId) {
+ return true;
+ }
+ }
+ }
+ if (target != null && mTargets != null) {
+ for (int i = 0; i < mTargets.length; ++i) {
+ if (mTargets[i] == target) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * This version of play() is called with the entire set of start/end
+ * values. The implementation in Transition iterates through these lists
+ * and calls {@link #play(ViewGroup, TransitionValues, TransitionValues)}
+ * with each set of start/end values on this transition. The
+ * TransitionGroup subclass overrides this method and delegates it to
+ * each of its children in succession.
+ *
+ * @hide
+ */
+ protected void play(ViewGroup sceneRoot,
+ final HashMap<View, TransitionValues> startValues,
+ final SparseArray<TransitionValues> startIdValues,
+ final LongSparseArray<TransitionValues> startItemIdValues,
+ final HashMap<View, TransitionValues> endValues,
+ final SparseArray<TransitionValues> endIdValues,
+ final LongSparseArray<TransitionValues> endItemIdValues) {
+
+ startTransition();
+ // Now walk the list of TransitionValues, calling play for each pair
+ for (int i = 0; i < mPlayStartValuesList.size(); ++i) {
+ TransitionValues start = mPlayStartValuesList.get(i);
+ TransitionValues end = mPlayEndValuesList.get(i);
+ startTransition();
+ animate(play(sceneRoot, start, end));
+ }
+ mPlayStartValuesList.clear();
+ mPlayEndValuesList.clear();
+ endTransition();
+ }
+
+ /**
+ * Captures the current scene of values for the properties that this
+ * transition monitors. These values can be either the start or end
+ * values used in a subsequent call to
+ * {@link #play(ViewGroup, TransitionValues, TransitionValues)}, as indicated by
+ * <code>start</code>. The main concern for an implementation is what the
+ * properties are that the transition cares about and what the values are
+ * for all of those properties. The start and end values will be compared
+ * later during the preplay and play() methods to determine what, if any,
+ * animations, should be run.
+ *
+ * @param transitionValues The holder any values that the Transition
+ * wishes to store. Values are stored in the fields of this
+ * TransitionValues object, according to their type, and are keyed from
+ * a String value. For example, to start a view's rotation value,
+ * a Transition might call
+ * <code>transitionValues.floatValues.put("rotation", view.getRotation())
+ * </code>. The target <code>View</code> will already be stored in
+ * the transitionValues structure when this method is called. The other
+ * fields in TransitionValues, e.g. <code>floatValues</code>,
+ * may need to be instantiated if they have not yet been created.
+ */
+ protected abstract void captureValues(TransitionValues transitionValues, boolean start);
+
+ /**
+ * Sets the ids of target views that this Transition is interested in
+ * animating. By default, there are no targetIds, and a Transition will
+ * listen for changes on every view in the hierarchy below the sceneRoot
+ * of the Scene being transitioned into. Setting targetIDs constrains
+ * the Transition to only listen for, and act on, views with these IDs.
+ * Views with different IDs, or no IDs whatsoever, will be ignored.
+ *
+ * @see View#getId()
+ * @param targetIds A list of IDs which specify the set of Views on which
+ * the Transition will act.
+ * @return Transition The Transition on which the targetIds have been set.
+ * Returning the same object makes it easier to chain calls during
+ * construction, such as
+ * <code>transitionGroup.addTransitions(new Fade()).setTargetIds(someId);</code>
+ */
+ public Transition setTargetIds(int... targetIds) {
+ int numTargets = targetIds.length;
+ mTargetIds = new int[numTargets];
+ System.arraycopy(targetIds, 0, mTargetIds, 0, numTargets);
+ return this;
+ }
+
+ /**
+ * Sets the target view instances that this Transition is interested in
+ * animating. By default, there are no targets, and a Transition will
+ * listen for changes on every view in the hierarchy below the sceneRoot
+ * of the Scene being transitioned into. Setting targets constrains
+ * the Transition to only listen for, and act on, these views.
+ * All other views will be ignored.
+ *
+ * <p>The target list is like the {@link #setTargetIds(int...) targetId}
+ * list except this list specifies the actual View instances, not the ids
+ * of the views. This is an important distinction when scene changes involve
+ * view hierarchies which have been inflated separately; different views may
+ * share the same id but not actually be the same instance. If the transition
+ * should treat those views as the same, then seTargetIds() should be used
+ * instead of setTargets(). If, on the other hand, scene changes involve
+ * changes all within the same view hierarchy, among views which do not
+ * necessary have ids set on them, then the target list may be more
+ * convenient.</p>
+ *
+ * @see #setTargetIds(int...)
+ * @param targets A list of Views on which the Transition will act.
+ * @return Transition The Transition on which the targets have been set.
+ * Returning the same object makes it easier to chain calls during
+ * construction, such as
+ * <code>transitionGroup.addTransitions(new Fade()).setTargets(someView);</code>
+ */
+ public Transition setTargets(View... targets) {
+ int numTargets = targets.length;
+ mTargets = new View[numTargets];
+ System.arraycopy(targets, 0, mTargets, 0, numTargets);
+ return this;
+ }
+
+ /**
+ * Returns the array of target IDs that this transition limits itself to
+ * tracking and animating. If the array is null for both this method and
+ * {@link #getTargets()}, then this transition is
+ * not limited to specific views, and will handle changes to any views
+ * in the hierarchy of a scene change.
+ *
+ * @return the list of target IDs
+ */
+ public int[] getTargetIds() {
+ return mTargetIds;
+ }
+
+ /**
+ * Returns the array of target views that this transition limits itself to
+ * tracking and animating. If the array is null for both this method and
+ * {@link #getTargetIds()}, then this transition is
+ * not limited to specific views, and will handle changes to any views
+ * in the hierarchy of a scene change.
+ *
+ * @return the list of target views
+ */
+ public View[] getTargets() {
+ return mTargets;
+ }
+
+ /**
+ * Recursive method that captures values for the given view and the
+ * hierarchy underneath it.
+ * @param sceneRoot The root of the view hierarchy being captured
+ * @param start true if this capture is happening before the scene change,
+ * false otherwise
+ */
+ void captureValues(ViewGroup sceneRoot, boolean start) {
+ if (mTargetIds != null && mTargetIds.length > 0 ||
+ mTargets != null && mTargets.length > 0) {
+ if (mTargetIds != null) {
+ for (int i = 0; i < mTargetIds.length; ++i) {
+ int id = mTargetIds[i];
+ View view = sceneRoot.findViewById(id);
+ if (view != null) {
+ TransitionValues values = new TransitionValues();
+ values.view = view;
+ captureValues(values, start);
+ if (start) {
+ mStartValues.put(view, values);
+ mStartIdValues.put(id, values);
+ } else {
+ mEndValues.put(view, values);
+ mEndIdValues.put(id, values);
+ }
+ }
+ }
+ }
+ if (mTargets != null) {
+ for (int i = 0; i < mTargets.length; ++i) {
+ View view = mTargets[i];
+ if (view != null) {
+ TransitionValues values = new TransitionValues();
+ values.view = view;
+ captureValues(values, start);
+ if (start) {
+ mStartValues.put(view, values);
+ } else {
+ mEndValues.put(view, values);
+ }
+ }
+ }
+ }
+ } else {
+ captureHierarchy(sceneRoot, start);
+ }
+ }
+
+ /**
+ * Recursive method which captures values for an entire view hierarchy,
+ * starting at some root view. Transitions without targetIDs will use this
+ * method to capture values for all possible views.
+ *
+ * @param view The view for which to capture values. Children of this View
+ * will also be captured, recursively down to the leaf nodes.
+ * @param start true if values are being captured in the start scene, false
+ * otherwise.
+ */
+ private void captureHierarchy(View view, boolean start) {
+ if (view == null) {
+ return;
+ }
+ boolean isListViewItem = false;
+ if (view.getParent() instanceof ListView) {
+ isListViewItem = true;
+ }
+ if (isListViewItem && !((ListView) view.getParent()).getAdapter().hasStableIds()) {
+ // ignore listview children unless we can track them with stable IDs
+ return;
+ }
+ long id;
+ if (!isListViewItem) {
+ id = view.getId();
+ } else {
+ ListView listview = (ListView) view.getParent();
+ int position = listview.getPositionForView(view);
+ id = listview.getItemIdAtPosition(position);
+ view.setHasTransientState(true);
+ }
+ TransitionValues values = new TransitionValues();
+ values.view = view;
+ captureValues(values, start);
+ if (start) {
+ if (!isListViewItem) {
+ mStartValues.put(view, values);
+ mStartIdValues.put((int) id, values);
+ } else {
+ mStartItemIdValues.put(id, values);
+ }
+ } else {
+ if (!isListViewItem) {
+ mEndValues.put(view, values);
+ mEndIdValues.put((int) id, values);
+ } else {
+ mEndItemIdValues.put(id, values);
+ }
+ }
+ if (view instanceof ViewGroup) {
+ ViewGroup parent = (ViewGroup) view;
+ for (int i = 0; i < parent.getChildCount(); ++i) {
+ captureHierarchy(parent.getChildAt(i), start);
+ }
+ }
+ }
+
+ /**
+ * Called by TransitionManager to play the transition. This calls
+ * prePlay() and then play() with the full set of per-view
+ * transitionValues objects
+ */
+ void play(ViewGroup sceneRoot) {
+ // prePlay() must be called on entire transition hierarchy and set of views
+ // before calling play() on anything; every transition needs a chance to set up
+ // target views appropriately before transitions begin running
+ prePlay(sceneRoot, mStartValues, mStartIdValues, mStartItemIdValues,
+ mEndValues, mEndIdValues, mEndItemIdValues);
+ play(sceneRoot, mStartValues, mStartIdValues, mStartItemIdValues,
+ mEndValues, mEndIdValues, mEndItemIdValues);
+ }
+
+ /**
+ * This is a utility method used by subclasses to handle standard parts of
+ * setting up and running an Animator: it sets the {@link #getDuration()
+ * duration} and the {@link #getStartDelay() startDelay}, starts the
+ * animation, and, when the animator ends, calls {@link #endTransition()}.
+ *
+ * @param animator The Animator to be run during this transition.
+ *
+ * @hide
+ */
+ protected void animate(Animator animator) {
+ // TODO: maybe pass auto-end as a boolean parameter?
+ if (animator == null) {
+ endTransition();
+ } else {
+ if (getDuration() >= 0) {
+ animator.setDuration(getDuration());
+ }
+ if (getStartDelay() >= 0) {
+ animator.setStartDelay(getStartDelay());
+ }
+ if (getInterpolator() != null) {
+ animator.setInterpolator(getInterpolator());
+ }
+ animator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationCancel(Animator animation) {
+ cancelTransition();
+ }
+
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ endTransition();
+ animation.removeListener(this);
+ }
+ });
+ animator.start();
+ }
+ }
+
+ /**
+ * Subclasses may override to receive notice of when the transition starts.
+ * This is equivalent to listening for the
+ * {@link TransitionListener#onTransitionStart(Transition)} callback.
+ */
+ protected void onTransitionStart() {
+ }
+
+ /**
+ * Subclasses may override to receive notice of when the transition is
+ * canceled. This is equivalent to listening for the
+ * {@link TransitionListener#onTransitionCancel(Transition)} callback.
+ */
+ protected void onTransitionCancel() {
+ }
+
+ /**
+ * Subclasses may override to receive notice of when the transition ends.
+ * This is equivalent to listening for the
+ * {@link TransitionListener#onTransitionEnd(Transition)} callback.
+ */
+ protected void onTransitionEnd() {
+ }
+
+ /**
+ * This method is called automatically by the transition and
+ * TransitionGroup classes prior to a Transition subclass starting;
+ * subclasses should not need to call it directly.
+ *
+ * @hide
+ */
+ protected void startTransition() {
+ if (mNumInstances == 0) {
+ onTransitionStart();
+ if (mListeners != null && mListeners.size() > 0) {
+ ArrayList<TransitionListener> tmpListeners =
+ (ArrayList<TransitionListener>) mListeners.clone();
+ int numListeners = tmpListeners.size();
+ for (int i = 0; i < numListeners; ++i) {
+ tmpListeners.get(i).onTransitionStart(this);
+ }
+ }
+ }
+ mNumInstances++;
+ }
+
+ /**
+ * This method is called automatically by the Transition and
+ * TransitionGroup classes when a transition finishes, either because
+ * a transition did nothing (returned a null Animator from
+ * {@link Transition#play(ViewGroup, TransitionValues,
+ * TransitionValues)}) or because the transition returned a valid
+ * Animator and endTransition() was called in the onAnimationEnd()
+ * callback of the AnimatorListener.
+ *
+ * @hide
+ */
+ protected void endTransition() {
+ --mNumInstances;
+ if (mNumInstances == 0) {
+ onTransitionEnd();
+ if (mListeners != null && mListeners.size() > 0) {
+ ArrayList<TransitionListener> tmpListeners =
+ (ArrayList<TransitionListener>) mListeners.clone();
+ int numListeners = tmpListeners.size();
+ for (int i = 0; i < numListeners; ++i) {
+ tmpListeners.get(i).onTransitionEnd(this);
+ }
+ }
+ for (int i = 0; i < mStartItemIdValues.size(); ++i) {
+ TransitionValues tv = mStartItemIdValues.valueAt(i);
+ View v = tv.view;
+ if (v.hasTransientState()) {
+ v.setHasTransientState(false);
+ }
+ }
+ for (int i = 0; i < mEndItemIdValues.size(); ++i) {
+ TransitionValues tv = mEndItemIdValues.valueAt(i);
+ View v = tv.view;
+ if (v.hasTransientState()) {
+ v.setHasTransientState(false);
+ }
+ }
+ mStartValues.clear();
+ mStartIdValues.clear();
+ mStartItemIdValues.clear();
+ mEndValues.clear();
+ mEndIdValues.clear();
+ mEndItemIdValues.clear();
+ }
+ }
+
+ /**
+ * This method cancels a transition that is currently running.
+ * Implementation TBD.
+ */
+ protected void cancelTransition() {
+ // TODO: how does this work with instances?
+ // TODO: this doesn't actually do *anything* yet
+ onTransitionCancel();
+ if (mListeners != null && mListeners.size() > 0) {
+ ArrayList<TransitionListener> tmpListeners =
+ (ArrayList<TransitionListener>) mListeners.clone();
+ int numListeners = tmpListeners.size();
+ for (int i = 0; i < numListeners; ++i) {
+ tmpListeners.get(i).onTransitionCancel(this);
+ }
+ }
+ }
+
+ /**
+ * Adds a listener to the set of listeners that are sent events through the
+ * life of an animation, such as start, repeat, and end.
+ *
+ * @param listener the listener to be added to the current set of listeners
+ * for this animation.
+ */
+ public void addListener(TransitionListener listener) {
+ if (mListeners == null) {
+ mListeners = new ArrayList<TransitionListener>();
+ }
+ mListeners.add(listener);
+ }
+
+ /**
+ * Removes a listener from the set listening to this animation.
+ *
+ * @param listener the listener to be removed from the current set of
+ * listeners for this transition.
+ */
+ public void removeListener(TransitionListener listener) {
+ if (mListeners == null) {
+ return;
+ }
+ mListeners.remove(listener);
+ if (mListeners.size() == 0) {
+ mListeners = null;
+ }
+ }
+
+ /**
+ * Gets the set of {@link TransitionListener} objects that are currently
+ * listening for events on this <code>Transition</code> object.
+ *
+ * @return ArrayList<TransitionListener> The set of listeners.
+ */
+ public ArrayList<TransitionListener> getListeners() {
+ return mListeners;
+ }
+
+ @Override
+ public String toString() {
+ return toString("");
+ }
+
+ String toString(String indent) {
+ String result = indent + getClass().getSimpleName() + "@" +
+ Integer.toHexString(hashCode()) + ": ";
+ result += "dur(" + mDuration + ") ";
+ result += "dly(" + mStartDelay + ") ";
+ result += "interp(" + mInterpolator + ") ";
+ result += "tgts(";
+ if (mTargetIds != null) {
+ for (int i = 0; i < mTargetIds.length; ++i) {
+ if (i > 0) {
+ result += ", ";
+ }
+ result += mTargetIds[i];
+ }
+ }
+ if (mTargets != null) {
+ for (int i = 0; i < mTargets.length; ++i) {
+ if (i > 0) {
+ result += ", ";
+ }
+ result += mTargets[i];
+ }
+ }
+ result += ")";
+ return result;
+ }
+
+ /**
+ * A transition listener receives notifications from a transition.
+ * Notifications indicate transition lifecycle events: when the transition
+ * begins, ends, or is canceled.
+ */
+ public static interface TransitionListener {
+ /**
+ * Notification about the start of the transition.
+ *
+ * @param transition The started transition.
+ */
+ void onTransitionStart(Transition transition);
+
+ /**
+ * Notification about the end of the transition. Canceled transitions
+ * will always notify listeners of both the cancellation and end
+ * events. That is, {@link #onTransitionEnd()} is always called,
+ * regardless of whether the transition was canceled or played
+ * through to completion.
+ *
+ * @param transition The transition which reached its end.
+ */
+ void onTransitionEnd(Transition transition);
+
+ /**
+ * Notification about the cancellation of the transition.
+ *
+ * @param transition The transition which was canceled.
+ */
+ void onTransitionCancel(Transition transition);
+ }
+
+ /**
+ * Utility adapter class to avoid having to override all three methods
+ * whenever someone just wants to listen for a single event.
+ *
+ * @hide
+ * */
+ public static class TransitionListenerAdapter implements TransitionListener {
+ @Override
+ public void onTransitionStart(Transition transition) {
+ }
+
+ @Override
+ public void onTransitionEnd(Transition transition) {
+ }
+
+ @Override
+ public void onTransitionCancel(Transition transition) {
+ }
+ }
+
+}
diff --git a/core/java/android/view/transition/TransitionGroup.java b/core/java/android/view/transition/TransitionGroup.java
new file mode 100644
index 0000000..363872a
--- /dev/null
+++ b/core/java/android/view/transition/TransitionGroup.java
@@ -0,0 +1,292 @@
+/*
+ * 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 android.view.transition;
+
+import android.animation.Animator;
+import android.util.AndroidRuntimeException;
+import android.util.LongSparseArray;
+import android.util.SparseArray;
+import android.view.View;
+import android.view.ViewGroup;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+/**
+ * A TransitionGroup is a parent of child transitions (including other
+ * TransitionGroups). Using TransitionGroups enables more complex
+ * choreography of transitions, where some groups play {@link #TOGETHER} and
+ * others play {@link #SEQUENTIALLY}. For example, {@link AutoTransition}
+ * uses a TransitionGroup to sequentially play a Fade(Fade.OUT), followed by
+ * a {@link Move}, followed by a Fade(Fade.OUT) transition.
+ */
+public class TransitionGroup extends Transition {
+
+ ArrayList<Transition> mTransitions = new ArrayList<Transition>();
+ private boolean mPlayTogether = true;
+ int mCurrentListeners;
+ boolean mStarted = false;
+
+ /**
+ * A flag used to indicate that the child transitions of this group
+ * should all start at the same time.
+ */
+ public static final int TOGETHER = 0;
+ /**
+ * A flag used to indicate that the child transitions of this group should
+ * play in sequence; when one child transition ends, the next child
+ * transition begins. Note that a transition does not end until all
+ * instances of it (which are playing on all applicable targets of the
+ * transition) end.
+ */
+ public static final int SEQUENTIALLY = 1;
+
+ /**
+ * Constructs an empty transition group. Add child transitions to the
+ * group by calling to {@link #addTransitions(Transition...)} )}. By default,
+ * child transitions will play {@link #TOGETHER}.
+ */
+ public TransitionGroup() {
+ }
+
+ /**
+ * Constructs an empty transition group with the specified ordering.
+ *
+ * @param ordering {@link #TOGETHER} to start this group's child
+ * transitions together, {@link #SEQUENTIALLY} to play the child
+ * transitions in sequence.
+ * @see #setOrdering(int)
+ */
+ public TransitionGroup(int ordering) {
+ setOrdering(ordering);
+ }
+
+ /**
+ * Sets the play order of this group's child transitions.
+ *
+ * @param ordering {@link #TOGETHER} to start this group's child
+ * transitions together, {@link #SEQUENTIALLY} to play the child
+ * transitions in sequence.
+ */
+ public void setOrdering(int ordering) {
+ switch (ordering) {
+ case SEQUENTIALLY:
+ mPlayTogether = false;
+ break;
+ case TOGETHER:
+ mPlayTogether = true;
+ break;
+ default:
+ throw new AndroidRuntimeException("Invalid parameter for TransitionGroup " +
+ "ordering: " + ordering);
+ }
+ }
+
+ /**
+ * Adds child transitions to this group. The order of the child transitions
+ * passed in determines the order in which they are started.
+ *
+ * @param transitions A list of child transition to be added to this group.
+ */
+ public void addTransitions(Transition... transitions) {
+ if (transitions != null) {
+ int numTransitions = transitions.length;
+ for (int i = 0; i < numTransitions; ++i) {
+ mTransitions.add(transitions[i]);
+ }
+ }
+ }
+
+ /**
+ * Removes the specified child transition from this group.
+ *
+ * @param transition The transition to be removed.
+ */
+ public void removeTransition(Transition transition) {
+ mTransitions.remove(transition);
+ }
+
+ /**
+ * Sets up listeners for each of the child transitions. This is used to
+ * determine when this transition group is finished (all child transitions
+ * must finish first).
+ */
+ private void setupStartEndListeners() {
+ for (Transition childTransition : mTransitions) {
+ childTransition.addListener(mListener);
+ }
+ mCurrentListeners = mTransitions.size();
+ }
+
+ /**
+ * This listener is used to detect when all child transitions are done, at
+ * which point this transition group is also done.
+ */
+ private TransitionListener mListener = new TransitionListenerAdapter() {
+ @Override
+ public void onTransitionStart(Transition transition) {
+ if (!mStarted) {
+ startTransition();
+ mStarted = true;
+ }
+ }
+
+ @Override
+ public void onTransitionEnd(Transition transition) {
+ --mCurrentListeners;
+ if (mCurrentListeners == 0) {
+ // All child trans
+ mStarted = false;
+ endTransition();
+ }
+ transition.removeListener(this);
+ }
+ };
+
+ /**
+ * @hide
+ */
+ @Override
+ protected void prePlay(ViewGroup sceneRoot,
+ HashMap<View, TransitionValues> startValues,
+ SparseArray<TransitionValues> startIdValues,
+ LongSparseArray<TransitionValues> startItemIdValues,
+ HashMap<View, TransitionValues> endValues,
+ SparseArray<TransitionValues> endIdValues,
+ LongSparseArray<TransitionValues> endItemIdValues) {
+ for (Transition childTransition : mTransitions) {
+ childTransition.prePlay(sceneRoot, startValues, startIdValues, startItemIdValues,
+ endValues, endIdValues, endItemIdValues);
+ }
+ }
+
+ /**
+ * @hide
+ */
+ @Override
+ protected void play(ViewGroup sceneRoot,
+ final HashMap<View, TransitionValues> startValues,
+ final SparseArray<TransitionValues> startIdValues,
+ final LongSparseArray<TransitionValues> startItemIdValues,
+ final HashMap<View, TransitionValues> endValues,
+ final SparseArray<TransitionValues> endIdValues,
+ final LongSparseArray<TransitionValues> endItemIdValues) {
+ setupStartEndListeners();
+ final ViewGroup finalSceneRoot = sceneRoot;
+ if (!mPlayTogether) {
+ // Setup sequence with listeners
+ // TODO: Need to add listeners in such a way that we can remove them later if canceled
+ for (int i = 1; i < mTransitions.size(); ++i) {
+ Transition previousTransition = mTransitions.get(i - 1);
+ final Transition nextTransition = mTransitions.get(i);
+ previousTransition.addListener(new TransitionListenerAdapter() {
+ @Override
+ public void onTransitionEnd(Transition transition) {
+ nextTransition.play(finalSceneRoot,
+ startValues, startIdValues, startItemIdValues,
+ endValues, endIdValues, endItemIdValues);
+ transition.removeListener(this);
+ }
+ });
+ }
+ Transition firstTransition = mTransitions.get(0);
+ if (firstTransition != null) {
+ firstTransition.play(finalSceneRoot, startValues, startIdValues, startItemIdValues,
+ endValues, endIdValues, endItemIdValues);
+ }
+ } else {
+ for (Transition childTransition : mTransitions) {
+ childTransition.play(finalSceneRoot, startValues, startIdValues, startItemIdValues,
+ endValues, endIdValues, endItemIdValues);
+ }
+ }
+ }
+
+ @Override
+ protected Animator play(ViewGroup sceneRoot,
+ TransitionValues startValues, TransitionValues endValues) {
+ final View view = (endValues != null) ? endValues.view :
+ (startValues != null) ? startValues.view : null;
+ final int targetId = (view != null) ? view.getId() : -1;
+ // TODO: not sure this is a valid check - what about auto-targets? No need for ids.
+ if (targetId < 0) {
+ return null;
+ }
+ setupStartEndListeners();
+ if (!mPlayTogether) {
+ final ViewGroup finalSceneRoot = sceneRoot;
+ final TransitionValues finalStartValues = startValues;
+ final TransitionValues finalEndValues = endValues;
+ // Setup sequence with listeners
+ // TODO: Need to add listeners in such a way that we can remove them later if canceled
+ for (int i = 1; i < mTransitions.size(); ++i) {
+ Transition previousTransition = mTransitions.get(i - 1);
+ final Transition nextTransition = mTransitions.get(i);
+ previousTransition.addListener(new TransitionListenerAdapter() {
+ @Override
+ public void onTransitionEnd(Transition transition) {
+ nextTransition.startTransition();
+ if (nextTransition.isValidTarget(view, targetId)) {
+ animate(nextTransition.play(finalSceneRoot, finalStartValues,
+ finalEndValues));
+ } else {
+ nextTransition.endTransition();
+ }
+ }
+ });
+ }
+ Transition firstTransition = mTransitions.get(0);
+ if (firstTransition != null) {
+ firstTransition.startTransition();
+ if (firstTransition.isValidTarget(view, targetId)) {
+ animate(firstTransition.play(finalSceneRoot, finalStartValues, finalEndValues));
+ } else {
+ firstTransition.endTransition();
+ }
+ }
+ } else {
+ for (Transition childTransition : mTransitions) {
+ childTransition.startTransition();
+ if (childTransition.isValidTarget(view, targetId)) {
+ animate(childTransition.play(sceneRoot, startValues, endValues));
+ } else {
+ childTransition.endTransition();
+ }
+ }
+ }
+ return null;
+ }
+
+ @Override
+ protected void captureValues(TransitionValues transitionValues, boolean start) {
+ int targetId = transitionValues.view.getId();
+ for (Transition childTransition : mTransitions) {
+ if (childTransition.isValidTarget(transitionValues.view, targetId)) {
+ childTransition.captureValues(transitionValues, start);
+ }
+ }
+ }
+
+ @Override
+ String toString(String indent) {
+ String result = super.toString(indent);
+ for (int i = 0; i < mTransitions.size(); ++i) {
+ result += "\n" + mTransitions.get(i).toString(indent + " ");
+ }
+ return result;
+ }
+
+}
diff --git a/core/java/android/view/transition/TransitionInflater.java b/core/java/android/view/transition/TransitionInflater.java
new file mode 100644
index 0000000..a5f5836
--- /dev/null
+++ b/core/java/android/view/transition/TransitionInflater.java
@@ -0,0 +1,392 @@
+/*
+ * 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 android.view.transition;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.content.res.XmlResourceParser;
+import android.util.AttributeSet;
+import android.util.SparseArray;
+import android.util.Xml;
+import android.view.InflateException;
+import android.view.ViewGroup;
+import android.view.animation.AnimationUtils;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+
+/**
+ * This class inflates scenes and transitions from resource files.
+ */
+public class TransitionInflater {
+
+ // We only need one inflater for any given context. Also, this allows us to associate
+ // ids with unique instances per-Context, used to avoid re-inflating
+ // already-inflated resources into new/different instances
+ private static final HashMap<Context, TransitionInflater> sInflaterMap =
+ new HashMap<Context, TransitionInflater>();
+
+ private Context mContext;
+ // TODO: do we need id maps for transitions and transitionMgrs as well?
+ SparseArray<Scene> mScenes = new SparseArray<Scene>();
+
+ private TransitionInflater(Context context) {
+ mContext = context;
+ }
+
+ /**
+ * Obtains the TransitionInflater from the given context.
+ */
+ public static TransitionInflater from(Context context) {
+ TransitionInflater inflater = sInflaterMap.get(context);
+ if (inflater != null) {
+ return inflater;
+ }
+ inflater = new TransitionInflater(context);
+ sInflaterMap.put(context, inflater);
+ return inflater;
+ }
+
+ /**
+ * Loads a {@link Transition} object from a resource
+ *
+ * @param resource The resource id of the transition to load
+ * @return The loaded Transition object
+ * @throws android.content.res.Resources.NotFoundException when the
+ * transition cannot be loaded
+ */
+ public Transition inflateTransition(int resource) {
+ XmlResourceParser parser = mContext.getResources().getXml(resource);
+ try {
+ return createTransitionFromXml(parser, Xml.asAttributeSet(parser), null);
+ } catch (XmlPullParserException e) {
+ InflateException ex = new InflateException(e.getMessage());
+ ex.initCause(e);
+ throw ex;
+ } catch (IOException e) {
+ InflateException ex = new InflateException(
+ parser.getPositionDescription()
+ + ": " + e.getMessage());
+ ex.initCause(e);
+ throw ex;
+ } finally {
+ parser.close();
+ }
+ }
+
+ /**
+ * Loads a {@link TransitionManager} object from a resource
+ *
+ *
+ *
+ * @param resource The resource id of the transition manager to load
+ * @return The loaded TransitionManager object
+ * @throws android.content.res.Resources.NotFoundException when the
+ * transition manager cannot be loaded
+ */
+ public TransitionManager inflateTransitionManager(int resource, ViewGroup sceneRoot) {
+ XmlResourceParser parser = mContext.getResources().getXml(resource);
+ try {
+ return createTransitionManagerFromXml(parser, Xml.asAttributeSet(parser), sceneRoot);
+ } catch (XmlPullParserException e) {
+ InflateException ex = new InflateException(e.getMessage());
+ ex.initCause(e);
+ throw ex;
+ } catch (IOException e) {
+ InflateException ex = new InflateException(
+ parser.getPositionDescription()
+ + ": " + e.getMessage());
+ ex.initCause(e);
+ throw ex;
+ } finally {
+ parser.close();
+ }
+ }
+
+ /**
+ * Loads a {@link Scene} object from a resource
+ *
+ * @param resource The resource id of the scene to load
+ * @return The loaded Scene object
+ * @throws android.content.res.Resources.NotFoundException when the scene
+ * cannot be loaded
+ */
+ public Scene inflateScene(int resource, ViewGroup parent) {
+ Scene scene = mScenes.get(resource);
+ if (scene != null) {
+ return scene;
+ }
+ XmlResourceParser parser = mContext.getResources().getXml(resource);
+ try {
+ scene = createSceneFromXml(parser, Xml.asAttributeSet(parser), parent);
+ mScenes.put(resource, scene);
+ return scene;
+ } catch (XmlPullParserException e) {
+ InflateException ex = new InflateException(e.getMessage());
+ ex.initCause(e);
+ throw ex;
+ } catch (IOException e) {
+ InflateException ex = new InflateException(
+ parser.getPositionDescription()
+ + ": " + e.getMessage());
+ ex.initCause(e);
+ throw ex;
+ } finally {
+ parser.close();
+ }
+ }
+
+
+ //
+ // Transition loading
+ //
+
+ private Transition createTransitionFromXml(XmlPullParser parser,
+ AttributeSet attrs, TransitionGroup transitionGroup)
+ throws XmlPullParserException, IOException {
+
+ Transition transition = null;
+
+ // Make sure we are on a start tag.
+ int type;
+ int depth = parser.getDepth();
+
+ while (((type=parser.next()) != XmlPullParser.END_TAG || parser.getDepth() > depth)
+ && type != XmlPullParser.END_DOCUMENT) {
+
+ boolean newTransition = false;
+
+ if (type != XmlPullParser.START_TAG) {
+ continue;
+ }
+
+ String name = parser.getName();
+ if ("fade".equals(name)) {
+ transition = new Fade();
+ newTransition = true;
+ } else if ("move".equals(name)) {
+ transition = new Move();
+ newTransition = true;
+ } else if ("slide".equals(name)) {
+ transition = new Slide();
+ newTransition = true;
+ } else if ("autoTransition".equals(name)) {
+ transition = new AutoTransition();
+ newTransition = true;
+ } else if ("recolor".equals(name)) {
+ transition = new Recolor();
+ newTransition = true;
+ } else if ("transitionGroup".equals(name)) {
+ transition = new TransitionGroup();
+ createTransitionFromXml(parser, attrs, ((TransitionGroup) transition));
+ newTransition = true;
+ } else if ("targets".equals(name)) {
+ if (parser.getDepth() - 1 > depth && transition != null) {
+ // We're inside the child tag - add targets to the child
+ getTargetIDs(parser, attrs, transition);
+ } else if (parser.getDepth() - 1 == depth && transitionGroup != null) {
+ // add targets to the group
+ getTargetIDs(parser, attrs, transitionGroup);
+ }
+ }
+ if (transition != null || "targets".equals(name)) {
+ if (newTransition) {
+ loadTransition(transition, attrs);
+ if (transitionGroup != null) {
+ transitionGroup.addTransitions(transition);
+ }
+ }
+ } else {
+ throw new RuntimeException("Unknown scene name: " + parser.getName());
+ }
+ }
+
+ return transition;
+ }
+
+ private void getTargetIDs(XmlPullParser parser,
+ AttributeSet attrs, Transition transition) throws XmlPullParserException, IOException {
+
+ // Make sure we are on a start tag.
+ int type;
+ int depth = parser.getDepth();
+
+ ArrayList<Integer> targetIds = new ArrayList<Integer>();
+ while (((type=parser.next()) != XmlPullParser.END_TAG || parser.getDepth() > depth)
+ && type != XmlPullParser.END_DOCUMENT) {
+
+ if (type != XmlPullParser.START_TAG) {
+ continue;
+ }
+
+ String name = parser.getName();
+ if (name.equals("target")) {
+ TypedArray a = mContext.obtainStyledAttributes(attrs,
+ com.android.internal.R.styleable.Transition);
+ int id = a.getResourceId(com.android.internal.R.styleable.Transition_targetID, -1);
+ if (id >= 0) {
+ targetIds.add(id);
+ }
+ } else {
+ throw new RuntimeException("Unknown scene name: " + parser.getName());
+ }
+ }
+ int numTargets = targetIds.size();
+ if (numTargets > 0) {
+ int[] targetsArray = new int[numTargets];
+ for (int i = 0; i < targetIds.size(); ++i) {
+ targetsArray[i] = targetIds.get(i);
+ }
+ transition.setTargetIds(targetsArray);
+ }
+ }
+
+ private Transition loadTransition(Transition transition, AttributeSet attrs)
+ throws Resources.NotFoundException {
+
+ TypedArray a =
+ mContext.obtainStyledAttributes(attrs, com.android.internal.R.styleable.Transition);
+ long duration = a.getInt(com.android.internal.R.styleable.Transition_duration, -1);
+ if (duration >= 0) {
+ transition.setDuration(duration);
+ }
+ long startOffset = a.getInt(com.android.internal.R.styleable.Transition_startOffset, -1);
+ if (startOffset > 0) {
+ transition.setStartDelay(startOffset);
+ }
+ final int resID =
+ a.getResourceId(com.android.internal.R.styleable.Animator_interpolator, 0);
+ if (resID > 0) {
+ transition.setInterpolator(AnimationUtils.loadInterpolator(mContext, resID));
+ }
+ a.recycle();
+ return transition;
+ }
+
+ //
+ // TransitionManager loading
+ //
+
+ private TransitionManager createTransitionManagerFromXml(XmlPullParser parser,
+ AttributeSet attrs, ViewGroup sceneRoot) throws XmlPullParserException, IOException {
+
+ // Make sure we are on a start tag.
+ int type;
+ int depth = parser.getDepth();
+ TransitionManager transitionManager = null;
+
+ while (((type=parser.next()) != XmlPullParser.END_TAG || parser.getDepth() > depth)
+ && type != XmlPullParser.END_DOCUMENT) {
+
+ if (type != XmlPullParser.START_TAG) {
+ continue;
+ }
+
+ String name = parser.getName();
+ if (name.equals("transitionManager")) {
+ transitionManager = new TransitionManager();
+ } else if (name.equals("transition") && (transitionManager != null)) {
+ loadTransition(attrs, sceneRoot, transitionManager);
+ } else {
+ throw new RuntimeException("Unknown scene name: " + parser.getName());
+ }
+ }
+ return transitionManager;
+ }
+
+ private void loadTransition(AttributeSet attrs, ViewGroup sceneRoot,
+ TransitionManager transitionManager)
+ throws Resources.NotFoundException {
+
+ TypedArray a = mContext.obtainStyledAttributes(attrs,
+ com.android.internal.R.styleable.TransitionManager);
+ int transitionId = attrs.getAttributeResourceValue(
+ com.android.internal.R.styleable.TransitionManager_transition, -1);
+ Scene fromScene = null, toScene = null;
+ int fromId = attrs.getAttributeResourceValue(
+ com.android.internal.R.styleable.TransitionManager_fromScene, -1);
+ if (fromId >= 0) fromScene = inflateScene(fromId, sceneRoot);
+ int toId = attrs.getAttributeResourceValue(
+ com.android.internal.R.styleable.TransitionManager_toScene, -1);
+ if (toId >= 0) toScene = inflateScene(toId, sceneRoot);
+ if (transitionId >= 0) {
+ Transition transition = inflateTransition(transitionId);
+ if (transition != null) {
+ if (fromScene != null) {
+ if (toScene == null){
+ throw new RuntimeException("No matching toScene for given fromScene " +
+ "for transition ID " + transitionId);
+ } else {
+ transitionManager.setTransition(fromScene, toScene, transition);
+ }
+ } else if (toId >= 0) {
+ transitionManager.setTransition(toScene, transition);
+ }
+ }
+ }
+ a.recycle();
+ }
+
+ //
+ // Scene loading
+ //
+
+ private Scene createSceneFromXml(XmlPullParser parser, AttributeSet attrs, ViewGroup parent)
+ throws XmlPullParserException, IOException {
+ Scene scene = null;
+
+ // Make sure we are on a start tag.
+ int type;
+ int depth = parser.getDepth();
+
+ while (((type=parser.next()) != XmlPullParser.END_TAG || parser.getDepth() > depth)
+ && type != XmlPullParser.END_DOCUMENT) {
+
+ if (type != XmlPullParser.START_TAG) {
+ continue;
+ }
+
+ String name = parser.getName();
+ if (name.equals("scene")) {
+ scene = loadScene(attrs, parent);
+ } else {
+ throw new RuntimeException("Unknown scene name: " + parser.getName());
+ }
+ }
+
+ return scene;
+ }
+
+ private Scene loadScene(AttributeSet attrs, ViewGroup parent)
+ throws Resources.NotFoundException {
+
+ Scene scene;
+ TypedArray a = mContext.obtainStyledAttributes(attrs,
+ com.android.internal.R.styleable.Scene);
+ int layoutId = a.getResourceId(com.android.internal.R.styleable.Scene_layout, -1);
+ if (layoutId >= 0) {
+ scene = new Scene(parent, layoutId, mContext);
+ } else {
+ scene = new Scene(parent);
+ }
+ a.recycle();
+ return scene;
+ }
+}
diff --git a/core/java/android/view/transition/TransitionManager.java b/core/java/android/view/transition/TransitionManager.java
new file mode 100644
index 0000000..5a1991c
--- /dev/null
+++ b/core/java/android/view/transition/TransitionManager.java
@@ -0,0 +1,261 @@
+/*
+ * 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 android.view.transition;
+
+import android.view.ViewGroup;
+import android.view.ViewTreeObserver;
+
+import java.util.HashMap;
+
+/**
+ * This class manages the set of transitions that fire when there is a
+ * change of {@link Scene}. To use the manager, add scenes along with
+ * transition objects with calls to {@link #setTransition(Scene, Transition)}
+ * or {@link #setTransition(Scene, Scene, Transition)}. Setting specific
+ * transitions for scene changes is not required; by default, a Scene change
+ * will use {@link AutoTransition} to do something reasonable for most
+ * situations. Specifying other transitions for particular scene changes is
+ * only necessary if the application wants different transition behavior
+ * in these situations.
+ */
+public class TransitionManager {
+ // TODO: how to handle enter/exit?
+
+ private static final Transition sDefaultTransition = new AutoTransition();
+ private Transition mDefaultTransition = new AutoTransition();
+
+ HashMap<Scene, Transition> mSceneTransitions = new HashMap<Scene, Transition>();
+ HashMap<Scene, HashMap<Scene, Transition>> mScenePairTransitions =
+ new HashMap<Scene, HashMap<Scene, Transition>>();
+
+ /**
+ * Sets the transition to be used for any scene change for which no
+ * other transition is explicitly set. The initial value is
+ * an {@link AutoTransition} instance.
+ *
+ * @param transition The default transition to be used for scene changes.
+ */
+ public void setDefaultTransition(Transition transition) {
+ mDefaultTransition = transition;
+ }
+
+ /**
+ * Gets the current default transition. The initial value is an {@link
+ * AutoTransition} instance.
+ *
+ * @return The current default transition.
+ * @see #setDefaultTransition(Transition)
+ */
+ public Transition getDefaultTransition() {
+ return mDefaultTransition;
+ }
+
+ /**
+ * Sets a specific transition to occur when the given scene is entered.
+ *
+ * @param scene The scene which, when applied, will cause the given
+ * transition to run.
+ * @param transition The transition that will play when the given scene is
+ * entered. A value of null will result in the default behavior of
+ * using {@link AutoTransition}.
+ */
+ public void setTransition(Scene scene, Transition transition) {
+ mSceneTransitions.put(scene, transition);
+ }
+
+ /**
+ * Sets a specific transition to occur when the given pair of scenes is
+ * exited/entered.
+ *
+ * @param fromScene The scene being exited when the given transition will
+ * be run
+ * @param toScene The scene being entered when the given transition will
+ * be run
+ * @param transition The transition that will play when the given scene is
+ * entered. A value of null will result in the default behavior of
+ * using {@link AutoTransition}.
+ */
+ public void setTransition(Scene fromScene, Scene toScene, Transition transition) {
+ HashMap<Scene, Transition> sceneTransitionMap = mScenePairTransitions.get(toScene);
+ if (sceneTransitionMap == null) {
+ sceneTransitionMap = new HashMap<Scene, Transition>();
+ mScenePairTransitions.put(toScene, sceneTransitionMap);
+ }
+ sceneTransitionMap.put(fromScene, transition);
+ }
+
+ /**
+ * Returns the Transition for the given scene being entered. The result
+ * depends not only on the given scene, but also the scene which the
+ * {@link Scene#getSceneRoot() sceneRoot} of the Scene is currently in.
+ *
+ * @param scene The scene being entered
+ * @return The Transition to be used for the given scene change. If no
+ * Transition was specified for this scene change, {@link AutoTransition}
+ * will be used instead.
+ */
+ private Transition getTransition(Scene scene) {
+ Transition transition = null;
+ ViewGroup sceneRoot = scene.getSceneRoot();
+ if (sceneRoot != null) {
+ // TODO: cached in Scene instead? long-term, cache in View itself
+ Scene currScene = sceneRoot.getCurrentScene();
+ if (currScene != null) {
+ HashMap<Scene, Transition> sceneTransitionMap = mScenePairTransitions.get(scene);
+ if (sceneTransitionMap != null) {
+ transition = sceneTransitionMap.get(currScene);
+ if (transition != null) {
+ return transition;
+ }
+ }
+ }
+ }
+ transition = mSceneTransitions.get(scene);
+ return (transition != null) ? transition : new AutoTransition();
+ }
+
+ /**
+ * This is where all of the work of a transition/scene-change is
+ * orchestrated. This method captures the start values for the given
+ * transition, exits the current Scene, enters the new scene, captures
+ * the end values for the transition, and finally plays the
+ * resulting values-populated transition.
+ *
+ * @param scene The scene being entered
+ * @param transition The transition to play for this scene change
+ */
+ private static void changeScene(Scene scene, final Transition transition) {
+
+ final ViewGroup sceneRoot = scene.getSceneRoot();
+
+ // Capture current values
+ if (transition != null) {
+ transition.captureValues(sceneRoot, true);
+ }
+
+ // Notify previous scene that it is being exited
+ Scene previousScene = sceneRoot.getCurrentScene();
+ if (previousScene != null) {
+ previousScene.exit();
+ }
+
+ scene.enter();
+
+ if (transition != null) {
+ final ViewTreeObserver observer = sceneRoot.getViewTreeObserver();
+ observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
+ public boolean onPreDraw() {
+ sceneRoot.getViewTreeObserver().removeOnPreDrawListener(this);
+ transition.captureValues(sceneRoot, false);
+ transition.play(sceneRoot);
+ return true;
+ }
+ });
+ }
+ }
+
+ /**
+ * Change to the given scene, using the
+ * appropriate transition for this particular scene change
+ * (as specified to the TransitionManager, or the default
+ * if no such transition exists).
+ *
+ * @param scene The Scene to change to
+ */
+ public void transitionTo(Scene scene) {
+ // Auto transition if there is no transition declared for the Scene, but there is
+ // a root or parent view
+ changeScene(scene, getTransition(scene));
+
+ }
+
+ /**
+ * Static utility method to simply change to the given scene using
+ * the default transition for TransitionManager.
+ *
+ * @param scene The Scene to change to
+ */
+ public static void go(Scene scene) {
+ changeScene(scene, sDefaultTransition);
+ }
+
+ /**
+ * Static utility method to simply change to the given scene using
+ * the given transition.
+ *
+ * <p>Passing in <code>null</code> for the transition parameter will
+ * result in the scene changing without any transition running, and is
+ * equivalent to calling {@link Scene#exit()} on the scene root's
+ * {@link ViewGroup#getCurrentScene() current scene}, followed by
+ * {@link Scene#enter()} on the scene specified by the <code>scene</code>
+ * parameter.</p>
+ *
+ * @param scene The Scene to change to
+ * @param transition The transition to use for this scene change. A
+ * value of null causes the scene change to happen with no transition.
+ */
+ public static void go(Scene scene, Transition transition) {
+ changeScene(scene, transition);
+ }
+
+ /**
+ * Static utility method to simply change to a scene defined by the
+ * code in the given runnable, which will be executed after
+ * the current values have been captured for the transition.
+ * This is equivalent to creating a Scene and calling {@link
+ * Scene#setEnterAction(Runnable)} with the runnable, then calling
+ * {@link #go(Scene, Transition)}. The transition used will be the
+ * default provided by TransitionManager.
+ *
+ * @param sceneRoot The root of the View hierarchy used when this scene
+ * runs a transition automatically.
+ * @param action The runnable whose {@link Runnable#run() run()} method will
+ * be called.
+ */
+ public static void go(ViewGroup sceneRoot, Runnable action) {
+ Scene scene = new Scene(sceneRoot);
+ scene.setEnterAction(action);
+ changeScene(scene, sDefaultTransition);
+ }
+
+ /**
+ * Static utility method to simply change to a scene defined by the
+ * code in the given runnable, which will be executed after
+ * the current values have been captured for the transition.
+ * This is equivalent to creating a Scene and calling {@link
+ * Scene#setEnterAction(Runnable)} with the runnable, then calling
+ * {@link #go(Scene, Transition)}. The given transition will be
+ * used to animate the changes.
+ *
+ * <p>Passing in <code>null</code> for the transition parameter will
+ * result in the scene changing without any transition running, and is
+ * equivalent to calling {@link Scene#exit()} on the scene root's
+ * {@link ViewGroup#getCurrentScene() current scene}, followed by
+ * {@link Scene#enter()} on a new scene specified by the
+ * <code>action</code> parameter.</p>
+ *
+ * @param sceneRoot The root of the View hierarchy to run the transition on.
+ * @param action The runnable whose {@link Runnable#run() run()} method will
+ * be called.
+ * @param transition The transition to use for this change. A
+ * value of null causes the change to happen with no transition.
+ */
+ public static void go(ViewGroup sceneRoot, Runnable action, Transition transition) {
+ Scene scene = new Scene(sceneRoot);
+ scene.setEnterAction(action);
+ changeScene(scene, transition);
+ }
+}
diff --git a/core/java/android/view/transition/TransitionValues.java b/core/java/android/view/transition/TransitionValues.java
new file mode 100644
index 0000000..120ace8
--- /dev/null
+++ b/core/java/android/view/transition/TransitionValues.java
@@ -0,0 +1,60 @@
+/*
+ * 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 android.view.transition;
+
+import android.view.View;
+import android.view.ViewGroup;
+
+import java.util.HashMap;
+
+/**
+ * Data structure which holds cached values for the transition.
+ * The view field is the target which all of the values pertain to.
+ * The values field is a hashmap which holds information for fields
+ * according to names selected by the transitions. These names should
+ * be unique to avoid clobbering values stored by other transitions,
+ * such as the convention project:transition_name:property_name. For
+ * example, the platform might store a property "alpha" in a transition
+ * "Fader" as "android:fader:alpha".
+ *
+ * <p>These values are cached during the
+ * {@link Transition#captureValues(TransitionValues, boolean)}
+ * capture} phases of a scene change, once when the start values are captured
+ * and again when the end values are captured. These start/end values are then
+ * passed into the transitions during the play phase of the scene change,
+ * for {@link Transition#prePlay(ViewGroup, TransitionValues, TransitionValues)} and
+ * for {@link Transition#play(ViewGroup, TransitionValues, TransitionValues)}.</p>
+ */
+public class TransitionValues {
+
+ /**
+ * The View with these values
+ */
+ public View view;
+
+ /**
+ * The set of values tracked by transitions for this scene
+ */
+ public final HashMap<String, Object> values = new HashMap<String, Object>();
+
+ @Override
+ public String toString() {
+ String returnValue = "TransitionValues@" + Integer.toHexString(hashCode()) + ":\n";
+ returnValue += " view = " + view + "\n";
+ returnValue += " values = " + values + "\n";
+ return returnValue;
+ }
+} \ No newline at end of file
diff --git a/core/java/android/view/transition/Visibility.java b/core/java/android/view/transition/Visibility.java
new file mode 100644
index 0000000..a3e6e77
--- /dev/null
+++ b/core/java/android/view/transition/Visibility.java
@@ -0,0 +1,243 @@
+/*
+ * 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 android.view.transition;
+
+import android.animation.Animator;
+import android.view.View;
+import android.view.ViewGroup;
+
+/**
+ * This transition tracks changes to the visibility of target views in the
+ * start and end scenes. Visibility is determined not just by the
+ * {@link View#setVisibility(int)} state of views, but also whether
+ * views exist in the current view hierarchy. The class is intended to be a
+ * utility for subclasses such as {@link Fade}, which use this visibility
+ * information to determine the specific animations to run when visibility
+ * changes occur. Subclasses should implement one or more of the methods
+ * {@link #preAppear(ViewGroup, View, int, View, int)},
+ * {@link #preDisappear(ViewGroup, View, int, View, int)},
+ * {@link #appear(ViewGroup, View, int, View, int)}, and
+ * {@link #disappear(ViewGroup, View, int, View, int)}.
+ */
+public abstract class Visibility extends Transition {
+
+ private static final String PROPNAME_VISIBILITY = "android:visibility:visibility";
+ private static final String PROPNAME_PARENT = "android:visibility:parent";
+
+ @Override
+ protected void captureValues(TransitionValues values, boolean start) {
+ int visibility = values.view.getVisibility();
+ values.values.put(PROPNAME_VISIBILITY, visibility);
+ values.values.put(PROPNAME_PARENT, values.view.getParent());
+ }
+
+ @Override
+ protected boolean prePlay(ViewGroup sceneRoot, TransitionValues startValues,
+ TransitionValues endValues) {
+ boolean visibilityChange = false;
+ boolean fadeIn = false;
+ int startVisibility, endVisibility;
+ View startParent, endParent;
+ if (startValues != null) {
+ startVisibility = (Integer) startValues.values.get(PROPNAME_VISIBILITY);
+ startParent = (View) startValues.values.get(PROPNAME_PARENT);
+ } else {
+ startVisibility = -1;
+ startParent = null;
+ }
+ if (endValues != null) {
+ endVisibility = (Integer) endValues.values.get(PROPNAME_VISIBILITY);
+ endParent = (View) endValues.values.get(PROPNAME_PARENT);
+ } else {
+ endVisibility = -1;
+ endParent = null;
+ }
+ boolean existenceChange = false;
+ if (startValues != null && endValues != null) {
+ if (startVisibility == endVisibility && startParent == endParent) {
+ return false;
+ } else {
+ if (startVisibility != endVisibility) {
+ if (startVisibility == View.VISIBLE) {
+ fadeIn = false;
+ visibilityChange = true;
+ } else if (endVisibility == View.VISIBLE) {
+ fadeIn = true;
+ visibilityChange = true;
+ }
+ // no visibilityChange if going between INVISIBLE and GONE
+ } else if (startParent != endParent) {
+ existenceChange = true;
+ if (endParent == null) {
+ fadeIn = false;
+ visibilityChange = true;
+ } else if (startParent == null) {
+ fadeIn = true;
+ visibilityChange = true;
+ }
+ }
+ }
+ }
+ if (startValues == null) {
+ existenceChange = true;
+ fadeIn = true;
+ visibilityChange = true;
+ } else if (endValues == null) {
+ existenceChange = true;
+ fadeIn = false;
+ visibilityChange = true;
+ }
+ if (visibilityChange) {
+ if (fadeIn) {
+ return preAppear(sceneRoot, existenceChange ? null : startValues.view,
+ startVisibility, endValues.view, endVisibility);
+ } else {
+ return preDisappear(sceneRoot, startValues.view, startVisibility,
+ existenceChange ? null : endValues.view, endVisibility);
+ }
+ } else {
+ return false;
+ }
+ }
+
+ @Override
+ protected Animator play(ViewGroup sceneRoot, TransitionValues startValues,
+ TransitionValues endValues) {
+ boolean visibilityChange = false;
+ boolean fadeIn = false;
+ int startVisibility, endVisibility;
+ View startParent, endParent;
+ if (startValues != null) {
+ startVisibility = (Integer) startValues.values.get(PROPNAME_VISIBILITY);
+ startParent = (View) startValues.values.get(PROPNAME_PARENT);
+ } else {
+ startVisibility = -1;
+ startParent = null;
+ }
+ if (endValues != null) {
+ endVisibility = (Integer) endValues.values.get(PROPNAME_VISIBILITY);
+ endParent = (View) endValues.values.get(PROPNAME_PARENT);
+ } else {
+ endVisibility = -1;
+ endParent = null;
+ }
+ boolean existenceChange = false;
+ if (startValues != null && endValues != null) {
+ if (startVisibility == endVisibility && startParent == endParent) {
+ return null;
+ } else {
+ if (startVisibility != endVisibility) {
+ if (startVisibility == View.VISIBLE) {
+ fadeIn = false;
+ visibilityChange = true;
+ } else if (endVisibility == View.VISIBLE) {
+ fadeIn = true;
+ visibilityChange = true;
+ }
+ // no visibilityChange if going between INVISIBLE and GONE
+ } else if (startParent != endParent) {
+ existenceChange = true;
+ if (endParent == null) {
+ fadeIn = false;
+ visibilityChange = true;
+ } else if (startParent == null) {
+ fadeIn = true;
+ visibilityChange = true;
+ }
+ }
+ }
+ }
+ if (startValues == null) {
+ existenceChange = true;
+ fadeIn = true;
+ visibilityChange = true;
+ } else if (endValues == null) {
+ existenceChange = true;
+ fadeIn = false;
+ visibilityChange = true;
+ }
+ if (visibilityChange) {
+ if (fadeIn) {
+ return appear(sceneRoot, existenceChange ? null : startValues.view, startVisibility,
+ endValues.view, endVisibility);
+ } else {
+ return disappear(sceneRoot, startValues.view, startVisibility,
+ existenceChange ? null : endValues.view, endVisibility);
+ }
+ }
+ return null;
+ }
+
+ /**
+ * The default implementation of this method does nothing. Subclasses
+ * should override if they need to set up anything prior to the
+ * transition starting.
+ *
+ * @param sceneRoot
+ * @param startView
+ * @param startVisibility
+ * @param endView
+ * @param endVisibility
+ * @return
+ */
+ protected boolean preAppear(ViewGroup sceneRoot, View startView, int startVisibility,
+ View endView, int endVisibility) {
+ return true;
+ }
+
+ /**
+ * The default implementation of this method does nothing. Subclasses
+ * should override if they need to set up anything prior to the
+ * transition starting.
+ * @param sceneRoot
+ * @param startView
+ * @param startVisibility
+ * @param endView
+ * @param endVisibility
+ * @return
+ */
+ protected boolean preDisappear(ViewGroup sceneRoot, View startView, int startVisibility,
+ View endView, int endVisibility) {
+ return true;
+ }
+
+ /**
+ * The default implementation of this method does nothing. Subclasses
+ * should override if they need to do anything when target objects
+ * appear during the scene change.
+ * @param sceneRoot
+ * @param startView
+ * @param startVisibility
+ * @param endView
+ * @param endVisibility
+ */
+ protected Animator appear(ViewGroup sceneRoot, View startView, int startVisibility,
+ View endView, int endVisibility) { return null; }
+
+ /**
+ * The default implementation of this method does nothing. Subclasses
+ * should override if they need to do anything when target objects
+ * disappear during the scene change.
+ * @param sceneRoot
+ * @param startView
+ * @param startVisibility
+ * @param endView
+ * @param endVisibility
+ */
+ protected Animator disappear(ViewGroup sceneRoot, View startView, int startVisibility,
+ View endView, int endVisibility) { return null; }
+
+}
diff --git a/core/java/android/view/transition/package.html b/core/java/android/view/transition/package.html
new file mode 100644
index 0000000..37dc0ec
--- /dev/null
+++ b/core/java/android/view/transition/package.html
@@ -0,0 +1,25 @@
+<html>
+<body>
+<p>The classes in this package enable "scenes & transitions" functionality for
+view hiearchies.</p>
+
+<p>A <b>Scene</b> is an encapsulation of the state of a view hiearchy,
+including the views in that hierarchy and the various values (layout-related
+and otherwise) that those views have. A scene be defined by a layout hierarchy
+directly or some code which sets up the scene dynamically as it is entered.</p>
+
+<p>A <b>Transition</b> is a mechanism to automatically animate changes that occur
+when a new scene is entered. Some transition capabilities are automatic. That
+is, entering a scene may cause animations to run which fade out views that
+go away, move and resize existing views that change, and fade in views that
+become visible. There are additional transitions that can animate other
+attributes, such as color changes, and which can optionally be specified
+to take place during particular scene changes. Finally, developers can
+define their own Transition subclasses which monitor particular property
+changes and which run custom animations when those properties change values.</p>
+
+<p><b>TransitionManager</b> is used to specify custom transitions for particular
+scene changes, and to cause scene changes with transitions to take place.</p>
+
+</body>
+</html>
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index bf66292..ba85c1a 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -1151,10 +1151,10 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
}
if (mChoiceMode != CHOICE_MODE_NONE) {
if (mCheckStates == null) {
- mCheckStates = new SparseBooleanArray();
+ mCheckStates = new SparseBooleanArray(0);
}
if (mCheckedIdStates == null && mAdapter != null && mAdapter.hasStableIds()) {
- mCheckedIdStates = new LongSparseArray<Integer>();
+ mCheckedIdStates = new LongSparseArray<Integer>(0);
}
// Modal multi-choice mode only has choices when the mode is active. Clear them.
if (mChoiceMode == CHOICE_MODE_MULTIPLE_MODAL) {
@@ -1615,10 +1615,12 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
public static final Parcelable.Creator<SavedState> CREATOR
= new Parcelable.Creator<SavedState>() {
+ @Override
public SavedState createFromParcel(Parcel in) {
return new SavedState(in);
}
+ @Override
public SavedState[] newArray(int size) {
return new SavedState[size];
}
@@ -1943,8 +1945,8 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
}
final int top = getChildAt(0).getTop();
- final float fadeLength = (float) getVerticalFadingEdgeLength();
- return top < mPaddingTop ? (float) -(top - mPaddingTop) / fadeLength : fadeEdge;
+ final float fadeLength = getVerticalFadingEdgeLength();
+ return top < mPaddingTop ? -(top - mPaddingTop) / fadeLength : fadeEdge;
}
}
@@ -1961,9 +1963,9 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
final int bottom = getChildAt(count - 1).getBottom();
final int height = getHeight();
- final float fadeLength = (float) getVerticalFadingEdgeLength();
+ final float fadeLength = getVerticalFadingEdgeLength();
return bottom > height - mPaddingBottom ?
- (float) (bottom - height + mPaddingBottom) / fadeLength : fadeEdge;
+ (bottom - height + mPaddingBottom) / fadeLength : fadeEdge;
}
}
@@ -2426,7 +2428,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
* @return True if the selector should be shown
*/
boolean shouldShowSelector() {
- return (hasFocus() && !isInTouchMode()) || touchModeDrawsInPressedState();
+ return (!isInTouchMode()) || touchModeDrawsInPressedState();
}
private void drawSelector(Canvas canvas) {
@@ -2764,13 +2766,14 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
}
public boolean sameWindow() {
- return hasWindowFocus() && getWindowAttachCount() == mOriginalAttachCount;
+ return getWindowAttachCount() == mOriginalAttachCount;
}
}
private class PerformClick extends WindowRunnnable implements Runnable {
int mClickMotionPosition;
+ @Override
public void run() {
// The data has changed since we posted this action in the event queue,
// bail out before bad things happen
@@ -2792,6 +2795,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
}
private class CheckForLongPress extends WindowRunnnable implements Runnable {
+ @Override
public void run() {
final int motionPosition = mMotionPosition;
final View child = getChildAt(motionPosition - mFirstPosition);
@@ -2815,6 +2819,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
}
private class CheckForKeyLongPress extends WindowRunnnable implements Runnable {
+ @Override
public void run() {
if (isPressed() && mSelectedPosition >= 0) {
int index = mSelectedPosition - mFirstPosition;
@@ -2989,6 +2994,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
}
final class CheckForTap implements Runnable {
+ @Override
public void run() {
if (mTouchMode == TOUCH_MODE_DOWN) {
mTouchMode = TOUCH_MODE_TAP;
@@ -3239,6 +3245,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
}
}
+ @Override
public void onTouchModeChanged(boolean isInTouchMode) {
if (isInTouchMode) {
// Get rid of the selection when we enter touch mode
@@ -3299,95 +3306,153 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
}
}
- final int action = ev.getAction();
-
- View v;
-
initVelocityTrackerIfNotExists();
mVelocityTracker.addMovement(ev);
- switch (action & MotionEvent.ACTION_MASK) {
- case MotionEvent.ACTION_DOWN: {
- switch (mTouchMode) {
- case TOUCH_MODE_OVERFLING: {
- mFlingRunnable.endFling();
- if (mPositionScroller != null) {
- mPositionScroller.stop();
- }
- mTouchMode = TOUCH_MODE_OVERSCROLL;
- mMotionX = (int) ev.getX();
- mMotionY = mLastY = (int) ev.getY();
- mMotionCorrection = 0;
- mActivePointerId = ev.getPointerId(0);
- mDirection = 0;
+ final int actionMasked = ev.getActionMasked();
+ switch (actionMasked) {
+ case MotionEvent.ACTION_DOWN: {
+ onTouchDown(ev);
break;
}
- default: {
- mActivePointerId = ev.getPointerId(0);
- final int x = (int) ev.getX();
- final int y = (int) ev.getY();
- int motionPosition = pointToPosition(x, y);
- if (!mDataChanged) {
- if ((mTouchMode != TOUCH_MODE_FLING) && (motionPosition >= 0)
- && (getAdapter().isEnabled(motionPosition))) {
- // User clicked on an actual view (and was not stopping a fling).
- // It might be a click or a scroll. Assume it is a click until
- // proven otherwise
- mTouchMode = TOUCH_MODE_DOWN;
- // FIXME Debounce
- if (mPendingCheckForTap == null) {
- mPendingCheckForTap = new CheckForTap();
- }
- postDelayed(mPendingCheckForTap, ViewConfiguration.getTapTimeout());
- } else {
- if (mTouchMode == TOUCH_MODE_FLING) {
- // Stopped a fling. It is a scroll.
- createScrollingCache();
- mTouchMode = TOUCH_MODE_SCROLL;
- mMotionCorrection = 0;
- motionPosition = findMotionRow(y);
- mFlingRunnable.flywheelTouch();
- }
- }
- }
+ case MotionEvent.ACTION_MOVE: {
+ onTouchMove(ev);
+ break;
+ }
+
+ case MotionEvent.ACTION_UP: {
+ onTouchUp(ev);
+ break;
+ }
+
+ case MotionEvent.ACTION_CANCEL: {
+ onTouchCancel();
+ break;
+ }
+ case MotionEvent.ACTION_POINTER_UP: {
+ onSecondaryPointerUp(ev);
+ final int x = mMotionX;
+ final int y = mMotionY;
+ final int motionPosition = pointToPosition(x, y);
if (motionPosition >= 0) {
// Remember where the motion event started
- v = getChildAt(motionPosition - mFirstPosition);
- mMotionViewOriginalTop = v.getTop();
+ final View child = getChildAt(motionPosition - mFirstPosition);
+ mMotionViewOriginalTop = child.getTop();
+ mMotionPosition = motionPosition;
}
+ mLastY = y;
+ break;
+ }
+
+ case MotionEvent.ACTION_POINTER_DOWN: {
+ // New pointers take over dragging duties
+ final int index = ev.getActionIndex();
+ final int id = ev.getPointerId(index);
+ final int x = (int) ev.getX(index);
+ final int y = (int) ev.getY(index);
+ mMotionCorrection = 0;
+ mActivePointerId = id;
mMotionX = x;
mMotionY = y;
- mMotionPosition = motionPosition;
- mLastY = Integer.MIN_VALUE;
+ final int motionPosition = pointToPosition(x, y);
+ if (motionPosition >= 0) {
+ // Remember where the motion event started
+ final View child = getChildAt(motionPosition - mFirstPosition);
+ mMotionViewOriginalTop = child.getTop();
+ mMotionPosition = motionPosition;
+ }
+ mLastY = y;
break;
}
+ }
+
+ return true;
+ }
+
+ private void onTouchDown(MotionEvent ev) {
+ View v;
+ switch (mTouchMode) {
+ case TOUCH_MODE_OVERFLING: {
+ mFlingRunnable.endFling();
+ if (mPositionScroller != null) {
+ mPositionScroller.stop();
}
+ mTouchMode = TOUCH_MODE_OVERSCROLL;
+ mMotionX = (int) ev.getX();
+ mMotionY = mLastY = (int) ev.getY();
+ mMotionCorrection = 0;
+ mActivePointerId = ev.getPointerId(0);
+ mDirection = 0;
+ break;
+ }
- if (performButtonActionOnTouchDown(ev)) {
- if (mTouchMode == TOUCH_MODE_DOWN) {
- removeCallbacks(mPendingCheckForTap);
+ default: {
+ mActivePointerId = ev.getPointerId(0);
+ final int x = (int) ev.getX();
+ final int y = (int) ev.getY();
+ int motionPosition = pointToPosition(x, y);
+ if (!mDataChanged) {
+ if ((mTouchMode != TOUCH_MODE_FLING) && (motionPosition >= 0)
+ && (getAdapter().isEnabled(motionPosition))) {
+ // User clicked on an actual view (and was not stopping a fling).
+ // It might be a click or a scroll. Assume it is a click until
+ // proven otherwise
+ mTouchMode = TOUCH_MODE_DOWN;
+ // FIXME Debounce
+ if (mPendingCheckForTap == null) {
+ mPendingCheckForTap = new CheckForTap();
+ }
+ postDelayed(mPendingCheckForTap, ViewConfiguration.getTapTimeout());
+ } else {
+ if (mTouchMode == TOUCH_MODE_FLING) {
+ // Stopped a fling. It is a scroll.
+ createScrollingCache();
+ mTouchMode = TOUCH_MODE_SCROLL;
+ mMotionCorrection = 0;
+ motionPosition = findMotionRow(y);
+ mFlingRunnable.flywheelTouch();
+ }
}
}
+
+ if (motionPosition >= 0) {
+ // Remember where the motion event started
+ v = getChildAt(motionPosition - mFirstPosition);
+ mMotionViewOriginalTop = v.getTop();
+ }
+ mMotionX = x;
+ mMotionY = y;
+ mMotionPosition = motionPosition;
+ mLastY = Integer.MIN_VALUE;
break;
}
+ }
- case MotionEvent.ACTION_MOVE: {
- int pointerIndex = ev.findPointerIndex(mActivePointerId);
- if (pointerIndex == -1) {
- pointerIndex = 0;
- mActivePointerId = ev.getPointerId(pointerIndex);
+ if (performButtonActionOnTouchDown(ev)) {
+ if (mTouchMode == TOUCH_MODE_DOWN) {
+ removeCallbacks(mPendingCheckForTap);
}
- final int y = (int) ev.getY(pointerIndex);
+ }
+ }
- if (mDataChanged) {
- // Re-sync everything if data has been changed
- // since the scroll operation can query the adapter.
- layoutChildren();
- }
+ private void onTouchMove(MotionEvent ev) {
+ int pointerIndex = ev.findPointerIndex(mActivePointerId);
+ if (pointerIndex == -1) {
+ pointerIndex = 0;
+ mActivePointerId = ev.getPointerId(pointerIndex);
+ }
- switch (mTouchMode) {
+ if (mDataChanged) {
+ // Re-sync everything if data has been changed
+ // since the scroll operation can query the adapter.
+ layoutChildren();
+ }
+
+ final int y = (int) ev.getY(pointerIndex);
+
+ switch (mTouchMode) {
case TOUCH_MODE_DOWN:
case TOUCH_MODE_TAP:
case TOUCH_MODE_DONE_WAITING:
@@ -3399,262 +3464,219 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
case TOUCH_MODE_OVERSCROLL:
scrollIfNeeded(y);
break;
- }
- break;
}
+ }
- case MotionEvent.ACTION_UP: {
- switch (mTouchMode) {
- case TOUCH_MODE_DOWN:
- case TOUCH_MODE_TAP:
- case TOUCH_MODE_DONE_WAITING:
- final int motionPosition = mMotionPosition;
- final View child = getChildAt(motionPosition - mFirstPosition);
+ private void onTouchUp(MotionEvent ev) {
+ switch (mTouchMode) {
+ case TOUCH_MODE_DOWN:
+ case TOUCH_MODE_TAP:
+ case TOUCH_MODE_DONE_WAITING:
+ final int motionPosition = mMotionPosition;
+ final View child = getChildAt(motionPosition - mFirstPosition);
- final float x = ev.getX();
- final boolean inList = x > mListPadding.left && x < getWidth() - mListPadding.right;
+ final float x = ev.getX();
+ final boolean inList = x > mListPadding.left && x < getWidth() - mListPadding.right;
- if (child != null && !child.hasFocusable() && inList) {
- if (mTouchMode != TOUCH_MODE_DOWN) {
- child.setPressed(false);
- }
+ if (child != null && !child.hasFocusable() && inList) {
+ if (mTouchMode != TOUCH_MODE_DOWN) {
+ child.setPressed(false);
+ }
- if (mPerformClick == null) {
- mPerformClick = new PerformClick();
- }
+ if (mPerformClick == null) {
+ mPerformClick = new PerformClick();
+ }
- final AbsListView.PerformClick performClick = mPerformClick;
- performClick.mClickMotionPosition = motionPosition;
- performClick.rememberWindowAttachCount();
+ final AbsListView.PerformClick performClick = mPerformClick;
+ performClick.mClickMotionPosition = motionPosition;
+ performClick.rememberWindowAttachCount();
- mResurrectToPosition = motionPosition;
+ mResurrectToPosition = motionPosition;
- if (mTouchMode == TOUCH_MODE_DOWN || mTouchMode == TOUCH_MODE_TAP) {
- final Handler handler = getHandler();
- if (handler != null) {
- handler.removeCallbacks(mTouchMode == TOUCH_MODE_DOWN ?
- mPendingCheckForTap : mPendingCheckForLongPress);
+ if (mTouchMode == TOUCH_MODE_DOWN || mTouchMode == TOUCH_MODE_TAP) {
+ final Handler handler = getHandler();
+ if (handler != null) {
+ handler.removeCallbacks(mTouchMode == TOUCH_MODE_DOWN ?
+ mPendingCheckForTap : mPendingCheckForLongPress);
+ }
+ mLayoutMode = LAYOUT_NORMAL;
+ if (!mDataChanged && mAdapter.isEnabled(motionPosition)) {
+ mTouchMode = TOUCH_MODE_TAP;
+ setSelectedPositionInt(mMotionPosition);
+ layoutChildren();
+ child.setPressed(true);
+ positionSelector(mMotionPosition, child);
+ setPressed(true);
+ if (mSelector != null) {
+ Drawable d = mSelector.getCurrent();
+ if (d != null && d instanceof TransitionDrawable) {
+ ((TransitionDrawable) d).resetTransition();
+ }
}
- mLayoutMode = LAYOUT_NORMAL;
- if (!mDataChanged && mAdapter.isEnabled(motionPosition)) {
- mTouchMode = TOUCH_MODE_TAP;
- setSelectedPositionInt(mMotionPosition);
- layoutChildren();
- child.setPressed(true);
- positionSelector(mMotionPosition, child);
- setPressed(true);
- if (mSelector != null) {
- Drawable d = mSelector.getCurrent();
- if (d != null && d instanceof TransitionDrawable) {
- ((TransitionDrawable) d).resetTransition();
+ if (mTouchModeReset != null) {
+ removeCallbacks(mTouchModeReset);
+ }
+ mTouchModeReset = new Runnable() {
+ @Override
+ public void run() {
+ mTouchModeReset = null;
+ mTouchMode = TOUCH_MODE_REST;
+ child.setPressed(false);
+ setPressed(false);
+ if (!mDataChanged) {
+ performClick.run();
}
}
- if (mTouchModeReset != null) {
- removeCallbacks(mTouchModeReset);
- }
- mTouchModeReset = new Runnable() {
- @Override
- public void run() {
- mTouchModeReset = null;
- mTouchMode = TOUCH_MODE_REST;
- child.setPressed(false);
- setPressed(false);
- if (!mDataChanged) {
- performClick.run();
- }
- }
- };
- postDelayed(mTouchModeReset,
- ViewConfiguration.getPressedStateDuration());
- } else {
- mTouchMode = TOUCH_MODE_REST;
- updateSelectorState();
- }
- return true;
- } else if (!mDataChanged && mAdapter.isEnabled(motionPosition)) {
- performClick.run();
+ };
+ postDelayed(mTouchModeReset,
+ ViewConfiguration.getPressedStateDuration());
+ } else {
+ mTouchMode = TOUCH_MODE_REST;
+ updateSelectorState();
}
+ return;
+ } else if (!mDataChanged && mAdapter.isEnabled(motionPosition)) {
+ performClick.run();
}
- mTouchMode = TOUCH_MODE_REST;
- updateSelectorState();
- break;
- case TOUCH_MODE_SCROLL:
- final int childCount = getChildCount();
- if (childCount > 0) {
- final int firstChildTop = getChildAt(0).getTop();
- final int lastChildBottom = getChildAt(childCount - 1).getBottom();
- final int contentTop = mListPadding.top;
- final int contentBottom = getHeight() - mListPadding.bottom;
- if (mFirstPosition == 0 && firstChildTop >= contentTop &&
- mFirstPosition + childCount < mItemCount &&
- lastChildBottom <= getHeight() - contentBottom) {
+ }
+ mTouchMode = TOUCH_MODE_REST;
+ updateSelectorState();
+ break;
+ case TOUCH_MODE_SCROLL:
+ final int childCount = getChildCount();
+ if (childCount > 0) {
+ final int firstChildTop = getChildAt(0).getTop();
+ final int lastChildBottom = getChildAt(childCount - 1).getBottom();
+ final int contentTop = mListPadding.top;
+ final int contentBottom = getHeight() - mListPadding.bottom;
+ if (mFirstPosition == 0 && firstChildTop >= contentTop &&
+ mFirstPosition + childCount < mItemCount &&
+ lastChildBottom <= getHeight() - contentBottom) {
+ mTouchMode = TOUCH_MODE_REST;
+ reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
+ } else {
+ final VelocityTracker velocityTracker = mVelocityTracker;
+ velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
+
+ final int initialVelocity = (int)
+ (velocityTracker.getYVelocity(mActivePointerId) * mVelocityScale);
+ // Fling if we have enough velocity and we aren't at a boundary.
+ // Since we can potentially overfling more than we can overscroll, don't
+ // allow the weird behavior where you can scroll to a boundary then
+ // fling further.
+ if (Math.abs(initialVelocity) > mMinimumVelocity &&
+ !((mFirstPosition == 0 &&
+ firstChildTop == contentTop - mOverscrollDistance) ||
+ (mFirstPosition + childCount == mItemCount &&
+ lastChildBottom == contentBottom + mOverscrollDistance))) {
+ if (mFlingRunnable == null) {
+ mFlingRunnable = new FlingRunnable();
+ }
+ reportScrollStateChange(OnScrollListener.SCROLL_STATE_FLING);
+
+ mFlingRunnable.start(-initialVelocity);
+ } else {
mTouchMode = TOUCH_MODE_REST;
reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
- } else {
- final VelocityTracker velocityTracker = mVelocityTracker;
- velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
-
- final int initialVelocity = (int)
- (velocityTracker.getYVelocity(mActivePointerId) * mVelocityScale);
- // Fling if we have enough velocity and we aren't at a boundary.
- // Since we can potentially overfling more than we can overscroll, don't
- // allow the weird behavior where you can scroll to a boundary then
- // fling further.
- if (Math.abs(initialVelocity) > mMinimumVelocity &&
- !((mFirstPosition == 0 &&
- firstChildTop == contentTop - mOverscrollDistance) ||
- (mFirstPosition + childCount == mItemCount &&
- lastChildBottom == contentBottom + mOverscrollDistance))) {
- if (mFlingRunnable == null) {
- mFlingRunnable = new FlingRunnable();
- }
- reportScrollStateChange(OnScrollListener.SCROLL_STATE_FLING);
-
- mFlingRunnable.start(-initialVelocity);
- } else {
- mTouchMode = TOUCH_MODE_REST;
- reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
- if (mFlingRunnable != null) {
- mFlingRunnable.endFling();
- }
- if (mPositionScroller != null) {
- mPositionScroller.stop();
- }
+ if (mFlingRunnable != null) {
+ mFlingRunnable.endFling();
+ }
+ if (mPositionScroller != null) {
+ mPositionScroller.stop();
}
}
- } else {
- mTouchMode = TOUCH_MODE_REST;
- reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
- }
- break;
-
- case TOUCH_MODE_OVERSCROLL:
- if (mFlingRunnable == null) {
- mFlingRunnable = new FlingRunnable();
- }
- final VelocityTracker velocityTracker = mVelocityTracker;
- velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
- final int initialVelocity = (int) velocityTracker.getYVelocity(mActivePointerId);
-
- reportScrollStateChange(OnScrollListener.SCROLL_STATE_FLING);
- if (Math.abs(initialVelocity) > mMinimumVelocity) {
- mFlingRunnable.startOverfling(-initialVelocity);
- } else {
- mFlingRunnable.startSpringback();
}
-
- break;
+ } else {
+ mTouchMode = TOUCH_MODE_REST;
+ reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
}
+ break;
- setPressed(false);
-
- if (mEdgeGlowTop != null) {
- mEdgeGlowTop.onRelease();
- mEdgeGlowBottom.onRelease();
+ case TOUCH_MODE_OVERSCROLL:
+ if (mFlingRunnable == null) {
+ mFlingRunnable = new FlingRunnable();
}
+ final VelocityTracker velocityTracker = mVelocityTracker;
+ velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
+ final int initialVelocity = (int) velocityTracker.getYVelocity(mActivePointerId);
- // Need to redraw since we probably aren't drawing the selector anymore
- invalidate();
-
- final Handler handler = getHandler();
- if (handler != null) {
- handler.removeCallbacks(mPendingCheckForLongPress);
+ reportScrollStateChange(OnScrollListener.SCROLL_STATE_FLING);
+ if (Math.abs(initialVelocity) > mMinimumVelocity) {
+ mFlingRunnable.startOverfling(-initialVelocity);
+ } else {
+ mFlingRunnable.startSpringback();
}
- recycleVelocityTracker();
+ break;
+ }
- mActivePointerId = INVALID_POINTER;
+ setPressed(false);
- if (PROFILE_SCROLLING) {
- if (mScrollProfilingStarted) {
- Debug.stopMethodTracing();
- mScrollProfilingStarted = false;
- }
- }
-
- if (mScrollStrictSpan != null) {
- mScrollStrictSpan.finish();
- mScrollStrictSpan = null;
- }
- break;
+ if (mEdgeGlowTop != null) {
+ mEdgeGlowTop.onRelease();
+ mEdgeGlowBottom.onRelease();
}
- case MotionEvent.ACTION_CANCEL: {
- switch (mTouchMode) {
- case TOUCH_MODE_OVERSCROLL:
- if (mFlingRunnable == null) {
- mFlingRunnable = new FlingRunnable();
- }
- mFlingRunnable.startSpringback();
- break;
+ // Need to redraw since we probably aren't drawing the selector anymore
+ invalidate();
- case TOUCH_MODE_OVERFLING:
- // Do nothing - let it play out.
- break;
+ final Handler handler = getHandler();
+ if (handler != null) {
+ handler.removeCallbacks(mPendingCheckForLongPress);
+ }
- default:
- mTouchMode = TOUCH_MODE_REST;
- setPressed(false);
- View motionView = this.getChildAt(mMotionPosition - mFirstPosition);
- if (motionView != null) {
- motionView.setPressed(false);
- }
- clearScrollingCache();
+ recycleVelocityTracker();
- final Handler handler = getHandler();
- if (handler != null) {
- handler.removeCallbacks(mPendingCheckForLongPress);
- }
+ mActivePointerId = INVALID_POINTER;
- recycleVelocityTracker();
+ if (PROFILE_SCROLLING) {
+ if (mScrollProfilingStarted) {
+ Debug.stopMethodTracing();
+ mScrollProfilingStarted = false;
}
+ }
- if (mEdgeGlowTop != null) {
- mEdgeGlowTop.onRelease();
- mEdgeGlowBottom.onRelease();
- }
- mActivePointerId = INVALID_POINTER;
- break;
+ if (mScrollStrictSpan != null) {
+ mScrollStrictSpan.finish();
+ mScrollStrictSpan = null;
}
+ }
- case MotionEvent.ACTION_POINTER_UP: {
- onSecondaryPointerUp(ev);
- final int x = mMotionX;
- final int y = mMotionY;
- final int motionPosition = pointToPosition(x, y);
- if (motionPosition >= 0) {
- // Remember where the motion event started
- v = getChildAt(motionPosition - mFirstPosition);
- mMotionViewOriginalTop = v.getTop();
- mMotionPosition = motionPosition;
+ private void onTouchCancel() {
+ switch (mTouchMode) {
+ case TOUCH_MODE_OVERSCROLL:
+ if (mFlingRunnable == null) {
+ mFlingRunnable = new FlingRunnable();
}
- mLastY = y;
+ mFlingRunnable.startSpringback();
break;
- }
- case MotionEvent.ACTION_POINTER_DOWN: {
- // New pointers take over dragging duties
- final int index = ev.getActionIndex();
- final int id = ev.getPointerId(index);
- final int x = (int) ev.getX(index);
- final int y = (int) ev.getY(index);
- mMotionCorrection = 0;
- mActivePointerId = id;
- mMotionX = x;
- mMotionY = y;
- final int motionPosition = pointToPosition(x, y);
- if (motionPosition >= 0) {
- // Remember where the motion event started
- v = getChildAt(motionPosition - mFirstPosition);
- mMotionViewOriginalTop = v.getTop();
- mMotionPosition = motionPosition;
- }
- mLastY = y;
+ case TOUCH_MODE_OVERFLING:
+ // Do nothing - let it play out.
break;
- }
+
+ default:
+ mTouchMode = TOUCH_MODE_REST;
+ setPressed(false);
+ View motionView = this.getChildAt(mMotionPosition - mFirstPosition);
+ if (motionView != null) {
+ motionView.setPressed(false);
+ }
+ clearScrollingCache();
+
+ final Handler handler = getHandler();
+ if (handler != null) {
+ handler.removeCallbacks(mPendingCheckForLongPress);
+ }
+
+ recycleVelocityTracker();
}
- return true;
+ if (mEdgeGlowTop != null) {
+ mEdgeGlowTop.onRelease();
+ mEdgeGlowBottom.onRelease();
+ }
+ mActivePointerId = INVALID_POINTER;
}
@Override
@@ -3733,7 +3755,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
if (scrollY != 0) {
// Pin to the top/bottom during overscroll
int restoreCount = canvas.save();
- canvas.translate(0, (float) scrollY);
+ canvas.translate(0, scrollY);
mFastScroller.draw(canvas);
canvas.restoreToCount(restoreCount);
} else {
@@ -3945,6 +3967,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
private int mLastFlingY;
private final Runnable mCheckFlywheel = new Runnable() {
+ @Override
public void run() {
final int activeId = mActivePointerId;
final VelocityTracker vt = mVelocityTracker;
@@ -4066,6 +4089,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
postDelayed(mCheckFlywheel, FLYWHEEL_TIMEOUT);
}
+ @Override
public void run() {
switch (mTouchMode) {
default:
@@ -4455,6 +4479,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
removeCallbacks(this);
}
+ @Override
public void run() {
final int listHeight = getHeight();
final int firstPos = mFirstPosition;
@@ -4637,9 +4662,6 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
/**
* The amount of friction applied to flings. The default value
* is {@link ViewConfiguration#getScrollFriction}.
- *
- * @return A scalar dimensionless value representing the coefficient of
- * friction.
*/
public void setFriction(float friction) {
if (mFlingRunnable == null) {
@@ -4806,6 +4828,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
if (!isHardwareAccelerated()) {
if (mClearScrollingCache == null) {
mClearScrollingCache = new Runnable() {
+ @Override
public void run() {
if (mCachingStarted) {
mCachingStarted = mCachingActive = false;
@@ -5083,7 +5106,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
requestLayout();
invalidate();
}
-
+
/**
* If there is a selection returns false.
* Otherwise resurrects the selection and returns true if resurrected.
@@ -5706,6 +5729,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
return mFiltered;
}
+ @Override
public void onGlobalLayout() {
if (isShown()) {
// Show the popup if we are filtered
@@ -5725,6 +5749,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
* For our text watcher that is associated with the text filter. Does
* nothing.
*/
+ @Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@@ -5733,6 +5758,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
* the actual filtering as the text changes, and takes care of hiding and
* showing the popup displaying the currently entered filter text.
*/
+ @Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (mPopup != null && isTextFilterEnabled()) {
int length = s.length();
@@ -5763,9 +5789,11 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
* For our text watcher that is associated with the text filter. Does
* nothing.
*/
+ @Override
public void afterTextChanged(Editable s) {
}
+ @Override
public void onFilterComplete(int count) {
if (mSelectedPosition < 0 && count > 0) {
mResurrectToPosition = INVALID_POSITION;
@@ -5934,6 +5962,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
* This defers a notifyDataSetChanged on the pending RemoteViewsAdapter if it has not
* connected yet.
*/
+ @Override
public void deferNotifyDataSetChanged() {
mDeferNotifyDataSetChanged = true;
}
@@ -5941,6 +5970,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
/**
* Called back when the adapter connects to the RemoteViewsService.
*/
+ @Override
public boolean onRemoteAdapterConnected() {
if (mRemoteAdapter != mAdapter) {
setAdapter(mRemoteAdapter);
@@ -5959,6 +5989,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
/**
* Called back when the adapter disconnects from the RemoteViewsService.
*/
+ @Override
public void onRemoteAdapterDisconnected() {
// If the remote adapter disconnects, we keep it around
// since the currently displayed items are still cached.
@@ -6041,6 +6072,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
return mWrapped != null;
}
+ @Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
if (mWrapped.onCreateActionMode(mode, menu)) {
// Initialize checked graphic state?
@@ -6050,14 +6082,17 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
return false;
}
+ @Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return mWrapped.onPrepareActionMode(mode, menu);
}
+ @Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
return mWrapped.onActionItemClicked(mode, item);
}
+ @Override
public void onDestroyActionMode(ActionMode mode) {
mWrapped.onDestroyActionMode(mode);
mChoiceActionMode = null;
@@ -6072,6 +6107,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
setLongClickable(true);
}
+ @Override
public void onItemCheckedStateChanged(ActionMode mode,
int position, long id, boolean checked) {
mWrapped.onItemCheckedStateChanged(mode, position, id, checked);
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index f57f333..91c989d 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -16,6 +16,13 @@
package android.widget;
+import android.content.UndoManager;
+import android.content.UndoOperation;
+import android.content.UndoOwner;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.text.InputFilter;
+import android.text.SpannableString;
import com.android.internal.util.ArrayUtils;
import com.android.internal.widget.EditableInputConnection;
@@ -107,11 +114,16 @@ import java.util.HashMap;
*/
public class Editor {
private static final String TAG = "Editor";
+ static final boolean DEBUG_UNDO = false;
static final int BLINK = 500;
private static final float[] TEMP_POSITION = new float[2];
private static int DRAG_SHADOW_MAX_TEXT_LENGTH = 20;
+ UndoManager mUndoManager;
+ UndoOwner mUndoOwner;
+ InputFilter mUndoInputFilter;
+
// Cursor Controllers.
InsertionPointCursorController mInsertionPointCursorController;
SelectionModifierCursorController mSelectionModifierCursorController;
@@ -181,7 +193,10 @@ public class Editor {
// Set when this TextView gained focus with some text selected. Will start selection mode.
boolean mCreatedWithASelection;
- private EasyEditSpanController mEasyEditSpanController;
+ // The span controller helps monitoring the changes to which the Editor needs to react:
+ // - EasyEditSpans, for which we have some UI to display on attach and on hide
+ // - SelectionSpans, for which we need to call updateSelection if an IME is attached
+ private SpanController mSpanController;
WordIterator mWordIterator;
SpellChecker mSpellChecker;
@@ -466,8 +481,8 @@ public class Editor {
}
private void hideSpanControllers() {
- if (mEasyEditSpanController != null) {
- mEasyEditSpanController.hide();
+ if (mSpanController != null) {
+ mSpanController.hide();
}
}
@@ -1082,9 +1097,12 @@ public class Editor {
mTextView.updateAfterEdit();
reportExtractedText();
} else if (ims.mCursorChanged) {
- // Cheezy way to get us to report the current cursor location.
+ // Cheesy way to get us to report the current cursor location.
mTextView.invalidateCursor();
}
+ // sendUpdateSelection knows to avoid sending if the selection did
+ // not actually change.
+ sendUpdateSelection();
}
static final int EXTRACT_NOTHING = -2;
@@ -1205,6 +1223,27 @@ public class Editor {
return false;
}
+ private void sendUpdateSelection() {
+ if (null != mInputMethodState && mInputMethodState.mBatchEditNesting <= 0) {
+ final InputMethodManager imm = InputMethodManager.peekInstance();
+ if (null != imm) {
+ final int selectionStart = mTextView.getSelectionStart();
+ final int selectionEnd = mTextView.getSelectionEnd();
+ int candStart = -1;
+ int candEnd = -1;
+ if (mTextView.getText() instanceof Spannable) {
+ final Spannable sp = (Spannable) mTextView.getText();
+ candStart = EditableInputConnection.getComposingSpanStart(sp);
+ candEnd = EditableInputConnection.getComposingSpanEnd(sp);
+ }
+ // InputMethodManager#updateSelection skips sending the message if
+ // none of the parameters have changed since the last time we called it.
+ imm.updateSelection(mTextView,
+ selectionStart, selectionEnd, candStart, candEnd);
+ }
+ }
+ }
+
void onDraw(Canvas canvas, Layout layout, Path highlight, Paint highlightPaint,
int cursorOffsetVertical) {
final int selectionStart = mTextView.getSelectionStart();
@@ -1222,17 +1261,6 @@ public class Editor {
// input method.
reported = reportExtractedText();
}
- if (!reported && highlight != null) {
- int candStart = -1;
- int candEnd = -1;
- if (mTextView.getText() instanceof Spannable) {
- Spannable sp = (Spannable) mTextView.getText();
- candStart = EditableInputConnection.getComposingSpanStart(sp);
- candEnd = EditableInputConnection.getComposingSpanEnd(sp);
- }
- imm.updateSelection(mTextView,
- selectionStart, selectionEnd, candStart, candEnd);
- }
}
if (imm.isWatchingCursor(mTextView) && highlight != null) {
@@ -1859,17 +1887,18 @@ public class Editor {
text.setSpan(mKeyListener, 0, textLength, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
}
- if (mEasyEditSpanController == null) {
- mEasyEditSpanController = new EasyEditSpanController();
+ if (mSpanController == null) {
+ mSpanController = new SpanController();
}
- text.setSpan(mEasyEditSpanController, 0, textLength, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+ text.setSpan(mSpanController, 0, textLength, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
}
/**
* Controls the {@link EasyEditSpan} monitoring when it is added, and when the related
* pop-up should be displayed.
+ * Also monitors {@link Selection} to call back to the attached input method.
*/
- class EasyEditSpanController implements SpanWatcher {
+ class SpanController implements SpanWatcher {
private static final int DISPLAY_TIMEOUT_MS = 3000; // 3 secs
@@ -1877,9 +1906,18 @@ public class Editor {
private Runnable mHidePopup;
+ // This function is pure but inner classes can't have static functions
+ private boolean isNonIntermediateSelectionSpan(final Spannable text,
+ final Object span) {
+ return (Selection.SELECTION_START == span || Selection.SELECTION_END == span)
+ && (text.getSpanFlags(span) & Spanned.SPAN_INTERMEDIATE) == 0;
+ }
+
@Override
public void onSpanAdded(Spannable text, Object span, int start, int end) {
- if (span instanceof EasyEditSpan) {
+ if (isNonIntermediateSelectionSpan(text, span)) {
+ sendUpdateSelection();
+ } else if (span instanceof EasyEditSpan) {
if (mPopupWindow == null) {
mPopupWindow = new EasyEditPopupWindow();
mHidePopup = new Runnable() {
@@ -1903,7 +1941,7 @@ public class Editor {
int start = editable.getSpanStart(span);
int end = editable.getSpanEnd(span);
if (start >= 0 && end >= 0) {
- sendNotification(EasyEditSpan.TEXT_DELETED, span);
+ sendEasySpanNotification(EasyEditSpan.TEXT_DELETED, span);
mTextView.deleteText_internal(start, end);
}
editable.removeSpan(span);
@@ -1934,7 +1972,9 @@ public class Editor {
@Override
public void onSpanRemoved(Spannable text, Object span, int start, int end) {
- if (mPopupWindow != null && span == mPopupWindow.mEasyEditSpan) {
+ if (isNonIntermediateSelectionSpan(text, span)) {
+ sendUpdateSelection();
+ } else if (mPopupWindow != null && span == mPopupWindow.mEasyEditSpan) {
hide();
}
}
@@ -1942,9 +1982,11 @@ public class Editor {
@Override
public void onSpanChanged(Spannable text, Object span, int previousStart, int previousEnd,
int newStart, int newEnd) {
- if (mPopupWindow != null && span instanceof EasyEditSpan) {
+ if (isNonIntermediateSelectionSpan(text, span)) {
+ sendUpdateSelection();
+ } else if (mPopupWindow != null && span instanceof EasyEditSpan) {
EasyEditSpan easyEditSpan = (EasyEditSpan) span;
- sendNotification(EasyEditSpan.TEXT_MODIFIED, easyEditSpan);
+ sendEasySpanNotification(EasyEditSpan.TEXT_MODIFIED, easyEditSpan);
text.removeSpan(easyEditSpan);
}
}
@@ -1956,7 +1998,7 @@ public class Editor {
}
}
- private void sendNotification(int textChangedType, EasyEditSpan span) {
+ private void sendEasySpanNotification(int textChangedType, EasyEditSpan span) {
try {
PendingIntent pendingIntent = span.getPendingIntent();
if (pendingIntent != null) {
@@ -1984,7 +2026,7 @@ public class Editor {
/**
* Displays the actions associated to an {@link EasyEditSpan}. The pop-up is controlled
- * by {@link EasyEditSpanController}.
+ * by {@link SpanController}.
*/
private class EasyEditPopupWindow extends PinnedPopupWindow
implements OnClickListener {
@@ -3929,4 +3971,166 @@ public class Editor {
mTextView.setCursorPosition_internal(newCursorPosition, newCursorPosition);
}
}
+
+ public static class UndoInputFilter implements InputFilter {
+ final Editor mEditor;
+
+ public UndoInputFilter(Editor editor) {
+ mEditor = editor;
+ }
+
+ @Override
+ public CharSequence filter(CharSequence source, int start, int end,
+ Spanned dest, int dstart, int dend) {
+ if (DEBUG_UNDO) {
+ Log.d(TAG, "filter: source=" + source + " (" + start + "-" + end + ")");
+ Log.d(TAG, "filter: dest=" + dest + " (" + dstart + "-" + dend + ")");
+ }
+ final UndoManager um = mEditor.mUndoManager;
+ if (um.isInUndo()) {
+ if (DEBUG_UNDO) Log.d(TAG, "*** skipping, currently performing undo/redo");
+ return null;
+ }
+
+ um.beginUpdate("Edit text");
+ TextModifyOperation op = um.getLastOperation(
+ TextModifyOperation.class, mEditor.mUndoOwner, UndoManager.MERGE_MODE_UNIQUE);
+ if (op != null) {
+ if (DEBUG_UNDO) Log.d(TAG, "Last op: range=(" + op.mRangeStart + "-" + op.mRangeEnd
+ + "), oldText=" + op.mOldText);
+ // See if we can continue modifying this operation.
+ if (op.mOldText == null) {
+ // The current operation is an add... are we adding more? We are adding
+ // more if we are either appending new text to the end of the last edit or
+ // completely replacing some or all of the last edit.
+ if (start < end && ((dstart >= op.mRangeStart && dend <= op.mRangeEnd)
+ || (dstart == op.mRangeEnd && dend == op.mRangeEnd))) {
+ op.mRangeEnd = dstart + (end-start);
+ um.endUpdate();
+ if (DEBUG_UNDO) Log.d(TAG, "*** merging with last op, mRangeEnd="
+ + op.mRangeEnd);
+ return null;
+ }
+ } else {
+ // The current operation is a delete... can we delete more?
+ if (start == end && dend == op.mRangeStart-1) {
+ SpannableStringBuilder str;
+ if (op.mOldText instanceof SpannableString) {
+ str = (SpannableStringBuilder)op.mOldText;
+ } else {
+ str = new SpannableStringBuilder(op.mOldText);
+ }
+ str.insert(0, dest, dstart, dend);
+ op.mRangeStart = dstart;
+ op.mOldText = str;
+ um.endUpdate();
+ if (DEBUG_UNDO) Log.d(TAG, "*** merging with last op, range=("
+ + op.mRangeStart + "-" + op.mRangeEnd
+ + "), oldText=" + op.mOldText);
+ return null;
+ }
+ }
+
+ // Couldn't add to the current undo operation, need to start a new
+ // undo state for a new undo operation.
+ um.commitState(null);
+ um.setUndoLabel("Edit text");
+ }
+
+ // Create a new undo state reflecting the operation being performed.
+ op = new TextModifyOperation(mEditor.mUndoOwner);
+ op.mRangeStart = dstart;
+ if (start < end) {
+ op.mRangeEnd = dstart + (end-start);
+ } else {
+ op.mRangeEnd = dstart;
+ }
+ if (dstart < dend) {
+ op.mOldText = dest.subSequence(dstart, dend);
+ }
+ if (DEBUG_UNDO) Log.d(TAG, "*** adding new op, range=(" + op.mRangeStart
+ + "-" + op.mRangeEnd + "), oldText=" + op.mOldText);
+ um.addOperation(op, UndoManager.MERGE_MODE_NONE);
+ um.endUpdate();
+ return null;
+ }
+ }
+
+ public static class TextModifyOperation extends UndoOperation<TextView> {
+ int mRangeStart, mRangeEnd;
+ CharSequence mOldText;
+
+ public TextModifyOperation(UndoOwner owner) {
+ super(owner);
+ }
+
+ public TextModifyOperation(Parcel src, ClassLoader loader) {
+ super(src, loader);
+ mRangeStart = src.readInt();
+ mRangeEnd = src.readInt();
+ mOldText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(src);
+ }
+
+ @Override
+ public void commit() {
+ }
+
+ @Override
+ public void undo() {
+ swapText();
+ }
+
+ @Override
+ public void redo() {
+ swapText();
+ }
+
+ private void swapText() {
+ // Both undo and redo involves swapping the contents of the range
+ // in the text view with our local text.
+ TextView tv = getOwnerData();
+ Editable editable = (Editable)tv.getText();
+ CharSequence curText;
+ if (mRangeStart >= mRangeEnd) {
+ curText = null;
+ } else {
+ curText = editable.subSequence(mRangeStart, mRangeEnd);
+ }
+ if (DEBUG_UNDO) {
+ Log.d(TAG, "Swap: range=(" + mRangeStart + "-" + mRangeEnd
+ + "), oldText=" + mOldText);
+ Log.d(TAG, "Swap: curText=" + curText);
+ }
+ if (mOldText == null) {
+ editable.delete(mRangeStart, mRangeEnd);
+ mRangeEnd = mRangeStart;
+ } else {
+ editable.replace(mRangeStart, mRangeEnd, mOldText);
+ mRangeEnd = mRangeStart + mOldText.length();
+ }
+ mOldText = curText;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(mRangeStart);
+ dest.writeInt(mRangeEnd);
+ TextUtils.writeToParcel(mOldText, dest, flags);
+ }
+
+ public static final Parcelable.ClassLoaderCreator<TextModifyOperation> CREATOR
+ = new Parcelable.ClassLoaderCreator<TextModifyOperation>() {
+ public TextModifyOperation createFromParcel(Parcel in) {
+ return new TextModifyOperation(in, null);
+ }
+
+ public TextModifyOperation createFromParcel(Parcel in, ClassLoader loader) {
+ return new TextModifyOperation(in, loader);
+ }
+
+ public TextModifyOperation[] newArray(int size) {
+ return new TextModifyOperation[size];
+ }
+ };
+ }
}
diff --git a/core/java/android/widget/GridLayout.java b/core/java/android/widget/GridLayout.java
index 2309001..b0ab70d 100644
--- a/core/java/android/widget/GridLayout.java
+++ b/core/java/android/widget/GridLayout.java
@@ -24,7 +24,9 @@ import android.graphics.Insets;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.Log;
+import android.util.LogPrinter;
import android.util.Pair;
+import android.util.Printer;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
@@ -124,6 +126,17 @@ import static java.lang.Math.min;
* GridLayout's algorithms favour rows and columns that are closer to its <em>right</em>
* and <em>bottom</em> edges.
*
+ * <h4>Interpretation of GONE</h4>
+ *
+ * For layout purposes, GridLayout treats views whose visibility status is
+ * {@link View#GONE GONE}, as having zero width and height. This is subtly different from
+ * the policy of ignoring views that are marked as GONE outright. If, for example, a gone-marked
+ * view was alone in a column, that column would itself collapse to zero width if and only if
+ * no gravity was defined on the view. If gravity was defined, then the gone-marked
+ * view has no effect on the layout and the container should be laid out as if the view
+ * had never been added to it.
+ * These statements apply equally to rows as well as columns, and to groups of rows or columns.
+ *
* <h5>Limitations</h5>
*
* GridLayout does not provide support for the principle of <em>weight</em>, as defined in
@@ -208,10 +221,15 @@ public class GridLayout extends ViewGroup {
// Misc constants
- static final String TAG = GridLayout.class.getName();
static final int MAX_SIZE = 100000;
static final int DEFAULT_CONTAINER_MARGIN = 0;
static final int UNINITIALIZED_HASH = 0;
+ static final Printer LOG_PRINTER = new LogPrinter(Log.DEBUG, GridLayout.class.getName());
+ static final Printer NO_PRINTER = new Printer() {
+ @Override
+ public void println(String x) {
+ }
+ };
// Defaults
@@ -240,6 +258,7 @@ public class GridLayout extends ViewGroup {
int alignmentMode = DEFAULT_ALIGNMENT_MODE;
int defaultGap;
int lastLayoutParamsHashCode = UNINITIALIZED_HASH;
+ Printer printer = LOG_PRINTER;
// Constructors
@@ -556,6 +575,29 @@ public class GridLayout extends ViewGroup {
requestLayout();
}
+ /**
+ * Return the printer that will log diagnostics from this layout.
+ *
+ * @see #setPrinter(android.util.Printer)
+ *
+ * @return the printer associated with this view
+ */
+ public Printer getPrinter() {
+ return printer;
+ }
+
+ /**
+ * Set the printer that will log diagnostics from this layout.
+ * The default value is created by {@link android.util.LogPrinter}.
+ *
+ * @param printer the printer associated with this layout
+ *
+ * @see #getPrinter()
+ */
+ public void setPrinter(Printer printer) {
+ this.printer = (printer == null) ? NO_PRINTER : printer;
+ }
+
// Static utility methods
static int max2(int[] a, int valueIfEmpty) {
@@ -915,7 +957,7 @@ public class GridLayout extends ViewGroup {
protected void onChildVisibilityChanged(View child, int oldVisibility, int newVisibility) {
super.onChildVisibilityChanged(child, oldVisibility, newVisibility);
if (oldVisibility == GONE || newVisibility == GONE) {
- invalidateStructure();
+ invalidateStructure();
}
}
@@ -935,8 +977,8 @@ public class GridLayout extends ViewGroup {
validateLayoutParams();
lastLayoutParamsHashCode = computeLayoutParamsHashCode();
} else if (lastLayoutParamsHashCode != computeLayoutParamsHashCode()) {
- Log.w(TAG, "The fields of some layout parameters were modified in between layout " +
- "operations. Check the javadoc for GridLayout.LayoutParams#rowSpec.");
+ printer.println("The fields of some layout parameters were modified in between "
+ + "layout operations. Check the javadoc for GridLayout.LayoutParams#rowSpec.");
invalidateStructure();
consistencyCheck();
}
@@ -1246,6 +1288,7 @@ public class GridLayout extends ViewGroup {
Assoc<Spec, Bounds> assoc = Assoc.of(Spec.class, Bounds.class);
for (int i = 0, N = getChildCount(); i < N; i++) {
View c = getChildAt(i);
+ // we must include views that are GONE here, see introductory javadoc
LayoutParams lp = getLayoutParams(c);
Spec spec = horizontal ? lp.columnSpec : lp.rowSpec;
Bounds bounds = getAlignment(spec.alignment, horizontal).getBounds();
@@ -1261,6 +1304,7 @@ public class GridLayout extends ViewGroup {
}
for (int i = 0, N = getChildCount(); i < N; i++) {
View c = getChildAt(i);
+ // we must include views that are GONE here, see introductory javadoc
LayoutParams lp = getLayoutParams(c);
Spec spec = horizontal ? lp.columnSpec : lp.rowSpec;
groupBounds.getValue(i).include(GridLayout.this, c, spec, this);
@@ -1527,8 +1571,8 @@ public class GridLayout extends ViewGroup {
removed.add(arc);
}
}
- Log.d(TAG, axisName + " constraints: " + arcsToString(culprits) + " are inconsistent; "
- + "permanently removing: " + arcsToString(removed) + ". ");
+ printer.println(axisName + " constraints: " + arcsToString(culprits) +
+ " are inconsistent; permanently removing: " + arcsToString(removed) + ". ");
}
/*
@@ -2666,6 +2710,9 @@ public class GridLayout extends ViewGroup {
@Override
public int getAlignmentValue(View view, int viewSize, int mode) {
+ if (view.getVisibility() == GONE) {
+ return 0;
+ }
int baseline = view.getBaseline();
return baseline == -1 ? UNDEFINED : baseline;
}
diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java
index f42999d..a82bebd 100644
--- a/core/java/android/widget/ListView.java
+++ b/core/java/android/widget/ListView.java
@@ -2425,24 +2425,37 @@ public class ListView extends AbsListView {
/**
* Used by {@link #arrowScrollImpl(int)} to help determine the next selected position
- * to move to. This can return a position currently not represented by a view on screen
- * but only in the direction given.
+ * to move to. This return a position in the direction given if the selected item
+ * is fully visible.
*
+ * @param selectedView Current selected view to move from
* @param selectedPos Current selected position to move from
* @param direction Direction to move in
* @return Desired selected position after moving in the given direction
*/
- private final int nextSelectedPositionForDirection(int selectedPos, int direction) {
+ private final int nextSelectedPositionForDirection(
+ View selectedView, int selectedPos, int direction) {
int nextSelected;
+
if (direction == View.FOCUS_DOWN) {
- nextSelected = selectedPos != INVALID_POSITION && selectedPos >= mFirstPosition ?
- selectedPos + 1 :
- mFirstPosition;
+ final int listBottom = getHeight() - mListPadding.bottom;
+ if (selectedView != null && selectedView.getBottom() <= listBottom) {
+ nextSelected = selectedPos != INVALID_POSITION && selectedPos >= mFirstPosition ?
+ selectedPos + 1 :
+ mFirstPosition;
+ } else {
+ return INVALID_POSITION;
+ }
} else {
- final int lastPos = mFirstPosition + getChildCount() - 1;
- nextSelected = selectedPos != INVALID_POSITION && selectedPos <= lastPos ?
- selectedPos - 1 :
- lastPos;
+ final int listTop = mListPadding.top;
+ if (selectedView != null && selectedView.getTop() >= listTop) {
+ final int lastPos = mFirstPosition + getChildCount() - 1;
+ nextSelected = selectedPos != INVALID_POSITION && selectedPos <= lastPos ?
+ selectedPos - 1 :
+ lastPos;
+ } else {
+ return INVALID_POSITION;
+ }
}
if (nextSelected < 0 || nextSelected >= mAdapter.getCount()) {
@@ -2466,7 +2479,7 @@ public class ListView extends AbsListView {
View selectedView = getSelectedView();
int selectedPos = mSelectedPosition;
- int nextSelectedPosition = nextSelectedPositionForDirection(selectedPos, direction);
+ int nextSelectedPosition = nextSelectedPositionForDirection(selectedView, selectedPos, direction);
int amountToScroll = amountToScroll(direction, nextSelectedPosition);
// if we are moving focus, we may OVERRIDE the default behavior
diff --git a/core/java/android/widget/RemoteViewsAdapter.java b/core/java/android/widget/RemoteViewsAdapter.java
index aeee111..3ff0cee 100644
--- a/core/java/android/widget/RemoteViewsAdapter.java
+++ b/core/java/android/widget/RemoteViewsAdapter.java
@@ -22,9 +22,11 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
+import android.Manifest;
import android.appwidget.AppWidgetManager;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.PackageManager;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
@@ -34,6 +36,7 @@ import android.os.Process;
import android.os.RemoteException;
import android.os.UserHandle;
import android.util.Log;
+import android.util.Slog;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.MeasureSpec;
@@ -50,9 +53,11 @@ import com.android.internal.widget.LockPatternUtils;
*/
/** @hide */
public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback {
+ private static final String MULTI_USER_PERM = Manifest.permission.INTERACT_ACROSS_USERS_FULL;
+
private static final String TAG = "RemoteViewsAdapter";
- // The max number of items in the cache
+ // The max number of items in the cache
private static final int sDefaultCacheSize = 40;
// The delay (in millis) to wait until attempting to unbind from a service after a request.
// This ensures that we don't stay continually bound to the service and that it can be destroyed
@@ -63,7 +68,7 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback
private static final int sDefaultLoadingViewHeight = 50;
// Type defs for controlling different messages across the main and worker message queues
- private static final int sDefaultMessageType = 0;
+ private static final int sDefaultMessageType = 0;
private static final int sUnbindServiceMessageType = 1;
private final Context mContext;
@@ -90,7 +95,7 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback
private Handler mMainQueue;
// We cache the FixedSizeRemoteViewsCaches across orientation. These are the related data
- // structures;
+ // structures;
private static final HashMap<RemoteViewsCacheKey,
FixedSizeRemoteViewsCache> sCachedRemoteViewsCaches
= new HashMap<RemoteViewsCacheKey,
@@ -155,13 +160,12 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback
try {
RemoteViewsAdapter adapter;
final AppWidgetManager mgr = AppWidgetManager.getInstance(context);
- if (Process.myUid() == Process.SYSTEM_UID
- && (adapter = mAdapter.get()) != null) {
+ if ((adapter = mAdapter.get()) != null) {
+ checkInteractAcrossUsersPermission(context, adapter.mUserId);
mgr.bindRemoteViewsService(appWidgetId, intent, asBinder(),
new UserHandle(adapter.mUserId));
} else {
- mgr.bindRemoteViewsService(appWidgetId, intent, asBinder(),
- Process.myUserHandle());
+ Slog.w(TAG, "bind: adapter was null");
}
mIsConnecting = true;
} catch (Exception e) {
@@ -176,12 +180,12 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback
try {
RemoteViewsAdapter adapter;
final AppWidgetManager mgr = AppWidgetManager.getInstance(context);
- if (Process.myUid() == Process.SYSTEM_UID
- && (adapter = mAdapter.get()) != null) {
+ if ((adapter = mAdapter.get()) != null) {
+ checkInteractAcrossUsersPermission(context, adapter.mUserId);
mgr.unbindRemoteViewsService(appWidgetId, intent,
new UserHandle(adapter.mUserId));
} else {
- mgr.unbindRemoteViewsService(appWidgetId, intent, Process.myUserHandle());
+ Slog.w(TAG, "unbind: adapter was null");
}
mIsConnecting = false;
} catch (Exception e) {
@@ -263,7 +267,7 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback
// Clear the main/worker queues
final RemoteViewsAdapter adapter = mAdapter.get();
if (adapter == null) return;
-
+
adapter.mMainQueue.post(new Runnable() {
@Override
public void run() {
@@ -828,11 +832,9 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback
}
mRequestedViews = new RemoteViewsFrameLayoutRefSet();
- if (Process.myUid() == Process.SYSTEM_UID) {
- mUserId = new LockPatternUtils(context).getCurrentUser();
- } else {
- mUserId = UserHandle.myUserId();
- }
+ checkInteractAcrossUsersPermission(context, UserHandle.myUserId());
+ mUserId = context.getUserId();
+
// Strip the previously injected app widget id from service intent
if (intent.hasExtra(RemoteViews.EXTRA_REMOTEADAPTER_APPWIDGET_ID)) {
intent.removeExtra(RemoteViews.EXTRA_REMOTEADAPTER_APPWIDGET_ID);
@@ -876,6 +878,15 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback
}
}
+ private static void checkInteractAcrossUsersPermission(Context context, int userId) {
+ if (context.getUserId() != userId
+ && context.checkCallingOrSelfPermission(MULTI_USER_PERM)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Must have permission " + MULTI_USER_PERM
+ + " to inflate another user's widget");
+ }
+ }
+
@Override
protected void finalize() throws Throwable {
try {
diff --git a/core/java/android/widget/ScrollBarDrawable.java b/core/java/android/widget/ScrollBarDrawable.java
index 93a1179..9886bc3 100644
--- a/core/java/android/widget/ScrollBarDrawable.java
+++ b/core/java/android/widget/ScrollBarDrawable.java
@@ -226,6 +226,12 @@ public class ScrollBarDrawable extends Drawable {
}
@Override
+ public int getAlpha() {
+ // All elements should have same alpha, just return one of them
+ return mVerticalThumb.getAlpha();
+ }
+
+ @Override
public void setColorFilter(ColorFilter cf) {
if (mVerticalTrack != null) {
mVerticalTrack.setColorFilter(cf);
diff --git a/core/java/android/widget/TextClock.java b/core/java/android/widget/TextClock.java
index a564c96..b3b95d9 100644
--- a/core/java/android/widget/TextClock.java
+++ b/core/java/android/widget/TextClock.java
@@ -95,6 +95,7 @@ public class TextClock extends TextView {
*
* @see #setFormat12Hour(CharSequence)
* @see #getFormat12Hour()
+ *
* @deprecated Let the system use locale-appropriate defaults instead.
*/
public static final CharSequence DEFAULT_FORMAT_12_HOUR = "h:mm a";
@@ -108,6 +109,7 @@ public class TextClock extends TextView {
*
* @see #setFormat24Hour(CharSequence)
* @see #getFormat24Hour()
+ *
* @deprecated Let the system use locale-appropriate defaults instead.
*/
public static final CharSequence DEFAULT_FORMAT_24_HOUR = "H:mm";
@@ -162,9 +164,7 @@ public class TextClock extends TextView {
};
/**
- * Creates a new clock using the default patterns
- * {@link #DEFAULT_FORMAT_24_HOUR} and {@link #DEFAULT_FORMAT_12_HOUR}
- * respectively for the 24-hour and 12-hour modes.
+ * Creates a new clock using the default patterns for the current locale.
*
* @param context The Context the view is running in, through which it can
* access the current theme, resources, etc.
@@ -258,20 +258,26 @@ public class TextClock extends TextView {
}
/**
- * Specifies the formatting pattern used to display the date and/or time
+ * <p>Specifies the formatting pattern used to display the date and/or time
* in 12-hour mode. The formatting pattern syntax is described in
- * {@link DateFormat}.
+ * {@link DateFormat}.</p>
*
- * If this pattern is set to null, {@link #getFormat24Hour()} will be used
+ * <p>If this pattern is set to null, {@link #getFormat24Hour()} will be used
* even in 12-hour mode. If both 24-hour and 12-hour formatting patterns
- * are set to null, {@link #DEFAULT_FORMAT_24_HOUR} and
- * {@link #DEFAULT_FORMAT_12_HOUR} will be used instead.
+ * are set to null, the default pattern for the current locale will be used
+ * instead.</p>
+ *
+ * <p><strong>Note:</strong> if styling is not needed, it is highly recommended
+ * you supply a format string generated by
+ * {@link DateFormat#getBestDateTimePattern(java.util.Locale, String)}. This method
+ * takes care of generating a format string adapted to the desired locale.</p>
+ *
*
* @param format A date/time formatting pattern as described in {@link DateFormat}
*
* @see #getFormat12Hour()
* @see #is24HourModeEnabled()
- * @see #DEFAULT_FORMAT_12_HOUR
+ * @see DateFormat#getBestDateTimePattern(java.util.Locale, String)
* @see DateFormat
*
* @attr ref android.R.styleable#TextClock_format12Hour
@@ -300,20 +306,25 @@ public class TextClock extends TextView {
}
/**
- * Specifies the formatting pattern used to display the date and/or time
+ * <p>Specifies the formatting pattern used to display the date and/or time
* in 24-hour mode. The formatting pattern syntax is described in
- * {@link DateFormat}.
+ * {@link DateFormat}.</p>
+ *
+ * <p>If this pattern is set to null, {@link #getFormat24Hour()} will be used
+ * even in 12-hour mode. If both 24-hour and 12-hour formatting patterns
+ * are set to null, the default pattern for the current locale will be used
+ * instead.</p>
*
- * If this pattern is set to null, {@link #getFormat12Hour()} will be used
- * even in 24-hour mode. If both 24-hour and 12-hour formatting patterns
- * are set to null, {@link #DEFAULT_FORMAT_24_HOUR} and
- * {@link #DEFAULT_FORMAT_12_HOUR} will be used instead.
+ * <p><strong>Note:</strong> if styling is not needed, it is highly recommended
+ * you supply a format string generated by
+ * {@link DateFormat#getBestDateTimePattern(java.util.Locale, String)}. This method
+ * takes care of generating a format string adapted to the desired locale.</p>
*
* @param format A date/time formatting pattern as described in {@link DateFormat}
*
* @see #getFormat24Hour()
* @see #is24HourModeEnabled()
- * @see #DEFAULT_FORMAT_24_HOUR
+ * @see DateFormat#getBestDateTimePattern(java.util.Locale, String)
* @see DateFormat
*
* @attr ref android.R.styleable#TextClock_format24Hour
@@ -334,8 +345,7 @@ public class TextClock extends TextView {
* returned by {@link #getFormat12Hour()} is used instead.
*
* If either one of the formats is null, the other format is used. If
- * both formats are null, the default values {@link #DEFAULT_FORMAT_12_HOUR}
- * and {@link #DEFAULT_FORMAT_24_HOUR} are used instead.
+ * both formats are null, the default formats for the current locale are used.
*
* @return true if time should be displayed in 24-hour format, false if it
* should be displayed in 12-hour format.
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 53cf82d..b1692d7 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -20,6 +20,7 @@ import android.R;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
+import android.content.UndoManager;
import android.content.res.ColorStateList;
import android.content.res.CompatibilityInfo;
import android.content.res.Resources;
@@ -284,6 +285,13 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
private boolean mPreDrawRegistered;
+ // A flag to prevent repeated movements from escaping the enclosing text view. The idea here is
+ // that if a user is holding down a movement key to traverse text, we shouldn't also traverse
+ // the view hierarchy. On the other hand, if the user is using the movement key to traverse views
+ // (i.e. the first movement was to traverse out of this view, or this view was traversed into by
+ // the user holding the movement key down) then we shouldn't prevent the focus from changing.
+ private boolean mPreventDefaultMovement;
+
private TextUtils.TruncateAt mEllipsize;
static class Drawables {
@@ -1503,6 +1511,47 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
/**
+ * Retrieve the {@link android.content.UndoManager} that is currently associated
+ * with this TextView. By default there is no associated UndoManager, so null
+ * is returned. One can be associated with the TextView through
+ * {@link #setUndoManager(android.content.UndoManager, String)}
+ */
+ public final UndoManager getUndoManager() {
+ return mEditor == null ? null : mEditor.mUndoManager;
+ }
+
+ /**
+ * Associate an {@link android.content.UndoManager} with this TextView. Once
+ * done, all edit operations on the TextView will result in appropriate
+ * {@link android.content.UndoOperation} objects pushed on the given UndoManager's
+ * stack.
+ *
+ * @param undoManager The {@link android.content.UndoManager} to associate with
+ * this TextView, or null to clear any existing association.
+ * @param tag String tag identifying this particular TextView owner in the
+ * UndoManager. This is used to keep the correct association with the
+ * {@link android.content.UndoOwner} of any operations inside of the UndoManager.
+ */
+ public final void setUndoManager(UndoManager undoManager, String tag) {
+ if (undoManager != null) {
+ createEditorIfNeeded();
+ mEditor.mUndoManager = undoManager;
+ mEditor.mUndoOwner = undoManager.getOwner(tag, this);
+ mEditor.mUndoInputFilter = new Editor.UndoInputFilter(mEditor);
+ if (!(mText instanceof Editable)) {
+ setText(mText, BufferType.EDITABLE);
+ }
+
+ setFilters((Editable) mText, mFilters);
+ } else if (mEditor != null) {
+ // XXX need to destroy all associated state.
+ mEditor.mUndoManager = null;
+ mEditor.mUndoOwner = null;
+ mEditor.mUndoInputFilter = null;
+ }
+ }
+
+ /**
* @return the current key listener for this TextView.
* This will frequently be null for non-EditText TextViews.
*
@@ -4394,16 +4443,30 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
* and includes mInput in the list if it is an InputFilter.
*/
private void setFilters(Editable e, InputFilter[] filters) {
- if (mEditor != null && mEditor.mKeyListener instanceof InputFilter) {
- InputFilter[] nf = new InputFilter[filters.length + 1];
-
- System.arraycopy(filters, 0, nf, 0, filters.length);
- nf[filters.length] = (InputFilter) mEditor.mKeyListener;
+ if (mEditor != null) {
+ final boolean undoFilter = mEditor.mUndoInputFilter != null;
+ final boolean keyFilter = mEditor.mKeyListener instanceof InputFilter;
+ int num = 0;
+ if (undoFilter) num++;
+ if (keyFilter) num++;
+ if (num > 0) {
+ InputFilter[] nf = new InputFilter[filters.length + num];
+
+ System.arraycopy(filters, 0, nf, 0, filters.length);
+ num = 0;
+ if (undoFilter) {
+ nf[filters.length] = mEditor.mUndoInputFilter;
+ num++;
+ }
+ if (keyFilter) {
+ nf[filters.length + num] = (InputFilter) mEditor.mKeyListener;
+ }
- e.setFilters(nf);
- } else {
- e.setFilters(filters);
+ e.setFilters(nf);
+ return;
+ }
}
+ e.setFilters(filters);
}
/**
@@ -5268,7 +5331,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
public boolean onKeyDown(int keyCode, KeyEvent event) {
int which = doKeyDown(keyCode, event, null);
if (which == 0) {
- // Go through default dispatching.
return super.onKeyDown(keyCode, event);
}
@@ -5366,6 +5428,15 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
return 0;
}
+ // If this is the initial keydown, we don't want to prevent a movement away from this view.
+ // While this shouldn't be necessary because any time we're preventing default movement we
+ // should be restricting the focus to remain within this view, thus we'll also receive
+ // the key up event, occasionally key up events will get dropped and we don't want to
+ // prevent the user from traversing out of this on the next key down.
+ if (event.getRepeatCount() == 0 && !KeyEvent.isModifierKey(keyCode)) {
+ mPreventDefaultMovement = false;
+ }
+
switch (keyCode) {
case KeyEvent.KEYCODE_ENTER:
if (event.hasNoModifiers()) {
@@ -5474,12 +5545,16 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
}
if (doDown) {
- if (mMovement.onKeyDown(this, (Spannable)mText, keyCode, event))
+ if (mMovement.onKeyDown(this, (Spannable)mText, keyCode, event)) {
+ if (event.getRepeatCount() == 0 && !KeyEvent.isModifierKey(keyCode)) {
+ mPreventDefaultMovement = true;
+ }
return 2;
+ }
}
}
- return 0;
+ return mPreventDefaultMovement && !KeyEvent.isModifierKey(keyCode) ? -1 : 0;
}
/**
@@ -5512,6 +5587,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
return super.onKeyUp(keyCode, event);
}
+ if (!KeyEvent.isModifierKey(keyCode)) {
+ mPreventDefaultMovement = false;
+ }
+
switch (keyCode) {
case KeyEvent.KEYCODE_DPAD_CENTER:
if (event.hasNoModifiers()) {
diff --git a/core/java/android/widget/Toast.java b/core/java/android/widget/Toast.java
index 1d85126..aaa1adaa 100644
--- a/core/java/android/widget/Toast.java
+++ b/core/java/android/widget/Toast.java
@@ -29,6 +29,7 @@ import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
+import android.view.View.OnClickListener;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
@@ -74,6 +75,9 @@ public class Toast {
*/
public static final int LENGTH_LONG = 1;
+ /** @hide */
+ public static final int LENGTH_INFINITE = 2;
+
final Context mContext;
final TN mTN;
int mDuration;
@@ -288,6 +292,61 @@ public class Toast {
tv.setText(s);
}
+ /** @hide */
+ public static Toast makeBar(Context context, int resId, int duration) {
+ return makeBar(context, context.getResources().getText(resId), duration);
+ }
+
+ /** @hide */
+ public static Toast makeBar(Context context, CharSequence text, int duration) {
+ Toast result = new Toast(context);
+
+ LayoutInflater inflate = (LayoutInflater)
+ context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ View v = inflate.inflate(com.android.internal.R.layout.toast_bar, null);
+ ((TextView)v.findViewById(android.R.id.message)).setText(text);
+ v.findViewById(android.R.id.button1).setVisibility(View.GONE);
+
+ result.mNextView = v;
+ result.mDuration = duration;
+ result.mTN.mParams.alpha = 0.9f;
+ result.mTN.mParams.windowAnimations = com.android.internal.R.style.Animation_ToastBar;
+
+ return result;
+ }
+
+ /** @hide */
+ public Toast setAction(int resId, Runnable action) {
+ return setAction(mContext.getResources().getText(resId), action);
+ }
+
+ /** @hide */
+ public Toast setAction(CharSequence actionText, final Runnable action) {
+ if (mNextView != null) {
+ TextView text1 = (TextView)mNextView.findViewById(android.R.id.text1);
+ View button1 = mNextView.findViewById(android.R.id.button1);
+ if (text1 != null && button1 != null) {
+ text1.setText(actionText);
+ button1.setVisibility(View.VISIBLE);
+ button1.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ if (action != null) {
+ action.run();
+ }
+ }});
+ return setInteractive(true);
+ }
+ }
+ throw new RuntimeException("This Toast was not created with Toast.makeBar()");
+ }
+
+ /** @hide */
+ public Toast setInteractive(boolean interactive) {
+ mTN.setInteractive(interactive);
+ return this;
+ }
+
// =======================================================================================
// All the gunk below is the interaction with the Notification Service, which handles
// the proper ordering of these system-wide.
@@ -340,13 +399,20 @@ public class Toast {
final WindowManager.LayoutParams params = mParams;
params.height = WindowManager.LayoutParams.WRAP_CONTENT;
params.width = WindowManager.LayoutParams.WRAP_CONTENT;
- params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
- | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
- | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
params.format = PixelFormat.TRANSLUCENT;
params.windowAnimations = com.android.internal.R.style.Animation_Toast;
params.type = WindowManager.LayoutParams.TYPE_TOAST;
params.setTitle("Toast");
+ setInteractive(false);
+ }
+
+ private void setInteractive(boolean interactive) {
+ mParams.flags = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
+ | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
+ | (interactive
+ ? (WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
+ | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH)
+ : WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
}
/**
diff --git a/core/java/com/android/internal/app/ActionBarImpl.java b/core/java/com/android/internal/app/ActionBarImpl.java
index acbb2b1..e092fff 100644
--- a/core/java/com/android/internal/app/ActionBarImpl.java
+++ b/core/java/com/android/internal/app/ActionBarImpl.java
@@ -1210,6 +1210,10 @@ public class ActionBarImpl extends ActionBar {
mActionView.setIcon(icon);
}
+ public boolean hasIcon() {
+ return mActionView.hasIcon();
+ }
+
@Override
public void setLogo(int resId) {
mActionView.setLogo(resId);
@@ -1220,6 +1224,10 @@ public class ActionBarImpl extends ActionBar {
mActionView.setLogo(logo);
}
+ public boolean hasLogo() {
+ return mActionView.hasLogo();
+ }
+
public void setDefaultDisplayHomeAsUpEnabled(boolean enable) {
if (!mDisplayHomeAsUpSet) {
setDisplayHomeAsUpEnabled(enable);
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index c22cd26..a674776 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -16,6 +16,7 @@
package com.android.internal.app;
+import android.os.AsyncTask;
import com.android.internal.R;
import com.android.internal.content.PackageMonitor;
@@ -621,9 +622,11 @@ public class ResolverActivity extends AlertActivity implements AdapterView.OnIte
view = mInflater.inflate(
com.android.internal.R.layout.resolve_list_item, parent, false);
+ final ViewHolder holder = new ViewHolder(view);
+ view.setTag(holder);
+
// Fix the icon size even if we have different sized resources
- ImageView icon = (ImageView)view.findViewById(R.id.icon);
- ViewGroup.LayoutParams lp = (ViewGroup.LayoutParams) icon.getLayoutParams();
+ ViewGroup.LayoutParams lp = holder.icon.getLayoutParams();
lp.width = lp.height = mIconSize;
} else {
view = convertView;
@@ -633,20 +636,30 @@ public class ResolverActivity extends AlertActivity implements AdapterView.OnIte
}
private final void bindView(View view, DisplayResolveInfo info) {
- TextView text = (TextView)view.findViewById(com.android.internal.R.id.text1);
- TextView text2 = (TextView)view.findViewById(com.android.internal.R.id.text2);
- ImageView icon = (ImageView)view.findViewById(R.id.icon);
- text.setText(info.displayLabel);
+ final ViewHolder holder = (ViewHolder) view.getTag();
+ holder.text.setText(info.displayLabel);
if (mShowExtended) {
- text2.setVisibility(View.VISIBLE);
- text2.setText(info.extendedInfo);
+ holder.text2.setVisibility(View.VISIBLE);
+ holder.text2.setText(info.extendedInfo);
} else {
- text2.setVisibility(View.GONE);
+ holder.text2.setVisibility(View.GONE);
}
if (info.displayIcon == null) {
- info.displayIcon = loadIconForResolveInfo(info.ri);
+ new LoadIconTask().execute(info);
}
- icon.setImageDrawable(info.displayIcon);
+ holder.icon.setImageDrawable(info.displayIcon);
+ }
+ }
+
+ static class ViewHolder {
+ public TextView text;
+ public TextView text2;
+ public ImageView icon;
+
+ public ViewHolder(View view) {
+ text = (TextView) view.findViewById(com.android.internal.R.id.text1);
+ text2 = (TextView) view.findViewById(com.android.internal.R.id.text2);
+ icon = (ImageView) view.findViewById(R.id.icon);
}
}
@@ -660,5 +673,21 @@ public class ResolverActivity extends AlertActivity implements AdapterView.OnIte
}
}
+
+ class LoadIconTask extends AsyncTask<DisplayResolveInfo, Void, DisplayResolveInfo> {
+ @Override
+ protected DisplayResolveInfo doInBackground(DisplayResolveInfo... params) {
+ final DisplayResolveInfo info = params[0];
+ if (info.displayIcon == null) {
+ info.displayIcon = loadIconForResolveInfo(info.ri);
+ }
+ return info;
+ }
+
+ @Override
+ protected void onPostExecute(DisplayResolveInfo info) {
+ mAdapter.notifyDataSetChanged();
+ }
+ }
}
diff --git a/core/java/com/android/internal/content/PackageMonitor.java b/core/java/com/android/internal/content/PackageMonitor.java
index 424c19b..ab871fb 100644
--- a/core/java/com/android/internal/content/PackageMonitor.java
+++ b/core/java/com/android/internal/content/PackageMonitor.java
@@ -25,6 +25,7 @@ import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.UserHandle;
+import com.android.internal.os.BackgroundThread;
import java.util.HashSet;
@@ -37,10 +38,6 @@ public abstract class PackageMonitor extends android.content.BroadcastReceiver {
static final IntentFilter sNonDataFilt = new IntentFilter();
static final IntentFilter sExternalFilt = new IntentFilter();
- static final Object sLock = new Object();
- static HandlerThread sBackgroundThread;
- static Handler sBackgroundHandler;
-
static {
sPackageFilt.addAction(Intent.ACTION_PACKAGE_ADDED);
sPackageFilt.addAction(Intent.ACTION_PACKAGE_REMOVED);
@@ -79,15 +76,7 @@ public abstract class PackageMonitor extends android.content.BroadcastReceiver {
}
mRegisteredContext = context;
if (thread == null) {
- synchronized (sLock) {
- if (sBackgroundThread == null) {
- sBackgroundThread = new HandlerThread("PackageMonitor",
- android.os.Process.THREAD_PRIORITY_BACKGROUND);
- sBackgroundThread.start();
- sBackgroundHandler = new Handler(sBackgroundThread.getLooper());
- }
- mRegisteredHandler = sBackgroundHandler;
- }
+ mRegisteredHandler = BackgroundThread.getHandler();
} else {
mRegisteredHandler = new Handler(thread);
}
diff --git a/core/java/com/android/internal/os/BackgroundThread.java b/core/java/com/android/internal/os/BackgroundThread.java
new file mode 100644
index 0000000..d6f7b20
--- /dev/null
+++ b/core/java/com/android/internal/os/BackgroundThread.java
@@ -0,0 +1,54 @@
+/*
+ * 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.internal.os;
+
+import android.os.Handler;
+import android.os.HandlerThread;
+
+/**
+ * Shared singleton background thread for each process.
+ */
+public final class BackgroundThread extends HandlerThread {
+ private static BackgroundThread sInstance;
+ private static Handler sHandler;
+
+ private BackgroundThread() {
+ super("android.bg", android.os.Process.THREAD_PRIORITY_BACKGROUND);
+ }
+
+ private static void ensureThreadLocked() {
+ if (sInstance == null) {
+ sInstance = new BackgroundThread();
+ sInstance.start();
+ sHandler = new Handler(sInstance.getLooper());
+ }
+ }
+
+ public static BackgroundThread get() {
+ synchronized (BackgroundThread.class) {
+ ensureThreadLocked();
+ return sInstance;
+ }
+ }
+
+ public static Handler getHandler() {
+ synchronized (BackgroundThread.class) {
+ ensureThreadLocked();
+ return sHandler;
+ }
+ }
+}
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index a2e8d49..38391df 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -83,7 +83,7 @@ public final class BatteryStatsImpl extends BatteryStats {
private static final int MAGIC = 0xBA757475; // 'BATSTATS'
// Current on-disk Parcel version
- private static final int VERSION = 64 + (USE_OLD_HISTORY ? 1000 : 0);
+ private static final int VERSION = 65 + (USE_OLD_HISTORY ? 1000 : 0);
// Maximum number of items we will record in the history.
private static final int MAX_HISTORY_ITEMS = 2000;
@@ -659,7 +659,7 @@ public final class BatteryStatsImpl extends BatteryStats {
}
public void logState(Printer pw, String prefix) {
- pw.println(prefix + " mCount=" + mCount
+ pw.println(prefix + "mCount=" + mCount
+ " mLoadedCount=" + mLoadedCount + " mLastCount=" + mLastCount
+ " mUnpluggedCount=" + mUnpluggedCount);
pw.println(prefix + "mTotalTime=" + mTotalTime
@@ -1044,7 +1044,7 @@ public final class BatteryStatsImpl extends BatteryStats {
public void logState(Printer pw, String prefix) {
super.logState(pw, prefix);
- pw.println(prefix + "mNesting=" + mNesting + "mUpdateTime=" + mUpdateTime
+ pw.println(prefix + "mNesting=" + mNesting + " mUpdateTime=" + mUpdateTime
+ " mAcquireTime=" + mAcquireTime);
}
@@ -2236,6 +2236,14 @@ public final class BatteryStatsImpl extends BatteryStats {
getUidStatsLocked(uid).noteVideoTurnedOffLocked();
}
+ public void noteActivityResumedLocked(int uid) {
+ getUidStatsLocked(uid).noteActivityResumedLocked();
+ }
+
+ public void noteActivityPausedLocked(int uid) {
+ getUidStatsLocked(uid).noteActivityPausedLocked();
+ }
+
public void noteVibratorOnLocked(int uid, long durationMillis) {
getUidStatsLocked(uid).noteVibratorOnLocked(durationMillis);
}
@@ -2537,6 +2545,8 @@ public final class BatteryStatsImpl extends BatteryStats {
boolean mVideoTurnedOn;
StopwatchTimer mVideoTurnedOnTimer;
+ StopwatchTimer mForegroundActivityTimer;
+
BatchTimer mVibratorOnTimer;
Counter[] mUserActivityCounters;
@@ -2772,6 +2782,27 @@ public final class BatteryStatsImpl extends BatteryStats {
}
}
+ public StopwatchTimer createForegroundActivityTimerLocked() {
+ if (mForegroundActivityTimer == null) {
+ mForegroundActivityTimer = new StopwatchTimer(
+ Uid.this, FOREGROUND_ACTIVITY, null, mUnpluggables);
+ }
+ return mForegroundActivityTimer;
+ }
+
+ @Override
+ public void noteActivityResumedLocked() {
+ // We always start, since we want multiple foreground PIDs to nest
+ createForegroundActivityTimerLocked().startRunningLocked(BatteryStatsImpl.this);
+ }
+
+ @Override
+ public void noteActivityPausedLocked() {
+ if (mForegroundActivityTimer != null) {
+ mForegroundActivityTimer.stopRunningLocked(BatteryStatsImpl.this);
+ }
+ }
+
public BatchTimer createVibratorOnTimerLocked() {
if (mVibratorOnTimer == null) {
mVibratorOnTimer = new BatchTimer(Uid.this, VIBRATOR_ON,
@@ -2840,6 +2871,11 @@ public final class BatteryStatsImpl extends BatteryStats {
}
@Override
+ public Timer getForegroundActivityTimer() {
+ return mForegroundActivityTimer;
+ }
+
+ @Override
public Timer getVibratorOnTimer() {
return mVibratorOnTimer;
}
@@ -2915,6 +2951,9 @@ public final class BatteryStatsImpl extends BatteryStats {
active |= !mVideoTurnedOnTimer.reset(BatteryStatsImpl.this, false);
active |= mVideoTurnedOn;
}
+ if (mForegroundActivityTimer != null) {
+ active |= !mForegroundActivityTimer.reset(BatteryStatsImpl.this, false);
+ }
if (mVibratorOnTimer != null) {
if (mVibratorOnTimer.reset(BatteryStatsImpl.this, false)) {
mVibratorOnTimer.detach();
@@ -3014,6 +3053,10 @@ public final class BatteryStatsImpl extends BatteryStats {
mVideoTurnedOnTimer.detach();
mVideoTurnedOnTimer = null;
}
+ if (mForegroundActivityTimer != null) {
+ mForegroundActivityTimer.detach();
+ mForegroundActivityTimer = null;
+ }
if (mUserActivityCounters != null) {
for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
mUserActivityCounters[i].detach();
@@ -3095,6 +3138,12 @@ public final class BatteryStatsImpl extends BatteryStats {
} else {
out.writeInt(0);
}
+ if (mForegroundActivityTimer != null) {
+ out.writeInt(1);
+ mForegroundActivityTimer.writeToParcel(out, batteryRealtime);
+ } else {
+ out.writeInt(0);
+ }
if (mVibratorOnTimer != null) {
out.writeInt(1);
mVibratorOnTimer.writeToParcel(out, batteryRealtime);
@@ -3200,6 +3249,12 @@ public final class BatteryStatsImpl extends BatteryStats {
mVideoTurnedOnTimer = null;
}
if (in.readInt() != 0) {
+ mForegroundActivityTimer = new StopwatchTimer(
+ Uid.this, FOREGROUND_ACTIVITY, null, mUnpluggables, in);
+ } else {
+ mForegroundActivityTimer = null;
+ }
+ if (in.readInt() != 0) {
mVibratorOnTimer = new BatchTimer(Uid.this, VIBRATOR_ON,
mUnpluggables, BatteryStatsImpl.this.mOnBatteryInternal, in);
} else {
@@ -3368,14 +3423,14 @@ public final class BatteryStatsImpl extends BatteryStats {
long mSystemTime;
/**
- * Number of times the process has been started.
+ * Amount of time the process was running in the foreground.
*/
- int mStarts;
+ long mForegroundTime;
/**
- * Amount of time the process was running in the foreground.
+ * Number of times the process has been started.
*/
- long mForegroundTime;
+ int mStarts;
/**
* The amount of user time loaded from a previous save.
@@ -3388,14 +3443,14 @@ public final class BatteryStatsImpl extends BatteryStats {
long mLoadedSystemTime;
/**
- * The number of times the process has started from a previous save.
+ * The amount of foreground time loaded from a previous save.
*/
- int mLoadedStarts;
+ long mLoadedForegroundTime;
/**
- * The amount of foreground time loaded from a previous save.
+ * The number of times the process has started from a previous save.
*/
- long mLoadedForegroundTime;
+ int mLoadedStarts;
/**
* The amount of user time loaded from the previous run.
@@ -3408,14 +3463,14 @@ public final class BatteryStatsImpl extends BatteryStats {
long mLastSystemTime;
/**
- * The number of times the process has started from the previous run.
+ * The amount of foreground time loaded from the previous run
*/
- int mLastStarts;
+ long mLastForegroundTime;
/**
- * The amount of foreground time loaded from the previous run
+ * The number of times the process has started from the previous run.
*/
- long mLastForegroundTime;
+ int mLastStarts;
/**
* The amount of user time when last unplugged.
@@ -3428,14 +3483,14 @@ public final class BatteryStatsImpl extends BatteryStats {
long mUnpluggedSystemTime;
/**
- * The number of times the process has started before unplugged.
+ * The amount of foreground time since unplugged.
*/
- int mUnpluggedStarts;
+ long mUnpluggedForegroundTime;
/**
- * The amount of foreground time since unplugged.
+ * The number of times the process has started before unplugged.
*/
- long mUnpluggedForegroundTime;
+ int mUnpluggedStarts;
SamplingCounter[] mSpeedBins;
@@ -3449,8 +3504,8 @@ public final class BatteryStatsImpl extends BatteryStats {
public void unplug(long elapsedRealtime, long batteryUptime, long batteryRealtime) {
mUnpluggedUserTime = mUserTime;
mUnpluggedSystemTime = mSystemTime;
- mUnpluggedStarts = mStarts;
mUnpluggedForegroundTime = mForegroundTime;
+ mUnpluggedStarts = mStarts;
}
public void plug(long elapsedRealtime, long batteryUptime, long batteryRealtime) {
@@ -5357,6 +5412,9 @@ public final class BatteryStatsImpl extends BatteryStats {
u.createVideoTurnedOnTimerLocked().readSummaryFromParcelLocked(in);
}
if (in.readInt() != 0) {
+ u.createForegroundActivityTimerLocked().readSummaryFromParcelLocked(in);
+ }
+ if (in.readInt() != 0) {
u.createVibratorOnTimerLocked().readSummaryFromParcelLocked(in);
}
@@ -5410,6 +5468,7 @@ public final class BatteryStatsImpl extends BatteryStats {
Uid.Proc p = u.getProcessStatsLocked(procName);
p.mUserTime = p.mLoadedUserTime = in.readLong();
p.mSystemTime = p.mLoadedSystemTime = in.readLong();
+ p.mForegroundTime = p.mLoadedForegroundTime = in.readLong();
p.mStarts = p.mLoadedStarts = in.readInt();
int NSB = in.readInt();
if (NSB > 100) {
@@ -5559,6 +5618,12 @@ public final class BatteryStatsImpl extends BatteryStats {
} else {
out.writeInt(0);
}
+ if (u.mForegroundActivityTimer != null) {
+ out.writeInt(1);
+ u.mForegroundActivityTimer.writeSummaryFromParcelLocked(out, NOWREAL);
+ } else {
+ out.writeInt(0);
+ }
if (u.mVibratorOnTimer != null) {
out.writeInt(1);
u.mVibratorOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
@@ -5628,6 +5693,7 @@ public final class BatteryStatsImpl extends BatteryStats {
Uid.Proc ps = ent.getValue();
out.writeLong(ps.mUserTime);
out.writeLong(ps.mSystemTime);
+ out.writeLong(ps.mForegroundTime);
out.writeInt(ps.mStarts);
final int N = ps.mSpeedBins.length;
out.writeInt(N);
@@ -5903,7 +5969,7 @@ public final class BatteryStatsImpl extends BatteryStats {
updateKernelWakelocksLocked();
}
- public void dumpLocked(PrintWriter pw) {
+ public void dumpLocked(PrintWriter pw, boolean isUnpluggedOnly) {
if (DEBUG) {
Printer pr = new PrintWriterPrinter(pw);
pr.println("*** Screen timer:");
@@ -5935,7 +6001,7 @@ public final class BatteryStatsImpl extends BatteryStats {
pr.println("*** Mobile ifaces:");
pr.println(mMobileIfaces.toString());
}
- super.dumpLocked(pw);
+ super.dumpLocked(pw, isUnpluggedOnly);
}
private NetworkStats mNetworkSummaryCache;
diff --git a/core/java/com/android/internal/os/ProcessStats.java b/core/java/com/android/internal/os/ProcessStats.java
index b1bb8c1..bd0914d 100644
--- a/core/java/com/android/internal/os/ProcessStats.java
+++ b/core/java/com/android/internal/os/ProcessStats.java
@@ -518,6 +518,10 @@ public class ProcessStats {
return pids;
}
+ /**
+ * Returns the total time (in clock ticks, or 1/100 sec) spent executing in
+ * both user and system code.
+ */
public long getCpuTimeForPid(int pid) {
final String statFile = "/proc/" + pid + "/stat";
final long[] statsData = mSinglePidStatsData;
@@ -531,9 +535,9 @@ public class ProcessStats {
}
/**
- * Returns the times spent at each CPU speed, since the last call to this method. If this
- * is the first time, it will return 1 for each value.
- * @return relative times spent at different speed steps.
+ * Returns the delta time (in clock ticks, or 1/100 sec) spent at each CPU
+ * speed, since the last call to this method. If this is the first call, it
+ * will return 1 for each value.
*/
public long[] getLastCpuSpeedTimes() {
if (mCpuSpeedTimes == null) {
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index fb22df7..ccc0089 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -22,9 +22,11 @@ import static libcore.io.OsConstants.S_IRWXO;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.net.LocalServerSocket;
+import android.opengl.EGL14;
import android.os.Debug;
import android.os.Process;
import android.os.SystemClock;
+import android.os.SystemProperties;
import android.os.Trace;
import android.util.EventLog;
import android.util.Log;
@@ -59,9 +61,10 @@ import java.util.ArrayList;
* @hide
*/
public class ZygoteInit {
-
private static final String TAG = "Zygote";
+ private static final String PROPERTY_DISABLE_OPENGL_PRELOADING = "ro.zygote.disable_gl_preload";
+
private static final String ANDROID_SOCKET_ENV = "ANDROID_SOCKET_zygote";
private static final int LOG_BOOT_PROGRESS_PRELOAD_START = 3020;
@@ -227,6 +230,13 @@ public class ZygoteInit {
static void preload() {
preloadClasses();
preloadResources();
+ preloadOpenGL();
+ }
+
+ private static void preloadOpenGL() {
+ if (!SystemProperties.getBoolean(PROPERTY_DISABLE_OPENGL_PRELOADING, false)) {
+ EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY);
+ }
}
/**
@@ -479,7 +489,6 @@ public class ZygoteInit {
OsConstants.CAP_NET_BIND_SERVICE,
OsConstants.CAP_NET_BROADCAST,
OsConstants.CAP_NET_RAW,
- OsConstants.CAP_SYS_BOOT,
OsConstants.CAP_SYS_MODULE,
OsConstants.CAP_SYS_NICE,
OsConstants.CAP_SYS_RESOURCE,
diff --git a/core/java/com/android/internal/policy/IKeyguardExitCallback.aidl b/core/java/com/android/internal/policy/IKeyguardExitCallback.aidl
new file mode 100644
index 0000000..3702712
--- /dev/null
+++ b/core/java/com/android/internal/policy/IKeyguardExitCallback.aidl
@@ -0,0 +1,20 @@
+/*
+ * 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.internal.policy;
+
+oneway interface IKeyguardExitCallback {
+ void onKeyguardExitResult(boolean success);
+}
diff --git a/core/java/com/android/internal/policy/IKeyguardService.aidl b/core/java/com/android/internal/policy/IKeyguardService.aidl
new file mode 100644
index 0000000..880464d
--- /dev/null
+++ b/core/java/com/android/internal/policy/IKeyguardService.aidl
@@ -0,0 +1,44 @@
+/*
+ * 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.internal.policy;
+
+import com.android.internal.policy.IKeyguardShowCallback;
+import com.android.internal.policy.IKeyguardExitCallback;
+
+import android.os.Bundle;
+
+interface IKeyguardService {
+ boolean isShowing();
+ boolean isSecure();
+ boolean isShowingAndNotHidden();
+ boolean isInputRestricted();
+ boolean isDismissable();
+ oneway void verifyUnlock(IKeyguardExitCallback callback);
+ oneway void keyguardDone(boolean authenticated, boolean wakeup);
+ oneway void setHidden(boolean isHidden);
+ oneway void dismiss();
+ oneway void onWakeKeyWhenKeyguardShowing(int keyCode);
+ oneway void onWakeMotionWhenKeyguardShowing();
+ oneway void onDreamingStarted();
+ oneway void onDreamingStopped();
+ oneway void onScreenTurnedOff(int reason);
+ oneway void onScreenTurnedOn(IKeyguardShowCallback callback);
+ oneway void setKeyguardEnabled(boolean enabled);
+ oneway void onSystemReady();
+ oneway void doKeyguardTimeout(in Bundle options);
+ oneway void setCurrentUser(int userId);
+ oneway void showAssistant();
+}
diff --git a/core/java/com/android/internal/policy/IKeyguardShowCallback.aidl b/core/java/com/android/internal/policy/IKeyguardShowCallback.aidl
new file mode 100644
index 0000000..a2784d9
--- /dev/null
+++ b/core/java/com/android/internal/policy/IKeyguardShowCallback.aidl
@@ -0,0 +1,20 @@
+/*
+ * 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.internal.policy;
+
+oneway interface IKeyguardShowCallback {
+ void onShown(IBinder windowToken);
+}
diff --git a/core/java/com/android/internal/util/IndentingPrintWriter.java b/core/java/com/android/internal/util/IndentingPrintWriter.java
index d01a817..6fddd09 100644
--- a/core/java/com/android/internal/util/IndentingPrintWriter.java
+++ b/core/java/com/android/internal/util/IndentingPrintWriter.java
@@ -68,6 +68,10 @@ public class IndentingPrintWriter extends PrintWriter {
print(key + "=" + String.valueOf(value) + " ");
}
+ public void printHexPair(String key, int value) {
+ print(key + "=0x" + Integer.toHexString(value) + " ");
+ }
+
@Override
public void write(char[] buf, int offset, int count) {
final int indentLength = mIndentBuilder.length();
diff --git a/core/java/com/android/internal/view/RotationPolicy.java b/core/java/com/android/internal/view/RotationPolicy.java
index 95130c8..70e2bfc 100644
--- a/core/java/com/android/internal/view/RotationPolicy.java
+++ b/core/java/com/android/internal/view/RotationPolicy.java
@@ -17,12 +17,13 @@
package com.android.internal.view;
import android.content.Context;
+import android.content.pm.PackageManager;
import android.database.ContentObserver;
import android.net.Uri;
import android.os.AsyncTask;
+import android.os.Build;
import android.os.Handler;
import android.os.RemoteException;
-import android.os.ServiceManager;
import android.os.UserHandle;
import android.provider.Settings;
import android.util.Log;
@@ -40,6 +41,21 @@ public final class RotationPolicy {
}
/**
+ * Gets whether the device supports rotation. In general such a
+ * device has an accelerometer and has the portrait and landscape
+ * features.
+ *
+ * @param context Context for accessing system resources.
+ * @return Whether the device supports rotation.
+ */
+ public static boolean isRotationSupported(Context context) {
+ PackageManager pm = context.getPackageManager();
+ return pm.hasSystemFeature(PackageManager.FEATURE_SENSOR_ACCELEROMETER)
+ && pm.hasSystemFeature(PackageManager.FEATURE_SCREEN_PORTRAIT)
+ && pm.hasSystemFeature(PackageManager.FEATURE_SCREEN_LANDSCAPE);
+ }
+
+ /**
* Returns true if the device supports the rotation-lock toggle feature
* in the system UI or system bar.
*
@@ -48,7 +64,8 @@ public final class RotationPolicy {
* settings.
*/
public static boolean isRotationLockToggleSupported(Context context) {
- return context.getResources().getConfiguration().smallestScreenWidthDp >= 600;
+ return isRotationSupported(context)
+ && context.getResources().getConfiguration().smallestScreenWidthDp >= 600;
}
/**
diff --git a/core/java/com/android/internal/widget/ActionBarView.java b/core/java/com/android/internal/widget/ActionBarView.java
index dda1a10..f2bd522 100644
--- a/core/java/com/android/internal/widget/ActionBarView.java
+++ b/core/java/com/android/internal/widget/ActionBarView.java
@@ -16,24 +16,12 @@
package com.android.internal.widget;
-import com.android.internal.R;
-import com.android.internal.view.menu.ActionMenuItem;
-import com.android.internal.view.menu.ActionMenuPresenter;
-import com.android.internal.view.menu.ActionMenuView;
-import com.android.internal.view.menu.MenuBuilder;
-import com.android.internal.view.menu.MenuItemImpl;
-import com.android.internal.view.menu.MenuPresenter;
-import com.android.internal.view.menu.MenuView;
-import com.android.internal.view.menu.SubMenuBuilder;
-
import android.animation.LayoutTransition;
import android.app.ActionBar;
import android.app.ActionBar.OnNavigationListener;
-import android.app.Activity;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Configuration;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
@@ -42,7 +30,6 @@ import android.os.Parcelable;
import android.text.Layout;
import android.text.TextUtils;
import android.util.AttributeSet;
-import android.util.Log;
import android.view.CollapsibleActionView;
import android.view.Gravity;
import android.view.LayoutInflater;
@@ -62,6 +49,15 @@ import android.widget.ProgressBar;
import android.widget.Spinner;
import android.widget.SpinnerAdapter;
import android.widget.TextView;
+import com.android.internal.R;
+import com.android.internal.view.menu.ActionMenuItem;
+import com.android.internal.view.menu.ActionMenuPresenter;
+import com.android.internal.view.menu.ActionMenuView;
+import com.android.internal.view.menu.MenuBuilder;
+import com.android.internal.view.menu.MenuItemImpl;
+import com.android.internal.view.menu.MenuPresenter;
+import com.android.internal.view.menu.MenuView;
+import com.android.internal.view.menu.SubMenuBuilder;
/**
* @hide
@@ -188,34 +184,8 @@ public class ActionBarView extends AbsActionBarView {
ActionBar.NAVIGATION_MODE_STANDARD);
mTitle = a.getText(R.styleable.ActionBar_title);
mSubtitle = a.getText(R.styleable.ActionBar_subtitle);
-
mLogo = a.getDrawable(R.styleable.ActionBar_logo);
- if (mLogo == null) {
- if (context instanceof Activity) {
- try {
- mLogo = pm.getActivityLogo(((Activity) context).getComponentName());
- } catch (NameNotFoundException e) {
- Log.e(TAG, "Activity component name not found!", e);
- }
- }
- if (mLogo == null) {
- mLogo = appInfo.loadLogo(pm);
- }
- }
-
mIcon = a.getDrawable(R.styleable.ActionBar_icon);
- if (mIcon == null) {
- if (context instanceof Activity) {
- try {
- mIcon = pm.getActivityIcon(((Activity) context).getComponentName());
- } catch (NameNotFoundException e) {
- Log.e(TAG, "Activity component name not found!", e);
- }
- }
- if (mIcon == null) {
- mIcon = appInfo.loadIcon(pm);
- }
- }
final LayoutInflater inflater = LayoutInflater.from(context);
@@ -729,7 +699,11 @@ public class ActionBarView extends AbsActionBarView {
}
public void setIcon(int resId) {
- setIcon(mContext.getResources().getDrawable(resId));
+ setIcon(resId != 0 ? mContext.getResources().getDrawable(resId) : null);
+ }
+
+ public boolean hasIcon() {
+ return mIcon != null;
}
public void setLogo(Drawable logo) {
@@ -740,7 +714,11 @@ public class ActionBarView extends AbsActionBarView {
}
public void setLogo(int resId) {
- setLogo(mContext.getResources().getDrawable(resId));
+ setLogo(resId != 0 ? mContext.getResources().getDrawable(resId) : null);
+ }
+
+ public boolean hasLogo() {
+ return mLogo != null;
}
public void setNavigationMode(int mode) {
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index d3ead26..521ba81 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -16,6 +16,7 @@
package com.android.internal.widget;
+import android.Manifest;
import android.app.ActivityManagerNative;
import android.app.admin.DevicePolicyManager;
import android.appwidget.AppWidgetManager;
@@ -149,6 +150,8 @@ public class LockPatternUtils {
private DevicePolicyManager mDevicePolicyManager;
private ILockSettings mLockSettingsService;
+ private final boolean mMultiUserMode;
+
// The current user is set by KeyguardViewMediator and shared by all LockPatternUtils.
private static volatile int sCurrentUserId = UserHandle.USER_NULL;
@@ -170,6 +173,12 @@ public class LockPatternUtils {
public LockPatternUtils(Context context) {
mContext = context;
mContentResolver = context.getContentResolver();
+
+ // If this is being called by the system or by an application like keyguard that
+ // has permision INTERACT_ACROSS_USERS, then LockPatternUtils will operate in multi-user
+ // mode where calls are for the current user rather than the user of the calling process.
+ mMultiUserMode = context.checkCallingOrSelfPermission(
+ Manifest.permission.INTERACT_ACROSS_USERS_FULL) == PackageManager.PERMISSION_GRANTED;
}
private ILockSettings getLockSettings() {
@@ -264,13 +273,12 @@ public class LockPatternUtils {
}
private int getCurrentOrCallingUserId() {
- int callingUid = Binder.getCallingUid();
- if (callingUid == android.os.Process.SYSTEM_UID) {
+ if (mMultiUserMode) {
// TODO: This is a little inefficient. See if all users of this are able to
// handle USER_CURRENT and pass that instead.
return getCurrentUser();
} else {
- return UserHandle.getUserId(callingUid);
+ return UserHandle.getCallingUserId();
}
}
diff --git a/core/java/com/android/internal/widget/TransportControlView.java b/core/java/com/android/internal/widget/TransportControlView.java
deleted file mode 100644
index ca797eb..0000000
--- a/core/java/com/android/internal/widget/TransportControlView.java
+++ /dev/null
@@ -1,515 +0,0 @@
-/*
- * 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.internal.widget;
-
-import java.lang.ref.WeakReference;
-
-import com.android.internal.widget.LockScreenWidgetCallback;
-import com.android.internal.widget.LockScreenWidgetInterface;
-
-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.MediaMetadataRetriever;
-import android.media.RemoteControlClient;
-import android.media.IRemoteControlDisplay;
-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 com.android.internal.R;
-
-public class TransportControlView extends FrameLayout implements OnClickListener,
- LockScreenWidgetInterface {
-
- 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 MAXDIM = 512;
- 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 LockScreenWidgetCallback mWidgetCallbacks;
- private IRemoteControlDisplayWeak mIRCD;
-
- /**
- * 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.
- if (mWidgetCallbacks != null) {
- mWidgetCallbacks.requestHide(TransportControlView.this);
- }
- }
- if (DEBUG) Log.v(TAG, "New genId = " + msg.arg1 + ", clearing = " + msg.arg2);
- mClientGeneration = msg.arg1;
- mClientIntent = (PendingIntent) msg.obj;
- break;
-
- }
- }
- };
-
- /**
- * 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,
- long currentPosMs, float speed) {
- 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 setTransportControlInfo(int generationId, int flags, int posCapabilities) {
- 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 TransportControlView(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);
- }
-
- 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 (mPopulateMetadataWhenAttached != null) {
- updateMetadata(mPopulateMetadataWhenAttached);
- mPopulateMetadataWhenAttached = null;
- }
- if (!mAttached) {
- if (DEBUG) Log.v(TAG, "Registering TCV " + this);
- mAudioManager.registerRemoteControlDisplay(mIRCD);
- }
- mAttached = true;
- }
-
- @Override
- public void onDetachedFromWindow() {
- super.onDetachedFromWindow();
- if (mAttached) {
- if (DEBUG) Log.v(TAG, "Unregistering TCV " + this);
- mAudioManager.unregisterRemoteControlDisplay(mIRCD);
- }
- mAttached = false;
- }
-
- @Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- super.onMeasure(widthMeasureSpec, heightMeasureSpec);
- int dim = Math.min(MAXDIM, Math.max(getWidth(), getHeight()));
-// Log.v(TAG, "setting max bitmap size: " + dim + "x" + dim);
-// mAudioManager.remoteControlDisplayUsesBitmapSize(mIRCD, dim, dim);
- }
-
- 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);
- }
-
- 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;
- boolean showIfHidden = false;
- switch (state) {
- case RemoteControlClient.PLAYSTATE_ERROR:
- imageResId = com.android.internal.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 = com.android.internal.R.string.lockscreen_transport_play_description;
- break;
-
- case RemoteControlClient.PLAYSTATE_PLAYING:
- imageResId = com.android.internal.R.drawable.ic_media_pause;
- imageDescId = com.android.internal.R.string.lockscreen_transport_pause_description;
- showIfHidden = true;
- break;
-
- case RemoteControlClient.PLAYSTATE_BUFFERING:
- imageResId = com.android.internal.R.drawable.ic_media_stop;
- imageDescId = com.android.internal.R.string.lockscreen_transport_stop_description;
- showIfHidden = true;
- break;
-
- case RemoteControlClient.PLAYSTATE_PAUSED:
- default:
- imageResId = com.android.internal.R.drawable.ic_media_play;
- imageDescId = com.android.internal.R.string.lockscreen_transport_play_description;
- showIfHidden = false;
- break;
- }
- mBtnPlay.setImageResource(imageResId);
- mBtnPlay.setContentDescription(getResources().getString(imageDescId));
- if (showIfHidden && mWidgetCallbacks != null && !mWidgetCallbacks.isVisible(this)) {
- mWidgetCallbacks.requestShow(this);
- }
- mCurrentPlayState = state;
- }
-
- static class SavedState extends BaseSavedState {
- boolean wasShowing;
-
- SavedState(Parcelable superState) {
- super(superState);
- }
-
- private SavedState(Parcel in) {
- super(in);
- this.wasShowing = in.readInt() != 0;
- }
-
- @Override
- public void writeToParcel(Parcel out, int flags) {
- super.writeToParcel(out, flags);
- out.writeInt(this.wasShowing ? 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() {
- if (DEBUG) Log.v(TAG, "onSaveInstanceState()");
- Parcelable superState = super.onSaveInstanceState();
- SavedState ss = new SavedState(superState);
- ss.wasShowing = mWidgetCallbacks != null && mWidgetCallbacks.isVisible(this);
- return ss;
- }
-
- @Override
- public void onRestoreInstanceState(Parcelable state) {
- if (DEBUG) Log.v(TAG, "onRestoreInstanceState()");
- if (!(state instanceof SavedState)) {
- super.onRestoreInstanceState(state);
- return;
- }
- SavedState ss = (SavedState) state;
- super.onRestoreInstanceState(ss.getSuperState());
- if (ss.wasShowing && mWidgetCallbacks != null) {
- mWidgetCallbacks.requestShow(this);
- }
- }
-
- 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);
- if (mWidgetCallbacks != null) {
- mWidgetCallbacks.userActivity(this);
- }
- }
- }
-
- 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 void setCallback(LockScreenWidgetCallback callback) {
- mWidgetCallbacks = callback;
- }
-
- 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;
- }
- }
-}
diff --git a/core/java/com/android/internal/widget/multiwaveview/TargetDrawable.java b/core/java/com/android/internal/widget/multiwaveview/TargetDrawable.java
index 30f5f2f..16bec16 100644
--- a/core/java/com/android/internal/widget/multiwaveview/TargetDrawable.java
+++ b/core/java/com/android/internal/widget/multiwaveview/TargetDrawable.java
@@ -46,36 +46,6 @@ public class TargetDrawable {
private boolean mEnabled = true;
private final int mResourceId;
- /* package */ static class DrawableWithAlpha extends Drawable {
- private float mAlpha = 1.0f;
- private Drawable mRealDrawable;
- public DrawableWithAlpha(Drawable realDrawable) {
- mRealDrawable = realDrawable;
- }
- public void setAlpha(float alpha) {
- mAlpha = alpha;
- }
- public float getAlpha() {
- return mAlpha;
- }
- public void draw(Canvas canvas) {
- mRealDrawable.setAlpha((int) Math.round(mAlpha * 255f));
- mRealDrawable.draw(canvas);
- }
- @Override
- public void setAlpha(int alpha) {
- mRealDrawable.setAlpha(alpha);
- }
- @Override
- public void setColorFilter(ColorFilter cf) {
- mRealDrawable.setColorFilter(cf);
- }
- @Override
- public int getOpacity() {
- return mRealDrawable.getOpacity();
- }
- }
-
public TargetDrawable(Resources res, int resId) {
mResourceId = resId;
setDrawable(res, resId);
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index 337c1ec..188941b 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -17,6 +17,10 @@ endif
LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES
+# When built as part of the system image we can enable certian non-NDK compliant
+# Skia optimizations.
+LOCAL_CFLAGS += -DSK_BUILD_FOR_ANDROID_FRAMEWORK
+
LOCAL_SRC_FILES:= \
AndroidRuntime.cpp \
Time.cpp \
@@ -51,6 +55,7 @@ LOCAL_SRC_FILES:= \
android_view_KeyEvent.cpp \
android_view_KeyCharacterMap.cpp \
android_view_HardwareRenderer.cpp \
+ android_view_GraphicBuffer.cpp \
android_view_GLES20DisplayList.cpp \
android_view_GLES20Canvas.cpp \
android_view_MotionEvent.cpp \
@@ -158,10 +163,6 @@ LOCAL_C_INCLUDES += \
$(call include-path-for, libhardware)/hardware \
$(call include-path-for, libhardware_legacy)/hardware_legacy \
$(TOP)/frameworks/av/include \
- external/skia/include/core \
- external/skia/include/effects \
- external/skia/include/images \
- external/skia/include/ports \
external/skia/src/core \
external/skia/src/images \
external/skia/include/utils \
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index ca658da..bfa2e06 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -24,7 +24,6 @@
#include <utils/Log.h>
#include <utils/misc.h>
#include <binder/Parcel.h>
-#include <utils/StringArray.h>
#include <utils/threads.h>
#include <cutils/properties.h>
@@ -117,6 +116,7 @@ extern int register_android_graphics_SurfaceTexture(JNIEnv* env);
extern int register_android_graphics_Xfermode(JNIEnv* env);
extern int register_android_graphics_PixelFormat(JNIEnv* env);
extern int register_android_view_DisplayEventReceiver(JNIEnv* env);
+extern int register_android_view_GraphicBuffer(JNIEnv* env);
extern int register_android_view_GLES20DisplayList(JNIEnv* env);
extern int register_android_view_GLES20Canvas(JNIEnv* env);
extern int register_android_view_HardwareRenderer(JNIEnv* env);
@@ -1112,6 +1112,7 @@ static const RegJNIRec gRegJNI[] = {
REG_JNI(register_android_nio_utils),
REG_JNI(register_android_graphics_PixelFormat),
REG_JNI(register_android_graphics_Graphics),
+ REG_JNI(register_android_view_GraphicBuffer),
REG_JNI(register_android_view_GLES20DisplayList),
REG_JNI(register_android_view_GLES20Canvas),
REG_JNI(register_android_view_HardwareRenderer),
diff --git a/core/jni/android/graphics/BitmapFactory.cpp b/core/jni/android/graphics/BitmapFactory.cpp
index daabce3..d6549a1 100644
--- a/core/jni/android/graphics/BitmapFactory.cpp
+++ b/core/jni/android/graphics/BitmapFactory.cpp
@@ -211,19 +211,17 @@ static jobject doDecode(JNIEnv* env, SkStream* stream, jobject padding,
SkBitmap* bitmap;
bool useExistingBitmap = false;
+ unsigned int existingBufferSize = 0;
if (javaBitmap == NULL) {
bitmap = new SkBitmap;
} else {
- if (sampleSize != 1) {
- return nullObjectReturn("SkImageDecoder: Cannot reuse bitmap with sampleSize != 1");
- }
-
bitmap = (SkBitmap*) env->GetIntField(javaBitmap, gBitmap_nativeBitmapFieldID);
- // only reuse the provided bitmap if it is immutable
+ // only reuse the provided bitmap if it is mutable
if (!bitmap->isImmutable()) {
useExistingBitmap = true;
// config of supplied bitmap overrules config set in options
prefConfig = bitmap->getConfig();
+ existingBufferSize = GraphicsJNI::getBitmapAllocationByteCount(env, javaBitmap);
} else {
ALOGW("Unable to reuse an immutable bitmap as an image decoder target.");
bitmap = new SkBitmap;
@@ -252,6 +250,26 @@ static jobject doDecode(JNIEnv* env, SkStream* stream, jobject padding,
decodeMode = SkImageDecoder::kDecodeBounds_Mode;
}
+ if (javaBitmap != NULL) {
+ // If we're reusing the pixelref from an existing bitmap, decode the bounds and
+ // reinitialize the native object for the new content, keeping the pixelRef
+ SkPixelRef* pixelRef = bitmap->pixelRef();
+ SkSafeRef(pixelRef);
+
+ SkBitmap boundsBitmap;
+ decoder->decode(stream, &boundsBitmap, prefConfig, SkImageDecoder::kDecodeBounds_Mode);
+ stream->rewind();
+
+ if (boundsBitmap.getSize() > existingBufferSize) {
+ return nullObjectReturn("bitmap marked for reuse too small to contain decoded data");
+ }
+
+ bitmap->setConfig(boundsBitmap.config(), boundsBitmap.width(), boundsBitmap.height(), 0);
+ bitmap->setPixelRef(pixelRef);
+ SkSafeUnref(pixelRef);
+ GraphicsJNI::reinitBitmap(env, javaBitmap);
+ }
+
SkBitmap* decoded;
if (willScale) {
decoded = new SkBitmap;
diff --git a/core/jni/android/graphics/Graphics.cpp b/core/jni/android/graphics/Graphics.cpp
index d4c7600..7c420ad 100644
--- a/core/jni/android/graphics/Graphics.cpp
+++ b/core/jni/android/graphics/Graphics.cpp
@@ -152,6 +152,8 @@ static jfieldID gPointF_yFieldID;
static jclass gBitmap_class;
static jfieldID gBitmap_nativeInstanceID;
static jmethodID gBitmap_constructorMethodID;
+static jmethodID gBitmap_reinitMethodID;
+static jmethodID gBitmap_getAllocationByteCountMethodID;
static jclass gBitmapConfig_class;
static jfieldID gBitmapConfig_nativeInstanceID;
@@ -363,6 +365,15 @@ jobject GraphicsJNI::createBitmap(JNIEnv* env, SkBitmap* bitmap, bool isMutable,
return createBitmap(env, bitmap, NULL, isMutable, ninepatch, NULL, density);
}
+void GraphicsJNI::reinitBitmap(JNIEnv* env, jobject javaBitmap)
+{
+ env->CallVoidMethod(javaBitmap, gBitmap_reinitMethodID);
+}
+
+int GraphicsJNI::getBitmapAllocationByteCount(JNIEnv* env, jobject javaBitmap)
+{
+ return env->CallIntMethod(javaBitmap, gBitmap_getAllocationByteCountMethodID);
+}
jobject GraphicsJNI::createBitmapRegionDecoder(JNIEnv* env, SkBitmapRegionDecoder* bitmap)
{
@@ -398,7 +409,7 @@ static JNIEnv* vm2env(JavaVM* vm)
///////////////////////////////////////////////////////////////////////////////
AndroidPixelRef::AndroidPixelRef(JNIEnv* env, void* storage, size_t size, jbyteArray storageObj,
- SkColorTable* ctable) : SkMallocPixelRef(storage, size, ctable) {
+ SkColorTable* ctable) : SkMallocPixelRef(storage, size, ctable, (storageObj == NULL)) {
SkASSERT(storage);
SkASSERT(env);
@@ -423,10 +434,6 @@ AndroidPixelRef::~AndroidPixelRef() {
env->DeleteGlobalRef(fStorageObj);
}
fStorageObj = NULL;
-
- // Set this to NULL to prevent the SkMallocPixelRef destructor
- // from freeing the memory.
- fStorage = NULL;
}
}
@@ -588,6 +595,8 @@ int register_android_graphics_Graphics(JNIEnv* env)
gBitmap_nativeInstanceID = getFieldIDCheck(env, gBitmap_class, "mNativeBitmap", "I");
gBitmap_constructorMethodID = env->GetMethodID(gBitmap_class, "<init>",
"(I[BZ[B[II)V");
+ gBitmap_reinitMethodID = env->GetMethodID(gBitmap_class, "reinit", "()V");
+ gBitmap_getAllocationByteCountMethodID = env->GetMethodID(gBitmap_class, "getAllocationByteCount", "()I");
gBitmapRegionDecoder_class = make_globalref(env, "android/graphics/BitmapRegionDecoder");
gBitmapRegionDecoder_constructorMethodID = env->GetMethodID(gBitmapRegionDecoder_class, "<init>", "(I)V");
diff --git a/core/jni/android/graphics/GraphicsJNI.h b/core/jni/android/graphics/GraphicsJNI.h
index c5b06f5..69b67cb 100644
--- a/core/jni/android/graphics/GraphicsJNI.h
+++ b/core/jni/android/graphics/GraphicsJNI.h
@@ -59,6 +59,10 @@ public:
static jobject createBitmap(JNIEnv* env, SkBitmap* bitmap, bool isMutable,
jbyteArray ninepatch, int density = -1);
+ static void reinitBitmap(JNIEnv* env, jobject javaBitmap);
+
+ static int getBitmapAllocationByteCount(JNIEnv* env, jobject javaBitmap);
+
static jobject createRegion(JNIEnv* env, SkRegion* region);
static jobject createBitmapRegionDecoder(JNIEnv* env, SkBitmapRegionDecoder* bitmap);
diff --git a/core/jni/android/graphics/HarfBuzzNGFaceSkia.cpp b/core/jni/android/graphics/HarfBuzzNGFaceSkia.cpp
index ce31c5b..a75efcf 100644
--- a/core/jni/android/graphics/HarfBuzzNGFaceSkia.cpp
+++ b/core/jni/android/graphics/HarfBuzzNGFaceSkia.cpp
@@ -138,16 +138,15 @@ static hb_font_funcs_t* harfbuzzSkiaGetFontFuncs()
hb_blob_t* harfbuzzSkiaReferenceTable(hb_face_t* face, hb_tag_t tag, void* userData)
{
SkTypeface* typeface = reinterpret_cast<SkTypeface*>(userData);
- SkFontID uniqueID = typeface->uniqueID();
- const size_t tableSize = SkFontHost::GetTableSize(uniqueID, tag);
+ const size_t tableSize = typeface->getTableSize(tag);
if (!tableSize)
return 0;
char* buffer = reinterpret_cast<char*>(malloc(tableSize));
if (!buffer)
return 0;
- size_t actualSize = SkFontHost::GetTableData(uniqueID, tag, 0, tableSize, buffer);
+ size_t actualSize = typeface->getTableData(tag, 0, tableSize, buffer);
if (tableSize != actualSize) {
free(buffer);
return 0;
diff --git a/core/jni/android/graphics/Paint.cpp b/core/jni/android/graphics/Paint.cpp
index 5454c08..380f061 100644
--- a/core/jni/android/graphics/Paint.cpp
+++ b/core/jni/android/graphics/Paint.cpp
@@ -58,6 +58,10 @@ static JMetricsID gFontMetricsInt_fieldID;
static void defaultSettingsForAndroid(SkPaint* paint) {
// GlyphID encoding is required because we are using Harfbuzz shaping
paint->setTextEncoding(SkPaint::kGlyphID_TextEncoding);
+
+ SkPaintOptionsAndroid paintOpts = paint->getPaintOptionsAndroid();
+ paintOpts.setUseFontFallbacks(true);
+ paint->setPaintOptionsAndroid(paintOpts);
}
class SkPaintGlue {
@@ -300,7 +304,10 @@ public:
ScopedUtfChars localeChars(env, locale);
char langTag[ULOC_FULLNAME_CAPACITY];
toLanguageTag(langTag, ULOC_FULLNAME_CAPACITY, localeChars.c_str());
- obj->setLanguage(SkLanguage(langTag));
+
+ SkPaintOptionsAndroid paintOpts = obj->getPaintOptionsAndroid();
+ paintOpts.setLanguage(langTag);
+ obj->setPaintOptionsAndroid(paintOpts);
}
static jfloat getTextSize(JNIEnv* env, jobject paint) {
diff --git a/core/jni/android/graphics/TextLayoutCache.cpp b/core/jni/android/graphics/TextLayoutCache.cpp
index b2cf9c1..73f3639 100644
--- a/core/jni/android/graphics/TextLayoutCache.cpp
+++ b/core/jni/android/graphics/TextLayoutCache.cpp
@@ -20,7 +20,6 @@
#include "TextLayoutCache.h"
#include "TextLayout.h"
-#include "SkFontHost.h"
#include "SkTypeface_android.h"
#include "HarfBuzzNGFaceSkia.h"
#include <unicode/unistr.h>
@@ -219,7 +218,8 @@ void TextLayoutCache::dumpCacheStats() {
*/
TextLayoutCacheKey::TextLayoutCacheKey(): start(0), count(0), contextCount(0),
dirFlags(0), typeface(NULL), textSize(0), textSkewX(0), textScaleX(0), flags(0),
- hinting(SkPaint::kNo_Hinting), variant(SkPaint::kDefault_Variant), language() {
+ hinting(SkPaint::kNo_Hinting) {
+ paintOpts.setUseFontFallbacks(true);
}
TextLayoutCacheKey::TextLayoutCacheKey(const SkPaint* paint, const UChar* text,
@@ -233,8 +233,7 @@ TextLayoutCacheKey::TextLayoutCacheKey(const SkPaint* paint, const UChar* text,
textScaleX = paint->getTextScaleX();
flags = paint->getFlags();
hinting = paint->getHinting();
- variant = paint->getFontVariant();
- language = paint->getLanguage();
+ paintOpts = paint->getPaintOptionsAndroid();
}
TextLayoutCacheKey::TextLayoutCacheKey(const TextLayoutCacheKey& other) :
@@ -249,8 +248,7 @@ TextLayoutCacheKey::TextLayoutCacheKey(const TextLayoutCacheKey& other) :
textScaleX(other.textScaleX),
flags(other.flags),
hinting(other.hinting),
- variant(other.variant),
- language(other.language) {
+ paintOpts(other.paintOpts) {
}
int TextLayoutCacheKey::compare(const TextLayoutCacheKey& lhs, const TextLayoutCacheKey& rhs) {
@@ -284,11 +282,8 @@ int TextLayoutCacheKey::compare(const TextLayoutCacheKey& lhs, const TextLayoutC
deltaInt = lhs.dirFlags - rhs.dirFlags;
if (deltaInt) return (deltaInt);
- deltaInt = lhs.variant - rhs.variant;
- if (deltaInt) return (deltaInt);
-
- if (lhs.language < rhs.language) return -1;
- if (lhs.language > rhs.language) return +1;
+ if (lhs.paintOpts != rhs.paintOpts)
+ return memcmp(&lhs.paintOpts, &rhs.paintOpts, sizeof(SkPaintOptionsAndroid));
return memcmp(lhs.getText(), rhs.getText(), lhs.contextCount * sizeof(UChar));
}
@@ -307,7 +302,7 @@ hash_t TextLayoutCacheKey::hash() const {
hash = JenkinsHashMix(hash, hash_type(textScaleX));
hash = JenkinsHashMix(hash, flags);
hash = JenkinsHashMix(hash, hinting);
- hash = JenkinsHashMix(hash, variant);
+ hash = JenkinsHashMix(hash, paintOpts.getFontVariant());
// Note: leaving out language is not problematic, as equality comparisons
// are still valid - the only bad thing that could happen is collisions.
hash = JenkinsHashMixShorts(hash, getText(), contextCount);
@@ -319,6 +314,7 @@ hash_t TextLayoutCacheKey::hash() const {
*/
TextLayoutValue::TextLayoutValue(size_t contextCount) :
mTotalAdvance(0), mElapsedTime(0) {
+ mBounds.setEmpty();
// Give a hint for advances and glyphs vectors size
mAdvances.setCapacity(contextCount);
mGlyphs.setCapacity(contextCount);
@@ -346,11 +342,11 @@ TextLayoutShaper::~TextLayoutShaper() {
hb_buffer_destroy(mBuffer);
}
-void TextLayoutShaper::computeValues(TextLayoutValue* value, const SkPaint* paint, const UChar* chars,
- size_t start, size_t count, size_t contextCount, int dirFlags) {
-
+void TextLayoutShaper::computeValues(TextLayoutValue* value, const SkPaint* paint,
+ const UChar* chars, size_t start, size_t count, size_t contextCount, int dirFlags) {
computeValues(paint, chars, start, count, contextCount, dirFlags,
- &value->mAdvances, &value->mTotalAdvance, &value->mGlyphs, &value->mPos);
+ &value->mAdvances, &value->mTotalAdvance, &value->mBounds,
+ &value->mGlyphs, &value->mPos);
#if DEBUG_ADVANCES
ALOGD("Advances - start = %d, count = %d, contextCount = %d, totalAdvance = %f", start, count,
contextCount, value->mTotalAdvance);
@@ -359,7 +355,7 @@ void TextLayoutShaper::computeValues(TextLayoutValue* value, const SkPaint* pain
void TextLayoutShaper::computeValues(const SkPaint* paint, const UChar* chars,
size_t start, size_t count, size_t contextCount, int dirFlags,
- Vector<jfloat>* const outAdvances, jfloat* outTotalAdvance,
+ Vector<jfloat>* const outAdvances, jfloat* outTotalAdvance, SkRect* outBounds,
Vector<jchar>* const outGlyphs, Vector<jfloat>* const outPos) {
*outTotalAdvance = 0;
if (!count) {
@@ -455,7 +451,7 @@ void TextLayoutShaper::computeValues(const SkPaint* paint, const UChar* chars,
i, startRun, lengthRun, isRTL);
#endif
computeRunValues(paint, chars, startRun, lengthRun, contextCount, isRTL,
- outAdvances, outTotalAdvance, outGlyphs, outPos);
+ outAdvances, outTotalAdvance, outBounds, outGlyphs, outPos);
}
}
@@ -479,7 +475,7 @@ void TextLayoutShaper::computeValues(const SkPaint* paint, const UChar* chars,
"-- run-start = %d, run-len = %d, isRTL = %d", start, count, isRTL);
#endif
computeRunValues(paint, chars, start, count, contextCount, isRTL,
- outAdvances, outTotalAdvance, outGlyphs, outPos);
+ outAdvances, outTotalAdvance, outBounds, outGlyphs, outPos);
}
#if DEBUG_GLYPHS
@@ -676,7 +672,7 @@ static void logGlyphs(hb_buffer_t* buffer) {
void TextLayoutShaper::computeRunValues(const SkPaint* paint, const UChar* contextChars,
size_t start, size_t count, size_t contextCount, bool isRTL,
- Vector<jfloat>* const outAdvances, jfloat* outTotalAdvance,
+ Vector<jfloat>* const outAdvances, jfloat* outTotalAdvance, SkRect* outBounds,
Vector<jchar>* const outGlyphs, Vector<jfloat>* const outPos) {
if (!count) {
// We cannot shape an empty run.
@@ -698,8 +694,7 @@ void TextLayoutShaper::computeRunValues(const SkPaint* paint, const UChar* conte
mShapingPaint.setTextScaleX(paint->getTextScaleX());
mShapingPaint.setFlags(paint->getFlags());
mShapingPaint.setHinting(paint->getHinting());
- mShapingPaint.setFontVariant(paint->getFontVariant());
- mShapingPaint.setLanguage(paint->getLanguage());
+ mShapingPaint.setPaintOptionsAndroid(paint->getPaintOptionsAndroid());
// Split the BiDi run into Script runs. Harfbuzz will populate the pos, length and script
// into the shaperItem
@@ -750,12 +745,22 @@ void TextLayoutShaper::computeRunValues(const SkPaint* paint, const UChar* conte
size_t cluster = info[i].cluster - start;
float xAdvance = HBFixedToFloat(positions[i].x_advance);
outAdvances->replaceAt(outAdvances->itemAt(cluster) + xAdvance, cluster);
- outGlyphs->add(info[i].codepoint + glyphBaseCount);
+ jchar glyphId = info[i].codepoint + glyphBaseCount;
+ outGlyphs->add(glyphId);
float xo = HBFixedToFloat(positions[i].x_offset);
float yo = -HBFixedToFloat(positions[i].y_offset);
- outPos->add(totalAdvance + xo + yo * skewX);
- outPos->add(yo);
+
+ float xpos = totalAdvance + xo + yo * skewX;
+ float ypos = yo;
+ outPos->add(xpos);
+ outPos->add(ypos);
totalAdvance += xAdvance;
+
+ // TODO: consider using glyph cache
+ const SkGlyph& metrics = mShapingPaint.getGlyphMetrics(glyphId, NULL);
+ outBounds->join(xpos + metrics.fLeft, ypos + metrics.fTop,
+ xpos + metrics.fLeft + metrics.fWidth, ypos + metrics.fTop + metrics.fHeight);
+
}
}
@@ -839,7 +844,7 @@ size_t TextLayoutShaper::shapeFontRun(const SkPaint* paint) {
if (typeface) {
SkSafeRef(typeface);
} else {
- typeface = SkFontHost::CreateTypeface(NULL, NULL, SkTypeface::kNormal);
+ typeface = SkTypeface::CreateFromName(NULL, SkTypeface::kNormal);
#if DEBUG_GLYPHS
ALOGD("Using Default Typeface (normal style)");
#endif
diff --git a/core/jni/android/graphics/TextLayoutCache.h b/core/jni/android/graphics/TextLayoutCache.h
index 5414a11..54704ec 100644
--- a/core/jni/android/graphics/TextLayoutCache.h
+++ b/core/jni/android/graphics/TextLayoutCache.h
@@ -28,7 +28,6 @@
#include <utils/Singleton.h>
#include <SkAutoKern.h>
-#include <SkLanguage.h>
#include <SkPaint.h>
#include <SkTemplates.h>
#include <SkTypeface.h>
@@ -104,8 +103,7 @@ private:
SkScalar textScaleX;
uint32_t flags;
SkPaint::Hinting hinting;
- SkPaint::FontVariant variant;
- SkLanguage language;
+ SkPaintOptionsAndroid paintOpts;
}; // TextLayoutCacheKey
@@ -134,6 +132,7 @@ public:
inline const jfloat* getAdvances() const { return mAdvances.array(); }
inline size_t getAdvancesCount() const { return mAdvances.size(); }
inline jfloat getTotalAdvance() const { return mTotalAdvance; }
+ inline const SkRect& getBounds() const { return mBounds; }
inline const jchar* getGlyphs() const { return mGlyphs.array(); }
inline size_t getGlyphsCount() const { return mGlyphs.size(); }
inline const jfloat* getPos() const { return mPos.array(); }
@@ -150,6 +149,11 @@ public:
jfloat mTotalAdvance;
/**
+ * Bounds containing all glyphs
+ */
+ SkRect mBounds;
+
+ /**
* Glyphs vector
*/
Vector<jchar> mGlyphs;
@@ -208,12 +212,12 @@ private:
void computeValues(const SkPaint* paint, const UChar* chars,
size_t start, size_t count, size_t contextCount, int dirFlags,
- Vector<jfloat>* const outAdvances, jfloat* outTotalAdvance,
+ Vector<jfloat>* const outAdvances, jfloat* outTotalAdvance, SkRect* outBounds,
Vector<jchar>* const outGlyphs, Vector<jfloat>* const outPos);
void computeRunValues(const SkPaint* paint, const UChar* chars,
size_t start, size_t count, size_t contextCount, bool isRTL,
- Vector<jfloat>* const outAdvances, jfloat* outTotalAdvance,
+ Vector<jfloat>* const outAdvances, jfloat* outTotalAdvance, SkRect* outBounds,
Vector<jchar>* const outGlyphs, Vector<jfloat>* const outPos);
SkTypeface* setCachedTypeface(SkTypeface** typeface, hb_script_t script, SkTypeface::Style style);
diff --git a/core/jni/android_hardware_Camera.cpp b/core/jni/android_hardware_Camera.cpp
index 686e4e3..dec4cd4 100644
--- a/core/jni/android_hardware_Camera.cpp
+++ b/core/jni/android_hardware_Camera.cpp
@@ -586,6 +586,30 @@ static void android_hardware_Camera_setPreviewTexture(JNIEnv *env,
}
}
+static void android_hardware_Camera_setPreviewCallbackSurface(JNIEnv *env,
+ jobject thiz, jobject jSurface)
+{
+ ALOGV("setPreviewCallbackSurface");
+ JNICameraContext* context;
+ sp<Camera> camera = get_native_camera(env, thiz, &context);
+ if (camera == 0) return;
+
+ sp<IGraphicBufferProducer> gbp;
+ sp<Surface> surface;
+ if (jSurface) {
+ surface = android_view_Surface_getSurface(env, jSurface);
+ if (surface != NULL) {
+ gbp = surface->getIGraphicBufferProducer();
+ }
+ }
+ // Clear out normal preview callbacks
+ context->setCallbackMode(env, false, false);
+ // Then set up callback surface
+ if (camera->setPreviewCallbackTarget(gbp) != NO_ERROR) {
+ jniThrowException(env, "java/io/IOException", "setPreviewCallbackTarget failed");
+ }
+}
+
static void android_hardware_Camera_startPreview(JNIEnv *env, jobject thiz)
{
ALOGV("startPreview");
@@ -881,6 +905,9 @@ static JNINativeMethod camMethods[] = {
{ "setPreviewTexture",
"(Landroid/graphics/SurfaceTexture;)V",
(void *)android_hardware_Camera_setPreviewTexture },
+ { "setPreviewCallbackSurface",
+ "(Landroid/view/Surface;)V",
+ (void *)android_hardware_Camera_setPreviewCallbackSurface },
{ "startPreview",
"()V",
(void *)android_hardware_Camera_startPreview },
diff --git a/core/jni/android_net_wifi_Wifi.cpp b/core/jni/android_net_wifi_Wifi.cpp
index 9537ac4..08962e2 100644
--- a/core/jni/android_net_wifi_Wifi.cpp
+++ b/core/jni/android_net_wifi_Wifi.cpp
@@ -33,11 +33,11 @@ namespace android {
static jint DBG = false;
-static int doCommand(const char *ifname, const char *cmd, char *replybuf, int replybuflen)
+static int doCommand(const char *ifname, char *cmd, char *replybuf, int replybuflen)
{
size_t reply_len = replybuflen - 1;
- if (::wifi_command(ifname, cmd, replybuf, &reply_len) != 0)
+ if (::wifi_command(ifname, cmd, BUF_SIZE, replybuf, &reply_len) != 0)
return -1;
else {
// Strip off trailing newline
diff --git a/core/jni/android_opengl_EGL14.cpp b/core/jni/android_opengl_EGL14.cpp
index 664af07..48babb3 100644
--- a/core/jni/android_opengl_EGL14.cpp
+++ b/core/jni/android_opengl_EGL14.cpp
@@ -136,7 +136,7 @@ android_eglGetError
(JNIEnv *_env, jobject _this) {
EGLint _returnValue = (EGLint) 0;
_returnValue = eglGetError();
- return _returnValue;
+ return (jint)_returnValue;
}
/* EGLDisplay eglGetDisplay ( EGLNativeDisplayType display_id ) */
@@ -230,7 +230,7 @@ exit:
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
}
- return _returnValue;
+ return (jboolean)_returnValue;
}
/* EGLBoolean eglTerminate ( EGLDisplay dpy ) */
@@ -243,7 +243,7 @@ android_eglTerminate
_returnValue = eglTerminate(
(EGLDisplay)dpy_native
);
- return _returnValue;
+ return (jboolean)_returnValue;
}
/* const char * eglQueryString ( EGLDisplay dpy, EGLint name ) */
@@ -331,7 +331,7 @@ exit:
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
}
- return _returnValue;
+ return (jboolean)_returnValue;
}
/* EGLBoolean eglChooseConfig ( EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config ) */
@@ -454,7 +454,7 @@ exit:
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
}
- return _returnValue;
+ return (jboolean)_returnValue;
}
/* EGLBoolean eglGetConfigAttrib ( EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value ) */
@@ -509,7 +509,7 @@ exit:
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
}
- return _returnValue;
+ return (jboolean)_returnValue;
}
/* EGLSurface eglCreateWindowSurface ( EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list ) */
@@ -753,7 +753,7 @@ android_eglDestroySurface
(EGLDisplay)dpy_native,
(EGLSurface)surface_native
);
- return _returnValue;
+ return (jboolean)_returnValue;
}
/* EGLBoolean eglQuerySurface ( EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value ) */
@@ -808,7 +808,7 @@ exit:
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
}
- return _returnValue;
+ return (jboolean)_returnValue;
}
/* EGLBoolean eglBindAPI ( EGLenum api ) */
@@ -819,7 +819,7 @@ android_eglBindAPI
_returnValue = eglBindAPI(
(EGLenum)api
);
- return _returnValue;
+ return (jboolean)_returnValue;
}
/* EGLenum eglQueryAPI ( void ) */
@@ -828,7 +828,7 @@ android_eglQueryAPI
(JNIEnv *_env, jobject _this) {
EGLenum _returnValue = (EGLenum) 0;
_returnValue = eglQueryAPI();
- return _returnValue;
+ return (jint)_returnValue;
}
/* EGLBoolean eglWaitClient ( void ) */
@@ -837,7 +837,7 @@ android_eglWaitClient
(JNIEnv *_env, jobject _this) {
EGLBoolean _returnValue = (EGLBoolean) 0;
_returnValue = eglWaitClient();
- return _returnValue;
+ return (jboolean)_returnValue;
}
/* EGLBoolean eglReleaseThread ( void ) */
@@ -846,7 +846,7 @@ android_eglReleaseThread
(JNIEnv *_env, jobject _this) {
EGLBoolean _returnValue = (EGLBoolean) 0;
_returnValue = eglReleaseThread();
- return _returnValue;
+ return (jboolean)_returnValue;
}
/* EGLSurface eglCreatePbufferFromClientBuffer ( EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list ) */
@@ -927,7 +927,7 @@ android_eglSurfaceAttrib
(EGLint)attribute,
(EGLint)value
);
- return _returnValue;
+ return (jboolean)_returnValue;
}
/* EGLBoolean eglBindTexImage ( EGLDisplay dpy, EGLSurface surface, EGLint buffer ) */
@@ -943,7 +943,7 @@ android_eglBindTexImage
(EGLSurface)surface_native,
(EGLint)buffer
);
- return _returnValue;
+ return (jboolean)_returnValue;
}
/* EGLBoolean eglReleaseTexImage ( EGLDisplay dpy, EGLSurface surface, EGLint buffer ) */
@@ -959,7 +959,7 @@ android_eglReleaseTexImage
(EGLSurface)surface_native,
(EGLint)buffer
);
- return _returnValue;
+ return (jboolean)_returnValue;
}
/* EGLBoolean eglSwapInterval ( EGLDisplay dpy, EGLint interval ) */
@@ -973,7 +973,7 @@ android_eglSwapInterval
(EGLDisplay)dpy_native,
(EGLint)interval
);
- return _returnValue;
+ return (jboolean)_returnValue;
}
/* EGLContext eglCreateContext ( EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list ) */
@@ -1052,7 +1052,7 @@ android_eglDestroyContext
(EGLDisplay)dpy_native,
(EGLContext)ctx_native
);
- return _returnValue;
+ return (jboolean)_returnValue;
}
/* EGLBoolean eglMakeCurrent ( EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx ) */
@@ -1071,7 +1071,7 @@ android_eglMakeCurrent
(EGLSurface)read_native,
(EGLContext)ctx_native
);
- return _returnValue;
+ return (jboolean)_returnValue;
}
/* EGLContext eglGetCurrentContext ( void ) */
@@ -1155,7 +1155,7 @@ exit:
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
}
- return _returnValue;
+ return (jboolean)_returnValue;
}
/* EGLBoolean eglWaitGL ( void ) */
@@ -1164,7 +1164,7 @@ android_eglWaitGL
(JNIEnv *_env, jobject _this) {
EGLBoolean _returnValue = (EGLBoolean) 0;
_returnValue = eglWaitGL();
- return _returnValue;
+ return (jboolean)_returnValue;
}
/* EGLBoolean eglWaitNative ( EGLint engine ) */
@@ -1175,7 +1175,7 @@ android_eglWaitNative
_returnValue = eglWaitNative(
(EGLint)engine
);
- return _returnValue;
+ return (jboolean)_returnValue;
}
/* EGLBoolean eglSwapBuffers ( EGLDisplay dpy, EGLSurface surface ) */
@@ -1190,7 +1190,7 @@ android_eglSwapBuffers
(EGLDisplay)dpy_native,
(EGLSurface)surface_native
);
- return _returnValue;
+ return (jboolean)_returnValue;
}
/* EGLBoolean eglCopyBuffers ( EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target ) */
diff --git a/core/jni/android_opengl_GLES10.cpp b/core/jni/android_opengl_GLES10.cpp
index 336c0ec..cc34e99 100644
--- a/core/jni/android_opengl_GLES10.cpp
+++ b/core/jni/android_opengl_GLES10.cpp
@@ -63,6 +63,12 @@ static void glVertexAttribPointerBounds(GLuint indx, GLint size, GLenum type,
glVertexAttribPointer(indx, size, type, normalized, stride, pointer);
}
#endif
+#ifdef GL_ES_VERSION_3_0
+static void glVertexAttribIPointerBounds(GLuint indx, GLint size, GLenum type,
+ GLsizei stride, const GLvoid *pointer, GLsizei count) {
+ glVertexAttribIPointer(indx, size, type, stride, pointer);
+}
+#endif
}
/* Cache method IDs each time the class is loaded. */
@@ -288,6 +294,7 @@ getarray
int _needed = 0;
params = (CTYPE *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ _remaining /= sizeof(CTYPE); // convert from bytes to item count
_needed = getNeededCount(pname);
// if we didn't find this pname, we just assume the user passed
// an array of the right size -- this might happen with extensions
@@ -1184,7 +1191,7 @@ android_glGetError__
(JNIEnv *_env, jobject _this) {
GLenum _returnValue;
_returnValue = glGetError();
- return _returnValue;
+ return (jint)_returnValue;
}
/* void glGetIntegerv ( GLenum pname, GLint *params ) */
diff --git a/core/jni/android_opengl_GLES10Ext.cpp b/core/jni/android_opengl_GLES10Ext.cpp
index 59e63e1..9284384 100644
--- a/core/jni/android_opengl_GLES10Ext.cpp
+++ b/core/jni/android_opengl_GLES10Ext.cpp
@@ -63,6 +63,12 @@ static void glVertexAttribPointerBounds(GLuint indx, GLint size, GLenum type,
glVertexAttribPointer(indx, size, type, normalized, stride, pointer);
}
#endif
+#ifdef GL_ES_VERSION_3_0
+static void glVertexAttribIPointerBounds(GLuint indx, GLint size, GLenum type,
+ GLsizei stride, const GLvoid *pointer, GLsizei count) {
+ glVertexAttribIPointer(indx, size, type, stride, pointer);
+}
+#endif
}
/* Cache method IDs each time the class is loaded. */
@@ -288,6 +294,7 @@ getarray
int _needed = 0;
params = (CTYPE *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ _remaining /= sizeof(CTYPE); // convert from bytes to item count
_needed = getNeededCount(pname);
// if we didn't find this pname, we just assume the user passed
// an array of the right size -- this might happen with extensions
@@ -395,7 +402,7 @@ exit:
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
}
- return _returnValue;
+ return (jint)_returnValue;
}
/* GLbitfield glQueryMatrixxOES ( GLfixed *mantissa, GLint *exponent ) */
@@ -452,7 +459,7 @@ exit:
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
}
- return _returnValue;
+ return (jint)_returnValue;
}
static const char *classPathName = "android/opengl/GLES10Ext";
diff --git a/core/jni/android_opengl_GLES11.cpp b/core/jni/android_opengl_GLES11.cpp
index 352f5bf..871e84d 100644
--- a/core/jni/android_opengl_GLES11.cpp
+++ b/core/jni/android_opengl_GLES11.cpp
@@ -63,6 +63,12 @@ static void glVertexAttribPointerBounds(GLuint indx, GLint size, GLenum type,
glVertexAttribPointer(indx, size, type, normalized, stride, pointer);
}
#endif
+#ifdef GL_ES_VERSION_3_0
+static void glVertexAttribIPointerBounds(GLuint indx, GLint size, GLenum type,
+ GLsizei stride, const GLvoid *pointer, GLsizei count) {
+ glVertexAttribIPointer(indx, size, type, stride, pointer);
+}
+#endif
}
/* Cache method IDs each time the class is loaded. */
@@ -288,6 +294,7 @@ getarray
int _needed = 0;
params = (CTYPE *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ _remaining /= sizeof(CTYPE); // convert from bytes to item count
_needed = getNeededCount(pname);
// if we didn't find this pname, we just assume the user passed
// an array of the right size -- this might happen with extensions
@@ -571,7 +578,7 @@ android_glColorPointer__IIII
(GLint)size,
(GLenum)type,
(GLsizei)stride,
- (const GLvoid *)offset
+ (GLvoid *)offset
);
}
@@ -672,7 +679,7 @@ android_glDrawElements__IIII
(GLenum)mode,
(GLsizei)count,
(GLenum)type,
- (const GLvoid *)offset
+ (GLvoid *)offset
);
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -2263,7 +2270,7 @@ android_glIsBuffer__I
_returnValue = glIsBuffer(
(GLuint)buffer
);
- return _returnValue;
+ return (jboolean)_returnValue;
}
/* GLboolean glIsEnabled ( GLenum cap ) */
@@ -2274,7 +2281,7 @@ android_glIsEnabled__I
_returnValue = glIsEnabled(
(GLenum)cap
);
- return _returnValue;
+ return (jboolean)_returnValue;
}
/* GLboolean glIsTexture ( GLuint texture ) */
@@ -2285,7 +2292,7 @@ android_glIsTexture__I
_returnValue = glIsTexture(
(GLuint)texture
);
- return _returnValue;
+ return (jboolean)_returnValue;
}
/* void glNormalPointer ( GLenum type, GLsizei stride, GLint offset ) */
@@ -2295,7 +2302,7 @@ android_glNormalPointer__III
glNormalPointer(
(GLenum)type,
(GLsizei)stride,
- (const GLvoid *)offset
+ (GLvoid *)offset
);
}
@@ -2522,7 +2529,7 @@ android_glTexCoordPointer__IIII
(GLint)size,
(GLenum)type,
(GLsizei)stride,
- (const GLvoid *)offset
+ (GLvoid *)offset
);
}
@@ -2930,7 +2937,7 @@ android_glVertexPointer__IIII
(GLint)size,
(GLenum)type,
(GLsizei)stride,
- (const GLvoid *)offset
+ (GLvoid *)offset
);
}
diff --git a/core/jni/android_opengl_GLES11Ext.cpp b/core/jni/android_opengl_GLES11Ext.cpp
index c91baa2..3e038ad 100644
--- a/core/jni/android_opengl_GLES11Ext.cpp
+++ b/core/jni/android_opengl_GLES11Ext.cpp
@@ -63,6 +63,12 @@ static void glVertexAttribPointerBounds(GLuint indx, GLint size, GLenum type,
glVertexAttribPointer(indx, size, type, normalized, stride, pointer);
}
#endif
+#ifdef GL_ES_VERSION_3_0
+static void glVertexAttribIPointerBounds(GLuint indx, GLint size, GLenum type,
+ GLsizei stride, const GLvoid *pointer, GLsizei count) {
+ glVertexAttribIPointer(indx, size, type, stride, pointer);
+}
+#endif
}
/* Cache method IDs each time the class is loaded. */
@@ -288,6 +294,7 @@ getarray
int _needed = 0;
params = (CTYPE *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ _remaining /= sizeof(CTYPE); // convert from bytes to item count
_needed = getNeededCount(pname);
// if we didn't find this pname, we just assume the user passed
// an array of the right size -- this might happen with extensions
@@ -2129,7 +2136,7 @@ android_glIsRenderbufferOES__I
_returnValue = glIsRenderbufferOES(
(GLuint)renderbuffer
);
- return _returnValue;
+ return (jboolean)_returnValue;
}
/* void glBindRenderbufferOES ( GLenum target, GLuint renderbuffer ) */
@@ -2422,7 +2429,7 @@ android_glIsFramebufferOES__I
_returnValue = glIsFramebufferOES(
(GLuint)framebuffer
);
- return _returnValue;
+ return (jboolean)_returnValue;
}
/* void glBindFramebufferOES ( GLenum target, GLuint framebuffer ) */
@@ -2615,7 +2622,7 @@ android_glCheckFramebufferStatusOES__I
_returnValue = glCheckFramebufferStatusOES(
(GLenum)target
);
- return _returnValue;
+ return (jint)_returnValue;
}
/* void glFramebufferRenderbufferOES ( GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer ) */
diff --git a/core/jni/android_opengl_GLES20.cpp b/core/jni/android_opengl_GLES20.cpp
index 4179785..9bc69ae 100644
--- a/core/jni/android_opengl_GLES20.cpp
+++ b/core/jni/android_opengl_GLES20.cpp
@@ -63,6 +63,12 @@ static void glVertexAttribPointerBounds(GLuint indx, GLint size, GLenum type,
glVertexAttribPointer(indx, size, type, normalized, stride, pointer);
}
#endif
+#ifdef GL_ES_VERSION_3_0
+static void glVertexAttribIPointerBounds(GLuint indx, GLint size, GLenum type,
+ GLsizei stride, const GLvoid *pointer, GLsizei count) {
+ glVertexAttribIPointer(indx, size, type, stride, pointer);
+}
+#endif
}
/* Cache method IDs each time the class is loaded. */
@@ -288,6 +294,7 @@ getarray
int _needed = 0;
params = (CTYPE *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ _remaining /= sizeof(CTYPE); // convert from bytes to item count
_needed = getNeededCount(pname);
// if we didn't find this pname, we just assume the user passed
// an array of the right size -- this might happen with extensions
@@ -549,7 +556,7 @@ android_glCheckFramebufferStatus__I
_returnValue = glCheckFramebufferStatus(
(GLenum)target
);
- return _returnValue;
+ return (jint)_returnValue;
}
/* void glClear ( GLbitfield mask ) */
@@ -709,7 +716,7 @@ android_glCreateProgram__
(JNIEnv *_env, jobject _this) {
GLuint _returnValue;
_returnValue = glCreateProgram();
- return _returnValue;
+ return (jint)_returnValue;
}
/* GLuint glCreateShader ( GLenum type ) */
@@ -720,7 +727,7 @@ android_glCreateShader__I
_returnValue = glCreateShader(
(GLenum)type
);
- return _returnValue;
+ return (jint)_returnValue;
}
/* void glCullFace ( GLenum mode ) */
@@ -1172,7 +1179,7 @@ android_glDrawElements__IIII
(GLenum)mode,
(GLsizei)count,
(GLenum)type,
- (const GLvoid *)offset
+ (GLvoid *)offset
);
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -2466,7 +2473,7 @@ exit:
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
}
- return _returnValue;
+ return (jint)_returnValue;
}
/* void glGetBooleanv ( GLenum pname, GLboolean *params ) */
@@ -2576,7 +2583,7 @@ android_glGetError__
(JNIEnv *_env, jobject _this) {
GLenum _returnValue;
_returnValue = glGetError();
- return _returnValue;
+ return (jint)_returnValue;
}
/* void glGetFloatv ( GLenum pname, GLfloat *params ) */
@@ -3614,7 +3621,7 @@ exit:
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
}
- return _returnValue;
+ return (jint)_returnValue;
}
/* void glGetVertexAttribfv ( GLuint index, GLenum pname, GLfloat *params ) */
@@ -3855,7 +3862,7 @@ android_glIsBuffer__I
_returnValue = glIsBuffer(
(GLuint)buffer
);
- return _returnValue;
+ return (jboolean)_returnValue;
}
/* GLboolean glIsEnabled ( GLenum cap ) */
@@ -3866,7 +3873,7 @@ android_glIsEnabled__I
_returnValue = glIsEnabled(
(GLenum)cap
);
- return _returnValue;
+ return (jboolean)_returnValue;
}
/* GLboolean glIsFramebuffer ( GLuint framebuffer ) */
@@ -3877,7 +3884,7 @@ android_glIsFramebuffer__I
_returnValue = glIsFramebuffer(
(GLuint)framebuffer
);
- return _returnValue;
+ return (jboolean)_returnValue;
}
/* GLboolean glIsProgram ( GLuint program ) */
@@ -3888,7 +3895,7 @@ android_glIsProgram__I
_returnValue = glIsProgram(
(GLuint)program
);
- return _returnValue;
+ return (jboolean)_returnValue;
}
/* GLboolean glIsRenderbuffer ( GLuint renderbuffer ) */
@@ -3899,7 +3906,7 @@ android_glIsRenderbuffer__I
_returnValue = glIsRenderbuffer(
(GLuint)renderbuffer
);
- return _returnValue;
+ return (jboolean)_returnValue;
}
/* GLboolean glIsShader ( GLuint shader ) */
@@ -3910,7 +3917,7 @@ android_glIsShader__I
_returnValue = glIsShader(
(GLuint)shader
);
- return _returnValue;
+ return (jboolean)_returnValue;
}
/* GLboolean glIsTexture ( GLuint texture ) */
@@ -3921,7 +3928,7 @@ android_glIsTexture__I
_returnValue = glIsTexture(
(GLuint)texture
);
- return _returnValue;
+ return (jboolean)_returnValue;
}
/* void glLineWidth ( GLfloat width ) */
@@ -5975,7 +5982,7 @@ android_glVertexAttribPointer__IIIZII
(GLenum)type,
(GLboolean)normalized,
(GLsizei)stride,
- (const GLvoid *)offset
+ (GLvoid *)offset
);
}
diff --git a/core/jni/android_opengl_GLES30.cpp b/core/jni/android_opengl_GLES30.cpp
index 3c50aa0..832d643 100644
--- a/core/jni/android_opengl_GLES30.cpp
+++ b/core/jni/android_opengl_GLES30.cpp
@@ -294,6 +294,7 @@ getarray
int _needed = 0;
params = (CTYPE *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ _remaining /= sizeof(CTYPE); // convert from bytes to item count
_needed = getNeededCount(pname);
// if we didn't find this pname, we just assume the user passed
// an array of the right size -- this might happen with extensions
diff --git a/core/jni/android_os_Debug.cpp b/core/jni/android_os_Debug.cpp
index 2883c10..f4cf2ee 100644
--- a/core/jni/android_os_Debug.cpp
+++ b/core/jni/android_os_Debug.cpp
@@ -43,6 +43,7 @@ enum {
HEAP_UNKNOWN,
HEAP_DALVIK,
HEAP_NATIVE,
+ HEAP_DALVIK_OTHER,
HEAP_STACK,
HEAP_CURSOR,
HEAP_ASHMEM,
@@ -52,38 +53,56 @@ enum {
HEAP_APK,
HEAP_TTF,
HEAP_DEX,
+ HEAP_OAT,
+ HEAP_ART,
HEAP_UNKNOWN_MAP,
+ HEAP_DALVIK_NORMAL,
+ HEAP_DALVIK_LARGE,
+ HEAP_DALVIK_LINEARALLOC,
+ HEAP_DALVIK_ACCOUNTING,
+ HEAP_DALVIK_CODE_CACHE,
+
_NUM_HEAP,
+ _NUM_EXCLUSIVE_HEAP = HEAP_UNKNOWN_MAP+1,
_NUM_CORE_HEAP = HEAP_NATIVE+1
};
struct stat_fields {
jfieldID pss_field;
+ jfieldID pssSwappable_field;
jfieldID privateDirty_field;
jfieldID sharedDirty_field;
+ jfieldID privateClean_field;
+ jfieldID sharedClean_field;
};
struct stat_field_names {
const char* pss_name;
+ const char* pssSwappable_name;
const char* privateDirty_name;
const char* sharedDirty_name;
+ const char* privateClean_name;
+ const char* sharedClean_name;
};
static stat_fields stat_fields[_NUM_CORE_HEAP];
static stat_field_names stat_field_names[_NUM_CORE_HEAP] = {
- { "otherPss", "otherPrivateDirty", "otherSharedDirty" },
- { "dalvikPss", "dalvikPrivateDirty", "dalvikSharedDirty" },
- { "nativePss", "nativePrivateDirty", "nativeSharedDirty" }
+ { "otherPss", "otherSwappablePss", "otherPrivateDirty", "otherSharedDirty", "otherPrivateClean", "otherSharedClean" },
+ { "dalvikPss", "dalvikSwappablePss", "dalvikPrivateDirty", "dalvikSharedDirty", "dalvikPrivateClean", "dalvikSharedClean" },
+ { "nativePss", "nativeSwappablePss", "nativePrivateDirty", "nativeSharedDirty", "nativePrivateClean", "nativeSharedClean" }
};
jfieldID otherStats_field;
struct stats_t {
int pss;
+ int swappablePss;
int privateDirty;
int sharedDirty;
+ int privateClean;
+ int sharedClean;
};
#define BINDER_STATS "/proc/binder/stats"
@@ -124,9 +143,11 @@ static void read_mapinfo(FILE *fp, stats_t* stats)
int len, nameLen;
bool skip, done = false;
- unsigned size = 0, resident = 0, pss = 0;
+ unsigned size = 0, resident = 0, pss = 0, swappable_pss = 0;
+ float sharing_proportion = 0.0;
unsigned shared_clean = 0, shared_dirty = 0;
unsigned private_clean = 0, private_dirty = 0;
+ bool is_swappable = false;
unsigned referenced = 0;
unsigned temp;
@@ -137,6 +158,7 @@ static void read_mapinfo(FILE *fp, stats_t* stats)
int name_pos;
int whichHeap = HEAP_UNKNOWN;
+ int subHeap = HEAP_UNKNOWN;
int prevHeap = HEAP_UNKNOWN;
if(fgets(line, sizeof(line), fp) == 0) return;
@@ -145,7 +167,9 @@ static void read_mapinfo(FILE *fp, stats_t* stats)
prevHeap = whichHeap;
prevEnd = end;
whichHeap = HEAP_UNKNOWN;
+ subHeap = HEAP_UNKNOWN;
skip = false;
+ is_swappable = false;
len = strlen(line);
if (len < 1) return;
@@ -160,30 +184,68 @@ static void read_mapinfo(FILE *fp, stats_t* stats)
name = line + name_pos;
nameLen = strlen(name);
- if ((strstr(name, "[heap]") == name) ||
- (strstr(name, "/dev/ashmem/libc malloc") == name)) {
+ if ((strstr(name, "[heap]") == name)) {
whichHeap = HEAP_NATIVE;
- } else if (strstr(name, "/dev/ashmem/dalvik-") == name) {
- whichHeap = HEAP_DALVIK;
- } else if (strstr(name, "[stack") == name) {
+ } else if (strncmp(name, "/dev/ashmem", 11) == 0) {
+ if (strncmp(name, "/dev/ashmem/dalvik-", 19) == 0) {
+ whichHeap = HEAP_DALVIK_OTHER;
+ if (strstr(name, "/dev/ashmem/dalvik-LinearAlloc") == name) {
+ subHeap = HEAP_DALVIK_LINEARALLOC;
+ } else if ((strstr(name, "/dev/ashmem/dalvik-mark") == name) ||
+ (strstr(name, "/dev/ashmem/dalvik-allocspace alloc space live-bitmap") == name) ||
+ (strstr(name, "/dev/ashmem/dalvik-allocspace alloc space mark-bitmap") == name) ||
+ (strstr(name, "/dev/ashmem/dalvik-card table") == name) ||
+ (strstr(name, "/dev/ashmem/dalvik-allocation stack") == name) ||
+ (strstr(name, "/dev/ashmem/dalvik-live stack") == name) ||
+ (strstr(name, "/dev/ashmem/dalvik-imagespace") == name) ||
+ (strstr(name, "/dev/ashmem/dalvik-bitmap") == name) ||
+ (strstr(name, "/dev/ashmem/dalvik-card-table") == name) ||
+ (strstr(name, "/dev/ashmem/dalvik-mark-stack") == name) ||
+ (strstr(name, "/dev/ashmem/dalvik-aux-structure") == name)) {
+ subHeap = HEAP_DALVIK_ACCOUNTING;
+ } else if (strstr(name, "/dev/ashmem/dalvik-large") == name) {
+ whichHeap = HEAP_DALVIK;
+ subHeap = HEAP_DALVIK_LARGE;
+ } else if (strstr(name, "/dev/ashmem/dalvik-jit-code-cache") == name) {
+ subHeap = HEAP_DALVIK_CODE_CACHE;
+ } else {
+ // This is the regular Dalvik heap.
+ whichHeap = HEAP_DALVIK;
+ subHeap = HEAP_DALVIK_NORMAL;
+ }
+ } else if (strncmp(name, "/dev/ashmem/CursorWindow", 24) == 0) {
+ whichHeap = HEAP_CURSOR;
+ } else if (strncmp(name, "/dev/ashmem/libc malloc", 23) == 0) {
+ whichHeap = HEAP_NATIVE;
+ } else {
+ whichHeap = HEAP_ASHMEM;
+ }
+ } else if (strncmp(name, "[stack", 6) == 0) {
whichHeap = HEAP_STACK;
- } else if (strstr(name, "/dev/ashmem/CursorWindow") == name) {
- whichHeap = HEAP_CURSOR;
- } else if (strstr(name, "/dev/ashmem/") == name) {
- whichHeap = HEAP_ASHMEM;
- } else if (strstr(name, "/dev/") == name) {
+ } else if (strncmp(name, "/dev/", 5) == 0) {
whichHeap = HEAP_UNKNOWN_DEV;
} else if (nameLen > 3 && strcmp(name+nameLen-3, ".so") == 0) {
whichHeap = HEAP_SO;
+ is_swappable = true;
} else if (nameLen > 4 && strcmp(name+nameLen-4, ".jar") == 0) {
whichHeap = HEAP_JAR;
+ is_swappable = true;
} else if (nameLen > 4 && strcmp(name+nameLen-4, ".apk") == 0) {
whichHeap = HEAP_APK;
+ is_swappable = true;
} else if (nameLen > 4 && strcmp(name+nameLen-4, ".ttf") == 0) {
whichHeap = HEAP_TTF;
+ is_swappable = true;
} else if ((nameLen > 4 && strcmp(name+nameLen-4, ".dex") == 0) ||
(nameLen > 5 && strcmp(name+nameLen-5, ".odex") == 0)) {
whichHeap = HEAP_DEX;
+ is_swappable = true;
+ } else if (nameLen > 4 && strcmp(name+nameLen-4, ".oat") == 0) {
+ whichHeap = HEAP_OAT;
+ is_swappable = true;
+ } else if (nameLen > 4 && strcmp(name+nameLen-4, ".art") == 0) {
+ whichHeap = HEAP_ART;
+ is_swappable = true;
} else if (nameLen > 0) {
whichHeap = HEAP_UNKNOWN_MAP;
} else if (start == prevEnd && prevHeap == HEAP_SO) {
@@ -225,9 +287,29 @@ static void read_mapinfo(FILE *fp, stats_t* stats)
}
if (!skip) {
+ if (is_swappable && (pss > 0)) {
+ sharing_proportion = 0.0;
+ if ((shared_clean > 0) || (shared_dirty > 0)) {
+ sharing_proportion = (pss - private_clean - private_dirty)/(shared_clean+shared_dirty);
+ }
+ swappable_pss = (sharing_proportion*shared_clean) + private_clean;
+ } else
+ swappable_pss = 0;
+
stats[whichHeap].pss += pss;
+ stats[whichHeap].swappablePss += swappable_pss;
stats[whichHeap].privateDirty += private_dirty;
stats[whichHeap].sharedDirty += shared_dirty;
+ stats[whichHeap].privateClean += private_clean;
+ stats[whichHeap].sharedClean += shared_clean;
+ if (whichHeap == HEAP_DALVIK || whichHeap == HEAP_DALVIK_OTHER) {
+ stats[subHeap].pss += pss;
+ stats[subHeap].swappablePss += swappable_pss;
+ stats[subHeap].privateDirty += private_dirty;
+ stats[subHeap].sharedDirty += shared_dirty;
+ stats[subHeap].privateClean += private_clean;
+ stats[subHeap].sharedClean += shared_clean;
+ }
}
}
}
@@ -251,20 +333,28 @@ static void android_os_Debug_getDirtyPagesPid(JNIEnv *env, jobject clazz,
stats_t stats[_NUM_HEAP];
memset(&stats, 0, sizeof(stats));
+
load_maps(pid, stats);
- for (int i=_NUM_CORE_HEAP; i<_NUM_HEAP; i++) {
+ for (int i=_NUM_CORE_HEAP; i<_NUM_EXCLUSIVE_HEAP; i++) {
stats[HEAP_UNKNOWN].pss += stats[i].pss;
+ stats[HEAP_UNKNOWN].swappablePss += stats[i].swappablePss;
stats[HEAP_UNKNOWN].privateDirty += stats[i].privateDirty;
stats[HEAP_UNKNOWN].sharedDirty += stats[i].sharedDirty;
+ stats[HEAP_UNKNOWN].privateClean += stats[i].privateClean;
+ stats[HEAP_UNKNOWN].sharedClean += stats[i].sharedClean;
}
for (int i=0; i<_NUM_CORE_HEAP; i++) {
env->SetIntField(object, stat_fields[i].pss_field, stats[i].pss);
+ env->SetIntField(object, stat_fields[i].pssSwappable_field, stats[i].swappablePss);
env->SetIntField(object, stat_fields[i].privateDirty_field, stats[i].privateDirty);
env->SetIntField(object, stat_fields[i].sharedDirty_field, stats[i].sharedDirty);
+ env->SetIntField(object, stat_fields[i].privateClean_field, stats[i].privateClean);
+ env->SetIntField(object, stat_fields[i].sharedClean_field, stats[i].sharedClean);
}
+
jintArray otherIntArray = (jintArray)env->GetObjectField(object, otherStats_field);
jint* otherArray = (jint*)env->GetPrimitiveArrayCritical(otherIntArray, 0);
@@ -275,8 +365,11 @@ static void android_os_Debug_getDirtyPagesPid(JNIEnv *env, jobject clazz,
int j=0;
for (int i=_NUM_CORE_HEAP; i<_NUM_HEAP; i++) {
otherArray[j++] = stats[i].pss;
+ otherArray[j++] = stats[i].swappablePss;
otherArray[j++] = stats[i].privateDirty;
otherArray[j++] = stats[i].sharedDirty;
+ otherArray[j++] = stats[i].privateClean;
+ otherArray[j++] = stats[i].sharedClean;
}
env->ReleasePrimitiveArrayCritical(otherIntArray, otherArray, 0);
@@ -617,11 +710,13 @@ int register_android_os_Debug(JNIEnv *env)
// Sanity check the number of other statistics expected in Java matches here.
jfieldID numOtherStats_field = env->GetStaticFieldID(clazz, "NUM_OTHER_STATS", "I");
jint numOtherStats = env->GetStaticIntField(clazz, numOtherStats_field);
+ jfieldID numDvkStats_field = env->GetStaticFieldID(clazz, "NUM_DVK_STATS", "I");
+ jint numDvkStats = env->GetStaticIntField(clazz, numDvkStats_field);
int expectedNumOtherStats = _NUM_HEAP - _NUM_CORE_HEAP;
- if (numOtherStats != expectedNumOtherStats) {
+ if ((numOtherStats + numDvkStats) != expectedNumOtherStats) {
jniThrowExceptionFmt(env, "java/lang/RuntimeException",
- "android.os.Debug.Meminfo.NUM_OTHER_STATS=%d expected %d",
- numOtherStats, expectedNumOtherStats);
+ "android.os.Debug.Meminfo.NUM_OTHER_STATS+android.os.Debug.Meminfo.NUM_DVK_STATS=%d expected %d",
+ numOtherStats+numDvkStats, expectedNumOtherStats);
return JNI_ERR;
}
@@ -630,10 +725,16 @@ int register_android_os_Debug(JNIEnv *env)
for (int i=0; i<_NUM_CORE_HEAP; i++) {
stat_fields[i].pss_field =
env->GetFieldID(clazz, stat_field_names[i].pss_name, "I");
+ stat_fields[i].pssSwappable_field =
+ env->GetFieldID(clazz, stat_field_names[i].pssSwappable_name, "I");
stat_fields[i].privateDirty_field =
env->GetFieldID(clazz, stat_field_names[i].privateDirty_name, "I");
stat_fields[i].sharedDirty_field =
env->GetFieldID(clazz, stat_field_names[i].sharedDirty_name, "I");
+ stat_fields[i].privateClean_field =
+ env->GetFieldID(clazz, stat_field_names[i].privateClean_name, "I");
+ stat_fields[i].sharedClean_field =
+ env->GetFieldID(clazz, stat_field_names[i].sharedClean_name, "I");
}
return jniRegisterNativeMethods(env, "android/os/Debug", gMethods, NELEM(gMethods));
diff --git a/core/jni/android_os_MessageQueue.cpp b/core/jni/android_os_MessageQueue.cpp
index 7540645..c9c3720 100644
--- a/core/jni/android_os_MessageQueue.cpp
+++ b/core/jni/android_os_MessageQueue.cpp
@@ -141,6 +141,11 @@ static void android_os_MessageQueue_nativeWake(JNIEnv* env, jclass clazz, jint p
return nativeMessageQueue->wake();
}
+static jboolean android_os_MessageQueue_nativeIsIdling(JNIEnv* env, jclass clazz, jint ptr) {
+ NativeMessageQueue* nativeMessageQueue = reinterpret_cast<NativeMessageQueue*>(ptr);
+ return nativeMessageQueue->getLooper()->isIdling();
+}
+
// ----------------------------------------------------------------------------
static JNINativeMethod gMessageQueueMethods[] = {
@@ -148,7 +153,8 @@ static JNINativeMethod gMessageQueueMethods[] = {
{ "nativeInit", "()I", (void*)android_os_MessageQueue_nativeInit },
{ "nativeDestroy", "(I)V", (void*)android_os_MessageQueue_nativeDestroy },
{ "nativePollOnce", "(II)V", (void*)android_os_MessageQueue_nativePollOnce },
- { "nativeWake", "(I)V", (void*)android_os_MessageQueue_nativeWake }
+ { "nativeWake", "(I)V", (void*)android_os_MessageQueue_nativeWake },
+ { "nativeIsIdling", "(I)Z", (void*)android_os_MessageQueue_nativeIsIdling }
};
#define FIND_CLASS(var, className) \
diff --git a/core/jni/android_os_SystemClock.cpp b/core/jni/android_os_SystemClock.cpp
index 5c135ee..d20b800 100644
--- a/core/jni/android_os_SystemClock.cpp
+++ b/core/jni/android_os_SystemClock.cpp
@@ -19,18 +19,67 @@
* System clock functions.
*/
+#ifdef HAVE_ANDROID_OS
+#include <linux/ioctl.h>
+#include <linux/rtc.h>
+#include <utils/Atomic.h>
+#include <linux/android_alarm.h>
+#endif
+
+#include <sys/time.h>
+#include <limits.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+
#include "JNIHelp.h"
#include "jni.h"
#include "android_runtime/AndroidRuntime.h"
-#include "utils/SystemClock.h"
-
#include <sys/time.h>
#include <time.h>
+#include <utils/SystemClock.h>
+
namespace android {
/*
+ * Set the current time. This only works when running as root.
+ */
+static int setCurrentTimeMillis(int64_t millis)
+{
+ struct timeval tv;
+ struct timespec ts;
+ int fd;
+ int res;
+ int ret = 0;
+
+ if (millis <= 0 || millis / 1000LL >= INT_MAX) {
+ return -1;
+ }
+
+ tv.tv_sec = (time_t) (millis / 1000LL);
+ tv.tv_usec = (suseconds_t) ((millis % 1000LL) * 1000LL);
+
+ ALOGD("Setting time of day to sec=%d\n", (int) tv.tv_sec);
+
+ fd = open("/dev/alarm", O_RDWR);
+ if(fd < 0) {
+ ALOGW("Unable to open alarm driver: %s\n", strerror(errno));
+ return -1;
+ }
+ ts.tv_sec = tv.tv_sec;
+ ts.tv_nsec = tv.tv_usec * 1000;
+ res = ioctl(fd, ANDROID_ALARM_SET_RTC, &ts);
+ if(res < 0) {
+ ALOGW("Unable to set rtc to %ld: %s\n", tv.tv_sec, strerror(errno));
+ ret = -1;
+ }
+ close(fd);
+ return ret;
+}
+
+/*
* native public static void setCurrentTimeMillis(long millis)
*
* Set the current time. This only works when running as root.
diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp
index 8766cf9..1c92803 100644
--- a/core/jni/android_util_Binder.cpp
+++ b/core/jni/android_util_Binder.cpp
@@ -986,6 +986,7 @@ static bool push_eventlog_int(char** pos, const char* end, jint val) {
}
// From frameworks/base/core/java/android/content/EventLogTags.logtags:
+#define ENABLE_BINDER_SAMPLE 0
#define LOGTAG_BINDER_OPERATION 52004
static void conditionally_log_binder_call(int64_t start_millis,
@@ -1063,6 +1064,7 @@ static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj,
ALOGV("Java code calling transact on %p in Java object %p with code %d\n",
target, obj, code);
+#if ENABLE_BINDER_SAMPLE
// Only log the binder call duration for things on the Java-level main thread.
// But if we don't
const bool time_binder_calls = should_time_binder_calls();
@@ -1071,12 +1073,15 @@ static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj,
if (time_binder_calls) {
start_millis = uptimeMillis();
}
+#endif
//printf("Transact from Java code to %p sending: ", target); data->print();
status_t err = target->transact(code, *data, reply, flags);
//if (reply) printf("Transact from Java code to %p received: ", target); reply->print();
+#if ENABLE_BINDER_SAMPLE
if (time_binder_calls) {
conditionally_log_binder_call(start_millis, target, code);
}
+#endif
if (err == NO_ERROR) {
return JNI_TRUE;
diff --git a/core/jni/android_util_Process.cpp b/core/jni/android_util_Process.cpp
index 5d32328..61eb31b 100644
--- a/core/jni/android_util_Process.cpp
+++ b/core/jni/android_util_Process.cpp
@@ -99,6 +99,11 @@ jint android_os_Process_myPid(JNIEnv* env, jobject clazz)
return getpid();
}
+jint android_os_Process_myPpid(JNIEnv* env, jobject clazz)
+{
+ return getppid();
+}
+
jint android_os_Process_myUid(JNIEnv* env, jobject clazz)
{
return getuid();
@@ -990,6 +995,7 @@ jintArray android_os_Process_getPidsForCommands(JNIEnv* env, jobject clazz,
static const JNINativeMethod methods[] = {
{"myPid", "()I", (void*)android_os_Process_myPid},
+ {"myPpid", "()I", (void*)android_os_Process_myPpid},
{"myTid", "()I", (void*)android_os_Process_myTid},
{"myUid", "()I", (void*)android_os_Process_myUid},
{"getUidForName", "(Ljava/lang/String;)I", (void*)android_os_Process_getUidForName},
diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp
index b87fe27..983a838 100644
--- a/core/jni/android_view_GLES20Canvas.cpp
+++ b/core/jni/android_view_GLES20Canvas.cpp
@@ -16,18 +16,19 @@
#define LOG_TAG "OpenGLRenderer"
-#include <EGL/egl.h>
-
#include "jni.h"
#include "GraphicsJNI.h"
#include <nativehelper/JNIHelp.h>
+#include "android_view_GraphicBuffer.h"
+
#include <android_runtime/AndroidRuntime.h>
#include <android_runtime/android_graphics_SurfaceTexture.h>
-#include <gui/GLConsumer.h>
#include <androidfw/ResourceTypes.h>
+#include <gui/GLConsumer.h>
+
#include <private/hwui/DrawGlInfo.h>
#include <cutils/properties.h>
@@ -99,10 +100,11 @@ static void android_view_GLES20Canvas_flushCaches(JNIEnv* env, jobject clazz,
}
}
-static void android_view_GLES20Canvas_initCaches(JNIEnv* env, jobject clazz) {
+static bool android_view_GLES20Canvas_initCaches(JNIEnv* env, jobject clazz) {
if (Caches::hasInstance()) {
- Caches::getInstance().init();
+ return Caches::getInstance().init();
}
+ return false;
}
static void android_view_GLES20Canvas_terminateCaches(JNIEnv* env, jobject clazz) {
@@ -112,6 +114,21 @@ static void android_view_GLES20Canvas_terminateCaches(JNIEnv* env, jobject clazz
}
// ----------------------------------------------------------------------------
+// Caching
+// ----------------------------------------------------------------------------
+
+static void android_view_GLES20Canvas_initAtlas(JNIEnv* env, jobject clazz,
+ jobject graphicBuffer, jintArray atlasMapArray, jint count) {
+
+ sp<GraphicBuffer> buffer = graphicBufferForJavaObject(env, graphicBuffer);
+ jint* atlasMap = env->GetIntArrayElements(atlasMapArray, NULL);
+
+ Caches::getInstance().assetAtlas.init(buffer, atlasMap, count);
+
+ env->ReleaseIntArrayElements(atlasMapArray, atlasMap, 0);
+}
+
+// ----------------------------------------------------------------------------
// Constructors
// ----------------------------------------------------------------------------
@@ -168,6 +185,16 @@ static void android_view_GLES20Canvas_setName(JNIEnv* env,
}
}
+static void android_view_GLES20Canvas_setCountOverdrawEnabled(JNIEnv* env, jobject clazz,
+ OpenGLRenderer* renderer, jboolean enabled) {
+ renderer->setCountOverdrawEnabled(enabled);
+}
+
+static jfloat android_view_GLES20Canvas_getOverdraw(JNIEnv* env, jobject clazz,
+ OpenGLRenderer* renderer) {
+ return renderer->getOverdraw();
+}
+
// ----------------------------------------------------------------------------
// Functor
// ----------------------------------------------------------------------------
@@ -350,31 +377,20 @@ static void android_view_GLES20Canvas_concatMatrix(JNIEnv* env, jobject clazz,
// ----------------------------------------------------------------------------
static void android_view_GLES20Canvas_drawBitmap(JNIEnv* env, jobject clazz,
- OpenGLRenderer* renderer, SkBitmap* bitmap, jbyteArray buffer,
- jfloat left, jfloat top, SkPaint* paint) {
- // This object allows the renderer to allocate a global JNI ref to the buffer object.
- JavaHeapBitmapRef bitmapRef(env, bitmap, buffer);
-
+ OpenGLRenderer* renderer, SkBitmap* bitmap, jfloat left, jfloat top, SkPaint* paint) {
renderer->drawBitmap(bitmap, left, top, paint);
}
static void android_view_GLES20Canvas_drawBitmapRect(JNIEnv* env, jobject clazz,
- OpenGLRenderer* renderer, SkBitmap* bitmap, jbyteArray buffer,
+ OpenGLRenderer* renderer, SkBitmap* bitmap,
float srcLeft, float srcTop, float srcRight, float srcBottom,
float dstLeft, float dstTop, float dstRight, float dstBottom, SkPaint* paint) {
- // This object allows the renderer to allocate a global JNI ref to the buffer object.
- JavaHeapBitmapRef bitmapRef(env, bitmap, buffer);
-
renderer->drawBitmap(bitmap, srcLeft, srcTop, srcRight, srcBottom,
dstLeft, dstTop, dstRight, dstBottom, paint);
}
static void android_view_GLES20Canvas_drawBitmapMatrix(JNIEnv* env, jobject clazz,
- OpenGLRenderer* renderer, SkBitmap* bitmap, jbyteArray buffer, SkMatrix* matrix,
- SkPaint* paint) {
- // This object allows the renderer to allocate a global JNI ref to the buffer object.
- JavaHeapBitmapRef bitmapRef(env, bitmap, buffer);
-
+ OpenGLRenderer* renderer, SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint) {
renderer->drawBitmap(bitmap, matrix, paint);
}
@@ -404,12 +420,8 @@ static void android_view_GLES20Canvas_drawBitmapData(JNIEnv* env, jobject clazz,
}
static void android_view_GLES20Canvas_drawBitmapMesh(JNIEnv* env, jobject clazz,
- OpenGLRenderer* renderer, SkBitmap* bitmap, jbyteArray buffer,
- jint meshWidth, jint meshHeight, jfloatArray vertices, jint offset,
- jintArray colors, jint colorOffset, SkPaint* paint) {
- // This object allows the renderer to allocate a global JNI ref to the buffer object.
- JavaHeapBitmapRef bitmapRef(env, bitmap, buffer);
-
+ OpenGLRenderer* renderer, SkBitmap* bitmap, jint meshWidth, jint meshHeight,
+ jfloatArray vertices, jint offset, jintArray colors, jint colorOffset, SkPaint* paint) {
jfloat* verticesArray = vertices ? env->GetFloatArrayElements(vertices, NULL) + offset : NULL;
jint* colorsArray = colors ? env->GetIntArrayElements(colors, NULL) + colorOffset : NULL;
@@ -420,18 +432,13 @@ static void android_view_GLES20Canvas_drawBitmapMesh(JNIEnv* env, jobject clazz,
}
static void android_view_GLES20Canvas_drawPatch(JNIEnv* env, jobject clazz,
- OpenGLRenderer* renderer, SkBitmap* bitmap, jbyteArray buffer, jbyteArray chunks,
+ OpenGLRenderer* renderer, SkBitmap* bitmap, jbyteArray chunks,
float left, float top, float right, float bottom, SkPaint* paint) {
- // This object allows the renderer to allocate a global JNI ref to the buffer object.
- JavaHeapBitmapRef bitmapRef(env, bitmap, buffer);
-
jbyte* storage = env->GetByteArrayElements(chunks, NULL);
Res_png_9patch* patch = reinterpret_cast<Res_png_9patch*>(storage);
Res_png_9patch::deserialize(patch);
- renderer->drawPatch(bitmap, &patch->xDivs[0], &patch->yDivs[0],
- &patch->colors[0], patch->numXDivs, patch->numYDivs, patch->numColors,
- left, top, right, bottom, paint);
+ renderer->drawPatch(bitmap, patch, left, top, right, bottom, paint);
env->ReleaseByteArrayElements(chunks, storage, 0);
}
@@ -567,6 +574,20 @@ static void android_view_GLES20Canvas_resetPaintFilter(JNIEnv* env, jobject claz
// Text
// ----------------------------------------------------------------------------
+static float xOffsetForTextAlign(SkPaint* paint, float totalAdvance) {
+ switch (paint->getTextAlign()) {
+ case SkPaint::kCenter_Align:
+ return -totalAdvance / 2.0f;
+ break;
+ case SkPaint::kRight_Align:
+ return -totalAdvance;
+ break;
+ default:
+ break;
+ }
+ return 0;
+}
+
static void renderText(OpenGLRenderer* renderer, const jchar* text, int count,
jfloat x, jfloat y, int flags, SkPaint* paint) {
sp<TextLayoutValue> value = TextLayoutEngine::getInstance().getValue(paint,
@@ -579,8 +600,12 @@ static void renderText(OpenGLRenderer* renderer, const jchar* text, int count,
jfloat totalAdvance = value->getTotalAdvance();
const float* positions = value->getPos();
int bytesCount = glyphsCount * sizeof(jchar);
- renderer->drawText((const char*) glyphs, bytesCount, glyphsCount, x, y,
- positions, paint, totalAdvance);
+ const SkRect& r = value->getBounds();
+ android::uirenderer::Rect bounds(r.fLeft, r.fTop, r.fRight, r.fBottom);
+
+ renderer->drawText((const char*) glyphs, bytesCount, glyphsCount,
+ x + xOffsetForTextAlign(paint, totalAdvance), y, positions,
+ paint, totalAdvance, bounds);
}
static void renderTextOnPath(OpenGLRenderer* renderer, const jchar* text, int count,
@@ -610,8 +635,12 @@ static void renderTextRun(OpenGLRenderer* renderer, const jchar* text,
jfloat totalAdvance = value->getTotalAdvance();
const float* positions = value->getPos();
int bytesCount = glyphsCount * sizeof(jchar);
- renderer->drawText((const char*) glyphs, bytesCount, glyphsCount, x, y,
- positions, paint, totalAdvance);
+ const SkRect& r = value->getBounds();
+ android::uirenderer::Rect bounds(r.fLeft, r.fTop, r.fRight, r.fBottom);
+
+ renderer->drawText((const char*) glyphs, bytesCount, glyphsCount,
+ x + xOffsetForTextAlign(paint, totalAdvance), y, positions,
+ paint, totalAdvance, bounds);
}
static void android_view_GLES20Canvas_drawTextArray(JNIEnv* env, jobject clazz,
@@ -932,9 +961,12 @@ static JNINativeMethod gMethods[] = {
#ifdef USE_OPENGL_RENDERER
{ "nFlushCaches", "(I)V", (void*) android_view_GLES20Canvas_flushCaches },
- { "nInitCaches", "()V", (void*) android_view_GLES20Canvas_initCaches },
+ { "nInitCaches", "()Z", (void*) android_view_GLES20Canvas_initCaches },
{ "nTerminateCaches", "()V", (void*) android_view_GLES20Canvas_terminateCaches },
+ { "nInitAtlas", "(Landroid/view/GraphicBuffer;[II)V",
+ (void*) android_view_GLES20Canvas_initAtlas },
+
{ "nCreateRenderer", "()I", (void*) android_view_GLES20Canvas_createRenderer },
{ "nDestroyRenderer", "(I)V", (void*) android_view_GLES20Canvas_destroyRenderer },
{ "nSetViewport", "(III)V", (void*) android_view_GLES20Canvas_setViewport },
@@ -944,6 +976,9 @@ static JNINativeMethod gMethods[] = {
{ "nSetName", "(ILjava/lang/String;)V",
(void*) android_view_GLES20Canvas_setName },
+ { "nSetCountOverdrawEnabled", "(IZ)V", (void*) android_view_GLES20Canvas_setCountOverdrawEnabled },
+ { "nGetOverdraw", "(I)F", (void*) android_view_GLES20Canvas_getOverdraw },
+
{ "nGetStencilSize", "()I", (void*) android_view_GLES20Canvas_getStencilSize },
{ "nCallDrawGLFunction", "(II)I", (void*) android_view_GLES20Canvas_callDrawGLFunction },
@@ -977,14 +1012,14 @@ static JNINativeMethod gMethods[] = {
{ "nGetMatrix", "(II)V", (void*) android_view_GLES20Canvas_getMatrix },
{ "nConcatMatrix", "(II)V", (void*) android_view_GLES20Canvas_concatMatrix },
- { "nDrawBitmap", "(II[BFFI)V", (void*) android_view_GLES20Canvas_drawBitmap },
- { "nDrawBitmap", "(II[BFFFFFFFFI)V",(void*) android_view_GLES20Canvas_drawBitmapRect },
- { "nDrawBitmap", "(II[BII)V", (void*) android_view_GLES20Canvas_drawBitmapMatrix },
+ { "nDrawBitmap", "(IIFFI)V", (void*) android_view_GLES20Canvas_drawBitmap },
+ { "nDrawBitmap", "(IIFFFFFFFFI)V", (void*) android_view_GLES20Canvas_drawBitmapRect },
+ { "nDrawBitmap", "(IIII)V", (void*) android_view_GLES20Canvas_drawBitmapMatrix },
{ "nDrawBitmap", "(I[IIIFFIIZI)V", (void*) android_view_GLES20Canvas_drawBitmapData },
- { "nDrawBitmapMesh", "(II[BII[FI[III)V",(void*) android_view_GLES20Canvas_drawBitmapMesh },
+ { "nDrawBitmapMesh", "(IIII[FI[III)V", (void*) android_view_GLES20Canvas_drawBitmapMesh },
- { "nDrawPatch", "(II[B[BFFFFI)V", (void*) android_view_GLES20Canvas_drawPatch },
+ { "nDrawPatch", "(II[BFFFFI)V", (void*) android_view_GLES20Canvas_drawPatch },
{ "nDrawColor", "(III)V", (void*) android_view_GLES20Canvas_drawColor },
{ "nDrawRect", "(IFFFFI)V", (void*) android_view_GLES20Canvas_drawRect },
diff --git a/core/jni/android_view_GraphicBuffer.cpp b/core/jni/android_view_GraphicBuffer.cpp
new file mode 100644
index 0000000..d68c0b2
--- /dev/null
+++ b/core/jni/android_view_GraphicBuffer.cpp
@@ -0,0 +1,331 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "GraphicBuffer"
+
+#include "jni.h"
+#include "JNIHelp.h"
+
+#include "android_os_Parcel.h"
+#include "android_view_GraphicBuffer.h"
+
+#include <android_runtime/AndroidRuntime.h>
+
+#include <binder/Parcel.h>
+
+#include <ui/GraphicBuffer.h>
+#include <ui/PixelFormat.h>
+
+#include <gui/IGraphicBufferAlloc.h>
+#include <gui/ISurfaceComposer.h>
+
+#include <SkCanvas.h>
+#include <SkBitmap.h>
+
+#include <private/gui/ComposerService.h>
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+// Defines
+// ----------------------------------------------------------------------------
+
+// Debug
+#define DEBUG_GRAPHIC_BUFFER 0
+
+// Debug
+#if DEBUG_GRAPHIC_BUFFER
+ #define GB_LOGD(...) ALOGD(__VA_ARGS__)
+ #define GB_LOGW(...) ALOGW(__VA_ARGS__)
+#else
+ #define GB_LOGD(...)
+ #define GB_LOGW(...)
+#endif
+
+#define LOCK_CANVAS_USAGE GraphicBuffer::USAGE_SW_READ_OFTEN | GraphicBuffer::USAGE_SW_WRITE_OFTEN
+
+// ----------------------------------------------------------------------------
+// JNI Helpers
+// ----------------------------------------------------------------------------
+
+static struct {
+ jfieldID mNativeObject;
+} gGraphicBufferClassInfo;
+
+static struct {
+ jmethodID set;
+ jfieldID left;
+ jfieldID top;
+ jfieldID right;
+ jfieldID bottom;
+} gRectClassInfo;
+
+static struct {
+ jfieldID mFinalizer;
+ jfieldID mNativeCanvas;
+ jfieldID mSurfaceFormat;
+} gCanvasClassInfo;
+
+static struct {
+ jfieldID mNativeCanvas;
+} gCanvasFinalizerClassInfo;
+
+#define GET_INT(object, field) \
+ env->GetIntField(object, field)
+
+#define SET_INT(object, field, value) \
+ env->SetIntField(object, field, value)
+
+#define INVOKEV(object, method, ...) \
+ env->CallVoidMethod(object, method, __VA_ARGS__)
+
+// ----------------------------------------------------------------------------
+// Types
+// ----------------------------------------------------------------------------
+
+class GraphicBufferWrapper {
+public:
+ GraphicBufferWrapper(const sp<GraphicBuffer>& buffer): buffer(buffer) {
+ }
+
+ sp<GraphicBuffer> buffer;
+};
+
+// ----------------------------------------------------------------------------
+// GraphicBuffer lifecycle
+// ----------------------------------------------------------------------------
+
+static GraphicBufferWrapper* android_view_GraphiceBuffer_create(JNIEnv* env, jobject clazz,
+ jint width, jint height, jint format, jint usage) {
+
+ sp<ISurfaceComposer> composer(ComposerService::getComposerService());
+ sp<IGraphicBufferAlloc> alloc(composer->createGraphicBufferAlloc());
+ if (alloc == NULL) {
+ GB_LOGW("createGraphicBufferAlloc() failed in GraphicBuffer.create()");
+ return NULL;
+ }
+
+ status_t error;
+ sp<GraphicBuffer> buffer(alloc->createGraphicBuffer(width, height, format, usage, &error));
+ if (buffer == NULL) {
+ GB_LOGW("createGraphicBuffer() failed in GraphicBuffer.create()");
+ return NULL;
+ }
+
+ return new GraphicBufferWrapper(buffer);
+}
+
+static void android_view_GraphiceBuffer_destroy(JNIEnv* env, jobject clazz,
+ GraphicBufferWrapper* wrapper) {
+ delete wrapper;
+}
+
+// ----------------------------------------------------------------------------
+// Canvas management
+// ----------------------------------------------------------------------------
+
+static inline void swapCanvasPtr(JNIEnv* env, jobject canvasObj, SkCanvas* newCanvas) {
+ jobject canvasFinalizerObj = env->GetObjectField(canvasObj, gCanvasClassInfo.mFinalizer);
+ SkCanvas* previousCanvas = reinterpret_cast<SkCanvas*>(
+ GET_INT(canvasObj, gCanvasClassInfo.mNativeCanvas));
+ SET_INT(canvasObj, gCanvasClassInfo.mNativeCanvas, (int) newCanvas);
+ SET_INT(canvasFinalizerObj, gCanvasFinalizerClassInfo.mNativeCanvas, (int) newCanvas);
+ SkSafeUnref(previousCanvas);
+}
+
+static inline SkBitmap::Config convertPixelFormat(int32_t format) {
+ switch (format) {
+ case PIXEL_FORMAT_RGBA_8888:
+ return SkBitmap::kARGB_8888_Config;
+ case PIXEL_FORMAT_RGBX_8888:
+ return SkBitmap::kARGB_8888_Config;
+ case PIXEL_FORMAT_RGB_565:
+ return SkBitmap::kRGB_565_Config;
+ default:
+ return SkBitmap::kNo_Config;
+ }
+}
+
+static jboolean android_view_GraphicBuffer_lockCanvas(JNIEnv* env, jobject,
+ GraphicBufferWrapper* wrapper, jobject canvas, jobject dirtyRect) {
+
+ if (!wrapper) {
+ return false;
+ }
+
+ sp<GraphicBuffer> buffer(wrapper->buffer);
+
+ Rect rect;
+ if (dirtyRect) {
+ rect.left = GET_INT(dirtyRect, gRectClassInfo.left);
+ rect.top = GET_INT(dirtyRect, gRectClassInfo.top);
+ rect.right = GET_INT(dirtyRect, gRectClassInfo.right);
+ rect.bottom = GET_INT(dirtyRect, gRectClassInfo.bottom);
+ } else {
+ rect.set(Rect(buffer->getWidth(), buffer->getHeight()));
+ }
+
+ void* bits = NULL;
+ status_t status = buffer->lock(LOCK_CANVAS_USAGE, rect, &bits);
+
+ if (status) return false;
+ if (!bits) {
+ buffer->unlock();
+ return false;
+ }
+
+ ssize_t bytesCount = buffer->getStride() * bytesPerPixel(buffer->getPixelFormat());
+
+ SkBitmap bitmap;
+ bitmap.setConfig(convertPixelFormat(buffer->getPixelFormat()),
+ buffer->getWidth(), buffer->getHeight(), bytesCount);
+
+ if (buffer->getWidth() > 0 && buffer->getHeight() > 0) {
+ bitmap.setPixels(bits);
+ } else {
+ bitmap.setPixels(NULL);
+ }
+
+ SET_INT(canvas, gCanvasClassInfo.mSurfaceFormat, buffer->getPixelFormat());
+
+ SkCanvas* nativeCanvas = SkNEW_ARGS(SkCanvas, (bitmap));
+ swapCanvasPtr(env, canvas, nativeCanvas);
+
+ SkRect clipRect;
+ clipRect.set(rect.left, rect.top, rect.right, rect.bottom);
+ nativeCanvas->clipRect(clipRect);
+
+ if (dirtyRect) {
+ INVOKEV(dirtyRect, gRectClassInfo.set,
+ int(rect.left), int(rect.top), int(rect.right), int(rect.bottom));
+ }
+
+ return true;
+}
+
+static jboolean android_view_GraphicBuffer_unlockCanvasAndPost(JNIEnv* env, jobject,
+ GraphicBufferWrapper* wrapper, jobject canvas) {
+
+ SkCanvas* nativeCanvas = SkNEW(SkCanvas);
+ swapCanvasPtr(env, canvas, nativeCanvas);
+
+ if (wrapper) {
+ status_t status = wrapper->buffer->unlock();
+ return status == 0;
+ }
+
+ return false;
+}
+
+// ----------------------------------------------------------------------------
+// Serialization
+// ----------------------------------------------------------------------------
+
+static void android_view_GraphiceBuffer_write(JNIEnv* env, jobject clazz,
+ GraphicBufferWrapper* wrapper, jobject dest) {
+ Parcel* parcel = parcelForJavaObject(env, dest);
+ if (parcel) {
+ parcel->write(*wrapper->buffer);
+ }
+}
+
+static GraphicBufferWrapper* android_view_GraphiceBuffer_read(JNIEnv* env, jobject clazz,
+ jobject in) {
+
+ Parcel* parcel = parcelForJavaObject(env, in);
+ if (parcel) {
+ sp<GraphicBuffer> buffer = new GraphicBuffer();
+ parcel->read(*buffer);
+ return new GraphicBufferWrapper(buffer);
+ }
+
+ return NULL;
+}
+
+// ----------------------------------------------------------------------------
+// External helpers
+// ----------------------------------------------------------------------------
+
+sp<GraphicBuffer> graphicBufferForJavaObject(JNIEnv* env, jobject obj) {
+ if (obj) {
+ jint nativeObject = env->GetIntField(obj, gGraphicBufferClassInfo.mNativeObject);
+ GraphicBufferWrapper* wrapper = (GraphicBufferWrapper*) nativeObject;
+ if (wrapper != NULL) {
+ sp<GraphicBuffer> buffer(wrapper->buffer);
+ return buffer;
+ }
+ }
+ return NULL;
+}
+
+// ----------------------------------------------------------------------------
+// JNI Glue
+// ----------------------------------------------------------------------------
+
+#define FIND_CLASS(var, className) \
+ var = env->FindClass(className); \
+ LOG_FATAL_IF(! var, "Unable to find class " className);
+
+#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
+ var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
+ LOG_FATAL_IF(! var, "Unable to find field " fieldName);
+
+#define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \
+ var = env->GetMethodID(clazz, methodName, methodDescriptor); \
+ LOG_FATAL_IF(!var, "Unable to find method " methodName);
+
+const char* const kClassPathName = "android/view/GraphicBuffer";
+
+static JNINativeMethod gMethods[] = {
+ { "nCreateGraphicBuffer", "(IIII)I", (void*) android_view_GraphiceBuffer_create },
+ { "nDestroyGraphicBuffer", "(I)V", (void*) android_view_GraphiceBuffer_destroy },
+
+ { "nWriteGraphicBufferToParcel", "(ILandroid/os/Parcel;)V",
+ (void*) android_view_GraphiceBuffer_write },
+ { "nReadGraphicBufferFromParcel", "(Landroid/os/Parcel;)I",
+ (void*) android_view_GraphiceBuffer_read },
+
+ { "nLockCanvas", "(ILandroid/graphics/Canvas;Landroid/graphics/Rect;)Z",
+ (void*) android_view_GraphicBuffer_lockCanvas },
+ { "nUnlockCanvasAndPost", "(ILandroid/graphics/Canvas;)Z",
+ (void*) android_view_GraphicBuffer_unlockCanvasAndPost },
+};
+
+int register_android_view_GraphicBuffer(JNIEnv* env) {
+ jclass clazz;
+ FIND_CLASS(clazz, "android/view/GraphicBuffer");
+ GET_FIELD_ID(gGraphicBufferClassInfo.mNativeObject, clazz, "mNativeObject", "I");
+
+ FIND_CLASS(clazz, "android/graphics/Rect");
+ GET_METHOD_ID(gRectClassInfo.set, clazz, "set", "(IIII)V");
+ GET_FIELD_ID(gRectClassInfo.left, clazz, "left", "I");
+ GET_FIELD_ID(gRectClassInfo.top, clazz, "top", "I");
+ GET_FIELD_ID(gRectClassInfo.right, clazz, "right", "I");
+ GET_FIELD_ID(gRectClassInfo.bottom, clazz, "bottom", "I");
+
+ FIND_CLASS(clazz, "android/graphics/Canvas");
+ GET_FIELD_ID(gCanvasClassInfo.mFinalizer, clazz, "mFinalizer",
+ "Landroid/graphics/Canvas$CanvasFinalizer;");
+ GET_FIELD_ID(gCanvasClassInfo.mNativeCanvas, clazz, "mNativeCanvas", "I");
+ GET_FIELD_ID(gCanvasClassInfo.mSurfaceFormat, clazz, "mSurfaceFormat", "I");
+
+ FIND_CLASS(clazz, "android/graphics/Canvas$CanvasFinalizer");
+ GET_FIELD_ID(gCanvasFinalizerClassInfo.mNativeCanvas, clazz, "mNativeCanvas", "I");
+
+ return AndroidRuntime::registerNativeMethods(env, kClassPathName, gMethods, NELEM(gMethods));
+}
+
+};
diff --git a/core/jni/android_view_GraphicBuffer.h b/core/jni/android_view_GraphicBuffer.h
new file mode 100644
index 0000000..509587c
--- /dev/null
+++ b/core/jni/android_view_GraphicBuffer.h
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ */
+
+#include <ui/GraphicBuffer.h>
+
+#include "jni.h"
+
+namespace android {
+
+// This function does not perform any type checking, the specified
+// object must be an instance of android.view.GraphicBuffer
+extern sp<GraphicBuffer> graphicBufferForJavaObject(JNIEnv* env, jobject obj);
+
+}
diff --git a/core/jni/android_view_HardwareRenderer.cpp b/core/jni/android_view_HardwareRenderer.cpp
index 948a966..479fbe2 100644
--- a/core/jni/android_view_HardwareRenderer.cpp
+++ b/core/jni/android_view_HardwareRenderer.cpp
@@ -20,9 +20,14 @@
#include <nativehelper/JNIHelp.h>
#include <android_runtime/AndroidRuntime.h>
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
#include <EGL/egl_cache.h>
+#include <utils/Timers.h>
+
#include <Caches.h>
+#include <Extensions.h>
#ifdef USE_OPENGL_RENDERER
EGLAPI void EGLAPIENTRY eglBeginFrame(EGLDisplay dpy, EGLSurface surface);
@@ -119,6 +124,13 @@ static void android_view_HardwareRenderer_beginFrame(JNIEnv* env, jobject clazz,
eglBeginFrame(display, surface);
}
+static jlong android_view_HardwareRenderer_getSystemTime(JNIEnv* env, jobject clazz) {
+ if (uirenderer::Extensions::getInstance().hasNvSystemTime()) {
+ return eglGetSystemTimeNV();
+ }
+ return systemTime(SYSTEM_TIME_MONOTONIC);
+}
+
#endif // USE_OPENGL_RENDERER
// ----------------------------------------------------------------------------
@@ -146,6 +158,8 @@ static JNINativeMethod gMethods[] = {
{ "nLoadProperties", "()Z", (void*) android_view_HardwareRenderer_loadProperties },
{ "nBeginFrame", "([I)V", (void*) android_view_HardwareRenderer_beginFrame },
+
+ { "nGetSystemTime", "()J", (void*) android_view_HardwareRenderer_getSystemTime },
#endif
{ "nSetupShadersDiskCache", "(Ljava/lang/String;)V",
diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp
index d9f6be9..842a7f7 100644
--- a/core/jni/android_view_Surface.cpp
+++ b/core/jni/android_view_Surface.cpp
@@ -208,25 +208,19 @@ static void nativeLockCanvas(JNIEnv* env, jclass clazz,
return;
}
- // get dirty region
- Region dirtyRegion;
+ Rect dirtyRect;
+ Rect* dirtyRectPtr = NULL;
+
if (dirtyRectObj) {
- Rect dirty;
- dirty.left = env->GetIntField(dirtyRectObj, gRectClassInfo.left);
- dirty.top = env->GetIntField(dirtyRectObj, gRectClassInfo.top);
- dirty.right = env->GetIntField(dirtyRectObj, gRectClassInfo.right);
- dirty.bottom = env->GetIntField(dirtyRectObj, gRectClassInfo.bottom);
- if (!dirty.isEmpty()) {
- dirtyRegion.set(dirty);
- }
- } else {
- dirtyRegion.set(Rect(0x3FFF, 0x3FFF));
+ dirtyRect.left = env->GetIntField(dirtyRectObj, gRectClassInfo.left);
+ dirtyRect.top = env->GetIntField(dirtyRectObj, gRectClassInfo.top);
+ dirtyRect.right = env->GetIntField(dirtyRectObj, gRectClassInfo.right);
+ dirtyRect.bottom = env->GetIntField(dirtyRectObj, gRectClassInfo.bottom);
+ dirtyRectPtr = &dirtyRect;
}
ANativeWindow_Buffer outBuffer;
- Rect dirtyBounds(dirtyRegion.getBounds());
- status_t err = surface->lock(&outBuffer, &dirtyBounds);
- dirtyRegion.set(dirtyBounds);
+ status_t err = surface->lock(&outBuffer, dirtyRectPtr);
if (err < 0) {
const char* const exception = (err == NO_MEMORY) ?
OutOfResourcesException :
@@ -254,27 +248,15 @@ static void nativeLockCanvas(JNIEnv* env, jclass clazz,
SkCanvas* nativeCanvas = SkNEW_ARGS(SkCanvas, (bitmap));
swapCanvasPtr(env, canvasObj, nativeCanvas);
- SkRegion clipReg;
- if (dirtyRegion.isRect()) { // very common case
- const Rect b(dirtyRegion.getBounds());
- clipReg.setRect(b.left, b.top, b.right, b.bottom);
- } else {
- size_t count;
- Rect const* r = dirtyRegion.getArray(&count);
- while (count) {
- clipReg.op(r->left, r->top, r->right, r->bottom, SkRegion::kUnion_Op);
- r++, count--;
- }
+ if (dirtyRectPtr) {
+ nativeCanvas->clipRect( SkRect::Make(reinterpret_cast<const SkIRect&>(dirtyRect)) );
}
- nativeCanvas->clipRegion(clipReg);
-
if (dirtyRectObj) {
- const Rect& bounds(dirtyRegion.getBounds());
- env->SetIntField(dirtyRectObj, gRectClassInfo.left, bounds.left);
- env->SetIntField(dirtyRectObj, gRectClassInfo.top, bounds.top);
- env->SetIntField(dirtyRectObj, gRectClassInfo.right, bounds.right);
- env->SetIntField(dirtyRectObj, gRectClassInfo.bottom, bounds.bottom);
+ env->SetIntField(dirtyRectObj, gRectClassInfo.left, dirtyRect.left);
+ env->SetIntField(dirtyRectObj, gRectClassInfo.top, dirtyRect.top);
+ env->SetIntField(dirtyRectObj, gRectClassInfo.right, dirtyRect.right);
+ env->SetIntField(dirtyRectObj, gRectClassInfo.bottom, dirtyRect.bottom);
}
}
@@ -392,7 +374,7 @@ int register_android_view_Surface(JNIEnv* env)
jclass clazz = env->FindClass("android/view/Surface");
gSurfaceClassInfo.clazz = jclass(env->NewGlobalRef(clazz));
gSurfaceClassInfo.mNativeObject =
- env->GetFieldID(gSurfaceClassInfo.clazz, "mNativeSurface", "I");
+ env->GetFieldID(gSurfaceClassInfo.clazz, "mNativeObject", "I");
gSurfaceClassInfo.mLock =
env->GetFieldID(gSurfaceClassInfo.clazz, "mLock", "Ljava/lang/Object;");
gSurfaceClassInfo.ctor = env->GetMethodID(gSurfaceClassInfo.clazz, "<init>", "(I)V");
diff --git a/core/jni/android_view_TextureView.cpp b/core/jni/android_view_TextureView.cpp
index 5baae84..d515696 100644
--- a/core/jni/android_view_TextureView.cpp
+++ b/core/jni/android_view_TextureView.cpp
@@ -126,19 +126,19 @@ static void android_view_TextureView_destroyNativeWindow(JNIEnv* env, jobject te
}
static inline void swapCanvasPtr(JNIEnv* env, jobject canvasObj, SkCanvas* newCanvas) {
- jobject canvasFinalizerObj = env->GetObjectField(canvasObj, gCanvasClassInfo.mFinalizer);
- SkCanvas* previousCanvas = reinterpret_cast<SkCanvas*>(
+ jobject canvasFinalizerObj = env->GetObjectField(canvasObj, gCanvasClassInfo.mFinalizer);
+ SkCanvas* previousCanvas = reinterpret_cast<SkCanvas*>(
env->GetIntField(canvasObj, gCanvasClassInfo.mNativeCanvas));
- env->SetIntField(canvasObj, gCanvasClassInfo.mNativeCanvas, (int)newCanvas);
- env->SetIntField(canvasFinalizerObj, gCanvasFinalizerClassInfo.mNativeCanvas, (int)newCanvas);
- SkSafeUnref(previousCanvas);
+ env->SetIntField(canvasObj, gCanvasClassInfo.mNativeCanvas, (int)newCanvas);
+ env->SetIntField(canvasFinalizerObj, gCanvasFinalizerClassInfo.mNativeCanvas, (int)newCanvas);
+ SkSafeUnref(previousCanvas);
}
-static void android_view_TextureView_lockCanvas(JNIEnv* env, jobject,
+static jboolean android_view_TextureView_lockCanvas(JNIEnv* env, jobject,
jint nativeWindow, jobject canvas, jobject dirtyRect) {
if (!nativeWindow) {
- return;
+ return false;
}
ANativeWindow_Buffer buffer;
@@ -154,7 +154,8 @@ static void android_view_TextureView_lockCanvas(JNIEnv* env, jobject,
}
sp<ANativeWindow> window((ANativeWindow*) nativeWindow);
- native_window_lock(window.get(), &buffer, &rect);
+ int32_t status = native_window_lock(window.get(), &buffer, &rect);
+ if (status) return false;
ssize_t bytesCount = buffer.stride * bytesPerPixel(buffer.format);
@@ -184,6 +185,8 @@ static void android_view_TextureView_lockCanvas(JNIEnv* env, jobject,
INVOKEV(dirtyRect, gRectClassInfo.set,
int(rect.left), int(rect.top), int(rect.right), int(rect.bottom));
}
+
+ return true;
}
static void android_view_TextureView_unlockCanvasAndPost(JNIEnv* env, jobject,
@@ -213,7 +216,7 @@ static JNINativeMethod gMethods[] = {
{ "nDestroyNativeWindow", "()V",
(void*) android_view_TextureView_destroyNativeWindow },
- { "nLockCanvas", "(ILandroid/graphics/Canvas;Landroid/graphics/Rect;)V",
+ { "nLockCanvas", "(ILandroid/graphics/Canvas;Landroid/graphics/Rect;)Z",
(void*) android_view_TextureView_lockCanvas },
{ "nUnlockCanvasAndPost", "(ILandroid/graphics/Canvas;)V",
(void*) android_view_TextureView_unlockCanvasAndPost },
@@ -241,7 +244,8 @@ int register_android_view_TextureView(JNIEnv* env) {
GET_FIELD_ID(gRectClassInfo.bottom, clazz, "bottom", "I");
FIND_CLASS(clazz, "android/graphics/Canvas");
- GET_FIELD_ID(gCanvasClassInfo.mFinalizer, clazz, "mFinalizer", "Landroid/graphics/Canvas$CanvasFinalizer;");
+ GET_FIELD_ID(gCanvasClassInfo.mFinalizer, clazz, "mFinalizer",
+ "Landroid/graphics/Canvas$CanvasFinalizer;");
GET_FIELD_ID(gCanvasClassInfo.mNativeCanvas, clazz, "mNativeCanvas", "I");
GET_FIELD_ID(gCanvasClassInfo.mSurfaceFormat, clazz, "mSurfaceFormat", "I");
diff --git a/core/jni/com_android_internal_content_NativeLibraryHelper.cpp b/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
index 8d6fab4..bf5accd 100644
--- a/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
+++ b/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
@@ -20,7 +20,7 @@
#include <android_runtime/AndroidRuntime.h>
#include <utils/Log.h>
-#include <utils/ZipFileRO.h>
+#include <androidfw/ZipFileRO.h>
#include <ScopedUtfChars.h>
#include <zlib.h>
diff --git a/core/jni/com_google_android_gles_jni_GLImpl.cpp b/core/jni/com_google_android_gles_jni_GLImpl.cpp
index badd697..b0c26c5 100644
--- a/core/jni/com_google_android_gles_jni_GLImpl.cpp
+++ b/core/jni/com_google_android_gles_jni_GLImpl.cpp
@@ -1181,7 +1181,7 @@ android_glGetError__
(JNIEnv *_env, jobject _this) {
GLenum _returnValue;
_returnValue = glGetError();
- return _returnValue;
+ return (jint)_returnValue;
}
/* void glGetIntegerv ( GLenum pname, GLint *params ) */
@@ -4017,7 +4017,7 @@ exit:
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
}
- return _returnValue;
+ return (jint)_returnValue;
}
/* GLbitfield glQueryMatrixxOES ( GLfixed *mantissa, GLint *exponent ) */
@@ -4074,7 +4074,7 @@ exit:
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
}
- return _returnValue;
+ return (jint)_returnValue;
}
/* void glBindBuffer ( GLenum target, GLuint buffer ) */
@@ -4359,7 +4359,7 @@ android_glColorPointer__IIII
(GLint)size,
(GLenum)type,
(GLsizei)stride,
- (const GLvoid *)offset
+ (GLvoid *)offset
);
}
@@ -4460,7 +4460,7 @@ android_glDrawElements__IIII
(GLenum)mode,
(GLsizei)count,
(GLenum)type,
- (const GLvoid *)offset
+ (GLvoid *)offset
);
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -6067,7 +6067,7 @@ android_glIsBuffer__I
_returnValue = glIsBuffer(
(GLuint)buffer
);
- return _returnValue;
+ return (jboolean)_returnValue;
}
/* GLboolean glIsEnabled ( GLenum cap ) */
@@ -6078,7 +6078,7 @@ android_glIsEnabled__I
_returnValue = glIsEnabled(
(GLenum)cap
);
- return _returnValue;
+ return (jboolean)_returnValue;
}
/* GLboolean glIsTexture ( GLuint texture ) */
@@ -6089,7 +6089,7 @@ android_glIsTexture__I
_returnValue = glIsTexture(
(GLuint)texture
);
- return _returnValue;
+ return (jboolean)_returnValue;
}
/* void glNormalPointer ( GLenum type, GLsizei stride, GLint offset ) */
@@ -6099,7 +6099,7 @@ android_glNormalPointer__III
glNormalPointer(
(GLenum)type,
(GLsizei)stride,
- (const GLvoid *)offset
+ (GLvoid *)offset
);
}
@@ -6326,7 +6326,7 @@ android_glTexCoordPointer__IIII
(GLint)size,
(GLenum)type,
(GLsizei)stride,
- (const GLvoid *)offset
+ (GLvoid *)offset
);
}
@@ -6756,7 +6756,7 @@ android_glVertexPointer__IIII
(GLint)size,
(GLenum)type,
(GLsizei)stride,
- (const GLvoid *)offset
+ (GLvoid *)offset
);
}
@@ -7196,7 +7196,7 @@ android_glMatrixIndexPointerOES__IIII
(GLint)size,
(GLenum)type,
(GLsizei)stride,
- (const GLvoid *)offset
+ (GLvoid *)offset
);
}
@@ -7232,7 +7232,7 @@ android_glWeightPointerOES__IIII
(GLint)size,
(GLenum)type,
(GLsizei)stride,
- (const GLvoid *)offset
+ (GLvoid *)offset
);
}
@@ -7325,7 +7325,7 @@ android_glCheckFramebufferStatusOES__I
_returnValue = glCheckFramebufferStatusOES(
(GLint)target
);
- return _returnValue;
+ return (jint)_returnValue;
}
/* void glDeleteFramebuffersOES ( GLint n, GLuint *framebuffers ) */
@@ -8166,7 +8166,7 @@ android_glIsFramebufferOES__I
_returnValue = glIsFramebufferOES(
(GLint)framebuffer
);
- return _returnValue;
+ return (jboolean)_returnValue;
}
/* GLboolean glIsRenderbufferOES ( GLint renderbuffer ) */
@@ -8182,7 +8182,7 @@ android_glIsRenderbufferOES__I
_returnValue = glIsRenderbufferOES(
(GLint)renderbuffer
);
- return _returnValue;
+ return (jboolean)_returnValue;
}
/* void glRenderbufferStorageOES ( GLint target, GLint internalformat, GLint width, GLint height ) */
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 619a10b..6918099 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1078,6 +1078,14 @@
android:description="@string/permdesc_mediaStorageWrite"
android:protectionLevel="signature|system" />
+ <!-- Allows an application to manage access to documents, usually as part
+ of a document picker. -->
+ <permission android:name="android.permission.MANAGE_DOCUMENTS"
+ android:permissionGroup="android.permission-group.STORAGE"
+ android:label="@string/permlab_manageDocs"
+ android:description="@string/permdesc_manageDocs"
+ android:protectionLevel="signature|system" />
+
<!-- ================================== -->
<!-- Permissions for screenlock -->
<!-- ================================== -->
@@ -2202,6 +2210,20 @@
android:description="@string/permdesc_accessNotifications"
android:protectionLevel="signature|system" />
+ <!-- Allows access to keyguard secure storage. Only allowed for system processes.
+ @hide -->
+ <permission android:name="android.permission.ACCESS_KEYGUARD_SECURE_STORAGE"
+ android:protectionLevel="signature"
+ android:label="@string/permlab_access_keyguard_secure_storage"
+ android:description="@string/permdesc_access_keyguard_secure_storage" />
+
+ <!-- Allows an application to control keyguard. Only allowed for system processes.
+ @hide -->
+ <permission android:name="android.permission.CONTROL_KEYGUARD"
+ android:protectionLevel="signature"
+ android:label="@string/permlab_control_keyguard"
+ android:description="@string/permdesc_control_keyguard" />
+
<!-- Must be required by an {@link
android.service.notification.NotificationListenerService},
to ensure that only the system can bind to it. -->
@@ -2276,8 +2298,7 @@
<activity android:name="android.accounts.CantAddAccountActivity"
android:excludeFromRecents="true"
android:exported="true"
- android:theme="@android:style/Theme.Holo.Dialog"
- android:label="@string/error_message_title"
+ android:theme="@android:style/Theme.Holo.Dialog.NoActionBar"
android:process=":ui">
</activity>
diff --git a/core/res/res/anim/keyguard_action_assist_enter.xml b/core/res/res/anim/keyguard_action_assist_enter.xml
deleted file mode 100644
index f3333b7..0000000
--- a/core/res/res/anim/keyguard_action_assist_enter.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?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/core/res/res/anim/keyguard_security_animate_in.xml b/core/res/res/anim/keyguard_security_animate_in.xml
deleted file mode 100644
index 4ee30c3..0000000
--- a/core/res/res/anim/keyguard_security_animate_in.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?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/core/res/res/anim/keyguard_security_animate_out.xml b/core/res/res/anim/keyguard_security_animate_out.xml
deleted file mode 100644
index 76d065c..0000000
--- a/core/res/res/anim/keyguard_security_animate_out.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?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/core/res/res/anim/keyguard_security_fade_in.xml b/core/res/res/anim/keyguard_security_fade_in.xml
deleted file mode 100644
index 6293432..0000000
--- a/core/res/res/anim/keyguard_security_fade_in.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?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="@*android:integer/kg_security_fade_duration" />
-
-
diff --git a/core/res/res/anim/keyguard_security_fade_out.xml b/core/res/res/anim/keyguard_security_fade_out.xml
deleted file mode 100644
index 4ab0229..0000000
--- a/core/res/res/anim/keyguard_security_fade_out.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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="@*android:integer/kg_security_fade_duration"
-/>
diff --git a/core/res/res/anim/keyguard_action_assist_exit.xml b/core/res/res/anim/toast_bar_enter.xml
index b4ed278..5c0dfcf 100644
--- a/core/res/res/anim/keyguard_action_assist_exit.xml
+++ b/core/res/res/anim/toast_bar_enter.xml
@@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
-/*
-** Copyright 2012, The Android Open Source Project
+** 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.
@@ -17,7 +16,12 @@
*/
-->
-<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" />
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shareInterpolator="false">
+ <translate android:fromYDelta="10%" android:toYDelta="0"
+ android:interpolator="@interpolator/decelerate_quint"
+ android:duration="@android:integer/config_shortAnimTime"/>
+ <alpha android:fromAlpha="0.5" android:toAlpha="1.0"
+ android:interpolator="@interpolator/decelerate_cubic"
+ android:duration="@android:integer/config_shortAnimTime" />
+</set>
diff --git a/core/res/res/values-land/alias.xml b/core/res/res/anim/toast_bar_exit.xml
index eac5ece..4e3b7da 100644
--- a/core/res/res/values-land/alias.xml
+++ b/core/res/res/anim/toast_bar_exit.xml
@@ -1,8 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
-/* //device/apps/common/assets/res/any/colors.xml
-**
-** Copyright 2012, The Android Open Source Project
+** 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.
@@ -17,7 +15,12 @@
** limitations under the License.
*/
-->
-<resources>
- <!-- Alias used to reference one of two possible layouts in keyguard. -->
- <item type="layout" name="keyguard_eca">@android:layout/keyguard_emergency_carrier_area_empty</item>
-</resources>
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shareInterpolator="false">
+ <translate android:fromYDelta="0" android:toYDelta="10%"
+ android:interpolator="@interpolator/accelerate_quint"
+ android:duration="@android:integer/config_shortAnimTime"/>
+ <alpha android:fromAlpha="1.0" android:toAlpha="0.0"
+ android:interpolator="@interpolator/accelerate_cubic"
+ android:duration="@android:integer/config_shortAnimTime"/>
+</set>
diff --git a/core/res/res/drawable-hdpi/ic_facial_backup.png b/core/res/res/drawable-hdpi/ic_facial_backup.png
deleted file mode 100644
index 2956109..0000000
--- a/core/res/res/drawable-hdpi/ic_facial_backup.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_alarm.png b/core/res/res/drawable-hdpi/ic_lockscreen_alarm.png
deleted file mode 100644
index d7a8cfc..0000000
--- a/core/res/res/drawable-hdpi/ic_lockscreen_alarm.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_camera_activated.png b/core/res/res/drawable-hdpi/ic_lockscreen_camera_activated.png
deleted file mode 100644
index 19c8eb2..0000000
--- a/core/res/res/drawable-hdpi/ic_lockscreen_camera_activated.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_camera_normal.png b/core/res/res/drawable-hdpi/ic_lockscreen_camera_normal.png
deleted file mode 100644
index c79a245..0000000
--- a/core/res/res/drawable-hdpi/ic_lockscreen_camera_normal.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_emergencycall_normal.png b/core/res/res/drawable-hdpi/ic_lockscreen_emergencycall_normal.png
deleted file mode 100644
index 460495a..0000000
--- a/core/res/res/drawable-hdpi/ic_lockscreen_emergencycall_normal.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_emergencycall_pressed.png b/core/res/res/drawable-hdpi/ic_lockscreen_emergencycall_pressed.png
deleted file mode 100644
index b0f7ae9..0000000
--- a/core/res/res/drawable-hdpi/ic_lockscreen_emergencycall_pressed.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_forgotpassword_normal.png b/core/res/res/drawable-hdpi/ic_lockscreen_forgotpassword_normal.png
deleted file mode 100644
index 6402d3d..0000000
--- a/core/res/res/drawable-hdpi/ic_lockscreen_forgotpassword_normal.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_forgotpassword_pressed.png b/core/res/res/drawable-hdpi/ic_lockscreen_forgotpassword_pressed.png
deleted file mode 100644
index 83be046..0000000
--- a/core/res/res/drawable-hdpi/ic_lockscreen_forgotpassword_pressed.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_google_activated.png b/core/res/res/drawable-hdpi/ic_lockscreen_google_activated.png
deleted file mode 100644
index 2c4847c..0000000
--- a/core/res/res/drawable-hdpi/ic_lockscreen_google_activated.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_google_focused.png b/core/res/res/drawable-hdpi/ic_lockscreen_google_focused.png
deleted file mode 100644
index d98557d..0000000
--- a/core/res/res/drawable-hdpi/ic_lockscreen_google_focused.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_google_normal.png b/core/res/res/drawable-hdpi/ic_lockscreen_google_normal.png
deleted file mode 100644
index 656f3ba..0000000
--- a/core/res/res/drawable-hdpi/ic_lockscreen_google_normal.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_handle_normal.png b/core/res/res/drawable-hdpi/ic_lockscreen_handle_normal.png
deleted file mode 100644
index 1780ec0..0000000
--- a/core/res/res/drawable-hdpi/ic_lockscreen_handle_normal.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_ime.png b/core/res/res/drawable-hdpi/ic_lockscreen_ime.png
deleted file mode 100644
index 29a7989..0000000
--- a/core/res/res/drawable-hdpi/ic_lockscreen_ime.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_lock_normal.png b/core/res/res/drawable-hdpi/ic_lockscreen_lock_normal.png
deleted file mode 100644
index 732133c..0000000
--- a/core/res/res/drawable-hdpi/ic_lockscreen_lock_normal.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_lock_pressed.png b/core/res/res/drawable-hdpi/ic_lockscreen_lock_pressed.png
deleted file mode 100644
index 0bbf62f..0000000
--- a/core/res/res/drawable-hdpi/ic_lockscreen_lock_pressed.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_player_background.9.png b/core/res/res/drawable-hdpi/ic_lockscreen_player_background.9.png
deleted file mode 100644
index fbb75b5..0000000
--- a/core/res/res/drawable-hdpi/ic_lockscreen_player_background.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_search_activated.png b/core/res/res/drawable-hdpi/ic_lockscreen_search_activated.png
deleted file mode 100644
index 0d2e2ef..0000000
--- a/core/res/res/drawable-hdpi/ic_lockscreen_search_activated.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_search_normal.png b/core/res/res/drawable-hdpi/ic_lockscreen_search_normal.png
deleted file mode 100644
index 66d14ae..0000000
--- a/core/res/res/drawable-hdpi/ic_lockscreen_search_normal.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_silent_activated.png b/core/res/res/drawable-hdpi/ic_lockscreen_silent_activated.png
deleted file mode 100644
index 7060d59..0000000
--- a/core/res/res/drawable-hdpi/ic_lockscreen_silent_activated.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_silent_focused.png b/core/res/res/drawable-hdpi/ic_lockscreen_silent_focused.png
deleted file mode 100644
index f9a8c7c..0000000
--- a/core/res/res/drawable-hdpi/ic_lockscreen_silent_focused.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_silent_normal.png b/core/res/res/drawable-hdpi/ic_lockscreen_silent_normal.png
deleted file mode 100644
index b47cd08..0000000
--- a/core/res/res/drawable-hdpi/ic_lockscreen_silent_normal.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_sim.png b/core/res/res/drawable-hdpi/ic_lockscreen_sim.png
deleted file mode 100644
index 7cf9e36..0000000
--- a/core/res/res/drawable-hdpi/ic_lockscreen_sim.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_soundon_activated.png b/core/res/res/drawable-hdpi/ic_lockscreen_soundon_activated.png
deleted file mode 100644
index 88d0a9f..0000000
--- a/core/res/res/drawable-hdpi/ic_lockscreen_soundon_activated.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_soundon_focused.png b/core/res/res/drawable-hdpi/ic_lockscreen_soundon_focused.png
deleted file mode 100644
index 6e16e40..0000000
--- a/core/res/res/drawable-hdpi/ic_lockscreen_soundon_focused.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_soundon_normal.png b/core/res/res/drawable-hdpi/ic_lockscreen_soundon_normal.png
deleted file mode 100644
index 0dd81c0..0000000
--- a/core/res/res/drawable-hdpi/ic_lockscreen_soundon_normal.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_unlock_activated.png b/core/res/res/drawable-hdpi/ic_lockscreen_unlock_activated.png
deleted file mode 100644
index 374a62a..0000000
--- a/core/res/res/drawable-hdpi/ic_lockscreen_unlock_activated.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_unlock_normal.png b/core/res/res/drawable-hdpi/ic_lockscreen_unlock_normal.png
deleted file mode 100644
index 3960893..0000000
--- a/core/res/res/drawable-hdpi/ic_lockscreen_unlock_normal.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/intro_bg.png b/core/res/res/drawable-hdpi/intro_bg.png
deleted file mode 100644
index a758e7d..0000000
--- a/core/res/res/drawable-hdpi/intro_bg.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/kg_add_widget.png b/core/res/res/drawable-hdpi/kg_add_widget.png
deleted file mode 100644
index 68971a5..0000000
--- a/core/res/res/drawable-hdpi/kg_add_widget.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/kg_add_widget_disabled.png b/core/res/res/drawable-hdpi/kg_add_widget_disabled.png
deleted file mode 100644
index f24cf642..0000000
--- a/core/res/res/drawable-hdpi/kg_add_widget_disabled.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/kg_add_widget_pressed.png b/core/res/res/drawable-hdpi/kg_add_widget_pressed.png
deleted file mode 100644
index 55112ca..0000000
--- a/core/res/res/drawable-hdpi/kg_add_widget_pressed.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/kg_bouncer_bg_white.9.png b/core/res/res/drawable-hdpi/kg_bouncer_bg_white.9.png
deleted file mode 100644
index cfd5db3..0000000
--- a/core/res/res/drawable-hdpi/kg_bouncer_bg_white.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/kg_security_grip.9.png b/core/res/res/drawable-hdpi/kg_security_grip.9.png
deleted file mode 100644
index 1e40aef..0000000
--- a/core/res/res/drawable-hdpi/kg_security_grip.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/kg_security_lock.png b/core/res/res/drawable-hdpi/kg_security_lock.png
deleted file mode 100644
index c3c94c4..0000000
--- a/core/res/res/drawable-hdpi/kg_security_lock.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/kg_security_lock_focused.png b/core/res/res/drawable-hdpi/kg_security_lock_focused.png
deleted file mode 100644
index abcf683..0000000
--- a/core/res/res/drawable-hdpi/kg_security_lock_focused.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/kg_security_lock_normal.png b/core/res/res/drawable-hdpi/kg_security_lock_normal.png
deleted file mode 100644
index e8cff24..0000000
--- a/core/res/res/drawable-hdpi/kg_security_lock_normal.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/kg_security_lock_pressed.png b/core/res/res/drawable-hdpi/kg_security_lock_pressed.png
deleted file mode 100644
index 3214dcb..0000000
--- a/core/res/res/drawable-hdpi/kg_security_lock_pressed.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/kg_widget_bg_padded.9.png b/core/res/res/drawable-hdpi/kg_widget_bg_padded.9.png
deleted file mode 100644
index dff1dfa..0000000
--- a/core/res/res/drawable-hdpi/kg_widget_bg_padded.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/kg_widget_delete_drop_target.png b/core/res/res/drawable-hdpi/kg_widget_delete_drop_target.png
deleted file mode 100644
index 84549ff..0000000
--- a/core/res/res/drawable-hdpi/kg_widget_delete_drop_target.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/lockscreen_protection_pattern.png b/core/res/res/drawable-hdpi/lockscreen_protection_pattern.png
deleted file mode 100644
index 681d8be..0000000
--- a/core/res/res/drawable-hdpi/lockscreen_protection_pattern.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/sym_keyboard_return_holo.png b/core/res/res/drawable-hdpi/sym_keyboard_return_holo.png
deleted file mode 100644
index f1bcf48..0000000
--- a/core/res/res/drawable-hdpi/sym_keyboard_return_holo.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/toast_bar_bg.9.png b/core/res/res/drawable-hdpi/toast_bar_bg.9.png
new file mode 100644
index 0000000..2396b26
--- /dev/null
+++ b/core/res/res/drawable-hdpi/toast_bar_bg.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_facial_backup.png b/core/res/res/drawable-mdpi/ic_facial_backup.png
deleted file mode 100644
index 6ed1327..0000000
--- a/core/res/res/drawable-mdpi/ic_facial_backup.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_alarm.png b/core/res/res/drawable-mdpi/ic_lockscreen_alarm.png
deleted file mode 100644
index 330ade1..0000000
--- a/core/res/res/drawable-mdpi/ic_lockscreen_alarm.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_camera_activated.png b/core/res/res/drawable-mdpi/ic_lockscreen_camera_activated.png
deleted file mode 100644
index 862f33b..0000000
--- a/core/res/res/drawable-mdpi/ic_lockscreen_camera_activated.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_camera_normal.png b/core/res/res/drawable-mdpi/ic_lockscreen_camera_normal.png
deleted file mode 100644
index 30df0a3..0000000
--- a/core/res/res/drawable-mdpi/ic_lockscreen_camera_normal.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_emergencycall_normal.png b/core/res/res/drawable-mdpi/ic_lockscreen_emergencycall_normal.png
deleted file mode 100644
index cae795f..0000000
--- a/core/res/res/drawable-mdpi/ic_lockscreen_emergencycall_normal.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_emergencycall_pressed.png b/core/res/res/drawable-mdpi/ic_lockscreen_emergencycall_pressed.png
deleted file mode 100644
index 2867956..0000000
--- a/core/res/res/drawable-mdpi/ic_lockscreen_emergencycall_pressed.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_forgotpassword_normal.png b/core/res/res/drawable-mdpi/ic_lockscreen_forgotpassword_normal.png
deleted file mode 100644
index a7e063a..0000000
--- a/core/res/res/drawable-mdpi/ic_lockscreen_forgotpassword_normal.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_forgotpassword_pressed.png b/core/res/res/drawable-mdpi/ic_lockscreen_forgotpassword_pressed.png
deleted file mode 100644
index 53af5a5..0000000
--- a/core/res/res/drawable-mdpi/ic_lockscreen_forgotpassword_pressed.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_google_activated.png b/core/res/res/drawable-mdpi/ic_lockscreen_google_activated.png
deleted file mode 100644
index 32a68e0..0000000
--- a/core/res/res/drawable-mdpi/ic_lockscreen_google_activated.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_google_focused.png b/core/res/res/drawable-mdpi/ic_lockscreen_google_focused.png
deleted file mode 100644
index 3f96d03..0000000
--- a/core/res/res/drawable-mdpi/ic_lockscreen_google_focused.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_google_normal.png b/core/res/res/drawable-mdpi/ic_lockscreen_google_normal.png
deleted file mode 100644
index 2f7efcf..0000000
--- a/core/res/res/drawable-mdpi/ic_lockscreen_google_normal.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_handle_normal.png b/core/res/res/drawable-mdpi/ic_lockscreen_handle_normal.png
deleted file mode 100644
index 1d547e1..0000000
--- a/core/res/res/drawable-mdpi/ic_lockscreen_handle_normal.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_ime.png b/core/res/res/drawable-mdpi/ic_lockscreen_ime.png
deleted file mode 100644
index b27e059..0000000
--- a/core/res/res/drawable-mdpi/ic_lockscreen_ime.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_lock_normal.png b/core/res/res/drawable-mdpi/ic_lockscreen_lock_normal.png
deleted file mode 100644
index 30eb974..0000000
--- a/core/res/res/drawable-mdpi/ic_lockscreen_lock_normal.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_lock_pressed.png b/core/res/res/drawable-mdpi/ic_lockscreen_lock_pressed.png
deleted file mode 100644
index aab2f6b..0000000
--- a/core/res/res/drawable-mdpi/ic_lockscreen_lock_pressed.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_player_background.9.png b/core/res/res/drawable-mdpi/ic_lockscreen_player_background.9.png
deleted file mode 100644
index 17d97c4..0000000
--- a/core/res/res/drawable-mdpi/ic_lockscreen_player_background.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_search_activated.png b/core/res/res/drawable-mdpi/ic_lockscreen_search_activated.png
deleted file mode 100644
index 73c6be6..0000000
--- a/core/res/res/drawable-mdpi/ic_lockscreen_search_activated.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_search_normal.png b/core/res/res/drawable-mdpi/ic_lockscreen_search_normal.png
deleted file mode 100644
index 73c6be6..0000000
--- a/core/res/res/drawable-mdpi/ic_lockscreen_search_normal.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_silent_activated.png b/core/res/res/drawable-mdpi/ic_lockscreen_silent_activated.png
deleted file mode 100644
index 2bc3f52..0000000
--- a/core/res/res/drawable-mdpi/ic_lockscreen_silent_activated.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_silent_focused.png b/core/res/res/drawable-mdpi/ic_lockscreen_silent_focused.png
deleted file mode 100644
index 6a5af9d..0000000
--- a/core/res/res/drawable-mdpi/ic_lockscreen_silent_focused.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_silent_normal.png b/core/res/res/drawable-mdpi/ic_lockscreen_silent_normal.png
deleted file mode 100644
index c288ce4..0000000
--- a/core/res/res/drawable-mdpi/ic_lockscreen_silent_normal.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_sim.png b/core/res/res/drawable-mdpi/ic_lockscreen_sim.png
deleted file mode 100644
index 2e259c3..0000000
--- a/core/res/res/drawable-mdpi/ic_lockscreen_sim.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_soundon_activated.png b/core/res/res/drawable-mdpi/ic_lockscreen_soundon_activated.png
deleted file mode 100644
index 637eec6..0000000
--- a/core/res/res/drawable-mdpi/ic_lockscreen_soundon_activated.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_soundon_focused.png b/core/res/res/drawable-mdpi/ic_lockscreen_soundon_focused.png
deleted file mode 100644
index db59b5f..0000000
--- a/core/res/res/drawable-mdpi/ic_lockscreen_soundon_focused.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_soundon_normal.png b/core/res/res/drawable-mdpi/ic_lockscreen_soundon_normal.png
deleted file mode 100644
index eb6ceed..0000000
--- a/core/res/res/drawable-mdpi/ic_lockscreen_soundon_normal.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_unlock_activated.png b/core/res/res/drawable-mdpi/ic_lockscreen_unlock_activated.png
deleted file mode 100644
index 68409c5..0000000
--- a/core/res/res/drawable-mdpi/ic_lockscreen_unlock_activated.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_unlock_normal.png b/core/res/res/drawable-mdpi/ic_lockscreen_unlock_normal.png
deleted file mode 100644
index 52866f2..0000000
--- a/core/res/res/drawable-mdpi/ic_lockscreen_unlock_normal.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/intro_bg.png b/core/res/res/drawable-mdpi/intro_bg.png
deleted file mode 100644
index 540da31..0000000
--- a/core/res/res/drawable-mdpi/intro_bg.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/kg_add_widget.png b/core/res/res/drawable-mdpi/kg_add_widget.png
deleted file mode 100644
index 136ae17..0000000
--- a/core/res/res/drawable-mdpi/kg_add_widget.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/kg_add_widget_disabled.png b/core/res/res/drawable-mdpi/kg_add_widget_disabled.png
deleted file mode 100644
index 02e0f0e..0000000
--- a/core/res/res/drawable-mdpi/kg_add_widget_disabled.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/kg_add_widget_pressed.png b/core/res/res/drawable-mdpi/kg_add_widget_pressed.png
deleted file mode 100644
index 34a7aaa..0000000
--- a/core/res/res/drawable-mdpi/kg_add_widget_pressed.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/kg_bouncer_bg_white.9.png b/core/res/res/drawable-mdpi/kg_bouncer_bg_white.9.png
deleted file mode 100644
index e3cb6db..0000000
--- a/core/res/res/drawable-mdpi/kg_bouncer_bg_white.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/kg_security_grip.9.png b/core/res/res/drawable-mdpi/kg_security_grip.9.png
deleted file mode 100644
index 334a39b..0000000
--- a/core/res/res/drawable-mdpi/kg_security_grip.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/kg_security_lock.png b/core/res/res/drawable-mdpi/kg_security_lock.png
deleted file mode 100644
index a39f380..0000000
--- a/core/res/res/drawable-mdpi/kg_security_lock.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/kg_security_lock_focused.png b/core/res/res/drawable-mdpi/kg_security_lock_focused.png
deleted file mode 100644
index c567a82..0000000
--- a/core/res/res/drawable-mdpi/kg_security_lock_focused.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/kg_security_lock_normal.png b/core/res/res/drawable-mdpi/kg_security_lock_normal.png
deleted file mode 100644
index 6fbecc1..0000000
--- a/core/res/res/drawable-mdpi/kg_security_lock_normal.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/kg_security_lock_pressed.png b/core/res/res/drawable-mdpi/kg_security_lock_pressed.png
deleted file mode 100644
index a883258..0000000
--- a/core/res/res/drawable-mdpi/kg_security_lock_pressed.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/kg_widget_bg_padded.9.png b/core/res/res/drawable-mdpi/kg_widget_bg_padded.9.png
deleted file mode 100644
index c313df1..0000000
--- a/core/res/res/drawable-mdpi/kg_widget_bg_padded.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/kg_widget_delete_drop_target.png b/core/res/res/drawable-mdpi/kg_widget_delete_drop_target.png
deleted file mode 100644
index 219f3e5..0000000
--- a/core/res/res/drawable-mdpi/kg_widget_delete_drop_target.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/lockscreen_protection_pattern.png b/core/res/res/drawable-mdpi/lockscreen_protection_pattern.png
deleted file mode 100644
index 30bcea5..0000000
--- a/core/res/res/drawable-mdpi/lockscreen_protection_pattern.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/sym_keyboard_return_holo.png b/core/res/res/drawable-mdpi/sym_keyboard_return_holo.png
deleted file mode 100644
index d5a7708..0000000
--- a/core/res/res/drawable-mdpi/sym_keyboard_return_holo.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/toast_bar_bg.9.png b/core/res/res/drawable-mdpi/toast_bar_bg.9.png
new file mode 100644
index 0000000..291a936
--- /dev/null
+++ b/core/res/res/drawable-mdpi/toast_bar_bg.9.png
Binary files differ
diff --git a/core/res/res/drawable-sw600dp-hdpi/ic_lockscreen_handle_normal.png b/core/res/res/drawable-sw600dp-hdpi/ic_lockscreen_handle_normal.png
deleted file mode 100644
index f28fe38..0000000
--- a/core/res/res/drawable-sw600dp-hdpi/ic_lockscreen_handle_normal.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-sw600dp-mdpi/ic_lockscreen_handle_normal.png b/core/res/res/drawable-sw600dp-mdpi/ic_lockscreen_handle_normal.png
deleted file mode 100644
index 99e742f..0000000
--- a/core/res/res/drawable-sw600dp-mdpi/ic_lockscreen_handle_normal.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-sw600dp-xhdpi/ic_lockscreen_handle_normal.png b/core/res/res/drawable-sw600dp-xhdpi/ic_lockscreen_handle_normal.png
deleted file mode 100644
index 75e4783..0000000
--- a/core/res/res/drawable-sw600dp-xhdpi/ic_lockscreen_handle_normal.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_facial_backup.png b/core/res/res/drawable-xhdpi/ic_facial_backup.png
deleted file mode 100644
index 942cf23..0000000
--- a/core/res/res/drawable-xhdpi/ic_facial_backup.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_alarm.png b/core/res/res/drawable-xhdpi/ic_lockscreen_alarm.png
deleted file mode 100644
index e6cceef..0000000
--- a/core/res/res/drawable-xhdpi/ic_lockscreen_alarm.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_camera_activated.png b/core/res/res/drawable-xhdpi/ic_lockscreen_camera_activated.png
deleted file mode 100644
index 760ef2d..0000000
--- a/core/res/res/drawable-xhdpi/ic_lockscreen_camera_activated.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_camera_normal.png b/core/res/res/drawable-xhdpi/ic_lockscreen_camera_normal.png
deleted file mode 100644
index 093bc05..0000000
--- a/core/res/res/drawable-xhdpi/ic_lockscreen_camera_normal.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_emergencycall_normal.png b/core/res/res/drawable-xhdpi/ic_lockscreen_emergencycall_normal.png
deleted file mode 100644
index a61f7a5..0000000
--- a/core/res/res/drawable-xhdpi/ic_lockscreen_emergencycall_normal.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_emergencycall_pressed.png b/core/res/res/drawable-xhdpi/ic_lockscreen_emergencycall_pressed.png
deleted file mode 100644
index dd5e481..0000000
--- a/core/res/res/drawable-xhdpi/ic_lockscreen_emergencycall_pressed.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_forgotpassword_normal.png b/core/res/res/drawable-xhdpi/ic_lockscreen_forgotpassword_normal.png
deleted file mode 100644
index e4172ce..0000000
--- a/core/res/res/drawable-xhdpi/ic_lockscreen_forgotpassword_normal.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_forgotpassword_pressed.png b/core/res/res/drawable-xhdpi/ic_lockscreen_forgotpassword_pressed.png
deleted file mode 100644
index e2c7621..0000000
--- a/core/res/res/drawable-xhdpi/ic_lockscreen_forgotpassword_pressed.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_google_activated.png b/core/res/res/drawable-xhdpi/ic_lockscreen_google_activated.png
deleted file mode 100644
index d643f83..0000000
--- a/core/res/res/drawable-xhdpi/ic_lockscreen_google_activated.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_google_focused.png b/core/res/res/drawable-xhdpi/ic_lockscreen_google_focused.png
deleted file mode 100644
index 51863f4..0000000
--- a/core/res/res/drawable-xhdpi/ic_lockscreen_google_focused.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_google_normal.png b/core/res/res/drawable-xhdpi/ic_lockscreen_google_normal.png
deleted file mode 100644
index 9a9bf68..0000000
--- a/core/res/res/drawable-xhdpi/ic_lockscreen_google_normal.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_handle_normal.png b/core/res/res/drawable-xhdpi/ic_lockscreen_handle_normal.png
deleted file mode 100644
index b09071b..0000000
--- a/core/res/res/drawable-xhdpi/ic_lockscreen_handle_normal.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_ime.png b/core/res/res/drawable-xhdpi/ic_lockscreen_ime.png
deleted file mode 100644
index a40ddeb..0000000
--- a/core/res/res/drawable-xhdpi/ic_lockscreen_ime.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_lock_normal.png b/core/res/res/drawable-xhdpi/ic_lockscreen_lock_normal.png
deleted file mode 100644
index c44a330..0000000
--- a/core/res/res/drawable-xhdpi/ic_lockscreen_lock_normal.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_lock_pressed.png b/core/res/res/drawable-xhdpi/ic_lockscreen_lock_pressed.png
deleted file mode 100644
index 2264dc3..0000000
--- a/core/res/res/drawable-xhdpi/ic_lockscreen_lock_pressed.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_player_background.9.png b/core/res/res/drawable-xhdpi/ic_lockscreen_player_background.9.png
deleted file mode 100644
index 393bca6..0000000
--- a/core/res/res/drawable-xhdpi/ic_lockscreen_player_background.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_silent_activated.png b/core/res/res/drawable-xhdpi/ic_lockscreen_silent_activated.png
deleted file mode 100644
index 2900045..0000000
--- a/core/res/res/drawable-xhdpi/ic_lockscreen_silent_activated.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_silent_focused.png b/core/res/res/drawable-xhdpi/ic_lockscreen_silent_focused.png
deleted file mode 100644
index 5a93472..0000000
--- a/core/res/res/drawable-xhdpi/ic_lockscreen_silent_focused.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_silent_normal.png b/core/res/res/drawable-xhdpi/ic_lockscreen_silent_normal.png
deleted file mode 100644
index 73f6a2e..0000000
--- a/core/res/res/drawable-xhdpi/ic_lockscreen_silent_normal.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_sim.png b/core/res/res/drawable-xhdpi/ic_lockscreen_sim.png
deleted file mode 100644
index f4de96a..0000000
--- a/core/res/res/drawable-xhdpi/ic_lockscreen_sim.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_soundon_activated.png b/core/res/res/drawable-xhdpi/ic_lockscreen_soundon_activated.png
deleted file mode 100644
index da2adc2..0000000
--- a/core/res/res/drawable-xhdpi/ic_lockscreen_soundon_activated.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_soundon_focused.png b/core/res/res/drawable-xhdpi/ic_lockscreen_soundon_focused.png
deleted file mode 100644
index 0485af0..0000000
--- a/core/res/res/drawable-xhdpi/ic_lockscreen_soundon_focused.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_soundon_normal.png b/core/res/res/drawable-xhdpi/ic_lockscreen_soundon_normal.png
deleted file mode 100644
index 6af5375..0000000
--- a/core/res/res/drawable-xhdpi/ic_lockscreen_soundon_normal.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_unlock_activated.png b/core/res/res/drawable-xhdpi/ic_lockscreen_unlock_activated.png
deleted file mode 100644
index 8a0331d..0000000
--- a/core/res/res/drawable-xhdpi/ic_lockscreen_unlock_activated.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_unlock_normal.png b/core/res/res/drawable-xhdpi/ic_lockscreen_unlock_normal.png
deleted file mode 100644
index 0422117..0000000
--- a/core/res/res/drawable-xhdpi/ic_lockscreen_unlock_normal.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/intro_bg.png b/core/res/res/drawable-xhdpi/intro_bg.png
deleted file mode 100644
index 00466c5..0000000
--- a/core/res/res/drawable-xhdpi/intro_bg.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/kg_add_widget.png b/core/res/res/drawable-xhdpi/kg_add_widget.png
deleted file mode 100644
index ca48be2..0000000
--- a/core/res/res/drawable-xhdpi/kg_add_widget.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/kg_add_widget_disabled.png b/core/res/res/drawable-xhdpi/kg_add_widget_disabled.png
deleted file mode 100644
index 55fa1ac..0000000
--- a/core/res/res/drawable-xhdpi/kg_add_widget_disabled.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/kg_add_widget_pressed.png b/core/res/res/drawable-xhdpi/kg_add_widget_pressed.png
deleted file mode 100644
index 4b86727..0000000
--- a/core/res/res/drawable-xhdpi/kg_add_widget_pressed.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/kg_bouncer_bg_white.9.png b/core/res/res/drawable-xhdpi/kg_bouncer_bg_white.9.png
deleted file mode 100644
index b9e30e2..0000000
--- a/core/res/res/drawable-xhdpi/kg_bouncer_bg_white.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/kg_security_grip.9.png b/core/res/res/drawable-xhdpi/kg_security_grip.9.png
deleted file mode 100644
index c33b9d3..0000000
--- a/core/res/res/drawable-xhdpi/kg_security_grip.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/kg_security_lock.png b/core/res/res/drawable-xhdpi/kg_security_lock.png
deleted file mode 100644
index 81d577e..0000000
--- a/core/res/res/drawable-xhdpi/kg_security_lock.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/kg_security_lock_focused.png b/core/res/res/drawable-xhdpi/kg_security_lock_focused.png
deleted file mode 100644
index ee21647..0000000
--- a/core/res/res/drawable-xhdpi/kg_security_lock_focused.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/kg_security_lock_normal.png b/core/res/res/drawable-xhdpi/kg_security_lock_normal.png
deleted file mode 100644
index eae7d8c..0000000
--- a/core/res/res/drawable-xhdpi/kg_security_lock_normal.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/kg_security_lock_pressed.png b/core/res/res/drawable-xhdpi/kg_security_lock_pressed.png
deleted file mode 100644
index 5e9a52b..0000000
--- a/core/res/res/drawable-xhdpi/kg_security_lock_pressed.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/kg_widget_bg_padded.9.png b/core/res/res/drawable-xhdpi/kg_widget_bg_padded.9.png
deleted file mode 100644
index a84bfa3..0000000
--- a/core/res/res/drawable-xhdpi/kg_widget_bg_padded.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/kg_widget_delete_drop_target.png b/core/res/res/drawable-xhdpi/kg_widget_delete_drop_target.png
deleted file mode 100644
index d4965d9..0000000
--- a/core/res/res/drawable-xhdpi/kg_widget_delete_drop_target.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/lockscreen_protection_pattern.png b/core/res/res/drawable-xhdpi/lockscreen_protection_pattern.png
deleted file mode 100644
index c13afe2..0000000
--- a/core/res/res/drawable-xhdpi/lockscreen_protection_pattern.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/sym_keyboard_return_holo.png b/core/res/res/drawable-xhdpi/sym_keyboard_return_holo.png
deleted file mode 100644
index 55174e0..0000000
--- a/core/res/res/drawable-xhdpi/sym_keyboard_return_holo.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/toast_bar_bg.9.png b/core/res/res/drawable-xhdpi/toast_bar_bg.9.png
new file mode 100644
index 0000000..1dc4927
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/toast_bar_bg.9.png
Binary files differ
diff --git a/core/res/res/drawable/ic_lockscreen_camera.xml b/core/res/res/drawable/ic_lockscreen_camera.xml
deleted file mode 100644
index 41277fe..0000000
--- a/core/res/res/drawable/ic_lockscreen_camera.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-<?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/core/res/res/drawable/ic_lockscreen_handle.xml b/core/res/res/drawable/ic_lockscreen_handle.xml
deleted file mode 100644
index e7b4a6e..0000000
--- a/core/res/res/drawable/ic_lockscreen_handle.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?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/core/res/res/drawable/ic_lockscreen_silent.xml b/core/res/res/drawable/ic_lockscreen_silent.xml
deleted file mode 100644
index df23278..0000000
--- a/core/res/res/drawable/ic_lockscreen_silent.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-<?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/core/res/res/drawable/ic_lockscreen_soundon.xml b/core/res/res/drawable/ic_lockscreen_soundon.xml
deleted file mode 100644
index b44c86c..0000000
--- a/core/res/res/drawable/ic_lockscreen_soundon.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-<?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/core/res/res/drawable/ic_lockscreen_unlock.xml b/core/res/res/drawable/ic_lockscreen_unlock.xml
deleted file mode 100644
index bb1d0ee..0000000
--- a/core/res/res/drawable/ic_lockscreen_unlock.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-<?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/core/res/res/drawable/ic_lockscreen_unlock_phantom.xml b/core/res/res/drawable/ic_lockscreen_unlock_phantom.xml
deleted file mode 100644
index 83f0aed..0000000
--- a/core/res/res/drawable/ic_lockscreen_unlock_phantom.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-<?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/core/res/res/drawable/keyguard_add_widget_button.xml b/core/res/res/drawable/keyguard_add_widget_button.xml
deleted file mode 100644
index c26f81d..0000000
--- a/core/res/res/drawable/keyguard_add_widget_button.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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/core/res/res/drawable/keyguard_expand_challenge_handle.xml b/core/res/res/drawable/keyguard_expand_challenge_handle.xml
deleted file mode 100644
index 3e0780b..0000000
--- a/core/res/res/drawable/keyguard_expand_challenge_handle.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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/core/res/res/drawable/lockscreen_emergency_button.xml b/core/res/res/drawable/lockscreen_emergency_button.xml
deleted file mode 100644
index 4ec6a96..0000000
--- a/core/res/res/drawable/lockscreen_emergency_button.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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/core/res/res/drawable/lockscreen_forgot_password_button.xml b/core/res/res/drawable/lockscreen_forgot_password_button.xml
deleted file mode 100644
index 6c081bf..0000000
--- a/core/res/res/drawable/lockscreen_forgot_password_button.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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/core/res/res/drawable/lockscreen_password_field_dark.xml b/core/res/res/drawable/lockscreen_password_field_dark.xml
deleted file mode 100644
index 92ceb79..0000000
--- a/core/res/res/drawable/lockscreen_password_field_dark.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_window_focused="false" android:state_enabled="true" android:drawable="@drawable/textfield_bg_default_holo_dark" />
- <item android:state_window_focused="false" android:state_enabled="false" android:drawable="@drawable/textfield_bg_disabled_holo_dark" />
- <item android:state_enabled="true" android:state_focused="true" android:drawable="@drawable/textfield_bg_activated_holo_dark" />
- <iten android:state_enabled="true" android:state_activated="true" android:drawable="@drawable/textfield_bg_focused_holo_dark" />
- <item android:state_enabled="true" android:drawable="@drawable/textfield_bg_default_holo_dark" />
- <item android:state_focused="true" android:drawable="@drawable/textfield_bg_disabled_focused_holo_dark" />
- <item android:drawable="@drawable/textfield_bg_disabled_holo_dark" />
-</selector>
-
diff --git a/core/res/res/layout-land/keyguard_glow_pad_container.xml b/core/res/res/layout-land/keyguard_glow_pad_container.xml
deleted file mode 100644
index f8364f1..0000000
--- a/core/res/res/layout-land/keyguard_glow_pad_container.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?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/core/res/res/layout-land/keyguard_host_view.xml b/core/res/res/layout-land/keyguard_host_view.xml
deleted file mode 100644
index 6b36235..0000000
--- a/core/res/res/layout-land/keyguard_host_view.xml
+++ /dev/null
@@ -1,80 +0,0 @@
-<?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.internal.policy.impl.keyguard.KeyguardHostView
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:androidprv="http://schemas.android.com/apk/res/android"
- android:id="@+id/keyguard_host_view"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="horizontal">
-
- <com.android.internal.policy.impl.keyguard.MultiPaneChallengeLayout
- android:id="@+id/multi_pane_challenge"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- 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.internal.policy.impl.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.internal.policy.impl.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.internal.policy.impl.keyguard.KeyguardSecurityViewFlipper>
- </com.android.internal.policy.impl.keyguard.KeyguardSecurityContainer>
-
- </com.android.internal.policy.impl.keyguard.MultiPaneChallengeLayout>
-</com.android.internal.policy.impl.keyguard.KeyguardHostView>
-
diff --git a/core/res/res/layout-land/keyguard_status_area.xml b/core/res/res/layout-land/keyguard_status_area.xml
deleted file mode 100644
index 51ee740..0000000
--- a/core/res/res/layout-land/keyguard_status_area.xml
+++ /dev/null
@@ -1,56 +0,0 @@
-<?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/core/res/res/layout-land/keyguard_widget_pager.xml b/core/res/res/layout-land/keyguard_widget_pager.xml
deleted file mode 100644
index 02c6d0e..0000000
--- a/core/res/res/layout-land/keyguard_widget_pager.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?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.policy.impl.keyguard.KeyguardWidgetCarousel
- xmlns:androidprv="http://schemas.android.com/apk/res/android"
- 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.internal.policy.impl.keyguard.KeyguardWidgetCarousel> \ No newline at end of file
diff --git a/core/res/res/layout-port/keyguard_host_view.xml b/core/res/res/layout-port/keyguard_host_view.xml
deleted file mode 100644
index fb25f9c..0000000
--- a/core/res/res/layout-port/keyguard_host_view.xml
+++ /dev/null
@@ -1,94 +0,0 @@
-<?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.internal.policy.impl.keyguard.KeyguardHostView
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:androidprv="http://schemas.android.com/apk/res/android"
- 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.internal.policy.impl.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.internal.policy.impl.keyguard.KeyguardSecurityContainer
- android:id="@+id/keyguard_security_container"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_maxHeight="@dimen/keyguard_security_height"
- androidprv:layout_childType="challenge"
- android:padding="0dp"
- android:gravity="bottom|center_horizontal">
- <com.android.internal.policy.impl.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.internal.policy.impl.keyguard.KeyguardSecurityViewFlipper>
- </com.android.internal.policy.impl.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.internal.policy.impl.keyguard.SlidingChallengeLayout>
-</com.android.internal.policy.impl.keyguard.KeyguardHostView>
-
diff --git a/core/res/res/layout-port/keyguard_status_area.xml b/core/res/res/layout-port/keyguard_status_area.xml
deleted file mode 100644
index d274457..0000000
--- a/core/res/res/layout-port/keyguard_status_area.xml
+++ /dev/null
@@ -1,59 +0,0 @@
-<?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/core/res/res/layout-port/keyguard_widget_pager.xml b/core/res/res/layout-port/keyguard_widget_pager.xml
deleted file mode 100644
index 7f22709..0000000
--- a/core/res/res/layout-port/keyguard_widget_pager.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?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.policy.impl.keyguard.KeyguardWidgetPager
- xmlns:androidprv="http://schemas.android.com/apk/res/android"
- 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.internal.policy.impl.keyguard.KeyguardWidgetPager>
diff --git a/core/res/res/layout-sw600dp-port/keyguard_host_view.xml b/core/res/res/layout-sw600dp-port/keyguard_host_view.xml
deleted file mode 100644
index e3d577d..0000000
--- a/core/res/res/layout-sw600dp-port/keyguard_host_view.xml
+++ /dev/null
@@ -1,82 +0,0 @@
-<?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.internal.policy.impl.keyguard.KeyguardHostView
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:androidprv="http://schemas.android.com/apk/res/android"
- android:id="@+id/keyguard_host_view"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="horizontal">
-
- <com.android.internal.policy.impl.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.internal.policy.impl.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.internal.policy.impl.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.internal.policy.impl.keyguard.KeyguardSecurityViewFlipper>
- </com.android.internal.policy.impl.keyguard.KeyguardSecurityContainer>
-
- </com.android.internal.policy.impl.keyguard.MultiPaneChallengeLayout>
-</com.android.internal.policy.impl.keyguard.KeyguardHostView>
diff --git a/core/res/res/layout-sw600dp-port/keyguard_status_area.xml b/core/res/res/layout-sw600dp-port/keyguard_status_area.xml
deleted file mode 100644
index 88dd760..0000000
--- a/core/res/res/layout-sw600dp-port/keyguard_status_area.xml
+++ /dev/null
@@ -1,56 +0,0 @@
-<?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>
diff --git a/core/res/res/layout-sw600dp/keyguard_glow_pad_container.xml b/core/res/res/layout-sw600dp/keyguard_glow_pad_container.xml
deleted file mode 100644
index 930b14e..0000000
--- a/core/res/res/layout-sw600dp/keyguard_glow_pad_container.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?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/core/res/res/layout-sw600dp/keyguard_navigation.xml b/core/res/res/layout-sw600dp/keyguard_navigation.xml
deleted file mode 100644
index 2e6fa37..0000000
--- a/core/res/res/layout-sw600dp/keyguard_navigation.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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/default_navigation" />
-</merge>
diff --git a/core/res/res/layout-sw600dp/keyguard_sim_puk_pin_navigation.xml b/core/res/res/layout-sw600dp/keyguard_sim_puk_pin_navigation.xml
deleted file mode 100644
index 2e6fa37..0000000
--- a/core/res/res/layout-sw600dp/keyguard_sim_puk_pin_navigation.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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/default_navigation" />
-</merge>
diff --git a/core/res/res/layout-sw600dp/keyguard_transport_control.xml b/core/res/res/layout-sw600dp/keyguard_transport_control.xml
deleted file mode 100644
index f864339..0000000
--- a/core/res/res/layout-sw600dp/keyguard_transport_control.xml
+++ /dev/null
@@ -1,111 +0,0 @@
-<?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.
--->
-
-<!-- *** Note *** This should mirror the file in layout/ with the exception of the background set
- here for adding a drop shadow on tablets. -->
-
-<com.android.internal.widget.TransportControlView
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/transport_controls"
- android:background="@drawable/transportcontrol_bg">
-
- <!-- 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">
- <!-- We 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/lockscreen_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/lockscreen_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/lockscreen_transport_next_description"/>
- </FrameLayout>
- </LinearLayout>
- </LinearLayout>
-
-</com.android.internal.widget.TransportControlView>
diff --git a/core/res/res/layout/keyguard_account_view.xml b/core/res/res/layout/keyguard_account_view.xml
deleted file mode 100644
index fa36371..0000000
--- a/core/res/res/layout/keyguard_account_view.xml
+++ /dev/null
@@ -1,87 +0,0 @@
-<?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.internal.policy.impl.keyguard.KeyguardAccountView
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/keyguard_account_view"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_maxWidth="@dimen/keyguard_security_width"
- android: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.internal.policy.impl.keyguard.KeyguardAccountView>
diff --git a/core/res/res/layout/keyguard_add_widget.xml b/core/res/res/layout/keyguard_add_widget.xml
deleted file mode 100644
index d043fdb..0000000
--- a/core/res/res/layout/keyguard_add_widget.xml
+++ /dev/null
@@ -1,42 +0,0 @@
-<?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.internal.policy.impl.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.internal.policy.impl.keyguard.KeyguardWidgetFrame>
diff --git a/core/res/res/layout/keyguard_emergency_carrier_area.xml b/core/res/res/layout/keyguard_emergency_carrier_area.xml
deleted file mode 100644
index b8a7654..0000000
--- a/core/res/res/layout/keyguard_emergency_carrier_area.xml
+++ /dev/null
@@ -1,76 +0,0 @@
-<?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.internal.policy.impl.keyguard.EmergencyCarrierArea
- 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.internal.policy.impl.keyguard.CarrierText
- android:id="@+id/carrier_text"
- 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.internal.policy.impl.keyguard.EmergencyButton
- android:id="@+id/emergency_call_button"
- android:layout_width="0dip"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:drawableLeft="@*android: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="@*android: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>
-
-</com.android.internal.policy.impl.keyguard.EmergencyCarrierArea>
diff --git a/core/res/res/layout/keyguard_emergency_carrier_area_empty.xml b/core/res/res/layout/keyguard_emergency_carrier_area_empty.xml
deleted file mode 100644
index 2f4adae..0000000
--- a/core/res/res/layout/keyguard_emergency_carrier_area_empty.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?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/core/res/res/layout/keyguard_face_unlock_view.xml b/core/res/res/layout/keyguard_face_unlock_view.xml
deleted file mode 100644
index c9f1176..0000000
--- a/core/res/res/layout/keyguard_face_unlock_view.xml
+++ /dev/null
@@ -1,78 +0,0 @@
-<?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.internal.policy.impl.keyguard.KeyguardFaceUnlockView
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/keyguard_face_unlock_view"
- android:orientation="vertical"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_maxWidth="@dimen/keyguard_security_width"
- android: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="@*android: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="@*android:drawable/intro_bg"
- android:gravity="center">
-
- <View
- android:id="@+id/spotlightMask"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="@*android: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="@*android: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.internal.policy.impl.keyguard.KeyguardFaceUnlockView>
diff --git a/core/res/res/layout/keyguard_glow_pad_container.xml b/core/res/res/layout/keyguard_glow_pad_container.xml
deleted file mode 100644
index d86707f..0000000
--- a/core/res/res/layout/keyguard_glow_pad_container.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?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="-60dp"/>
-</merge> \ No newline at end of file
diff --git a/core/res/res/layout/keyguard_glow_pad_view.xml b/core/res/res/layout/keyguard_glow_pad_view.xml
deleted file mode 100644
index cfd8160..0000000
--- a/core/res/res/layout/keyguard_glow_pad_view.xml
+++ /dev/null
@@ -1,46 +0,0 @@
-<?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="@*android:array/lockscreen_direction_descriptions"
- prvandroid:handleDrawable="@*android:drawable/ic_lockscreen_handle"
- prvandroid:outerRingDrawable="@*android:drawable/ic_lockscreen_outerring"
- prvandroid:outerRadius="@*android:dimen/glowpadview_target_placement_radius"
- prvandroid:innerRadius="@*android:dimen/glowpadview_inner_radius"
- prvandroid:snapMargin="@*android:dimen/glowpadview_snap_margin"
- prvandroid:firstItemOffset="@integer/kg_glowpad_rotation_offset"
- prvandroid:magneticTargets="true"
- prvandroid:feedbackCount="1"
- prvandroid:vibrationDuration="20"
- prvandroid:glowRadius="@*android:dimen/glowpadview_glow_radius"
- prvandroid:pointDrawable="@*android:drawable/ic_lockscreen_glowdot"
- prvandroid:allowScaling="true" />
diff --git a/core/res/res/layout/keyguard_message_area.xml b/core/res/res/layout/keyguard_message_area.xml
deleted file mode 100644
index 37463cf..0000000
--- a/core/res/res/layout/keyguard_message_area.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?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.internal.policy.impl.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/core/res/res/layout/keyguard_message_area_large.xml b/core/res/res/layout/keyguard_message_area_large.xml
deleted file mode 100644
index 584cec4..0000000
--- a/core/res/res/layout/keyguard_message_area_large.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?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.internal.policy.impl.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/core/res/res/layout/keyguard_multi_user_avatar.xml b/core/res/res/layout/keyguard_multi_user_avatar.xml
deleted file mode 100644
index 2d8f02d..0000000
--- a/core/res/res/layout/keyguard_multi_user_avatar.xml
+++ /dev/null
@@ -1,45 +0,0 @@
-<?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.internal.policy.impl.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.internal.policy.impl.keyguard.KeyguardMultiUserAvatar>
diff --git a/core/res/res/layout/keyguard_multi_user_selector.xml b/core/res/res/layout/keyguard_multi_user_selector.xml
deleted file mode 100644
index ee01285..0000000
--- a/core/res/res/layout/keyguard_multi_user_selector.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-<?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.internal.policy.impl.keyguard.KeyguardMultiUserSelectorView
- xmlns:androidprv="http://schemas.android.com/apk/res/android"
- 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="@*android:string/keyguard_accessibility_user_selector"
- android:visibility="gone">
-
- <com.android.internal.policy.impl.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.internal.policy.impl.keyguard.KeyguardMultiUserSelectorView>
diff --git a/core/res/res/layout/keyguard_multi_user_selector_widget.xml b/core/res/res/layout/keyguard_multi_user_selector_widget.xml
deleted file mode 100644
index fc126fe..0000000
--- a/core/res/res/layout/keyguard_multi_user_selector_widget.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?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.internal.policy.impl.keyguard.KeyguardWidgetFrame
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/keyguard_multi_user_selector"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
-</com.android.internal.policy.impl.keyguard.KeyguardWidgetFrame> \ No newline at end of file
diff --git a/core/res/res/layout/keyguard_password_view.xml b/core/res/res/layout/keyguard_password_view.xml
deleted file mode 100644
index aab54c3..0000000
--- a/core/res/res/layout/keyguard_password_view.xml
+++ /dev/null
@@ -1,104 +0,0 @@
-<?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.internal.policy.impl.keyguard.KeyguardPasswordView
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/keyguard_password_view"
- android:orientation="vertical"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_maxWidth="@dimen/keyguard_security_width"
- android: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="@*android: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="@*android: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="@*android: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.internal.policy.impl.keyguard.KeyguardPasswordView>
diff --git a/core/res/res/layout/keyguard_pattern_view.xml b/core/res/res/layout/keyguard_pattern_view.xml
deleted file mode 100644
index 1bd3e4e..0000000
--- a/core/res/res/layout/keyguard_pattern_view.xml
+++ /dev/null
@@ -1,78 +0,0 @@
-<?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.internal.policy.impl.keyguard.KeyguardPatternView
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/keyguard_pattern_view"
- android:orientation="vertical"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_maxWidth="@dimen/keyguard_security_width"
- android: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="@*android: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.internal.policy.impl.keyguard.KeyguardPatternView>
diff --git a/core/res/res/layout/keyguard_pin_view.xml b/core/res/res/layout/keyguard_pin_view.xml
deleted file mode 100644
index 6a3b9e6..0000000
--- a/core/res/res/layout/keyguard_pin_view.xml
+++ /dev/null
@@ -1,224 +0,0 @@
-<?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.internal.policy.impl.keyguard.KeyguardPINView
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:androidprv="http://schemas.android.com/apk/res/android"
- android:id="@+id/keyguard_pin_view"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_maxWidth="@dimen/keyguard_security_width"
- android: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="@*android: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="@*android: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="@*android: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.internal.policy.impl.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.internal.policy.impl.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.internal.policy.impl.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.internal.policy.impl.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.internal.policy.impl.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.internal.policy.impl.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.internal.policy.impl.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.internal.policy.impl.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.internal.policy.impl.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.internal.policy.impl.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.internal.policy.impl.keyguard.KeyguardPINView>
diff --git a/core/res/res/layout/keyguard_selector_view.xml b/core/res/res/layout/keyguard_selector_view.xml
deleted file mode 100644
index dfacb6a..0000000
--- a/core/res/res/layout/keyguard_selector_view.xml
+++ /dev/null
@@ -1,64 +0,0 @@
-<?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.policy.impl.keyguard.KeyguardSelectorView
- xmlns:prvandroid="http://schemas.android.com/apk/prv/res/android"
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/keyguard_selector_view"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_maxWidth="420dp"
- android: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="@*android: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.internal.policy.impl.keyguard.KeyguardSelectorView>
-
diff --git a/core/res/res/layout/keyguard_sim_pin_view.xml b/core/res/res/layout/keyguard_sim_pin_view.xml
deleted file mode 100644
index 6e6fe08..0000000
--- a/core/res/res/layout/keyguard_sim_pin_view.xml
+++ /dev/null
@@ -1,230 +0,0 @@
-<?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.internal.policy.impl.keyguard.KeyguardSimPinView
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:androidprv="http://schemas.android.com/apk/res/android"
- android:id="@+id/keyguard_sim_pin_view"
- android:orientation="vertical"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_maxWidth="@dimen/keyguard_security_width"
- android: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="@*android: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="@*android: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="@*android: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.internal.policy.impl.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.internal.policy.impl.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.internal.policy.impl.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.internal.policy.impl.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.internal.policy.impl.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.internal.policy.impl.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.internal.policy.impl.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.internal.policy.impl.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.internal.policy.impl.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.internal.policy.impl.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.internal.policy.impl.keyguard.KeyguardSimPinView>
diff --git a/core/res/res/layout/keyguard_sim_puk_pin_account_navigation.xml b/core/res/res/layout/keyguard_sim_puk_pin_account_navigation.xml
deleted file mode 100644
index 2e6fa37..0000000
--- a/core/res/res/layout/keyguard_sim_puk_pin_account_navigation.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?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/default_navigation" />
-</merge>
diff --git a/core/res/res/layout/keyguard_sim_puk_view.xml b/core/res/res/layout/keyguard_sim_puk_view.xml
deleted file mode 100644
index 0412fdc..0000000
--- a/core/res/res/layout/keyguard_sim_puk_view.xml
+++ /dev/null
@@ -1,230 +0,0 @@
-<?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.internal.policy.impl.keyguard.KeyguardSimPukView
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:androidprv="http://schemas.android.com/apk/res/android"
- android:id="@+id/keyguard_sim_puk_view"
- android:orientation="vertical"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_maxWidth="@dimen/keyguard_security_width"
- android: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="@*android: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="@*android: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="@*android: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.internal.policy.impl.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.internal.policy.impl.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.internal.policy.impl.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.internal.policy.impl.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.internal.policy.impl.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.internal.policy.impl.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.internal.policy.impl.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.internal.policy.impl.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.internal.policy.impl.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.internal.policy.impl.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.internal.policy.impl.keyguard.KeyguardSimPukView>
diff --git a/core/res/res/layout/keyguard_status_view.xml b/core/res/res/layout/keyguard_status_view.xml
deleted file mode 100644
index 9e36df3..0000000
--- a/core/res/res/layout/keyguard_status_view.xml
+++ /dev/null
@@ -1,67 +0,0 @@
-<?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.internal.policy.impl.keyguard.KeyguardWidgetFrame
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/keyguard_status_view"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_maxWidth="@dimen/keyguard_security_width"
- android:layout_maxHeight="@dimen/keyguard_security_height"
- android:gravity="center_horizontal">
-
- <com.android.internal.policy.impl.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="@android: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.internal.policy.impl.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.internal.policy.impl.keyguard.ClockView>
-
- <include layout="@layout/keyguard_status_area" />
- </LinearLayout>
-
- </com.android.internal.policy.impl.keyguard.KeyguardStatusView>
-</com.android.internal.policy.impl.keyguard.KeyguardWidgetFrame>
diff --git a/core/res/res/layout/keyguard_transport_control_view.xml b/core/res/res/layout/keyguard_transport_control_view.xml
deleted file mode 100644
index 532322c..0000000
--- a/core/res/res/layout/keyguard_transport_control_view.xml
+++ /dev/null
@@ -1,112 +0,0 @@
-<?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.internal.policy.impl.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="@*android:drawable/ic_lockscreen_player_background"
- android:contentDescription="@*android: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="@*android:drawable/ic_media_previous"
- android:clickable="true"
- android:background="?android:attr/selectableItemBackground"
- android:padding="10dip"
- android:contentDescription="@*android:string/lockscreen_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="@*android:drawable/ic_media_play"
- android:background="?android:attr/selectableItemBackground"
- android:padding="10dip"
- android:contentDescription="@*android:string/lockscreen_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="@*android:drawable/ic_media_next"
- android:background="?android:attr/selectableItemBackground"
- android:padding="10dip"
- android:contentDescription="@*android:string/lockscreen_transport_next_description"/>
- </FrameLayout>
- </LinearLayout>
- </LinearLayout>
-
-</com.android.internal.policy.impl.keyguard.KeyguardTransportControlView> \ No newline at end of file
diff --git a/core/res/res/layout/keyguard_widget_remove_drop_target.xml b/core/res/res/layout/keyguard_widget_remove_drop_target.xml
deleted file mode 100644
index 294c386..0000000
--- a/core/res/res/layout/keyguard_widget_remove_drop_target.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?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/core/res/res/layout/toast_bar.xml b/core/res/res/layout/toast_bar.xml
new file mode 100644
index 0000000..b7443d5
--- /dev/null
+++ b/core/res/res/layout/toast_bar.xml
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<FrameLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <LinearLayout
+ android:background="@drawable/toast_bar_bg"
+ android:layout_height="50dp"
+ android:layout_width="match_parent">
+
+ <TextView
+ android:id="@android:id/message"
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ android:ellipsize="end"
+ android:gravity="center_vertical"
+ android:paddingLeft="16dp"
+ android:paddingRight="16dp"
+ android:singleLine="true"
+ android:textColor="@android:color/white"
+ android:textSize="16sp" />
+
+ <LinearLayout
+ android:id="@android:id/button1"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:background="?android:attr/selectableItemBackground"
+ android:clickable="true">
+
+ <View
+ android:layout_width="1dp"
+ android:layout_height="match_parent"
+ android:layout_marginBottom="10dp"
+ android:layout_marginRight="12dp"
+ android:layout_marginTop="10dp"
+ android:background="#aaaaaa" />
+
+ <TextView
+ android:id="@android:id/text1"
+ android:textSize="12sp"
+ android:textColor="#aaaaaa"
+ android:textStyle="bold"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:gravity="center_vertical"
+ android:paddingLeft="8dp"
+ android:paddingRight="20dp"
+ android:textAllCaps="true" />
+ </LinearLayout>
+
+ </LinearLayout>
+
+</FrameLayout>
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 7306042..c3b1ac5 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -613,6 +613,8 @@
<string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Laat die program toe om na die SD-kaart te skryf."</string>
<string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"verander/vee uit interne mediabergingsinhoud"</string>
<string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Laat die program toe om die inhoud van die interne mediaberging te verander."</string>
+ <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"bestuur dokumentberging"</string>
+ <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Laat die program toe om dokumentberging te bestuur."</string>
<string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"verkry toegang tot alle gebruikers se eksterne berging"</string>
<string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Laat die program toe om toegang tot eksterne berging vir alle gebruikers te verkry."</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"lees die kaslêerstelsel"</string>
@@ -1255,6 +1257,10 @@
<string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Laat die program toe om die verstek houerdiens in te roep om inhoud te kopieer. Nie vir gebruik deur normale programme nie."</string>
<string name="permlab_route_media_output" msgid="1642024455750414694">"Roeteer media-uitvoer"</string>
<string name="permdesc_route_media_output" msgid="4932818749547244346">"Laat \'n program toe om media-uitvoere na ander eksterne toestelle te roeteer."</string>
+ <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Kry toegang tot keyguard se veilige berging"</string>
+ <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Laat \'n program toe om toegang tot keyguard se veilige berging te kry."</string>
+ <string name="permlab_control_keyguard" msgid="172195184207828387">"Beheer wys en versteek van keyguard"</string>
+ <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Laat \'n program toe om keyguard te beheer."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Raak twee keer vir zoembeheer"</string>
<string name="gadget_host_error_inflating" msgid="4882004314906466162">"Kon nie legstuk byvoeg nie."</string>
<string name="ime_action_go" msgid="8320845651737369027">"Gaan"</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index eb58502..12cfbf4 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -613,6 +613,8 @@
<string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"መተግበሪያውን ወደ SD ካርድ ለመፃፍ ይፈቅዳል።"</string>
<string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"የውስጥ ማህደረ መረጃ ማከማቻ ይዘቶችን ቀይር/ሰርዝ"</string>
<string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"የውስጥ ማህደረ መረጃ ማከማቻ ይዘትን ለመቀየር ለመተግበሪያው ይፈቅዳሉ፡፡"</string>
+ <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"የሰነድ ማከማቻን ያስተዳድሩ"</string>
+ <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"መተግበሪያው የሰነድ ማከማቻን እንዲያስተዳድር ይፈቅድለታል።"</string>
<string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"የሁሉም ተጠቃሚዎች ውጫዊ ማከማቻውን ይደርስበታል"</string>
<string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"መተግበሪያውን የሁሉም ተጠቃሚዎች ውጫዊ ማከማቻውን እንዲደርስ ይፈቅድለታል።"</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"የመሸጎጫ ስርዓተ ፋይል ድረስ"</string>
@@ -1255,6 +1257,10 @@
<string name="permdesc_copyProtectedData" msgid="4390697124288317831">"ይዘትን ለመቅዳት ነባሪ መያዣ አገልግሎት እንዲያስነሳ ለመተግበሪው ይፈቅዳሉ፡፡ ለመደበኛ መተግበሪያዎች ለመጠቀም አይሆንም፡፡"</string>
<string name="permlab_route_media_output" msgid="1642024455750414694">"የሚዲያ ውፅአት መንገድ"</string>
<string name="permdesc_route_media_output" msgid="4932818749547244346">"አንድ መተግበሪያ የሚዲያ ውፅአትን ወደ ሌላ ውጫዊ መሳሪያ እንዲመራ ይፈቅድለታል።"</string>
+ <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"ደህንነቱ በቁልፍ የተጠበቀ ማከማቻን ይድረሱ"</string>
+ <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"አንድ መተግበሪያ ደህንነቱ በቁልፍ የተጠበቀ ማከማቻ እንዲደርስ ያስችለዋል።"</string>
+ <string name="permlab_control_keyguard" msgid="172195184207828387">"የቁልፍ መጠበቂያውን ማሳየት እና መደበቅ ይቆጣጠሩ"</string>
+ <string name="permdesc_control_keyguard" msgid="3043732290518629061">"አንድ መተግበሪያ የቁልፍ መጠበቂያውን እንዲቆጣጠር ያስችለዋል።"</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"ለአጉላ መቆጣጠሪያ ሁለት ጊዜ ነካ አድርግ"</string>
<string name="gadget_host_error_inflating" msgid="4882004314906466162">"ምግብር ማከል አልተቻለም።"</string>
<string name="ime_action_go" msgid="8320845651737369027">"ሂድ"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index cade61d..9b2f284 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -613,6 +613,8 @@
<string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"للسماح للتطبيق بالكتابة إلى بطاقة SD."</string>
<string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"تعديل/حذف محتويات وحدة تخزين الوسائط الداخلية"</string>
<string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"للسماح للتطبيق بتعديل محتويات وحدة تخزين الوسائط الداخلية."</string>
+ <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"إدارة السعة التخزينية للمستند"</string>
+ <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"السماح للتطبيق بإدارة السعة التخزينية للمستند."</string>
<string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"الوصول إلى سعة التخزين الخارجية لجميع المستخدمين"</string>
<string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"للسماح للتطبيق بالدخول إلى سعة التخزين الخارجية لجميع المستخدمين."</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"الدخول إلى نظام ملفات ذاكرة التخزين المؤقت"</string>
@@ -1255,6 +1257,10 @@
<string name="permdesc_copyProtectedData" msgid="4390697124288317831">"للسماح باستدعاء خدمة الحاوية الافتراضية لنسخ المحتوى. ليس للاستخدام بواسطة التطبيقات العادية."</string>
<string name="permlab_route_media_output" msgid="1642024455750414694">"توجيه إخراج الوسائط"</string>
<string name="permdesc_route_media_output" msgid="4932818749547244346">"للسماح للتطبيق بتوجيه إخراج الوسائط إلى أجهزة خارجية أخرى."</string>
+ <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"الدخول إلى التخزين المحمي بقفل المفاتيح"</string>
+ <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"السماح لأحد التطبيقات بالدخول إلى التخزين المحمي بقفل المفاتيح."</string>
+ <string name="permlab_control_keyguard" msgid="172195184207828387">"التحكم في عرض وإخفاء قفل المفاتيح"</string>
+ <string name="permdesc_control_keyguard" msgid="3043732290518629061">"للسماح لأحد التطبيقات بالتحكم في قفل المفاتيح."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"المس مرتين للتحكم في التكبير/التصغير"</string>
<string name="gadget_host_error_inflating" msgid="4882004314906466162">"تعذرت إضافة أداة."</string>
<string name="ime_action_go" msgid="8320845651737369027">"تنفيذ"</string>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index 10e3d45..5cb4c43 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -613,6 +613,8 @@
<string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Дазваляе прыкладанням запісваць на SD-карту."</string>
<string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"змяніць/выдаліць унутраныя носьбіты змесціва"</string>
<string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Дазваляе прыкладанням змяняць змесціва ўнутранай памяці."</string>
+ <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"кіраваць сховішчам для дакументаў"</string>
+ <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Дазваляе прыкладанню кіраваць сховішчам для дакументаў."</string>
<string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"доступ да знешніх захоўвання для ўсіх карыстальнікаў"</string>
<string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Дазваляе ўсiм карыстальнiкам прыкладання атрымлiваць доступ да знешнега сховiшча"</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"доступ да файлавай сістэмы кэша"</string>
@@ -1255,6 +1257,10 @@
<string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Дазваляе прыкладанням выклікаць службу захавання па змаўчанні для капіявання змесціва. Не выкарыстоўваецца звычайнымі прыкладаннямі."</string>
<string name="permlab_route_media_output" msgid="1642024455750414694">"Маршрутны мультымедыйны выхад"</string>
<string name="permdesc_route_media_output" msgid="4932818749547244346">"Дазваляе прыкладанням маршрутызаваць мультымедыйны выхад на iншыя знешнiя прылады."</string>
+ <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Доступ да блакіроўкі клавіятуры бяспечнага сховішча"</string>
+ <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Дазваляе прыкладанню атрымліваць доступ да блакіроўкі клавіятуры бяспечнага сховішча."</string>
+ <string name="permlab_control_keyguard" msgid="172195184207828387">"Кiраванне адлюстраваннем і схаваннем блакiроўкi клавіятуры"</string>
+ <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Дазваляе прыкладанню кiраваць блакiроўкай клавiятуры."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Двойчы дакраніцеся, каб змянiць маштаб"</string>
<string name="gadget_host_error_inflating" msgid="4882004314906466162">"Немагчыма дадаць віджэт."</string>
<string name="ime_action_go" msgid="8320845651737369027">"Пачаць"</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 11c97c2..afa6c118 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -613,6 +613,8 @@
<string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Разрешава на приложението да записва върху SD картата."</string>
<string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"пром./изтр. на съдърж. на вътр. мултим. хранил."</string>
<string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Разрешава на приложението да променя съдържанието на вътрешното мултимедийно хранилище."</string>
+ <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"управл. на хранил. с документи"</string>
+ <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Разрешава на приложението да управлява хранилището с документи."</string>
<string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"достъп до външ. хранилище за всички потребители"</string>
<string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Разрешава на приложението достъп до външното хранилище за всички потребители."</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"достъп до файловата система на кеша"</string>
@@ -1255,6 +1257,10 @@
<string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Разрешава на приложението да извиква стандартната услуга на контейнера, за да се копира съдържание. Не е предназначено за нормални приложения."</string>
<string name="permlab_route_media_output" msgid="1642024455750414694">"Насочване на изходящата мултимедия"</string>
<string name="permdesc_route_media_output" msgid="4932818749547244346">"Разрешава на приложението да насочва изходящата мултимедия към други външни устройства."</string>
+ <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Достъп до надеждното хранилище, свързано с функцията за защита на клавишите"</string>
+ <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Позволява на приложението да осъществява достъп до надеждното хранилище, свързано с функцията за защита на клавишите."</string>
+ <string name="permlab_control_keyguard" msgid="172195184207828387">"Контролиране на показването и скриването на функцията за защита на клавишите"</string>
+ <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Разрешава на приложението да контролира функцията за защита на клавишите."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Докоснете двукратно за управление на промяната на мащаба"</string>
<string name="gadget_host_error_inflating" msgid="4882004314906466162">"Приспособлението не можа да бъде добавено."</string>
<string name="ime_action_go" msgid="8320845651737369027">"Старт"</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 21f4357..aaa911d 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -613,6 +613,8 @@
<string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Permet a l\'aplicació escriure a la targeta SD."</string>
<string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"Canvia/esborra emmagatz. intern"</string>
<string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Permet que l\'aplicació modifiqui el contingut de l\'emmagatzematge multimèdia intern."</string>
+ <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"gestió emmagatzematge docum."</string>
+ <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Permet que l\'aplicació gestioni l\'emmagatzematge de documents."</string>
<string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"accedeix a l\'emmagatzematge extern per a tots els usuaris"</string>
<string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Permet que l\'aplicació accedeixi a l\'emmagatzematge extern per a tots els usuaris."</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"accedir al sistema de fitxers de la memòria cau"</string>
@@ -1255,6 +1257,10 @@
<string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Permet invocar el servei de contenidor predeterminat per copiar contingut. No indicat per a les aplicacions normals."</string>
<string name="permlab_route_media_output" msgid="1642024455750414694">"Indicació de ruta de sortida de contingut multimèdia"</string>
<string name="permdesc_route_media_output" msgid="4932818749547244346">"Permet que una aplicació indiqui la ruta de sortida de contingut multimèdia a altres dispositius externs."</string>
+ <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Accedeix a l\'emmagatzematge protegit per contrasenya"</string>
+ <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Permet que una aplicació accedeixi a l\'emmagatzematge protegit per contrasenya."</string>
+ <string name="permlab_control_keyguard" msgid="172195184207828387">"Controla si es mostra o s\'amaga el bloqueig de les tecles."</string>
+ <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Permet que una aplicació controli el bloqueig de les tecles."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Toca dos cops per controlar el zoom"</string>
<string name="gadget_host_error_inflating" msgid="4882004314906466162">"No s\'ha pogut afegir el widget."</string>
<string name="ime_action_go" msgid="8320845651737369027">"Vés"</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index d1d83a0..abe6dad 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -613,6 +613,8 @@
<string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Umožňuje aplikaci zapisovat na kartu SD."</string>
<string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"Upravit/smazat interní úlož."</string>
<string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Umožňuje aplikaci upravovat obsah interního úložiště médií."</string>
+ <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"spravovat úložiště dokumentů"</string>
+ <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Umožňuje aplikaci spravovat úložiště dokumentů."</string>
<string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"přístup k externímu úložišti všech uživatelů"</string>
<string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Umožňuje aplikaci přistupovat k externímu úložišti pro všechny uživatele."</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"přistupovat do souborového systému mezipaměti"</string>
@@ -1255,6 +1257,10 @@
<string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Umožňuje aplikaci dát výchozí službě kontejneru příkaz ke zkopírování obsahu. Toto oprávnění není určeno pro běžné aplikace."</string>
<string name="permlab_route_media_output" msgid="1642024455750414694">"Směrování výstupu médií"</string>
<string name="permdesc_route_media_output" msgid="4932818749547244346">"Umožňuje aplikaci směrovat výstup médií do dalších externích zařízení."</string>
+ <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Přístup k bezpečnému úložišti keyguard"</string>
+ <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Umožňuje aplikaci přístup k bezpečnému úložišti keyguard."</string>
+ <string name="permlab_control_keyguard" msgid="172195184207828387">"Ovládání zobrazování a skrývání zámku obrazovky"</string>
+ <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Umožňuje aplikaci ovládat zámek obrazovky."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Dvojitým dotykem můžete ovládat přiblížení"</string>
<string name="gadget_host_error_inflating" msgid="4882004314906466162">"Widget nelze přidat."</string>
<string name="ime_action_go" msgid="8320845651737369027">"Přejít"</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 3c6818b..e00597a 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -613,6 +613,8 @@
<string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Tillader, at appen kan skrive til SD-kortet."</string>
<string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"Rediger/slet internt medielagringsindhold"</string>
<string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Tillader, appen kan ændre indholdet af det interne medielager."</string>
+ <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"administrer dokumentlagring"</string>
+ <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Tillader, at appen kan administrere dokumentlagring."</string>
<string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"få adgang til alle brugeres eksterne lagre"</string>
<string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Tillader, at appen får adgang til eksterne lagre for alle brugere."</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"få adgang til cache-filsystemet"</string>
@@ -1255,6 +1257,10 @@
<string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Tillader, at appen kan benytte standardlagertjenesten til at kopiere indhold. Anvendes ikke af almindelige apps."</string>
<string name="permlab_route_media_output" msgid="1642024455750414694">"Viderefør medieoutput"</string>
<string name="permdesc_route_media_output" msgid="4932818749547244346">"Tillader, at en applikation viderefører medieoutput til andre eksterne enheder."</string>
+ <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Få adgang nøglebeskyttet lager"</string>
+ <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Tillader, at en applikation får adgang til et nøglebeskyttet lager."</string>
+ <string name="permlab_control_keyguard" msgid="172195184207828387">"Administrer, om nøglebeskyttelse skal vises eller skjules"</string>
+ <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Tillader, at en applikation styrer nøglebeskyttelsen."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Tryk to gange for zoomstyring"</string>
<string name="gadget_host_error_inflating" msgid="4882004314906466162">"Widget kunne ikke tilføjes."</string>
<string name="ime_action_go" msgid="8320845651737369027">"Gå"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 0bed825..655d5d0 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -613,6 +613,8 @@
<string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Ermöglicht der App, auf die SD-Karte zu schreiben"</string>
<string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"Internen Medienspeicher ändern/löschen"</string>
<string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Ermöglicht der App, den Inhalt des internen Medienspeichers zu ändern"</string>
+ <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"Dokumentenspeicher verwalten"</string>
+ <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"App kann Dokumentenspeicher verwalten"</string>
<string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"Auf externen Speicher aller Nutzer zugreifen"</string>
<string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Ermöglicht der App, auf externen Speicher aller Nutzer zuzugreifen."</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"Auf das Cache-Dateisystem zugreifen"</string>
@@ -1255,6 +1257,10 @@
<string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Ermöglicht der App das Aufrufen des Standard-Containerdienstes zum Kopieren von Inhalten. Nicht für normale Apps vorgesehen."</string>
<string name="permlab_route_media_output" msgid="1642024455750414694">"Medienausgabe umleiten"</string>
<string name="permdesc_route_media_output" msgid="4932818749547244346">"Ermöglicht einer App, die Medienausgabe auf andere externe Geräte umzuleiten."</string>
+ <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Zugriff auf mit Keyguard geschützten Speicher"</string>
+ <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Ermöglicht einer App den Zugriff auf mit Keyguard geschützten Speicher"</string>
+ <string name="permlab_control_keyguard" msgid="172195184207828387">"Anzeige und Ausblenden des Keyguard steuern"</string>
+ <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Apps können den Keyguard steuern."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Für Zoomeinstellung zweimal berühren"</string>
<string name="gadget_host_error_inflating" msgid="4882004314906466162">"Widget konnte nicht hinzugefügt werden."</string>
<string name="ime_action_go" msgid="8320845651737369027">"Los"</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 3d27568..5135847 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -613,6 +613,8 @@
<string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Επιτρέπει στην εφαρμογή την εγγραφή στην κάρτα SD."</string>
<string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"τροπ./διαγ. περ. απ. εσ. μνήμ."</string>
<string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Επιτρέπει στην εφαρμογή να τροποποιήσει τα περιεχόμενα των εσωτερικών μέσων αποθήκευσης."</string>
+ <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"διαχείριση αποθ.χώρου εγγράφων"</string>
+ <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Επιτρέπει στην εφαρμογή τη διαχείριση του αποθηκευτικού χώρου εγγράφων."</string>
<string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"πρόσβ.εξωτ.χωρ. αποθ. όλων των χρηστ."</string>
<string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Επιτρέπει στην εφαρμογή να αποκτήσει πρόσβαση σε εξωτερικό χώρο αποθήκευσης για όλους τους χρήστες."</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"πρόσβαση στο σύστημα αρχείων προσωρινής μνήμης"</string>
@@ -1255,6 +1257,10 @@
<string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Επιτρέπει στην εφαρμογή την κλήση της προεπιλεγμένης υπηρεσίας κοντέινερ για την αντιγραφή περιεχομένου. Δεν χρησιμοποιείται από συνήθεις εφαρμογές."</string>
<string name="permlab_route_media_output" msgid="1642024455750414694">"Διαγραφή διαδρομής δεδομένων εξόδου μέσων"</string>
<string name="permdesc_route_media_output" msgid="4932818749547244346">"Επιτρέπει σε μια εφαρμογή τη διαγραφή διαδρομής δεδομένων εξόδου μέσων σε άλλες εξωτερικές συσκευές."</string>
+ <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Πρόσβαση στον ασφαλή αποθηκευτικό χώρο με κλείδωμα"</string>
+ <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Επιτρέπει σε μια εφαρμογή να αποκτήσει πρόσβαση στον ασφαλή αποθηκευτικό χώρο με κλείδωμα."</string>
+ <string name="permlab_control_keyguard" msgid="172195184207828387">"Έλεγχος εμφάνισης και απόκρυψης κλειδώματος πληκτρολογίου"</string>
+ <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Επιτρέπει σε μια εφαρμογή τον έλεγχο του κλειδώματος πληκτρολογίου."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Αγγίξτε δύο φορές για έλεγχο εστίασης"</string>
<string name="gadget_host_error_inflating" msgid="4882004314906466162">"Δεν ήταν δυνατή η προσθήκη του γραφικού στοιχείου."</string>
<string name="ime_action_go" msgid="8320845651737369027">"Μετάβαση"</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 95dec80..2d5e70c 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -613,6 +613,8 @@
<string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Allows the app to write to the SD card."</string>
<string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"modify/delete internal media storage contents"</string>
<string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Allows the app to modify the contents of the internal media storage."</string>
+ <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"manage document storage"</string>
+ <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Allows the app to manage document storage."</string>
<string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"access external storage of all users"</string>
<string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Allows the app to access external storage for all users."</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"access the cache file system"</string>
@@ -1255,6 +1257,10 @@
<string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Allows the app to invoke default container service to copy content. Not for use by normal apps."</string>
<string name="permlab_route_media_output" msgid="1642024455750414694">"Route media output"</string>
<string name="permdesc_route_media_output" msgid="4932818749547244346">"Allows an application to route media output to other external devices."</string>
+ <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Access keyguard secure storage"</string>
+ <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Allows an application to access keyguard secure storage."</string>
+ <string name="permlab_control_keyguard" msgid="172195184207828387">"Control displaying and hiding keyguard"</string>
+ <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Allows an application to control keyguard."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Touch twice for zoom control"</string>
<string name="gadget_host_error_inflating" msgid="4882004314906466162">"Couldn\'t add widget."</string>
<string name="ime_action_go" msgid="8320845651737369027">"Go"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 8fe234d..501d56f 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -613,6 +613,8 @@
<string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Admite que la aplicación escriba en la tarjeta SD."</string>
<string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"modificar/eliminar los contenidos del almacenamientos de medios internos"</string>
<string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Permite que la aplicación modifique el contenido del almacenamiento de medios interno."</string>
+ <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"Administrar almac. de documen."</string>
+ <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Permite que la aplicación administre el almacenamiento de documentos."</string>
<string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"acceder almacenamiento externo"</string>
<string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Permite que la aplicación acceda al almacenamiento externo de todos los usuarios."</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"Acceder al sistema de archivos caché"</string>
@@ -1255,6 +1257,10 @@
<string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Permite que la aplicación ejecute el servicio de contenedor predeterminado para que copie contenido. Las aplicaciones normales no deben utilizar este permiso."</string>
<string name="permlab_route_media_output" msgid="1642024455750414694">"Dirigir salida de medios"</string>
<string name="permdesc_route_media_output" msgid="4932818749547244346">"Permite que la aplicación dirija salidas de medios a otros dispositivos externos."</string>
+ <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Acceder al almacenamiento seguro de bloqueos"</string>
+ <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Permite que una aplicación acceda al almacenamiento seguro de bloqueos."</string>
+ <string name="permlab_control_keyguard" msgid="172195184207828387">"Controlar cuándo se muestra y se oculta el bloqueo"</string>
+ <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Permite que una aplicación controle los bloqueos."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Toca dos veces para acceder al control de zoom."</string>
<string name="gadget_host_error_inflating" msgid="4882004314906466162">"No se pudo agregar el widget."</string>
<string name="ime_action_go" msgid="8320845651737369027">"Ir"</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 0ab7fca..0685e66 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -613,6 +613,8 @@
<string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Permite que la aplicación escriba en la tarjeta SD."</string>
<string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"modificar o eliminar el contenido del almacenamiento de medios interno"</string>
<string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Permite que la aplicación modifique el contenido del almacenamiento multimedia interno."</string>
+ <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"administrar el almacenamiento de documentos"</string>
+ <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Permite que la aplicación administre el almacenamiento de documentos."</string>
<string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"acceder al almacenamiento externo de todos los usuarios"</string>
<string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Permite que la aplicación acceda al almacenamiento externo de todos los usuarios."</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"acceder al sistema de archivos almacenado en caché"</string>
@@ -1255,6 +1257,10 @@
<string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Permite que la aplicación ejecute el servicio de contenedor predeterminado para copiar contenido. Las aplicaciones normales no deben usar este permiso."</string>
<string name="permlab_route_media_output" msgid="1642024455750414694">"Dirigir salida de medio"</string>
<string name="permdesc_route_media_output" msgid="4932818749547244346">"Permite que la aplicación dirija salidas de medios a otros dispositivos externos."</string>
+ <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Acceder al almacenamiento seguro de bloqueos"</string>
+ <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Permite que una aplicación acceda al almacenamiento seguro de bloqueos."</string>
+ <string name="permlab_control_keyguard" msgid="172195184207828387">"Controlar cuándo se muestra y se oculta el bloqueo"</string>
+ <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Permite que una aplicación controle los bloqueos."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Toca dos veces para acceder al control de zoom."</string>
<string name="gadget_host_error_inflating" msgid="4882004314906466162">"No se ha podido añadir el widget."</string>
<string name="ime_action_go" msgid="8320845651737369027">"Ir"</string>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index 013a2eb..b1997d1 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -613,6 +613,8 @@
<string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Võimaldab rakendusel kirjutada SD-kaardile."</string>
<string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"sisemälu sisu muutm./kustut."</string>
<string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Võimaldab rakendusel muuta sisemise andmekandja sisu."</string>
+ <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"dokumendi talletuse haldamine"</string>
+ <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Lubab rakendusel hallata dokumendi talletamist."</string>
<string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"juurdepääs välismäluseadmele (kõikidele kasutajatele)"</string>
<string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Võimaldab rakenduse kõikidel kasutajatel pöörduda välismäluseadme poole."</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"juurdepääs vahemälu failisüsteemile"</string>
@@ -1255,6 +1257,10 @@
<string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Võimaldab rakendusel võtta sisu kopeerimiseks appi vaikekonteinerteenuse. Mitte kasutada tavarakenduste puhul."</string>
<string name="permlab_route_media_output" msgid="1642024455750414694">"Meediaväljundi teekonna koostamine"</string>
<string name="permdesc_route_media_output" msgid="4932818749547244346">"Võimaldab rakendusel koostada teekonna meediaväljundist teistesse välistesse seadmetesse."</string>
+ <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Juurdepääs võtmekaitsega turvalisele talletusruumile"</string>
+ <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Lubab rakendusel hankida juurdepääsu võtmekaitsega turvalisele talletusruumile."</string>
+ <string name="permlab_control_keyguard" msgid="172195184207828387">"Võtmekaitse kuvamise ja peitmise juhtimine"</string>
+ <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Lubab rakendusel võtmekaitset juhtida."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Suumi juhtimiseks puudutage kaks korda"</string>
<string name="gadget_host_error_inflating" msgid="4882004314906466162">"Vidinat ei saanud lisada."</string>
<string name="ime_action_go" msgid="8320845651737369027">"Mine"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 97b430e..b47bf9f 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -613,6 +613,8 @@
<string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"به برنامه اجازه می‎دهد تا در کارت SD بنویسد."</string>
<string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"تغییر/حذف محتواهای حافظه رسانه داخلی"</string>
<string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"به برنامه اجازه می‎دهد تا محتویات حافظه رسانه داخلی را تغییر دهد."</string>
+ <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"مدیریت فضای ذخیره‌سازی اسناد"</string>
+ <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"به برنامه اجازه می‌دهد فضای ذخیره‌سازی اسناد را مدیریت کند."</string>
<string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"دسترسی به دستگاه ذخیره خارجی تمام کاربران"</string>
<string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"به برنامه اجازه می‌دهد به دستگاه ذخیره خارجی برای همه کاربران دسترسی داشته باشد."</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"دسترسی به سیستم فایل حافظهٔ پنهان"</string>
@@ -1255,6 +1257,10 @@
<string name="permdesc_copyProtectedData" msgid="4390697124288317831">"به برنامه اجازه می‎دهد تا سرویس پیش‌فرض را فراخوانی کند و محتوا را کپی کند. برای استفاده برنامه‎های عادی مورد نیاز نیست."</string>
<string name="permlab_route_media_output" msgid="1642024455750414694">"تعیین مسیر خروجی رسانه"</string>
<string name="permdesc_route_media_output" msgid="4932818749547244346">"به یک برنامه اجازه می‌دهد خروجی رسانه را به دستگاه‌های خارجی دیگر تعیین مسیر کند."</string>
+ <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"دسترسی به فضای ذخیره‌سازی ایمن محافظ کلید"</string>
+ <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"به یک برنامه کاربردی برای دسترسی به فضای ذخیره‌سازی ایمن محافظ کلید اجازه می‌دهد."</string>
+ <string name="permlab_control_keyguard" msgid="172195184207828387">"کنترل نمایش و پنهان کردن محافظ کلید"</string>
+ <string name="permdesc_control_keyguard" msgid="3043732290518629061">"اجازه می‌دهد برنامه‌ای محافظ کلید را کنترل کند."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"دوبار لمس کنید تا بزرگنمایی کنترل شود"</string>
<string name="gadget_host_error_inflating" msgid="4882004314906466162">"افزودن ابزارک انجام نشد."</string>
<string name="ime_action_go" msgid="8320845651737369027">"برو"</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 25336b0..feeed53 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -613,6 +613,8 @@
<string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Antaa sovelluksen kirjoittaa SD-kortille."</string>
<string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"muokkaa/poista sisäisen säilytystilan sisältöä"</string>
<string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Antaa sovelluksen muokata sisäisen tallennustilan sisältöä."</string>
+ <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"hallinnoi dokum. tallennusta"</string>
+ <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Antaa sovelluksen hallinnoida dokumenttien tallennusta."</string>
<string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"käyttää kaikkien käyttäjien ulk. tallennustilaa"</string>
<string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Sallii sovelluksen käyttää ulkoista tallennustilaa kaikille käyttäjille."</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"käytä välimuistin tiedostojärjestelmää"</string>
@@ -1255,6 +1257,10 @@
<string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Antaa sovelluksen kutsua oletussäilöpalvelua sisällön kopioimiseen. Ei tavallisten sovellusten käyttöön."</string>
<string name="permlab_route_media_output" msgid="1642024455750414694">"Median reititys"</string>
<string name="permdesc_route_media_output" msgid="4932818749547244346">"Antaa sovelluksen reitittää mediaa muihin ulkoisiin laitteisiin."</string>
+ <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Salasanalla suojatun tallennustilan hallinta"</string>
+ <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Sallii sovelluksen käyttää salasanalla suojattua tallennustilaa."</string>
+ <string name="permlab_control_keyguard" msgid="172195184207828387">"Hallinnoi näppäinvahdin näyttämistä ja piilottamista"</string>
+ <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Antaa sovelluksen hallita näppäinvahtia."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Ohjaa zoomausta napauttamalla kahdesti"</string>
<string name="gadget_host_error_inflating" msgid="4882004314906466162">"Widgetin lisääminen epäonnistui."</string>
<string name="ime_action_go" msgid="8320845651737369027">"Siirry"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 88033d2..97e0a82 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -613,6 +613,8 @@
<string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Permet à l\'application de modifier le contenu de la carte SD."</string>
<string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"Modifier/Supprimer contenu mémoire interne"</string>
<string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Permet à l\'application de modifier le contenu de la mémoire de stockage multimédia interne."</string>
+ <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"gérer stockage des documents"</string>
+ <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Permet à l\'application de gérer le stockage des documents."</string>
<string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"Accès stock. ext. tous utilis."</string>
<string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Permet à l\'application d\'accéder à la mémoire de stockage externe pour tous les utilisateurs."</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"accéder au système de fichiers en cache"</string>
@@ -1255,6 +1257,10 @@
<string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Permet à l\'application d\'invoquer le service de conteneur par défaut pour copier du contenu. Les applications standards ne doivent pas utiliser cette fonctionnalité."</string>
<string name="permlab_route_media_output" msgid="1642024455750414694">"Diriger la sortie multimédia"</string>
<string name="permdesc_route_media_output" msgid="4932818749547244346">"Permet à une application de diriger la sortie multimédia vers d\'autres appareils externes."</string>
+ <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Accéder au stockage sécurisé keyguard"</string>
+ <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Permet à une application d\'accéder au stockage sécurisé keyguard."</string>
+ <string name="permlab_control_keyguard" msgid="172195184207828387">"Contrôler l\'affichage et le masquage de la protection des touches"</string>
+ <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Permet à une application de contrôler la protection des touches."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Appuyez deux fois pour régler le zoom."</string>
<string name="gadget_host_error_inflating" msgid="4882004314906466162">"Impossible d\'ajouter le widget."</string>
<string name="ime_action_go" msgid="8320845651737369027">"OK"</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index fa09220..b135c2e 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -613,6 +613,8 @@
<string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"एप्लिकेशन को SD कार्ड पर लिखने देता है."</string>
<string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"आंतरिक मीडिया संग्रहण सामग्रियों को बदलें/हटाएं"</string>
<string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"एप्लिकेशन को आंतरिक मीडिया संग्रहण की सामग्री को संशोधित करने देता है."</string>
+ <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"दस्तावेज़ संग्रहण प्रबंधित करें"</string>
+ <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"एप्लिकेशन को दस्तावेज़ संग्रहण प्रबंधित करने की अनुमति दें."</string>
<string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"सभी उपयोगकर्ताओं के बाहरी संग्रहण तक पहुंचें"</string>
<string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"एप्लिकेशन को सभी उपयोगकर्ताओं के बाहरी संग्रहण तक पहुंचने दें."</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"कैश फ़ाइल सिस्‍टम में पहंचे"</string>
@@ -1255,6 +1257,10 @@
<string name="permdesc_copyProtectedData" msgid="4390697124288317831">"एप्लिकेशन को सामग्री की प्रतिलिपि बनाने के लिए डिफ़ॉल्ट कंटेनर सेवा शुरू करने देता है. सामान्‍य एप्‍लिकेशन द्वारा उपयोग करने के लिए नहीं."</string>
<string name="permlab_route_media_output" msgid="1642024455750414694">"मीडिया आउटपुट को रूट करें"</string>
<string name="permdesc_route_media_output" msgid="4932818749547244346">"एप्लिकेशन को मीडिया आउटपुट को अन्य बाहरी उपकरणों पर रूट करने देता है."</string>
+ <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"कीगार्ड सुरक्षित संग्रहण एक्सेस करें"</string>
+ <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"एप्लिकेशन को कीगार्ड सुरक्षित संग्रहण एक्सेस करने देती है."</string>
+ <string name="permlab_control_keyguard" msgid="172195184207828387">"कीगार्ड दिखाना और छिपाना नियंत्रित करें"</string>
+ <string name="permdesc_control_keyguard" msgid="3043732290518629061">"एप्लिकेशन को कीगार्ड नियंत्रित करने देती है."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"ज़ूम नियंत्रण के लिए दो बार स्पर्श करें"</string>
<string name="gadget_host_error_inflating" msgid="4882004314906466162">"विजेट नहीं जोड़ा जा सका."</string>
<string name="ime_action_go" msgid="8320845651737369027">"जाएं"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index ef9b50a..f033a16 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -613,6 +613,8 @@
<string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Aplikaciji omogućuje pisanje na SD karticu."</string>
<string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"izmijeni/izbriši sadržaj pohranjen na internim medijima"</string>
<string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Aplikaciji omogućuje izmjenu sadržaja pohranjenog na internim medijima."</string>
+ <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"upravljanje pohr. dokumenata"</string>
+ <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Omogućuje aplikaciji upravljanje pohranom dokumenata."</string>
<string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"pristup vanjskoj pohrani svima"</string>
<string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Omogućuje aplikaciji pristup vanjskoj pohrani za sve korisnike."</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"pristup sustavu datoteka predmemorije"</string>
@@ -1255,6 +1257,10 @@
<string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Omogućuje aplikaciji dozivanje usluge zadanog spremnika radi kopiranja sadržaja. Nije namijenjena uobičajenim aplikacijama."</string>
<string name="permlab_route_media_output" msgid="1642024455750414694">"Usmjeravanje medijskog izlaza"</string>
<string name="permdesc_route_media_output" msgid="4932818749547244346">"Aplikaciji omogućuje usmjeravanje medijskog izlaza na druge vanjske uređaje."</string>
+ <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Pristup zaključanoj sigurnoj pohrani"</string>
+ <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Omogućuje aplikaciji pristupanje zaključanoj sigurnoj pohrani."</string>
+ <string name="permlab_control_keyguard" msgid="172195184207828387">"Upravljanje prikazivanjem i skrivanjem zaključavanja tipkovnice"</string>
+ <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Omogućuje aplikaciji upravljanje zaključavanjem tipkovnice."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Dodirnite dvaput za upravljanje zumiranjem"</string>
<string name="gadget_host_error_inflating" msgid="4882004314906466162">"Widget nije moguće dodati."</string>
<string name="ime_action_go" msgid="8320845651737369027">"Idi"</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 4c87604..516241f 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -613,6 +613,8 @@
<string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Lehetővé teszi az alkalmazás számára, hogy írjon az SD-kártyára."</string>
<string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"belső tár tartalmának módosítása/törlése"</string>
<string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Lehetővé teszi az alkalmazás számára, hogy módosítsa a belső háttértár tartalmát."</string>
+ <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"dokumentumtárhely kezelése"</string>
+ <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Lehetővé teszi az alkalmazás számára a dokumentumtárhely kezelését."</string>
<string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"hozzáf. minden felh. külső tár"</string>
<string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Minden felhasználó számára lehetővé teszi, hogy az alkalmazás hozzáférjen külső tárolókhoz."</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"hozzáférés a gyorsítótár fájlrendszeréhez"</string>
@@ -1255,6 +1257,10 @@
<string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Lehetővé teszi az alkalmazás számára az alapértelmezett tárolószolgáltatás használatát tartalom másolásához. Normál alkalmazások nem használhatják."</string>
<string name="permlab_route_media_output" msgid="1642024455750414694">"Médiafájlok kimenetének irányítása"</string>
<string name="permdesc_route_media_output" msgid="4932818749547244346">"Lehetővé teszi az alkalmazás számára, hogy más külső eszközökre irányítsa a médiafájlok lejátszását."</string>
+ <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Hozzáférés a kóddal védett tárhelyhez"</string>
+ <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Lehetővé teszi egy alkalmazás számára, hogy hozzáférjen a kóddal védett tárhelyhez."</string>
+ <string name="permlab_control_keyguard" msgid="172195184207828387">"Billentyűzár megjelenítésének és elrejtésének vezérlése"</string>
+ <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Lehetővé teszi egy alkalmazás számára a billentyűzár vezérlését."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Érintse meg kétszer a nagyítás beállításához"</string>
<string name="gadget_host_error_inflating" msgid="4882004314906466162">"Nem sikerült hozzáadni a modult."</string>
<string name="ime_action_go" msgid="8320845651737369027">"Ugrás"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 39106ad..812d016 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -613,6 +613,8 @@
<string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Memungkinkan apl menulis ke kartu SD."</string>
<string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"ubah/hapus konten penyimpanan media internal"</string>
<string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Mengizinkan apl memodifikasi konten penyimpanan media internal."</string>
+ <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"kelola penyimpanan dokumen"</string>
+ <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Mengizinkan aplikasi mengelola penyimpanan dokumen."</string>
<string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"akses penyimpanan eksternal"</string>
<string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Izinkan aplikasi mengakses penyimpanan eksternal untuk semua pengguna."</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"akses sistem file cache."</string>
@@ -1255,6 +1257,10 @@
<string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Mengizinkan apl menjalankan layanan kontainer default untuk menyalin konten. Tidak untuk digunakan oleh apl normal."</string>
<string name="permlab_route_media_output" msgid="1642024455750414694">"Menentukan rute keluaran media"</string>
<string name="permdesc_route_media_output" msgid="4932818749547244346">"Memungkinkan aplikasi menentukan rute keluaran media ke perangkat eksternal lainnya."</string>
+ <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Mengakses pengaman penyimpanan aman"</string>
+ <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Mengizinkan aplikasi mengakses pengaman penyimpanan aman."</string>
+ <string name="permlab_control_keyguard" msgid="172195184207828387">"Kontrol untuk menampilkan dan menyembunyikan pengaman"</string>
+ <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Izinkan aplikasi untuk mengontrol pengaman."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Sentuh dua kali untuk mengontrol perbesar/perkecil"</string>
<string name="gadget_host_error_inflating" msgid="4882004314906466162">"Tidak dapat menambahkan widget."</string>
<string name="ime_action_go" msgid="8320845651737369027">"Buka"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 14e346f..05bed06 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -613,6 +613,8 @@
<string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Consente all\'applicazione di scrivere sulla scheda SD."</string>
<string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"modifica/eliminaz. contenuti archivio media int."</string>
<string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Consente all\'applicazione di modificare i contenuti dell\'archivio media interno."</string>
+ <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"gestione della memorizzazione dei documenti"</string>
+ <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Consente all\'app di gestire la memorizzazione dei documenti."</string>
<string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"accesso memoria esterna utenti"</string>
<string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Consente all\'applicazione di accedere alla memoria esterna di tutti gli utenti."</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"accesso al filesystem nella cache"</string>
@@ -1255,6 +1257,10 @@
<string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Consente all\'applicazione di richiamare il servizio container predefinito per la copia di contenuti. Da non usare per normali applicazioni."</string>
<string name="permlab_route_media_output" msgid="1642024455750414694">"Indirizzamento uscita media"</string>
<string name="permdesc_route_media_output" msgid="4932818749547244346">"Consente a un\'applicazione di indirizzare l\'uscita di media verso altri dispositivi esterni."</string>
+ <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Accesso all\'archivio sicuro keyguard"</string>
+ <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Consente a un\'applicazione di accedere all\'archivio sicuro keguard."</string>
+ <string name="permlab_control_keyguard" msgid="172195184207828387">"Controllo della visualizzazione e dell\'occultamento di keyguard"</string>
+ <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Consente a un\'applicazione di controllare keguard."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Tocca due volte per il comando dello zoom"</string>
<string name="gadget_host_error_inflating" msgid="4882004314906466162">"Aggiunta del widget non riuscita."</string>
<string name="ime_action_go" msgid="8320845651737369027">"Vai"</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index cc70005..1e0e204 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -613,6 +613,8 @@
<string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"מאפשר ליישום לכתוב לכרטיס ה-SD."</string>
<string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"שנה/מחק תוכן של אחסון מדיה פנימי"</string>
<string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"מאפשר ליישום לשנות את התוכן של אמצעי האחסון הפנימי למדיה."</string>
+ <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"ניהול של אחסון מסמכים"</string>
+ <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"מאפשר ליישום לנהל אחסון מסמכים."</string>
<string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"גישה לאחסון חיצוני, כל המשתמשים"</string>
<string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"מאפשר ליישום לגשת לאחסון חיצוני עבור כל המשתמשים."</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"גישה למערכת הקבצים בקובץ השמור"</string>
@@ -1255,6 +1257,10 @@
<string name="permdesc_copyProtectedData" msgid="4390697124288317831">"מאפשר ליישום להפעיל שירות גורם מכיל המוגדר כברירת מחדל להעתקת תוכן. לא מיועד לשימוש על ידי יישומים רגילים."</string>
<string name="permlab_route_media_output" msgid="1642024455750414694">"ניתוב פלט מדיה"</string>
<string name="permdesc_route_media_output" msgid="4932818749547244346">"מאפשר ליישום לנתב פלט מדיה למכשירים חיצוניים אחרים."</string>
+ <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"גישה לאחסון המוגן באמצעות מפתח"</string>
+ <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"מאפשר ליישום לגשת לאחסון המוגן באמצעות מפתח."</string>
+ <string name="permlab_control_keyguard" msgid="172195184207828387">"שלוט בהצגה והסתרה של מגן המקלדת"</string>
+ <string name="permdesc_control_keyguard" msgid="3043732290518629061">"מאפשר ליישום לשלוט במגן המקלדת."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"גע פעמיים לבקרת מרחק מתצוגה"</string>
<string name="gadget_host_error_inflating" msgid="4882004314906466162">"לא ניתן להוסיף widget."</string>
<string name="ime_action_go" msgid="8320845651737369027">"התחל"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 99778a0..3241159 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -613,6 +613,8 @@
<string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"SDカードへの書き込みをアプリに許可します。"</string>
<string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"内部メディアストレージの内容の変更/削除"</string>
<string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"内部メディアストレージの内容を変更することをアプリに許可します。"</string>
+ <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"ドキュメントストレージの管理"</string>
+ <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"ドキュメントストレージの管理をアプリに許可します。"</string>
<string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"全ユーザー外部ストレージへのアクセス"</string>
<string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"すべてのユーザーの外部ストレージへのアクセスをアプリに許可します。"</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"キャッシュファイルシステムにアクセス"</string>
@@ -1255,6 +1257,10 @@
<string name="permdesc_copyProtectedData" msgid="4390697124288317831">"デフォルトのコンテナサービスを呼び出してコンテンツをコピーすることをアプリに許可します。通常のアプリでは使用しません。"</string>
<string name="permlab_route_media_output" msgid="1642024455750414694">"メディア出力のルーティング"</string>
<string name="permdesc_route_media_output" msgid="4932818749547244346">"メディア出力を他の外部デバイスにルーティングすることをアプリに許可します。"</string>
+ <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"キーガードセキュアストレージへのアクセス"</string>
+ <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"キーガードセキュアストレージへのアクセスをアプリに許可する"</string>
+ <string name="permlab_control_keyguard" msgid="172195184207828387">"キーガードの表示/非表示の制御"</string>
+ <string name="permdesc_control_keyguard" msgid="3043732290518629061">"キーガードの制御をアプリに許可します。"</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"ダブルタップでズームコントロール"</string>
<string name="gadget_host_error_inflating" msgid="4882004314906466162">"ウィジェットを追加できませんでした。"</string>
<string name="ime_action_go" msgid="8320845651737369027">"移動"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index a97bf9b..b6e07c8 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -613,6 +613,8 @@
<string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"앱이 SD 카드에 쓸 수 있도록 허용합니다."</string>
<string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"내부 미디어 저장소 콘텐츠 수정/삭제"</string>
<string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"앱이 내부 미디어 저장소의 콘텐츠를 수정할 수 있도록 허용합니다."</string>
+ <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"문서 저장공간 관리"</string>
+ <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"앱이 문서 저장공간을 관리할 수 있도록 허용합니다."</string>
<string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"모든 사용자의 외부 저장소에 액세스"</string>
<string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"앱이 모든 사용자의 외부 저장소에 액세스하도록 허용합니다."</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"캐시 파일시스템 액세스"</string>
@@ -1255,6 +1257,10 @@
<string name="permdesc_copyProtectedData" msgid="4390697124288317831">"기본 컨테이너 서비스를 호출하여 콘텐츠를 복사할 수 있도록 허용합니다. 일반 앱에서는 사용하지 않습니다."</string>
<string name="permlab_route_media_output" msgid="1642024455750414694">"미디어 출력 연결"</string>
<string name="permdesc_route_media_output" msgid="4932818749547244346">"앱이 미디어 출력을 기타 외부 기기에 연결할 수 있도록 허용합니다."</string>
+ <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"키가드 보안 저장소 액세스"</string>
+ <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"애플리케이션에서 키가드 보안 저장소에 액세스하도록 허용합니다."</string>
+ <string name="permlab_control_keyguard" msgid="172195184207828387">"키가드 표시 및 숨기기 설정"</string>
+ <string name="permdesc_control_keyguard" msgid="3043732290518629061">"애플리케이션에서 키가드를 제어하도록 허용합니다."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"확대/축소하려면 두 번 터치하세요."</string>
<string name="gadget_host_error_inflating" msgid="4882004314906466162">"위젯을 추가할 수 없습니다."</string>
<string name="ime_action_go" msgid="8320845651737369027">"이동"</string>
diff --git a/core/res/res/values-land/arrays.xml b/core/res/res/values-land/arrays.xml
index 240b9e4..5602a1c 100644
--- a/core/res/res/values-land/arrays.xml
+++ b/core/res/res/values-land/arrays.xml
@@ -19,54 +19,4 @@
-->
<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/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 2bde748..2ad0598 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -613,6 +613,8 @@
<string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Leidžiama programai rašyti į SD kortelę."</string>
<string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"keisti / ištr. vid. med. atm. tur."</string>
<string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Leidžiama programai keisti vidinės medijos saugyklos turinį."</string>
+ <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"tvarkyti dokumentų saugyklą"</string>
+ <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Leidžiama programai tvarkyti dokumentų saugyklą."</string>
<string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"pasiekti visų naud. išor. atm."</string>
<string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Leidžiama programai pasiekti visų naudotojų išorinę atmintinę."</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"pasiekti talpyklos failų sistemą"</string>
@@ -1255,6 +1257,10 @@
<string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Leidžiama programai iškviesti numatytąją sudėtinio rodinio paslaugą, kad būtų kopijuojamas turinys. Neskirta naudoti įprastoms programoms."</string>
<string name="permlab_route_media_output" msgid="1642024455750414694">"Medijos išvesties nukreipimas"</string>
<string name="permdesc_route_media_output" msgid="4932818749547244346">"Leidžiama programai nukreipti medijos išvestį į kitus išorinius įrenginius."</string>
+ <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Pasiekti „KeyGuard“ saugyklą"</string>
+ <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Programai leidžiama pasiekti „KeyGuard“ saugyklą."</string>
+ <string name="permlab_control_keyguard" msgid="172195184207828387">"Valdyti „KeyGuard“ rodymą ir slėpimą"</string>
+ <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Programai leidžiama valdyti „KeyGuard“."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Dukart palieskite, kad valdytumėte mastelio keitimą"</string>
<string name="gadget_host_error_inflating" msgid="4882004314906466162">"Nepavyko pridėti."</string>
<string name="ime_action_go" msgid="8320845651737369027">"Pradėti"</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 4cca123..de30037 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -613,6 +613,8 @@
<string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Ļauj lietotnei rakstīt SD kartē."</string>
<string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"pārv./dz.datu n.iekš.atm.sat."</string>
<string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Ļauj lietotnei modificēt datu nesēja iekšējās atmiņas saturu."</string>
+ <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"Dokumentu krātuves pārvaldība"</string>
+ <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Ļauj lietotnei pārvaldīt dokumentu krātuvi."</string>
<string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"piekļ. visu liet. ārējai krāt."</string>
<string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Ļauj lietotnei piekļūt visu lietotāju ārējai krātuvei."</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"piekļūt kešatmiņas failu sistēmai"</string>
@@ -1255,6 +1257,10 @@
<string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Ļauj lietotnei izsaukt noklusējuma konteinera pakalpojumu, lai kopētu saturu. Atļauja neattiecas uz parastām lietotnēm."</string>
<string name="permlab_route_media_output" msgid="1642024455750414694">"Multivides datu izejas maršrutēšana"</string>
<string name="permdesc_route_media_output" msgid="4932818749547244346">"Ļauj lietojumprogrammai maršrutēt multivides datu izeju uz citām ārējām ierīcēm."</string>
+ <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Piekļūt krātuvei, kas aizsargāta ar atslēgu"</string>
+ <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Ļauj lietojumprogrammai piekļūt krātuvei, kas aizsargāta ar atslēgu."</string>
+ <string name="permlab_control_keyguard" msgid="172195184207828387">"Pārvaldīt krātuves rādīšanu un paslēpšanu."</string>
+ <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Ļauj lietojumprogrammai pārvaldīt krātuvi."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Pieskarieties divreiz, lai kontrolētu tālummaiņu."</string>
<string name="gadget_host_error_inflating" msgid="4882004314906466162">"Nevarēja pievienot logrīku."</string>
<string name="ime_action_go" msgid="8320845651737369027">"Doties uz"</string>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index 06548c6..b518ea9 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -613,6 +613,8 @@
<string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Membenarkan apl menulis ke kad SD."</string>
<string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"ubh suai/pdm kdg strn mdia dlm"</string>
<string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Membenarkan apl mengubah suai kandungan storan media dalaman."</string>
+ <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"urus storan dokumen"</string>
+ <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Membenarkan apl mengurus storan dokumen."</string>
<string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"mengakses storan luaran untuk semua pengguna"</string>
<string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Membenarkan apl untuk mengakses storan luaran untuk semua pengguna."</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"akses sistem fail cache"</string>
@@ -1255,6 +1257,10 @@
<string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Membenarkan apl untuk menggunakan perkhidmatan bekas lalai untuk menyalin kandungan. Bukan untuk digunakan oleh apl biasa."</string>
<string name="permlab_route_media_output" msgid="1642024455750414694">"Buat laluan output media"</string>
<string name="permdesc_route_media_output" msgid="4932818749547244346">"Membenarkan apl untuk membuat laluan output media ke peranti luaran lain."</string>
+ <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Akses storan selamat pengawal kekunci"</string>
+ <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Membenarkan aplikasi mengakses storan selamat pengawal kekunci."</string>
+ <string name="permlab_control_keyguard" msgid="172195184207828387">"Kawal paparkan dan sembunyikan pengawal kekunci"</string>
+ <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Membenarkan aplikasi untuk mengawal pengawal kekunci."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Sentuh dua kali untuk mendapatkan kawalan zum"</string>
<string name="gadget_host_error_inflating" msgid="4882004314906466162">"Tidak dapat menambahkan widget."</string>
<string name="ime_action_go" msgid="8320845651737369027">"Pergi"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index b339738..080a05c 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -613,6 +613,8 @@
<string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Lar appen skrive til SD-kortet."</string>
<string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"endre eller slette innhold på interne medier"</string>
<string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Lar appen endre innholdet i det interne lagringsmediet."</string>
+ <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"administrere dokumentlagring"</string>
+ <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Lar appen administrere dokumentlagring."</string>
<string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"åpne eksternlagring for alle brukere"</string>
<string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Tillater appen å åpne eksternlagring for alle brukere."</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"tilgang til bufrede filer"</string>
@@ -1255,6 +1257,10 @@
<string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Lar appen påkalle standard meldingsbeholdertjeneste for kopiering av innhold. Ikke beregnet på vanlige apper."</string>
<string name="permlab_route_media_output" msgid="1642024455750414694">"Videresending av medieutdata"</string>
<string name="permdesc_route_media_output" msgid="4932818749547244346">"Lar en app videresende medieutdata til andre eksterne enheter."</string>
+ <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Bruk av sikker lagring via keyguard."</string>
+ <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Lar en app bruke sikker lagring via keyguard."</string>
+ <string name="permlab_control_keyguard" msgid="172195184207828387">"Kontrollér om tastelåsen er skjult eller vist"</string>
+ <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Tillater at en app kontrollerer tastelåsen."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Trykk to ganger for zoomkontroll"</string>
<string name="gadget_host_error_inflating" msgid="4882004314906466162">"Kunne ikke legge til modulen."</string>
<string name="ime_action_go" msgid="8320845651737369027">"Utfør"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 358dfe3..299658e 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -613,6 +613,8 @@
<string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Hiermee kan de app schrijven naar de SD-kaart."</string>
<string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"inh. mediaopsl. wijz./verw."</string>
<string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Hiermee kan de app de inhoud van de interne mediaopslag aanpassen."</string>
+ <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"documentopslag beheren"</string>
+ <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Hiermee kan de app documentopslag beheren."</string>
<string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"toegang tot externe opslag van alle gebruikers"</string>
<string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Hiermee krijgt de app toegang tot externe opslag van alle gebruikers."</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"het cachebestandssysteem openen"</string>
@@ -1255,6 +1257,10 @@
<string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Hiermee kan de app de standaard containerservice aanroepen om inhoud te kopiëren. Niet voor gebruik door normale apps."</string>
<string name="permlab_route_media_output" msgid="1642024455750414694">"Media-uitvoer aansturen"</string>
<string name="permdesc_route_media_output" msgid="4932818749547244346">"Hiermee kan een app media-uitvoer naar andere externe apparaten doorsturen."</string>
+ <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Toegang tot opslag met toetsbeveiliging"</string>
+ <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Hiermee krijgt een app toegang tot opslag met toetsbeveiliging."</string>
+ <string name="permlab_control_keyguard" msgid="172195184207828387">"Weergeven en verbergen van toetsbeveiliging beheren"</string>
+ <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Staat toe dat een app de toetsbeveiliging beheert."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Raak twee keer aan voor zoomregeling"</string>
<string name="gadget_host_error_inflating" msgid="4882004314906466162">"Kan widget niet toevoegen."</string>
<string name="ime_action_go" msgid="8320845651737369027">"Ga"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index d3b340b..7897763 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -613,6 +613,8 @@
<string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Pozwala aplikacji na zapis na karcie SD."</string>
<string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"modyfikowanie/usuwanie zawartości pamięci wew."</string>
<string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Pozwala aplikacji na modyfikowanie zawartości pamięci wewnętrznej."</string>
+ <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"zarządzaj przechowywaniem dokumentów"</string>
+ <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Pozwala aplikacji zarządzać przechowywaniem dokumentów."</string>
<string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"dostęp do zewnętrznej pamięci wszystkich"</string>
<string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Pozwala aplikacji na dostęp do zewnętrznej pamięci masowej dla wszystkich użytkowników."</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"dostęp do systemu plików pamięci podręcznej"</string>
@@ -1255,6 +1257,10 @@
<string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Pozwala aplikacji na wywoływanie domyślnej usługi kontenera w celu skopiowania zawartości. Nieprzeznaczone dla zwykłych aplikacji."</string>
<string name="permlab_route_media_output" msgid="1642024455750414694">"Kierowanie wyjścia multimediów"</string>
<string name="permdesc_route_media_output" msgid="4932818749547244346">"Pozwala aplikacji na kierowanie wyjściowych danych multimedialnych do innych urządzeń zewnętrznych."</string>
+ <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Dostęp do bezpiecznego magazynu kluczy"</string>
+ <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Zezwala aplikacji na dostęp do bezpiecznego magazynu kluczy."</string>
+ <string name="permlab_control_keyguard" msgid="172195184207828387">"Kontroluj wyświetlanie i ukrywanie zabezpieczenia kluczami"</string>
+ <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Umożliwia aplikacji kontrolowanie zabezpieczenia kluczami."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Dotknij dwukrotnie, aby sterować powiększeniem."</string>
<string name="gadget_host_error_inflating" msgid="4882004314906466162">"Nie można dodać widżetu."</string>
<string name="ime_action_go" msgid="8320845651737369027">"OK"</string>
diff --git a/core/res/res/values-port/alias.xml b/core/res/res/values-port/alias.xml
deleted file mode 100644
index bf3eecb..0000000
--- a/core/res/res/values-port/alias.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?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">@android:layout/keyguard_emergency_carrier_area</item>
-</resources>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 32d3692..6d76248 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -613,6 +613,8 @@
<string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Permite que a aplicação escreva no cartão SD."</string>
<string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"modif./elim. armaz. interno"</string>
<string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Permite que a aplicação modifique o conteúdo de armazenamento de suportes internos."</string>
+ <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"gerir o armaz. de documentos"</string>
+ <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Permite que a aplicação faça a gestão do armazenamento de documentos."</string>
<string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"aceder ao armazenamento externo de todos os utilizadores"</string>
<string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Permite que a aplicação aceda ao armazenamento externo para todos os utilizadores."</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"aceder ao sistema de ficheiros da cache"</string>
@@ -1255,6 +1257,10 @@
<string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Permite à aplicação invocar o serviço de contentor predefinido para copiar conteúdo. Não se destina a ser utilizado por aplicações normais."</string>
<string name="permlab_route_media_output" msgid="1642024455750414694">"Encaminhar saída de som multimédia"</string>
<string name="permdesc_route_media_output" msgid="4932818749547244346">"Permite que a aplicação encaminhe a saída de som multimédia para outros dispositivos externos."</string>
+ <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Aceder ao armazenamento seguro de proteção de teclado"</string>
+ <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Permite a uma aplicação aceder ao armazenamento seguro de proteção de teclado."</string>
+ <string name="permlab_control_keyguard" msgid="172195184207828387">"Controlar apresentação e ocultação de proteção de teclado"</string>
+ <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Permite que uma aplicação controle a proteção de teclado."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Toque duas vezes para controlar o zoom"</string>
<string name="gadget_host_error_inflating" msgid="4882004314906466162">"Não foi possível adicionar widget."</string>
<string name="ime_action_go" msgid="8320845651737369027">"Ir"</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index fb9154f..8730604 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -613,6 +613,8 @@
<string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Permite que o aplicativo grave em seu cartão SD."</string>
<string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"modificar/excluir conteúdos de armazenamento de mídia internos"</string>
<string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Permite que o aplicativo modifique o conteúdo da mídia de armazenamento interno."</string>
+ <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"gerenciar armaz. de documentos"</string>
+ <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Permitir que o aplicativo gerencie o armazenamento de documentos."</string>
<string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"acessar arm. ext. dos usuários"</string>
<string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Permite que o aplicativo acesse o armazenamento externo para todos os usuários."</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"acessar o sistema de arquivos de cache"</string>
@@ -1255,6 +1257,10 @@
<string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Permite que o aplicativo invoque serviços contêiner padrão para copiar conteúdo. Não deve ser usado em aplicativos normais."</string>
<string name="permlab_route_media_output" msgid="1642024455750414694">"Rotear saída de mídia"</string>
<string name="permdesc_route_media_output" msgid="4932818749547244346">"Permite que um aplicativo faça o roteamento de saída de mídia para outros dispositivos externos."</string>
+ <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Acessar o armazenamento seguro do bloqueio de teclado"</string>
+ <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Permite que o aplicativo acesse o armazenamento seguro do bloqueio de teclado."</string>
+ <string name="permlab_control_keyguard" msgid="172195184207828387">"Controlar a exibição e ocultação do bloqueio de tela"</string>
+ <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Permite que o aplicativo controle o bloqueio de teclado."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Toque duas vezes para controlar o zoom"</string>
<string name="gadget_host_error_inflating" msgid="4882004314906466162">"Não foi possível adicionar widget."</string>
<string name="ime_action_go" msgid="8320845651737369027">"Ir"</string>
diff --git a/core/res/res/values-rm/strings.xml b/core/res/res/values-rm/strings.xml
index 361b18a..4404d87 100644
--- a/core/res/res/values-rm/strings.xml
+++ b/core/res/res/values-rm/strings.xml
@@ -1025,6 +1025,10 @@
<skip />
<!-- no translation found for permdesc_mediaStorageWrite (8189160597698529185) -->
<skip />
+ <!-- no translation found for permlab_manageDocs (5778318598448849829) -->
+ <skip />
+ <!-- no translation found for permdesc_manageDocs (8704323176914121484) -->
+ <skip />
<!-- no translation found for permlab_sdcardAccessAll (8150613823900460576) -->
<skip />
<!-- no translation found for permdesc_sdcardAccessAll (3215208357415891320) -->
@@ -1981,6 +1985,14 @@
<skip />
<!-- no translation found for permdesc_route_media_output (4932818749547244346) -->
<skip />
+ <!-- no translation found for permlab_access_keyguard_secure_storage (7565552237977815047) -->
+ <skip />
+ <!-- no translation found for permdesc_access_keyguard_secure_storage (5866245484303285762) -->
+ <skip />
+ <!-- no translation found for permlab_control_keyguard (172195184207828387) -->
+ <skip />
+ <!-- no translation found for permdesc_control_keyguard (3043732290518629061) -->
+ <skip />
<!-- no translation found for tutorial_double_tap_to_zoom_message_short (4070433208160063538) -->
<skip />
<!-- no translation found for gadget_host_error_inflating (4882004314906466162) -->
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 4694e15..4267fe1 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -613,6 +613,8 @@
<string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Permite aplicaţiei să scrie pe cardul SD."</string>
<string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"modif./şterg. conţinutul media stocat intern"</string>
<string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Permite aplicaţiei să modifice conţinutul stocării media interne."</string>
+ <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"gestionare stocare documente"</string>
+ <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Permite aplicației să gestioneze stocarea documentelor."</string>
<string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"acces. stoc. ext. pt. toţi utilizat."</string>
<string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Permite aplicaţiei să acceseze stocarea externă pentru toţi utilizatorii."</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"accesare sistem de fişiere cache"</string>
@@ -1255,6 +1257,10 @@
<string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Permite aplicaţiei să invoce serviciul containerului prestabilit pentru a copia conţinutul. Nu se utilizează de aplicaţiile obişnuite."</string>
<string name="permlab_route_media_output" msgid="1642024455750414694">"Direcţionează rezultatele media"</string>
<string name="permdesc_route_media_output" msgid="4932818749547244346">"Permite unei aplicaţii să direcţioneze rezultate media către alte dispozitive externe."</string>
+ <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Accesează stocarea securizată când tastatura este blocată"</string>
+ <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Permite unei aplicații să acceseze stocarea securizată când tastatura este blocată."</string>
+ <string name="permlab_control_keyguard" msgid="172195184207828387">"Stabilește afișarea și ascunderea blocării tastaturii"</string>
+ <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Permite unei aplicații să controleze blocarea tastaturii."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Atingeţi de două ori pentru a mări/micşora"</string>
<string name="gadget_host_error_inflating" msgid="4882004314906466162">"Nu s-a putut adăuga widgetul."</string>
<string name="ime_action_go" msgid="8320845651737369027">"Accesaţi"</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 1b9b750..b05bef7 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -613,6 +613,8 @@
<string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Приложение сможет записывать данные на SD-карту."</string>
<string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"Доступ к данным мультимедиа"</string>
<string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Приложение сможет изменять контент внутреннего хранилища мультимедиа."</string>
+ <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"управлять хранением документов"</string>
+ <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Приложение сможет управлять хранением документов."</string>
<string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"Доступ к внешним накопителям из всех аккаунтов"</string>
<string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Приложение сможет обращаться к внешним накопителям из всех аккаунтов."</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"Доступ к файловой системе кэша"</string>
@@ -1255,6 +1257,10 @@
<string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Приложение сможет вызывать службу контейнеров по умолчанию для копирования данных. Это разрешение не используется обычными приложениями."</string>
<string name="permlab_route_media_output" msgid="1642024455750414694">"Перенаправление мультимедийных данных"</string>
<string name="permdesc_route_media_output" msgid="4932818749547244346">"Приложение сможет направлять поток мультимедиа на другие внешние устройства."</string>
+ <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Доступ к хранилищу ключей"</string>
+ <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Приложение сможет получить доступ к хранилищу ключей."</string>
+ <string name="permlab_control_keyguard" msgid="172195184207828387">"Управлять отображением хранилища ключей"</string>
+ <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Приложение сможет управлять хранилищем ключей."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Нажмите дважды для изменения масштаба"</string>
<string name="gadget_host_error_inflating" msgid="4882004314906466162">"Не удалось добавить виджет."</string>
<string name="ime_action_go" msgid="8320845651737369027">"Выбрать"</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 03e18be..96b44f7 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -613,6 +613,8 @@
<string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Umožňuje aplikácii zápis na kartu SD."</string>
<string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"úprava alebo odstránenie obsahu interného ukladacieho priestoru média"</string>
<string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Umožňuje aplikácii zmeniť obsah interného ukladacieho priestoru média."</string>
+ <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"správa ukladacieho priestoru dokumentov"</string>
+ <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Umožňuje aplikácii spravovať ukladací priestor dokumentov."</string>
<string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"pristupovať k externému ukladaciemu priestoru pre všetkých používateľov"</string>
<string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Umožňuje aplikácii pristupovať k externému ukladaciemu priestoru pre všetkých používateľov."</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"pristupovať do súborového systému vyrovnávacej pamäte"</string>
@@ -1255,6 +1257,10 @@
<string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Umožňuje volať predvolenú službu kontajnera na skopírovanie obsahu. Bežné aplikácie toto nastavenie nepoužívajú."</string>
<string name="permlab_route_media_output" msgid="1642024455750414694">"Smerovanie výstupu médií"</string>
<string name="permdesc_route_media_output" msgid="4932818749547244346">"Umožňuje aplikácii smerovať výstup médií do ďalších externých zariadení."</string>
+ <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Prístup k ukladaciemu priestoru zabezpečenému technológiou keyguard"</string>
+ <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Umožňuje aplikácii získať prístup k ukladaciemu priestoru zabezpečenému technológiou keyguard."</string>
+ <string name="permlab_control_keyguard" msgid="172195184207828387">"Ovládanie zobrazenia alebo skrytia technológie keyguard"</string>
+ <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Umožňuje aplikácii ovládať technológiu keyguard."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Ovládacie prvky lupy zobrazíte dvojitým dotknutím"</string>
<string name="gadget_host_error_inflating" msgid="4882004314906466162">"Miniaplikáciu sa nepodarilo pridať."</string>
<string name="ime_action_go" msgid="8320845651737369027">"Hľadať"</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 80cb710..5280b06 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -613,6 +613,8 @@
<string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Programu omogoča pisanje na kartico SD."</string>
<string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"spreminjanje/brisanje vsebine notranje shrambe nosilca podatkov"</string>
<string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Programu omogoča spreminjanje vsebine notranje shrambe nosilca podatkov."</string>
+ <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"upravljanje shranjevanja dokumentov"</string>
+ <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Aplikaciji omogoči upravljanje shranjevanja dokumentov."</string>
<string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"dostop do zunanje naprave za shranjevanje za vse uporabnike"</string>
<string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Aplikaciji omogoča dostop do zunanje naprave za shranjevanje za vse uporabnike."</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"dostop do datotečnega sistema predpomnilnika"</string>
@@ -1255,6 +1257,10 @@
<string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Programu omogoča pozivanje privzete storitve vsebnika, da kopira vsebino. Ni za uporabo z navadnimi programi."</string>
<string name="permlab_route_media_output" msgid="1642024455750414694">"Preusmeritev predstavnosti"</string>
<string name="permdesc_route_media_output" msgid="4932818749547244346">"Aplikaciji omogoča preusmerjanje predstavnosti v druge zunanje naprave."</string>
+ <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Dostop do varne shrambe Keyguard."</string>
+ <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Aplikaciji omogoča dostop do varne shrambe Keyguard."</string>
+ <string name="permlab_control_keyguard" msgid="172195184207828387">"Nadzira prikaz in skrivanje zaklepanja tipkovnice"</string>
+ <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Aplikaciji omogoča nadzor zaklepanja tipkovnice."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Dvakrat se dotaknite za nadzor povečave/pomanjšave"</string>
<string name="gadget_host_error_inflating" msgid="4882004314906466162">"Pripomočka ni bilo mogoče dodati."</string>
<string name="ime_action_go" msgid="8320845651737369027">"Pojdi"</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 0965b46..79a3d87 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -613,6 +613,8 @@
<string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Дозвољава апликацији да уписује податке на SD картицу."</string>
<string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"измена/брисање интерне меморије медија"</string>
<string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Дозвољава апликацији да мења садржај интерне меморије медијума."</string>
+ <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"управ. складиштењем докумената"</string>
+ <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Дозвољава апликацији да управља складиштењем докумената."</string>
<string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"приступ спољној меморији свих корисника"</string>
<string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Дозвољава апликацији да приступа спољној меморији за све кориснике."</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"приступ систему датотека кеша"</string>
@@ -1255,6 +1257,10 @@
<string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Дозвољава апликацији да од подразумеване услуге контејнера захтева да копира садржај. Не користе је уобичајене апликације."</string>
<string name="permlab_route_media_output" msgid="1642024455750414694">"Усмеравање излаза медија"</string>
<string name="permdesc_route_media_output" msgid="4932818749547244346">"Дозвољава апликацији да усмерава излаз медија на друге спољне уређаје."</string>
+ <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Приступај безбедној меморији заштићеној шифром"</string>
+ <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Дозвољава апликацији да приступа безбедној меморији заштићеној шифром."</string>
+ <string name="permlab_control_keyguard" msgid="172195184207828387">"Контролиши приказивање и скривање заштите шифром"</string>
+ <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Дозвољава апликацији да контролише заштиту шифром."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Додирните двапут да бисте контролисали зум"</string>
<string name="gadget_host_error_inflating" msgid="4882004314906466162">"Није могуће додати виџет."</string>
<string name="ime_action_go" msgid="8320845651737369027">"Иди"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 0df55b9..0775d0a 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -613,6 +613,8 @@
<string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Tillåter att appen skriver till SD-kortet."</string>
<string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"ändra/ta bort innehåll"</string>
<string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Tillåter att appen ändrar innehållet på den interna lagringsenheten."</string>
+ <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"hantera dokumentlagring"</string>
+ <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Tillåter att appen hanterar dokumentlagring."</string>
<string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"åtkomst till lagringsutrymme"</string>
<string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Tillåter att appen får åtkomst till en extern lagringsenhet för alla användare."</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"åtkomst till cachefilsystemet"</string>
@@ -1255,6 +1257,10 @@
<string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Tillåter att appen kopierar innehåll genom att standardbehållartjänsten startas. Används inte av vanliga appar."</string>
<string name="permlab_route_media_output" msgid="1642024455750414694">"Omdirigera medieuppspelning"</string>
<string name="permdesc_route_media_output" msgid="4932818749547244346">"Tillåter att appen omdirigerar medieuppspelningar till andra externa enheter."</string>
+ <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Åtkomst till säkert keyguard-lagringsutrymme"</string>
+ <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Tillåter att en app får åtkomst till säkert keyguard-lagringsutrymme."</string>
+ <string name="permlab_control_keyguard" msgid="172195184207828387">"Kontrollera hur knapplåset visas och döljs"</string>
+ <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Tillåter att en app kontrollerar knapplåsfunktionen."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Tryck två gånger för zoomkontroll"</string>
<string name="gadget_host_error_inflating" msgid="4882004314906466162">"Det gick inte att lägga till widgeten."</string>
<string name="ime_action_go" msgid="8320845651737369027">"Kör"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index c2d7dec..450e6a3 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -613,6 +613,8 @@
<string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Inaruhusu programu kuandikia kadi ya SD."</string>
<string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"badilisha/futa maudhui ya hifadhi ya media ya ndani."</string>
<string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Inaruhusu programu kurekebisha maudhui ya hifadhi ya ndani vyombo vya habari."</string>
+ <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"dhibiti hifadhi ya hati"</string>
+ <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Huruhusu programu kudhibiti hifadhi ya hati."</string>
<string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"Fikia hifadhi ya nje ya watumiaji wote"</string>
<string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Inaruhusu programu kufikia hifadhi ya nje kwa watumiaji wote."</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"fikia faili za mfumo za kache"</string>
@@ -1255,6 +1257,10 @@
<string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Inaruhusu programu kuomba huduma ya chombo chaguo-msingi kunakili maudhui. Si ya matumizi na programu za kawiada."</string>
<string name="permlab_route_media_output" msgid="1642024455750414694">"Fuatalia utoaji wa habari"</string>
<string name="permdesc_route_media_output" msgid="4932818749547244346">"Inaruhusu programu kufuatilia utoaji wa habari kwa vifaa vingine vya nje."</string>
+ <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Kufikia hifadhi salama ya ufunguo wa ulinzi"</string>
+ <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Inaruhusu programu kufikia hifadhi salama ya ufunguo wa ulinzi."</string>
+ <string name="permlab_control_keyguard" msgid="172195184207828387">"Dhibiti uonyeshaji na ufichaji wa kilinda-funguo"</string>
+ <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Huruhusu programu kudhibiti kilinda-funguo."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Gusa mara mbili kwa udhibiti cha kuza"</string>
<string name="gadget_host_error_inflating" msgid="4882004314906466162">"Haikuweza kuongeza wijeti."</string>
<string name="ime_action_go" msgid="8320845651737369027">"Nenda"</string>
diff --git a/core/res/res/values-sw600dp-land/arrays.xml b/core/res/res/values-sw600dp-land/arrays.xml
index 5550216..5602a1c 100644
--- a/core/res/res/values-sw600dp-land/arrays.xml
+++ b/core/res/res/values-sw600dp-land/arrays.xml
@@ -19,54 +19,4 @@
-->
<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/core/res/res/values-sw600dp/alias.xml b/core/res/res/values-sw600dp/alias.xml
deleted file mode 100644
index bf3eecb..0000000
--- a/core/res/res/values-sw600dp/alias.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?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">@android:layout/keyguard_emergency_carrier_area</item>
-</resources>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 3010f0d..fd3ab94 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -613,6 +613,8 @@
<string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"อนุญาตให้แอปพลิเคชันเขียนลงบนการ์ด SD"</string>
<string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"แก้/ลบเนื้อหาข้อมูลสื่อภายใน"</string>
<string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"อนุญาตให้แอปพลิเคชันแก้ไขเนื้อหาของที่เก็บข้อมูลสื่อภายใน"</string>
+ <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"จัดการที่เก็บเอกสาร"</string>
+ <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"อนุญาตให้แอปจัดการที่เก็บเอกสาร"</string>
<string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"เข้าถึงที่จัดเก็บภายนอกของทุกคน"</string>
<string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"อนุญาตให้แอปพลิเคชันเข้าถึงที่จัดเก็บข้อมูลภายนอกสำหรับผู้ใช้ทั้งหมด"</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"เข้าถึงระบบไฟล์แคช"</string>
@@ -1255,6 +1257,10 @@
<string name="permdesc_copyProtectedData" msgid="4390697124288317831">"อนุญาตให้แอปพลิเคชันเรียกใช้บริการที่เก็บค่าเริ่มต้นเพื่อคัดลอกเนื้อหา ไม่ใช้สำหรับแอปพลิเคชันทั่วไป"</string>
<string name="permlab_route_media_output" msgid="1642024455750414694">"กำหนดเส้นทางเอาต์พุตของสื่อ"</string>
<string name="permdesc_route_media_output" msgid="4932818749547244346">"อนุญาตให้แอปพลิเคชันกำหนดเส้นทางเอาต์พุตของสื่อไปยังอุปกรณ์ภายนอกอื่นๆ"</string>
+ <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"เข้าถึงพื้นที่จัดเก็บที่รักษาความปลอดภัยด้วยคีย์การ์ด"</string>
+ <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"อนุญาตให้แอปพลิเคชันเข้าถึงพื้นที่จัดเก็บที่รักษาความปลอดภัยด้วยคีย์การ์ด"</string>
+ <string name="permlab_control_keyguard" msgid="172195184207828387">"ควบคุมการแสดงผลและการซ่อนตัวล็อกปุ่มกด"</string>
+ <string name="permdesc_control_keyguard" msgid="3043732290518629061">"อนุญาตให้แอปพลิเคชันควบคุมตัวล็อกปุ่มกด"</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"แตะสองครั้งเพื่อควบคุมการซูม"</string>
<string name="gadget_host_error_inflating" msgid="4882004314906466162">"ไม่สามารถเพิ่มวิดเจ็ต"</string>
<string name="ime_action_go" msgid="8320845651737369027">"ไป"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index c64de9a..ce46219 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -613,6 +613,8 @@
<string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Pinapayagan ang app na magsulat sa SD card."</string>
<string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"baguhin/tanggalin ang mga nilalaman ng panloob na imbakan ng media"</string>
<string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Pinapayagan ang app na baguhin ang mga nilalaman ng panloob na media storage."</string>
+ <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"pamahalaan document storage"</string>
+ <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Pinapayagan ang app na pamahalaan ang storage ng dokumento."</string>
<string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"i-access panlabas na storage ng user"</string>
<string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Pinapayagan ang app na mag-access ng panlabas na storage para sa lahat ng user."</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"i-access ang cache filesystem"</string>
@@ -1255,6 +1257,10 @@
<string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Pinapayagan ang app na i-apela ang default na serbisyo ng container upang kopyahin ang nilalaman. Hindi para sa paggamit ng normal na apps."</string>
<string name="permlab_route_media_output" msgid="1642024455750414694">"I-route ang output ng media"</string>
<string name="permdesc_route_media_output" msgid="4932818749547244346">"Pinapayagan ang application na mag-route ng output ng media sa iba pang mga panlabas na device."</string>
+ <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"I-access ang secure na storage ng keyguard"</string>
+ <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Nagbibigay-daan sa isang application na i-access ang secure na storage ng keyguard."</string>
+ <string name="permlab_control_keyguard" msgid="172195184207828387">"Kontrolin ang pagpapakita at pagtago sa keyguard"</string>
+ <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Pinapayagan ang isang application na kontrolin ang keyguard."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Pindutin nang dalawang beses para sa pagkontrol ng zoom"</string>
<string name="gadget_host_error_inflating" msgid="4882004314906466162">"Hindi maidagdag ang widget."</string>
<string name="ime_action_go" msgid="8320845651737369027">"Pumunta"</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 8a3d85a..c6e8519 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -613,6 +613,8 @@
<string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Uygulamaya, SD karta yazma izni verir."</string>
<string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"dahili medya depolama birimi içeriğini değiştir/sil"</string>
<string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Uygulamaya, dahili medya depolama içeriğini değiştirme izni verir."</string>
+ <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"doküman deposunu yönet"</string>
+ <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Uygulamaya, doküman deposunu yönetme izni verir."</string>
<string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"tüm kullanıcılar için harici depolama eriş"</string>
<string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Uygulamaya tüm kullanıcılar için harici depolamaya erişim izni verir."</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"önbellek dosya sistemine eriş"</string>
@@ -1255,6 +1257,10 @@
<string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Uygulamaya, içerik kopyalamak için varsayılan kapsayıcı hizmetini çağırma izni verir. Normal uygulamaların kullanımına yönelik değildir."</string>
<string name="permlab_route_media_output" msgid="1642024455750414694">"Medya çıktısını yönlendir"</string>
<string name="permdesc_route_media_output" msgid="4932818749547244346">"Uygulamaya medya çıktısını başka harici cihazlara yönlendirme izni verir."</string>
+ <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Tuş kilitli güvenli depolamaya erişim"</string>
+ <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Bir uygulamanın tuş kilitli güvenli depolamaya erişimine izin verir."</string>
+ <string name="permlab_control_keyguard" msgid="172195184207828387">"Tuş koruyucuyu görüntülemeyi ve gizlemeyi kontrol et"</string>
+ <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Bir uygulamaya tuş koruyucuyu denetleme izni verir."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Yakınlaştırma denetimi için iki kez dokunun"</string>
<string name="gadget_host_error_inflating" msgid="4882004314906466162">"Widget eklenemedi."</string>
<string name="ime_action_go" msgid="8320845651737369027">"Git"</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 8a89a20..216a9b1 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -613,6 +613,8 @@
<string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Дозволяє програмі записувати на карту SD."</string>
<string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"змінювати/видаляти вміст внутр. сховища даних"</string>
<string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Дозволяє програмі змінювати вміст внутрішнього сховища даних."</string>
+ <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"керувати зберіганням"</string>
+ <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Дозволяє програмі керувати зберіганням документів."</string>
<string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"доступ до зовн. пам’яті всіх корист."</string>
<string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Дозволяє програмі отримувати доступ до зовнішньої пам’яті всіх користувачів."</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"отр. дост. до файл. сист. кешу"</string>
@@ -1255,6 +1257,10 @@
<string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Дозволяє програмі викликати службу контейнерів за умовчанням для копіювання вмісту. Не для використання звичайними програмами."</string>
<string name="permlab_route_media_output" msgid="1642024455750414694">"Скеровувати вивід медіа-даних"</string>
<string name="permdesc_route_media_output" msgid="4932818749547244346">"Дозволяє програмі скеровувати вивід медіа-даних на інші зовнішні пристрої."</string>
+ <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Отримувати доступ до безпечного сховища через клавіатуру"</string>
+ <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Дозволяє програмі отримувати доступ до безпечного сховища через клавіатуру."</string>
+ <string name="permlab_control_keyguard" msgid="172195184207828387">"Керувати відображенням і хованням клавіатури"</string>
+ <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Дозволяє програмі керувати клавіатурою."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Двічі торкніться, щоб керувати масштабом"</string>
<string name="gadget_host_error_inflating" msgid="4882004314906466162">"Не вдалося додати віджет."</string>
<string name="ime_action_go" msgid="8320845651737369027">"Йти"</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 57fe95a..7f076b9 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -613,6 +613,8 @@
<string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Cho phép ứng dụng ghi vào thẻ SD."</string>
<string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"sửa đổi/xóa nội dung trên bộ nhớ phương tiện cục bộ"</string>
<string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Cho phép ứng dụng sửa đổi nội dung của bộ lưu trữ phương tiện nội bộ."</string>
+ <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"quản lý bộ nhớ tài liệu"</string>
+ <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Cho phép ứng dụng quản lý bộ nhớ tài liệu."</string>
<string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"truy cập bộ nhớ ngoài của tất cả người dùng"</string>
<string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Cho phép ứng dụng truy cập bộ nhớ ngoài của tất cả người dùng."</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"truy cập hệ thống tệp bộ nhớ cache"</string>
@@ -1255,6 +1257,10 @@
<string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Cho phép ứng dụng gọi ra dịch vụ bộ chứa mặc định để sao chép nội dung. Không dành cho ứng dụng thông thường."</string>
<string name="permlab_route_media_output" msgid="1642024455750414694">"Định tuyến thiết bị ra phương tiện"</string>
<string name="permdesc_route_media_output" msgid="4932818749547244346">"Cho phép ứng dụng định tuyến thiết bị ra phương tiện đến các thiết bị bên ngoài khác."</string>
+ <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Truy cập bộ nhớ an toàn khóa bàn phím"</string>
+ <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Cho phép ứng dụng truy cập bộ nhớ an toàn khóa"</string>
+ <string name="permlab_control_keyguard" msgid="172195184207828387">"Kiểm soát việc hiển thị và ẩn tính năng bảo vệ phím"</string>
+ <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Cho phép ứng dụng kiểm soát tính năng bảo vệ phím."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Chạm hai lần để kiểm soát thu phóng"</string>
<string name="gadget_host_error_inflating" msgid="4882004314906466162">"Không thể thêm tiện ích."</string>
<string name="ime_action_go" msgid="8320845651737369027">"Đến"</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index b131962..2e93751 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -613,6 +613,8 @@
<string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"允许应用写入 SD 卡。"</string>
<string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"修改/删除内部媒体存储设备的内容"</string>
<string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"允许应用修改内部媒体存储设备的内容。"</string>
+ <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"管理文档存储空间"</string>
+ <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"允许应用管理文档存储空间。"</string>
<string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"访问所有用户的外部存储设备"</string>
<string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"允许应用访问所有用户的外部存储设备。"</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"访问缓存文件系统"</string>
@@ -1255,6 +1257,10 @@
<string name="permdesc_copyProtectedData" msgid="4390697124288317831">"允许应用调用默认的容器服务,以便复制内容。普通应用不应使用此权限。"</string>
<string name="permlab_route_media_output" msgid="1642024455750414694">"更改媒体输出线路"</string>
<string name="permdesc_route_media_output" msgid="4932818749547244346">"允许该应用将媒体输出线路更改到其他外部设备。"</string>
+ <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"访问密钥保护安全存储空间"</string>
+ <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"允许应用访问密钥保护安全存储空间。"</string>
+ <string name="permlab_control_keyguard" msgid="172195184207828387">"控制是显示还是隐藏锁屏"</string>
+ <string name="permdesc_control_keyguard" msgid="3043732290518629061">"允许应用控制锁屏。"</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"触摸两次可进行缩放控制"</string>
<string name="gadget_host_error_inflating" msgid="4882004314906466162">"无法添加小部件。"</string>
<string name="ime_action_go" msgid="8320845651737369027">"开始"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 6c3991a..5d55678 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -613,6 +613,8 @@
<string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"允許應用程式寫入 SD 卡。"</string>
<string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"修改/刪除內部媒體儲存裝置內容"</string>
<string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"允許應用程式修改內部媒體儲存空間的內容。"</string>
+ <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"管理文件儲存空間"</string>
+ <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"允許應用程式管理文件儲存空間。"</string>
<string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"存取外部儲存空間 (所有使用者)"</string>
<string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"允許應用程式存取外部儲存空間 (所有使用者)。"</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"存取快取檔案系統"</string>
@@ -1255,6 +1257,10 @@
<string name="permdesc_copyProtectedData" msgid="4390697124288317831">"允許觸發預設容器服務,以便複製內容 (不建議一般應用程式使用)。"</string>
<string name="permlab_route_media_output" msgid="1642024455750414694">"轉送媒體輸出"</string>
<string name="permdesc_route_media_output" msgid="4932818749547244346">"允許應用程式將媒體輸出轉送至其他外部裝置。"</string>
+ <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"存取 Keyguard 安全儲存空間"</string>
+ <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"允許應用程式存取 Keyguard 安全儲存空間。"</string>
+ <string name="permlab_control_keyguard" msgid="172195184207828387">"控制鍵盤鎖的顯示和隱藏"</string>
+ <string name="permdesc_control_keyguard" msgid="3043732290518629061">"允許應用程式控制鍵盤鎖。"</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"輕觸兩下即可控制縮放"</string>
<string name="gadget_host_error_inflating" msgid="4882004314906466162">"無法新增小工具。"</string>
<string name="ime_action_go" msgid="8320845651737369027">"開始"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index f2e6d5e..df86b74 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -613,6 +613,8 @@
<string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Ivumela insiza ukuthi ibhalele ekhadini le-SD."</string>
<string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"guqula/susa okuqukethwe kwisitoreji semidiya yangaphakathi"</string>
<string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Ivumela insiza ukuthi iguqule okuqukethwe kokulondoloza imidiya yangaphakathi."</string>
+ <string name="permlab_manageDocs" product="default" msgid="5778318598448849829">"phatha isitoreji sedokhumenti"</string>
+ <string name="permdesc_manageDocs" product="default" msgid="8704323176914121484">"Ivumela uhlelo lokusebenza ukuthi luphathe isitoreji sedokhumenti."</string>
<string name="permlab_sdcardAccessAll" msgid="8150613823900460576">"ukufinyelela isilondolozi sangaphandle sabo bonke abasebenzisi"</string>
<string name="permdesc_sdcardAccessAll" msgid="3215208357415891320">"Vumela uhlelo lokusebenza ukufinyelela isilondolozi sangaphandle kubo bonke abasebenzisi."</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"finyelela kunqolobane yesistimu yefayela"</string>
@@ -1255,6 +1257,10 @@
<string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Ivumela insiza ukuthi inqabe okutholakala kukhona ukukopisha okuqukethwe. Akusetshenziswa izinsiza ezijwayelekile."</string>
<string name="permlab_route_media_output" msgid="1642024455750414694">"Yenza umzila wemidiya wokukhiphayo"</string>
<string name="permdesc_route_media_output" msgid="4932818749547244346">"Ivumela uhlelo lokusebenza ukwenza umzila wokukhiphayo wemidiya kuya kumadivayisi angaphandle."</string>
+ <string name="permlab_access_keyguard_secure_storage" msgid="7565552237977815047">"Finyelela kusitoreji esiqashwa ngesikhiya esiphephile"</string>
+ <string name="permdesc_access_keyguard_secure_storage" msgid="5866245484303285762">"Ivumela uhlelo lokusebenza ukuthi lufinyelele kusitoreji esiqashwa ngesikhiya esiphephile."</string>
+ <string name="permlab_control_keyguard" msgid="172195184207828387">"Lawula ukubonisa nokufihla ukhiye wokuqapha"</string>
+ <string name="permdesc_control_keyguard" msgid="3043732290518629061">"Ivumela uhlelo lokusebenza ukuthi lulawule ukhiye wokuqapha."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Thinta kabili ukulawula ukusondeza"</string>
<string name="gadget_host_error_inflating" msgid="4882004314906466162">"Yehlulekile ukwengeza i-widget."</string>
<string name="ime_action_go" msgid="8320845651737369027">"Iya"</string>
diff --git a/core/res/res/values/arrays.xml b/core/res/res/values/arrays.xml
index 146607e..ef30b98 100644
--- a/core/res/res/values/arrays.xml
+++ b/core/res/res/values/arrays.xml
@@ -346,75 +346,4 @@
<item>中文 (繁體)</item>
</string-array>
- <!-- 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>@*android:drawable/ic_lockscreen_unlock</item>
- </array>
-
- <array name="lockscreen_target_descriptions_unlock_only">
- <item>@*android: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/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 4dcbaec..459a634 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -4057,10 +4057,6 @@
<attr name="drawable" />
</declare-styleable>
- <declare-styleable name="MipmapDrawableItem">
- <attr name="drawable" />
- </declare-styleable>
-
<!-- Drawable used to rotate another drawable. -->
<declare-styleable name="RotateDrawable">
<attr name="visible" />
@@ -4408,6 +4404,28 @@
</declare-styleable>
<!-- ========================== -->
+ <!-- State class attributes -->
+ <!-- ========================== -->
+ <eat-comment />
+
+ <declare-styleable name="Scene">
+ <attr name="layout" />
+ </declare-styleable>
+
+ <declare-styleable name="Transition">
+ <attr name="duration" />
+ <attr name="startOffset" />
+ <attr name="interpolator" />
+ <attr name="targetID" format="reference" />
+ </declare-styleable>
+
+ <declare-styleable name="TransitionManager">
+ <attr name="transition" format="reference" />
+ <attr name="fromScene" format="reference" />
+ <attr name="toScene" format="reference" />
+ </declare-styleable>
+
+ <!-- ========================== -->
<!-- ValueAnimator class attributes -->
<!-- ========================== -->
<eat-comment />
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index e7f6c53..0aaa5b7 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -1781,4 +1781,12 @@
<!-- Concrete value to put for this named extra data. -->
<attr name="value" />
</declare-styleable>
+
+ <attr name="keyset" />
+ <declare-styleable name="PublicKey">
+ <attr name="value" />
+ </declare-styleable>
+ <declare-styleable name="KeySet">
+ <attr name="name" />
+ </declare-styleable>
</resources>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 2d97138..089a859 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2052,4 +2052,15 @@
<public type="style" name="Theme.DeviceDefault.NoActionBar.Overscan" id="0x010301df" />
<public type="style" name="Theme.DeviceDefault.Light.NoActionBar.Overscan" id="0x010301e0" />
+<!-- ===============================================================
+ Resources added in version 19 of the platform
+ =============================================================== -->
+ <eat-comment />
+
+ <public type="attr" name="keyset" />
+ <public type="attr" name="targetID" />
+ <public type="attr" name="fromScene" />
+ <public type="attr" name="toScene" />
+ <public type="attr" name="transition" />
+
</resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index b595d6e..d40eb64 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1797,6 +1797,11 @@
<string name="permdesc_mediaStorageWrite" product="default">Allows the app to modify the contents of the internal media storage.</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. [CHAR LIMIT=30] -->
+ <string name="permlab_manageDocs" product="default">manage document storage</string>
+ <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. [CHAR LIMIT=NONE] -->
+ <string name="permdesc_manageDocs" product="default">Allows the app to manage document storage.</string>
+
+ <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. [CHAR LIMIT=30] -->
<string name="permlab_sdcardAccessAll">access external storage of all users</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_sdcardAccessAll">Allows the app to access external storage for all users.</string>
@@ -3469,6 +3474,16 @@
<!-- Description of an application permission that lets an application route media output. -->
<string name="permdesc_route_media_output">Allows an application to route media output to other external devices.</string>
+ <!-- Title of an application permission that lets an application access keyguard secure storage. -->
+ <string name="permlab_access_keyguard_secure_storage">Access keyguard secure storage</string>
+ <!-- Description of an application permission that lets an application access keyguard secure storage. -->
+ <string name="permdesc_access_keyguard_secure_storage">Allows an application to access keguard secure storage.</string>
+
+ <!-- Title of an application permission that lets it control keyguard. -->
+ <string name="permlab_control_keyguard">Control displaying and hiding keyguard</string>
+ <!-- Description of an application permission that lets it control keyguard. -->
+ <string name="permdesc_control_keyguard">Allows an application to control keguard.</string>
+
<!-- Shown in the tutorial for tap twice for zoom control. -->
<string name="tutorial_double_tap_to_zoom_message_short">Touch twice for zoom control</string>
@@ -4108,7 +4123,7 @@
<!-- Error message title [CHAR LIMIT=35] -->
<string name="error_message_title">Error</string>
<!-- Message informing user that app is not permitted to access accounts. [CHAR LIMIT=none] -->
- <string name="app_no_restricted_accounts">This application does not support accounts for restricted profiles</string>
+ <string name="app_no_restricted_accounts">This app doesn\'t support accounts for restricted profiles</string>
<!-- Message informing user that the requested activity could not be found [CHAR LIMIT=none] -->
<string name="app_not_found">No application found to handle this action</string>
<string name="revoke">Revoke</string>
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index f494d8c..bd82f35 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -138,6 +138,12 @@ please see styles_device_defaults.xml.
<item name="windowExitAnimation">@anim/submenu_exit</item>
</style>
+ <!-- {@hide} -->
+ <style name="Animation.ToastBar">
+ <item name="windowEnterAnimation">@anim/toast_bar_enter</item>
+ <item name="windowExitAnimation">@anim/toast_bar_exit</item>
+ </style>
+
<style name="Animation.TypingFilter">
<item name="windowEnterAnimation">@anim/grow_fade_in_center</item>
<item name="windowExitAnimation">@anim/shrink_fade_out_center</item>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 3ecdc0c..3718220 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -38,16 +38,12 @@
<java-symbol type="id" name="action_menu_presenter" />
<java-symbol type="id" name="action_mode_close_button" />
<java-symbol type="id" name="activity_chooser_view_content" />
- <java-symbol type="id" name="albumart" />
<java-symbol type="id" name="alertTitle" />
<java-symbol type="id" name="allow_button" />
<java-symbol type="id" name="alwaysUse" />
<java-symbol type="id" name="amPm" />
<java-symbol type="id" name="authtoken_type" />
<java-symbol type="id" name="back_button" />
- <java-symbol type="id" name="btn_next" />
- <java-symbol type="id" name="btn_play" />
- <java-symbol type="id" name="btn_prev" />
<java-symbol type="id" name="button_bar" />
<java-symbol type="id" name="buttonPanel" />
<java-symbol type="id" name="by_common" />
@@ -572,26 +568,6 @@
<java-symbol type="string" name="keyboardview_keycode_enter" />
<java-symbol type="string" name="keyboardview_keycode_mode_change" />
<java-symbol type="string" name="keyboardview_keycode_shift" />
- <java-symbol type="string" name="keyguard_accessibility_add_widget" />
- <java-symbol type="string" name="keyguard_accessibility_camera" />
- <java-symbol type="string" name="keyguard_accessibility_expand_lock_area" />
- <java-symbol type="string" name="keyguard_accessibility_face_unlock" />
- <java-symbol type="string" name="keygaurd_accessibility_media_controls" />
- <java-symbol type="string" name="keyguard_accessibility_pattern_area" />
- <java-symbol type="string" name="keyguard_accessibility_pattern_unlock" />
- <java-symbol type="string" name="keyguard_accessibility_password_unlock" />
- <java-symbol type="string" name="keyguard_accessibility_pin_unlock" />
- <java-symbol type="string" name="keyguard_accessibility_slide_area" />
- <java-symbol type="string" name="keyguard_accessibility_slide_unlock" />
- <java-symbol type="string" name="keyguard_accessibility_status" />
- <java-symbol type="string" name="keyguard_accessibility_user_selector" />
- <java-symbol type="string" name="keyguard_accessibility_widget" />
- <java-symbol type="string" name="keyguard_accessibility_widget_deleted" />
- <java-symbol type="string" name="keyguard_accessibility_widget_empty_slot" />
- <java-symbol type="string" name="keyguard_accessibility_widget_reorder_start" />
- <java-symbol type="string" name="keyguard_accessibility_widget_reorder_end" />
- <java-symbol type="string" name="keyguard_accessibility_unlock_area_collapsed" />
- <java-symbol type="string" name="keyguard_accessibility_unlock_area_expanded" />
<java-symbol type="string" name="kilobyteShort" />
<java-symbol type="string" name="last_month" />
<java-symbol type="string" name="launchBrowserDefault" />
@@ -601,9 +577,6 @@
<java-symbol type="string" name="lockscreen_access_pattern_start" />
<java-symbol type="string" name="lockscreen_emergency_call" />
<java-symbol type="string" name="lockscreen_return_to_call" />
- <java-symbol type="string" name="lockscreen_transport_pause_description" />
- <java-symbol type="string" name="lockscreen_transport_play_description" />
- <java-symbol type="string" name="lockscreen_transport_stop_description" />
<java-symbol type="string" name="low_memory" />
<java-symbol type="string" name="media_bad_removal" />
<java-symbol type="string" name="media_checking" />
@@ -1018,21 +991,17 @@
<java-symbol type="drawable" name="text_select_handle_left" />
<java-symbol type="drawable" name="text_select_handle_middle" />
<java-symbol type="drawable" name="text_select_handle_right" />
+ <java-symbol type="drawable" name="toast_bar_bg" />
<java-symbol type="drawable" name="unknown_image" />
<java-symbol type="drawable" name="unlock_default" />
<java-symbol type="drawable" name="unlock_halo" />
<java-symbol type="drawable" name="unlock_ring" />
<java-symbol type="drawable" name="unlock_wave" />
- <java-symbol type="drawable" name="ic_lockscreen_camera" />
- <java-symbol type="drawable" name="ic_lockscreen_silent" />
- <java-symbol type="drawable" name="ic_lockscreen_unlock" />
<java-symbol type="drawable" name="ic_action_assist_generic" />
- <java-symbol type="drawable" name="ic_lockscreen_alarm" />
<java-symbol type="drawable" name="notification_bg" />
<java-symbol type="drawable" name="notification_bg_low" />
<java-symbol type="drawable" name="notification_template_icon_bg" />
<java-symbol type="drawable" name="notification_template_icon_low_bg" />
- <java-symbol type="drawable" name="ic_lockscreen_unlock_phantom" />
<java-symbol type="drawable" name="ic_media_route_on_holo_dark" />
<java-symbol type="drawable" name="ic_media_route_disabled_holo_dark" />
@@ -1111,6 +1080,7 @@
<java-symbol type="layout" name="textview_hint" />
<java-symbol type="layout" name="time_picker" />
<java-symbol type="layout" name="time_picker_dialog" />
+ <java-symbol type="layout" name="toast_bar" />
<java-symbol type="layout" name="transient_notification" />
<java-symbol type="layout" name="volume_adjust" />
<java-symbol type="layout" name="volume_adjust_item" />
@@ -1132,10 +1102,7 @@
<java-symbol type="layout" name="notification_template_part_time" />
<java-symbol type="layout" name="notification_template_part_chronometer" />
<java-symbol type="layout" name="notification_template_inbox" />
- <java-symbol type="layout" name="keyguard_multi_user_avatar" />
- <java-symbol type="layout" name="keyguard_multi_user_selector_widget" />
<java-symbol type="layout" name="sms_short_code_confirmation_dialog" />
- <java-symbol type="layout" name="keyguard_add_widget" />
<java-symbol type="layout" name="action_bar_up_container" />
<java-symbol type="layout" name="app_not_authorized" />
@@ -1153,7 +1120,6 @@
<java-symbol type="xml" name="password_kbd_qwerty_shifted" />
<java-symbol type="xml" name="password_kbd_symbols" />
<java-symbol type="xml" name="password_kbd_symbols_shift" />
- <java-symbol type="xml" name="kg_password_kbd_numeric" />
<java-symbol type="xml" name="power_profile" />
<java-symbol type="xml" name="time_zones_by_country" />
<java-symbol type="xml" name="sms_short_codes" />
@@ -1168,6 +1134,7 @@
<java-symbol type="style" name="Animation.DropDownUp" />
<java-symbol type="style" name="Animation.DropDownDown" />
<java-symbol type="style" name="Animation.PopupWindow" />
+ <java-symbol type="style" name="Animation.ToastBar" />
<java-symbol type="style" name="Animation.TypingFilter" />
<java-symbol type="style" name="Animation.TypingFilterRestore" />
<java-symbol type="style" name="Animation.Dream" />
@@ -1207,8 +1174,6 @@
<!-- From android.policy -->
<java-symbol type="anim" name="app_starting_exit" />
- <java-symbol type="anim" name="lock_screen_behind_enter" />
- <java-symbol type="anim" name="lock_screen_wallpaper_behind_enter" />
<java-symbol type="anim" name="dock_top_enter" />
<java-symbol type="anim" name="dock_top_exit" />
<java-symbol type="anim" name="dock_bottom_enter" />
@@ -1217,22 +1182,12 @@
<java-symbol type="anim" name="dock_left_exit" />
<java-symbol type="anim" name="dock_right_enter" />
<java-symbol type="anim" name="dock_right_exit" />
- <java-symbol type="anim" name="keyguard_security_animate_in" />
- <java-symbol type="anim" name="keyguard_security_animate_out" />
- <java-symbol type="anim" name="keyguard_security_fade_in" />
- <java-symbol type="anim" name="keyguard_security_fade_out" />
- <java-symbol type="anim" name="keyguard_action_assist_exit" />
- <java-symbol type="anim" name="keyguard_action_assist_enter" />
<java-symbol type="array" name="config_keyboardTapVibePattern" />
<java-symbol type="array" name="config_longPressVibePattern" />
<java-symbol type="array" name="config_safeModeDisabledVibePattern" />
<java-symbol type="array" name="config_safeModeEnabledVibePattern" />
<java-symbol type="array" name="config_virtualKeyVibePattern" />
- <java-symbol type="array" name="lockscreen_targets_when_silent" />
- <java-symbol type="array" name="lockscreen_targets_when_soundon" />
- <java-symbol type="array" name="lockscreen_targets_with_camera" />
- <java-symbol type="array" name="lockscreen_num_pad_klondike" />
<java-symbol type="attr" name="actionModePopupWindowStyle" />
<java-symbol type="attr" name="dialogCustomTitleDecorLayout" />
<java-symbol type="attr" name="dialogTitleDecorLayout" />
@@ -1247,33 +1202,11 @@
<java-symbol type="bool" name="config_lidControlsSleep" />
<java-symbol type="bool" name="config_reverseDefaultRotation" />
<java-symbol type="bool" name="config_showNavigationBar" />
- <java-symbol type="bool" name="kg_enable_camera_default_widget" />
- <java-symbol type="bool" name="kg_share_status_area" />
- <java-symbol type="bool" name="kg_sim_puk_account_full_screen" />
- <java-symbol type="bool" name="kg_top_align_page_shrink_on_bouncer_visible" />
<java-symbol type="bool" name="target_honeycomb_needs_options_menu" />
- <java-symbol type="bool" name="kg_center_small_widgets_vertically" />
- <java-symbol type="bool" name="kg_show_ime_at_screen_on" />
- <java-symbol type="color" name="kg_multi_user_text_active" />
- <java-symbol type="color" name="kg_multi_user_text_inactive" />
- <java-symbol type="color" name="kg_widget_pager_gradient" />
- <java-symbol type="color" name="keyguard_avatar_frame_color" />
- <java-symbol type="color" name="keyguard_avatar_frame_pressed_color" />
- <java-symbol type="color" name="keyguard_avatar_frame_shadow_color" />
- <java-symbol type="color" name="keyguard_avatar_nick_color" />
<java-symbol type="dimen" name="navigation_bar_height" />
<java-symbol type="dimen" name="navigation_bar_height_landscape" />
<java-symbol type="dimen" name="navigation_bar_width" />
<java-symbol type="dimen" name="status_bar_height" />
- <java-symbol type="dimen" name="kg_widget_pager_horizontal_padding" />
- <java-symbol type="dimen" name="kg_widget_pager_top_padding" />
- <java-symbol type="dimen" name="kg_widget_pager_bottom_padding" />
- <java-symbol type="dimen" name="keyguard_avatar_size" />
- <java-symbol type="dimen" name="keyguard_avatar_frame_stroke_width" />
- <java-symbol type="dimen" name="keyguard_avatar_frame_shadow_radius" />
- <java-symbol type="dimen" name="kg_edge_swipe_region_size" />
- <java-symbol type="dimen" name="kg_squashed_layout_threshold" />
- <java-symbol type="dimen" name="kg_small_widget_height" />
<java-symbol type="drawable" name="ic_jog_dial_sound_off" />
<java-symbol type="drawable" name="ic_jog_dial_sound_on" />
<java-symbol type="drawable" name="ic_jog_dial_unlock" />
@@ -1292,9 +1225,7 @@
<java-symbol type="drawable" name="magnified_region_frame" />
<java-symbol type="drawable" name="menu_background" />
<java-symbol type="drawable" name="stat_sys_secure" />
- <java-symbol type="drawable" name="kg_widget_bg_padded" />
<java-symbol type="id" name="action_mode_bar_stub" />
- <java-symbol type="id" name="alarm_status" />
<java-symbol type="id" name="button0" />
<java-symbol type="id" name="button4" />
<java-symbol type="id" name="button5" />
@@ -1302,15 +1233,12 @@
<java-symbol type="id" name="button7" />
<java-symbol type="id" name="date" />
<java-symbol type="id" name="eight" />
- <java-symbol type="id" name="face_unlock_area_view" />
- <java-symbol type="id" name="face_unlock_cancel_button" />
<java-symbol type="id" name="five" />
<java-symbol type="id" name="four" />
<java-symbol type="id" name="icon_menu_presenter" />
<java-symbol type="id" name="keyboard" />
<java-symbol type="id" name="list_menu_presenter" />
<java-symbol type="id" name="lock_screen" />
- <java-symbol type="id" name="login" />
<java-symbol type="id" name="nine" />
<java-symbol type="id" name="no_applications_message" />
<java-symbol type="id" name="ok" />
@@ -1318,57 +1246,14 @@
<java-symbol type="id" name="option1" />
<java-symbol type="id" name="option2" />
<java-symbol type="id" name="option3" />
- <java-symbol type="id" name="password" />
- <java-symbol type="id" name="passwordEntry" />
- <java-symbol type="id" name="pinEntry" />
<java-symbol type="id" name="right_icon" />
<java-symbol type="id" name="seven" />
<java-symbol type="id" name="six" />
<java-symbol type="id" name="status" />
- <java-symbol type="id" name="switch_ime_button" />
<java-symbol type="id" name="three" />
<java-symbol type="id" name="title_container" />
<java-symbol type="id" name="two" />
<java-symbol type="id" name="zero" />
- <java-symbol type="id" name="keyguard_message_area" />
- <java-symbol type="id" name="keyguard_click_area" />
- <java-symbol type="id" name="keyguard_selector_view" />
- <java-symbol type="id" name="keyguard_pattern_view" />
- <java-symbol type="id" name="keyguard_password_view" />
- <java-symbol type="id" name="keyguard_pin_view" />
- <java-symbol type="id" name="keyguard_face_unlock_view" />
- <java-symbol type="id" name="keyguard_sim_pin_view" />
- <java-symbol type="id" name="keyguard_sim_puk_view" />
- <java-symbol type="id" name="keyguard_account_view" />
- <java-symbol type="id" name="keyguard_selector_fade_container" />
- <java-symbol type="id" name="keyguard_widget_pager_delete_target" />
- <java-symbol type="id" name="keyguard_bouncer_frame" />
- <java-symbol type="id" name="app_widget_container" />
- <java-symbol type="id" name="view_flipper" />
- <java-symbol type="id" name="carrier_text" />
- <java-symbol type="id" name="emergency_call_button" />
- <java-symbol type="id" name="keyguard_host_view" />
- <java-symbol type="id" name="delete_button" />
- <java-symbol type="id" name="lockPatternView" />
- <java-symbol type="id" name="forgot_password_button" />
- <java-symbol type="id" name="glow_pad_view" />
- <java-symbol type="id" name="delete_button" />
- <java-symbol type="id" name="keyguard_user_avatar" />
- <java-symbol type="id" name="keyguard_user_name" />
- <java-symbol type="id" name="keyguard_transport_control" />
- <java-symbol type="id" name="keyguard_status_view" />
- <java-symbol type="id" name="keyguard_status_view_face_palm" />
- <java-symbol type="id" name="keyguard_users_grid" />
- <java-symbol type="id" name="clock_text" />
- <java-symbol type="id" name="clock_view" />
- <java-symbol type="id" name="keyguard_multi_user_selector" />
- <java-symbol type="id" name="sliding_layout" />
- <java-symbol type="id" name="keyguard_add_widget" />
- <java-symbol type="id" name="keyguard_add_widget_view" />
- <java-symbol type="id" name="multi_pane_challenge" />
- <java-symbol type="id" name="keyguard_user_selector" />
- <java-symbol type="id" name="key_enter" />
- <java-symbol type="id" name="keyguard_selector_view_frame" />
<java-symbol type="integer" name="config_carDockRotation" />
<java-symbol type="integer" name="config_defaultUiModeType" />
<java-symbol type="integer" name="config_deskDockRotation" />
@@ -1377,18 +1262,8 @@
<java-symbol type="integer" name="config_lidNavigationAccessibility" />
<java-symbol type="integer" name="config_lidOpenRotation" />
<java-symbol type="integer" name="config_longPressOnHomeBehavior" />
- <java-symbol type="integer" name="kg_security_flip_duration" />
- <java-symbol type="integer" name="kg_carousel_angle" />
<java-symbol type="layout" name="global_actions_item" />
<java-symbol type="layout" name="global_actions_silent_mode" />
- <java-symbol type="layout" name="keyguard_selector_view" />
- <java-symbol type="layout" name="keyguard_pattern_view" />
- <java-symbol type="layout" name="keyguard_password_view" />
- <java-symbol type="layout" name="keyguard_pin_view" />
- <java-symbol type="layout" name="keyguard_face_unlock_view" />
- <java-symbol type="layout" name="keyguard_sim_pin_view" />
- <java-symbol type="layout" name="keyguard_sim_puk_view" />
- <java-symbol type="layout" name="keyguard_account_view" />
<java-symbol type="layout" name="recent_apps_dialog" />
<java-symbol type="layout" name="screen_action_bar" />
<java-symbol type="layout" name="screen_custom_title" />
@@ -1397,9 +1272,6 @@
<java-symbol type="layout" name="screen_simple_overlay_action_mode" />
<java-symbol type="layout" name="screen_title" />
<java-symbol type="layout" name="screen_title_icons" />
- <java-symbol type="layout" name="keyguard_host_view" />
- <java-symbol type="layout" name="keyguard_transport_control_view" />
- <java-symbol type="layout" name="keyguard_status_view" />
<java-symbol type="string" name="abbrev_wday_month_day_no_year" />
<java-symbol type="string" name="system_ui_date_pattern" />
<java-symbol type="string" name="android_upgrading_title" />
@@ -1415,41 +1287,7 @@
<java-symbol type="string" name="global_action_silent_mode_on_status" />
<java-symbol type="string" name="global_action_toggle_silent_mode" />
<java-symbol type="string" name="invalidPuk" />
- <java-symbol type="string" name="keyguard_password_enter_pin_code" />
- <java-symbol type="string" name="keyguard_password_enter_puk_code" />
- <java-symbol type="string" name="keyguard_password_wrong_pin_code" />
<java-symbol type="string" name="lockscreen_carrier_default" />
- <java-symbol type="string" name="lockscreen_charged" />
- <java-symbol type="string" name="lockscreen_failed_attempts_almost_at_wipe" />
- <java-symbol type="string" name="lockscreen_failed_attempts_almost_glogin" />
- <java-symbol type="string" name="lockscreen_failed_attempts_now_wiping" />
- <java-symbol type="string" name="lockscreen_forgot_pattern_button_text" />
- <java-symbol type="string" name="lockscreen_glogin_checking_password" />
- <java-symbol type="string" name="lockscreen_glogin_forgot_pattern" />
- <java-symbol type="string" name="lockscreen_glogin_invalid_input" />
- <java-symbol type="string" name="lockscreen_glogin_too_many_attempts" />
- <java-symbol type="string" name="lockscreen_instructions_when_pattern_disabled" />
- <java-symbol type="string" name="lockscreen_low_battery" />
- <java-symbol type="string" name="lockscreen_missing_sim_instructions" />
- <java-symbol type="string" name="lockscreen_missing_sim_instructions_long" />
- <java-symbol type="string" name="lockscreen_missing_sim_message_short" />
- <java-symbol type="string" name="lockscreen_network_locked_message" />
- <java-symbol type="string" name="lockscreen_password_wrong" />
- <java-symbol type="string" name="lockscreen_pattern_instructions" />
- <java-symbol type="string" name="lockscreen_pattern_wrong" />
- <java-symbol type="string" name="lockscreen_permanent_disabled_sim_message_short" />
- <java-symbol type="string" name="lockscreen_permanent_disabled_sim_instructions" />
- <java-symbol type="string" name="lockscreen_plugged_in" />
- <java-symbol type="string" name="lockscreen_sim_locked_message" />
- <java-symbol type="string" name="lockscreen_sim_puk_locked_message" />
- <java-symbol type="string" name="lockscreen_sim_unlock_progress_dialog_message" />
- <java-symbol type="string" name="lockscreen_sound_off_label" />
- <java-symbol type="string" name="lockscreen_sound_on_label" />
- <java-symbol type="string" name="lockscreen_too_many_failed_attempts_countdown" />
- <java-symbol type="string" name="lockscreen_too_many_failed_attempts_dialog_message" />
- <java-symbol type="string" name="lockscreen_too_many_failed_password_attempts_dialog_message" />
- <java-symbol type="string" name="lockscreen_too_many_failed_pin_attempts_dialog_message" />
- <java-symbol type="string" name="lockscreen_unlock_label" />
<java-symbol type="string" name="status_bar_device_locked" />
<java-symbol type="style" name="Animation.LockScreen" />
<java-symbol type="style" name="Theme.Dialog.RecentApplications" />
@@ -1457,40 +1295,6 @@
<java-symbol type="style" name="Widget.Button.NumPadKey" />
<java-symbol type="style" name="TextAppearance.NumPadKey" />
<java-symbol type="style" name="TextAppearance.NumPadKey.Klondike" />
- <java-symbol type="string" name="kg_emergency_call_label" />
- <java-symbol type="string" name="kg_forgot_pattern_button_text" />
- <java-symbol type="string" name="kg_wrong_pattern" />
- <java-symbol type="string" name="kg_wrong_password" />
- <java-symbol type="string" name="kg_wrong_pin" />
- <java-symbol type="string" name="kg_too_many_failed_attempts_countdown" />
- <java-symbol type="string" name="kg_pattern_instructions" />
- <java-symbol type="string" name="kg_sim_pin_instructions" />
- <java-symbol type="string" name="kg_pin_instructions" />
- <java-symbol type="string" name="kg_password_instructions" />
- <java-symbol type="string" name="kg_puk_enter_puk_hint" />
- <java-symbol type="string" name="kg_puk_enter_pin_hint" />
- <java-symbol type="string" name="kg_sim_unlock_progress_dialog_message" />
- <java-symbol type="string" name="kg_password_wrong_pin_code" />
- <java-symbol type="string" name="kg_invalid_sim_pin_hint" />
- <java-symbol type="string" name="kg_invalid_sim_puk_hint" />
- <java-symbol type="string" name="kg_invalid_puk" />
- <java-symbol type="string" name="kg_login_too_many_attempts" />
- <java-symbol type="string" name="kg_login_instructions" />
- <java-symbol type="string" name="kg_login_username_hint" />
- <java-symbol type="string" name="kg_login_password_hint" />
- <java-symbol type="string" name="kg_login_submit_button" />
- <java-symbol type="string" name="kg_login_invalid_input" />
- <java-symbol type="string" name="kg_login_account_recovery_hint" />
- <java-symbol type="string" name="kg_login_checking_password" />
- <java-symbol type="string" name="kg_too_many_failed_pin_attempts_dialog_message" />
- <java-symbol type="string" name="kg_too_many_failed_pattern_attempts_dialog_message" />
- <java-symbol type="string" name="kg_too_many_failed_password_attempts_dialog_message" />
- <java-symbol type="string" name="kg_failed_attempts_almost_at_wipe" />
- <java-symbol type="string" name="kg_failed_attempts_now_wiping" />
- <java-symbol type="string" name="kg_failed_attempts_almost_at_login" />
- <java-symbol type="string" name="kg_enter_confirm_pin_hint" />
- <java-symbol type="string" name="kg_invalid_confirm_pin_hint" />
- <java-symbol type="string" name="kg_text_message_separator" />
<!-- From services -->
<java-symbol type="anim" name="screen_rotate_0_enter" />
@@ -1717,6 +1521,9 @@
<java-symbol type="anim" name="push_down_out" />
<java-symbol type="anim" name="push_up_in" />
<java-symbol type="anim" name="push_up_out" />
+ <java-symbol type="anim" name="lock_screen_wallpaper_behind_enter" />
+ <java-symbol type="anim" name="lock_screen_behind_enter" />
+
<java-symbol type="bool" name="config_alwaysUseCdmaRssi" />
<java-symbol type="dimen" name="status_bar_icon_size" />
<java-symbol type="dimen" name="system_bar_icon_size" />